You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I finally figure out that the leak function overwrites some part of environ on the stack, which leads to failure of execve inside system...
But why the DynELF needs to write something onto stack to find addr of an exported symbol? According doc of pwntools, it compares the hash of, like 'printf' to the content of an addr. So only reading should work.
DynELF leak函数导致堆栈不平衡
Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击
根据蒸米大牛的文章,在没有目标
libc.so
的情况下,如何进行ROP
攻击exp
代码我的环境会出现这种情况
之后进行了各种调试,各种测试
payload
,但是都没有找到问题,在寻找解决方法时,在pwntools
的issue
里找到了,是这么说的他出现的问题和
gdb
调试出现的问题,与我一模一样。说是
leak
函数覆盖了栈,导致环境变量被更改,从而造成system
执行失败,那我们就来测试排查
首先看一下
leak
函数根据上面的输出,
leak
函数会不断执行,会一直进行如下循环在这个循环的过程中,真的有可能会造成栈被破坏吗?
利用
gdb.attach
进行附加测试,代码做一下更改执行,并观察栈的变化
成功附加
继续执行,注意查看栈
再次继续执行
比上一次增加了8,再次执行验证
同样也是增加了8,如果继续
continue
,会发现结果也是一样的,每次执行leak
一次,esp
便会增加8个字节。至于为什么会每次执行都会把栈增加8个字节,其实很好理解,正常汇编调用函数每次都会把当前指令压入栈,执行完函数弹出eip
,但是我们通过覆盖的方式直接调用可以发现每个函数会相差4个字节,俩函数就是8个字节。理论上也解释通了。现在需要每次执行
leak
函数后把栈平衡了,需要做的就是sub esp, 8
,这个问题想了很久也没有找到办法。ROPGadget
搜索不到合适的指令。最后发现网上依然有大牛解决了,详细看参考PWN——堆栈平衡的考虑
他的解决方案:
测试跳转到
main
函数断在
vulnerable_function
继续执行
一直执行下去也是一样,确实每次执行
esp
都会减少0x10
个字节,所以需要寻找栈平衡,其实跟我们上面那个是一样的,pop|pop|pop|ret
那我们就再改写
leak
,再次测试首先看一下栈是否平衡了
多次执行可以发现,目前栈已经平衡了,再看看能否
getshell
成功执行
其中我的方法和
purpleroc
大牛的解决方法不太一样,而且大牛应该有个地方误解或者没有想清楚,也有可能没有说清楚,他的payload
后面的一部分没用(但确实是可以使用的!)这样就可以了
后面那个
add_esp
直接会被略过add_esp
的方案,我也使用了,也测试了,其中add_esp
处的指令是这样的可以看到具体汇编指令,也会明白,执行完第一个
add_esp
直接会将esp增加0x10个字节其他解决方案
上面的方法是从原理上比较原始的解决了我们遇到的问题,但是有没有更加优美的解决方案呢?
有!直接通过
pwntools
的ROP
模块win.py
执行试试
可以发现其中利用
ROP
构造的gadgets
会自动进行栈平衡,并且注意这句利用
read
的got
地址减去read
的plt
地址就可以得到libc
的地址,这个暂时还没有理解是为什么,并且这种方法的优势是相当于只用一次leak
即可找到libc.address
,这样即使栈会被覆盖部分数据,正常情况下也不会对getshell
产生较大影响利用
vulnerable_function
测试多次测试,每次测试都可以成功
getshell
通过
rop
的leak
方式win2.py
但是这种方式不知因何原因只能执行一次命令,之后就退出了,想了各种方法也没有调试出原因
总结
解决这个问题,花费了自己挺长时间的,从发现不能成功执行,到解决栈平衡的问题,想了各种各样的办法,最后收获也挺大
参考
蒸米:一步一步学ROP之linux_x64篇
PWN——堆栈平衡的考虑
pwntools issue: pwnlib.dynelf.DynELF breaks something to make exploit broken
gist:win.py
gist:win2.py
The text was updated successfully, but these errors were encountered: