glibc版本大于2.27时xmm寄存器的干扰问题

发布于 11 天前  75 次阅读


调试一个程序时发现/bin/sh参数已经传入system,但并未拿到shell,最后才发现原来多了一个xmm寄存器的干扰。

下面看图:

rdi寄存器已经被传入/bin/sh参数,并且返回地址是system,接着调试发现执行了system但并没拿到shell,如下图:

查询资料得知glibc2.27之后引入了xmm寄存器,记录程序状态,其会执行movaps指令,要求rsp是按16字节对齐的(之前的栈对齐是按8字节对齐,与此处的对齐略有不同),因此是xmm寄存器的问题,当glibc版本大于2.27的时候,系统调用system("/bin/sh")之前有个xmm寄存器使用。要确保rsp是与16对齐的,也就是末尾必须是0。

payload如果按这样写:

p=flat(b'a'*(0x100+8),pop_rdi,sh,execve_addr,word_size=64)

弹出的数据是奇数个就会报错。

payload应按这样的形式写:

p=flat(b'a'*(0x100+8),ret,pop_rdi,sh,ret,execve_addr,word_size=64)

但如果是偶数个pop远程和本地就能打通,但需要刚开始有个ret抬高栈,然后中间一个ret实现rsp16字节对齐,即可远程和本地打通。

因为ubuntu版本, glibc版本等问题受到的困扰有不少, 不过一个个搜索/调试解决之后, 有了更深刻的认知/见解, 环境问题一直是pwn的老大难问题, 跨过这道槛就能逐渐体会到pwn的乐趣所在

pwn本身就是对环境高度依赖的技术,

补充:gdb调试时exp崩溃原因大概率是发送的数据的字长问题:

如下报错:

这是一个数字编码错误。 pack() 函数是 Python 中的二进制编码函数,它将数字编码为二进制格式并存储在字符串中。 number 参数表示要编码的数字,word_size 参数表示数字的字长。当 number 参数的值大于 word_size 时,会发生“数字不适合字长”错误。

解决方案:您可以通过更改 word_size 参数的值来解决此错误,如 word_size=64,以确保 number 参数的值适合字长。您也可以使用其他编码方法来存储数字,例如使用 struct 库的其他函数。


穿过云层我试着努力向你奔跑