这个坑其实应该是初学者踩的,但是因为绝大部分栈题都是ret2libc,我又喜欢用ogg(ogg调用的是execve),所以今天打第五空间才遇到……
下午闲着没事看了看第五空间,pwn有道签到。没给libc,但因为是ret2text的缘故就直接拿16.04的虚拟机打了打,在本地秒了之后打不通远程,换成18之后在本地也打不通(已经进入system函数且rdi指向sh的情况下)然后学到了这个坑。
system
程序使用 system("echo ....")
来输出,导致无法调试,IDA中将 call system
patch成 nop
即可
栈
不同版本的情况下,栈上的偏移也不同
本题在16.04上的偏移是0x90,在18.04上是0x98
movaps
主要原因是system
中的movaps [rsp+198h+var_158], xmm0
指令要求rsp+198h+var_158
的值是对齐16byte
(0x10),否则会直接触发中断从而crash。
1 | .text:000000000004F2F1 movhps xmm0, [rsp+198h+var_190] |
很明显,这就是为什么在16上打得通,18上打不通,因为有0x8的偏差导致了执行到movaps
时会crash
解决方案
推荐方案:在padding后加一个ret,既可以改变栈的长度,又不影响rop链的执行
其他方案包括
1.改变payload长度
直接更改我们的payload长度,在栈溢出的时候栈的地址自然不同,然后将栈地址+1
,如果不行的话,就继续增加,最多也就改16次就一定会遇到栈对齐的情况。2.栈转移
当payload有长度限制的时候,我们可以尝试进行栈转移来进行栈地址的改变,如果遇到了没有对齐的情况就继续将栈地址+1
,直到遇到栈对齐的情况。3.调用execve
用execve函数来替换system函数,这个要求就更高,应为他需要三个参数才能正常调用。也就是说我们需要构造rdi
、rsi
、rdx
这三个参数。
经验教训
调试的时候可以看卡住的地方,结合汇编分析crash的原因
到这里之后,continue会一直卡在这里,往上面翻一下就能看到报错信息……之前一直没注意
可以看到已经crash了,这时候就该分析当前的汇编指令了