ISITDTU CTF 2019 writeups
TOC
不算很难的国际赛,但是比赛的服务器是真的差,题目质量还算可以,就是体验不太好。
题目文件:isitdtu_ctf_2019.zip 。
pwn
iz_heap_lv1
溢出点
qword_602060
长度为20,但是我们使用的长度却是21,所以可以直接使用name
控制指针。
.bss:0000000000602060 qword_602060 dq 20 dup(?) ; DATA XREF: Add+21↑o |
思路
- 填满
tcache
,泄漏libc基地址。 - 劫持
hook
。
脚本
##!/usr/bin/python2 |
iz_heap_lv2
溢出点
read_n_off_by_one
函数存在off by one
。
.text:000000000040091E read_n_off_by_one proc near ; CODE XREF: get_int+28↑p |
思路
- unlink
- 泄露got.puts计算libc基地址
- 控制hook
脚本
##!/usr/bin/python2 |
babyshellcode
后面的pwn题都是赛时没做出来的,根据大佬的writeup复现的,感觉后面两道题都不难,最后那一道prisonbreak
才是真的难,只能怪自己粗心。
安全防护
ex@Ex:~/isitdtu$ checksec babyshellcode |
分析
这题初始化的时候把基本上所有的系统调用都禁了:
void __cdecl set_seccomp() |
刚开始我也很困惑,以为解法是要绕过seccomp
,赛后看了大佬的writeup才知道,原来出题人在.init
段里还有一段初始化函数,而且是混淆过的,只有调试才能知道函数的具体行为。比赛的时候根本没注意这个函数。
其函数如下:
其功能是先用access
判断/flag
是否可读,然后mmap
申请0xcafe000
这个固定地址,再open
并read
出flag
到0xcafe000
上。然后读取8个随机字符和flag进行异或。
这题如果没注意到这点,程序在判断/flag
是否可读时,就会直接判读失败,从而不会执行后面的代码,所以这里需要我们用心去看汇编。
思路
由于flag只有0x28
个字节,所以还有剩余的8个字节就是'\0'
,那么在和8
个随机字符异或时,则结果就相当于赋值了一遍。
虽然我们不能用系统调用了,但我们可以利用延时注入技术,通过三次握手和收到分手包的时间差来逐个判断字符,利用0x28-0x30
的值对flag进行异或就能还原flag。
原理就是判断错误直接系统调用从而crash,成功则不停循环。
脚本
##!/usr/bin/python2 |
运行结果:
x@Ex:~/isitdtu$ python exp.py |
Tokenizer
安全防护
ex@Ex:~/isitdtu$ checksec tokenizer |
溢出点
程序先是接受要处理的字符串,然后接受要分割的字符,之后把字符切割开来,分割用的函数是strsep
,在strsep
函数中,有这样一句话This token is terminated by overwriting the delimiter with a null byte ('\0')
,所以该函数会更改原字符串,并且字符串是在栈上处理的,当字符串长度填充为0x400
时,则字符串将会和上一层函数保存的rbp
相连,这时候我们就能用strsep
函数对rbp
进行更改。
也就是当字符串填充满时,就会泄露栈地址。
sh.sendline('a' * 0x3f8 + 'b' * 8) |
执行后结果如下:
pwndbg> search -s bbbbbbbb stack |
这时候delimiters
输入为\xf0
的话就能将该[rbp]
低位写0。
思路
- 为了方便调试,关闭随机化
- 构造好payload,泄露libc基地址
- 返回main函数
- 改写返回地址为system
构造payload的时候,由于strsep
函数会被\0
截断,所以需要提前将\0
替换成delimiters
,这样它们就会被strsep
函数写为\0
,但是我们不能提前知道[rsp]
的低位是什么,所以需要进行爆破,概率是1/16
。
可以把返回main函数(重新开始),换成接受新的payload,但是觉得payload可能不够,所以还是选择返回main比较好点。
脚本
##!/usr/bin/python2 |
运行结果:
ex@Ex:~/isitdtu$ ./exp.sh toke.py |
RE
Recovery
就是排序二叉树的还原。
import java.util.Arrays; |
还原之后便能得到答案。
509, 278, 9, 201, 101, 61, 11, 48, 38, 33, 35, 40, 44, 89, 85, 106, 180, 135, 110, 159, 150, 200, 188, 241, 214, 253, 269, 268, 275, 358, 356, 327, 285, 301, 301, 381, 363, 476, 471, 428, 399, 396, 413, 449, 434, 445, 462, 497, 496, 492, 481, 634, 628, 540, 520, 526, 534, 589, 621, 599, 613, 621, 623, 965, 658, 652, 650, 653, 946, 877, 708, 679, 665, 691, 836, 764, 716, 711, 722, 752, 756, 827, 808, 771, 773, 786, 807, 826, 842, 867, 856, 875, 922, 889, 879, 892, 951, 993, 980, 996 |