这道rop题主要是考虑到rop链长度不够的问题,还有就是通过pop_ret调整参数位置使得其成功满足函数条件。这道题最大的收获就是做题要耐心,只要耐心思路清晰肯定能发现问题,一定不要急躁。
第一步还是分析文件格式和保护措施。
1 | [*] '/home/wood/pwn/i_chunqiu/ROP/lce_Ctf2016/ropi' |
1 | ropi: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.24, BuildID[sha1]=5e2ed875c2a5f3b2df94f42bd7f82893b288559f, not stripped |
文件32位并且没有PIE,然后先用IDA反汇编可以看到ezy函数中的read函数存在栈溢出。
1 | ssize_t ezy() |
然后观察这个文件里的其它函数,看看有没有什么其它奇怪的函数和system函数以及系统调用等。果然发现了几个很有用的函数。
1 | int __cdecl ret(int a1) #打开flag文件 |
1 | int __cdecl ori(int a1, int a2) #将flag文件内容写入dati中 |
1 | int pro() #输出dati中的内容 |
分析可知我们只需依次执行这三个函数,就可以拿到flag。然而构造完payload以后发现并没有成功获取flag,这时通过gdb.attach下断点动态调试(一般下在ret处),通过一些有用的命令(如下)查看内存中数据的情况,我发现了payload超出了read的读入范围,于是分两次payload将这三个函数依次调用,拿到了flag。
1 | stack --100 查看栈上的值 |
下面是这道题的exp
1 | from pwn import * |