6.1.5 pwn GreHackCTF2017 beerfighter
题目复现
$ file game
game: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=1f9b11cb913afcbbbf9cb615709b3c62b2fdb5a2, stripped
$ checksec -f game
RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH No 0 0 game64 位,静态链接,stripped。
既然是个小游戏,先玩一下,然后发现,进入 City Hall 后,有一个可以输入字符串的地方,然而即使我们什么也不输入,直接回车,在 Leave the town 时也会出现 Segmentation fault:
[0] The bar
[1] The City Hall
[2] The dark yard
[3] Leave the town for ever
Type your action number > 1
Welcome Newcomer! I am the mayor of this small town and my role is to register the names of its citizens.
How should I call you?
[0] Tell him your name
[1] Leave
Type your action number > 0
Type your character name here >
...
[0] The bar
[1] The City Hall
[2] The dark yard
[3] Leave the town for ever
Type your action number > 3
By !
Segmentation fault (core dumped)题目解析
程序大概清楚了,看代码吧,经过一番搜索,发现了一个很有意思的函数:
syscall;ret,你想到了什么,对,就是前面讲的 SROP。
其实前面的输入一个字符串,程序也是通过 syscall 来读入的,从函数 0x004004b8 开始仔细跟踪代码后就会知道,系统调用为 read()。
缓冲区还挺大的,1040+8=1048。
漏洞利用
好,现在思路已经清晰了,先利用缓冲区溢出漏洞,用 syscall;ret 地址覆盖返回地址,通过 frame_1 调用 read() 读入 frame_2 到 .data 段(这个程序没有.bss,而且.data可写),然后将栈转移过去,调用 execve() 执行“/bin/sh”,从而拿到 shell。
构造 sigreturn:
然后是 frame_1,通过设定 frame_1.rsp = base_addr 来转移栈:
frame_2 执行 execve():
Bingo!!!
exploit
完整的 exp 如下:
参考资料
Last updated
Was this helpful?