*CTF2019 PWN quicksort
TOC
源文件、IDA分析文件、修复文件打包下载:quicksort.zip 。
该题主要考验的是对栈的构造能力,以及对算法的简单了解。
程序功能介绍
安全防护
ex@Ex:~/test$ checksec ./quicksort |
主要代码
void __cdecl main_function() |
分析
gets(user_input)
明显存在溢出。只要我们合理的构造栈布局就可以控制程序流了。
栈布局
-0000002C user_input db 16 dup(?) |
思路
- 泄露基地址
- getshell
泄露基地址
这里关键是要控制利用sort函数来控制数据流,这里我主要是控制got表。
ex@ubuntu:~/test$ readelf --dyn-syms quicksort |
主要思路是劫持array_ptr,然后劫持got表,将free
修改为main函数的地址,这样在程序结尾处调用free
的时候,又会重新运行一遍main
,而且即使sort之后,下面两个顺序也不会变,这个很重要,所以一定要控制好这个。
3: 00000000 0 FUNC GLOBAL DEFAULT UND gets@GLIBC_2.0 (2) |
sh.recvuntil('how many numbers do you want to sort?\n') |
由于p32函数不支持负数,所以main_addr
需要自行转换为int类型。
getshell
# again |
上面的代码可主要分为两部分。
把free改成system
system_addr_int = struct.unpack('i', p32(system_addr))[0] |
后面在调用free的时候就相当于直接调用system。
把sh 写入到bss部分
temp_int = struct.unpack('i', 'sh\0\0')[0] |
这里把array_ptr
指向了bss段,并把sh
写入到bss段,elf.bss() + 0x100
中的0x100
是为了防止换行截断。
完整脚本
#!/usr/bin/python2 |
运行实例
ex@ubuntu:~/test$ ./exp.py |
修复
原理是在文件的’\x00’填充部分写一个跳转函数,在这个跳转函数里面设置每次接受的字符数目。
修改导入表
将导入表中的
gets
修改为read
,这个直接用vim
编辑器就可以做到了。填充指令
将我们的指令填充在
0x8048C90
处,具体指令如下。push 16
push DWORD PTR 8[esp]
push 0
call _read
add esp, 12
retpatched
将下面的指令,
8048901: e8 fa fb ff ff call 8048500 <gets@plt>
修改为如下的指令:
8048901: e8 8a 03 00 00 call 8048c90 <_IO_stdin_used@@Base+0x214>
这样栈溢出的漏洞就被修复了,修复文件在上面的下载包里。
总结
这题还是比较综合的,不仅考验对栈的构建,还有排序算法需要我们对其进行控制。