BUUCTF - rip
刚看完 csapp 第三章程序的机器级表示,过来做道 pwn 题小试牛刀,实践一下(
ida 打开看一看,非常简单嗷
1 | char s[15]; // [rsp+1h] [rbp-Fh] BYREF |
同时还有一个 backdo♂or ,用 system 执行 shell ,就在 main 的下面
一看就知道是栈溢出了,通过构造过长的输入 s ,把要 ret 的地址给覆盖掉,从而达成跳转到后门函数的目的
gdb 进去看一下,可以发现 $rsp 在 df30 ,而 ret 的返回地址就在 df48
(这里我一开始以为要覆盖 gets 函数的 ret 地址,后来发现 gets 的返回地址肯定比外面的 $rsp 高,查了题解才知道要覆写 main 的返回地址)
输入 123 进去就可以看到 gets 是从 df31 开始填的(ida 看汇编也可以看到,s 的地址是 rbp - 0xf)
那么只需构造 23 个无意义字符,和后门地址就可以了
写完 exp 之后你会惊喜地发现两件事情:
第一件事是直接 recv 会什么都收不到,必须先 send 才能 recv ,不知道为什么
可以直接 send 然后进交互
第二件事是 exp 打上去之后等待你的不是 shell 而是 timeout: the monitored command dumped core
这个是因为 buuctf 最新使用的 ubuntu 18.04 要求 system 函数调用时栈指针必须 16 对齐(还有谁要对齐不知道)
因此要先原地 tp ,ret 到 ret 这个指令本身的地址,再 ret 一遍到后门,这时再调用 system 时栈就对齐了
exp:
1 | from pwn import * |