1. 程式人生 > >棧溢位之Return2libc

棧溢位之Return2libc

參考文章:https://zhuanlan.zhihu.com/p/25816426

我們利用函式呼叫來實現攻擊,核心目的是用攻擊指令的地址來覆蓋返回地址

通常用的有以下四種方法:

修改返回地址,讓其指向溢位資料中的一段指令(shellcode)
修改返回地址,讓其指向記憶體中已有的某個函式(return2libc)
修改返回地址,讓其指向記憶體中已有的一段指令(ROP)
修改某個被呼叫函式的地址,讓其指向另一個函式(hijack GOT)

上次我們講解了一下shellcode,其適合於NX和PIE都不開啟的情況下,但是這種情況幾乎是遇不到的,所以這次我們來了解一下Return2libc

從上面的描述我們知道,要完成的任務包括:在記憶體中確定某個函式的地址,並用其覆蓋掉返回地址

由於 libc 動態連結庫中的函式被廣泛使用,所以有很大概率可以在記憶體中找到該動態庫。同時由於該庫包含了一些系統級的函式(例如 system() 等),所以通常使用這些系統級函式來獲得當前程序的控制權。

鑑於要執行的函式可能需要引數,比如呼叫 system() 函式開啟 shell 的完整形式為 system(“/bin/sh”) ,所以溢位資料也要包括必要的引數。

上圖即為return2libc 所用溢位資料的構造。

padding1處的資料可以隨意填充(注意不要包含 “\x00” ,否則向程式傳入溢位資料時會造成截斷),長度應該剛好覆蓋函式的基地址。其長度的確定可以通過跟shellcode一樣的,在執行程式時用不斷增加輸入長度的方法來試探。

address of system() 是 system() 在記憶體中的地址,用來覆蓋返回地址。該地址如何確定呢?我們可能需要了解一下動態連結庫的知識:
當函式被動態連結至程式中,程式在執行時首先確定動態連結庫在記憶體的起始地址,再加上函式在動態庫中的相對偏移量,最終得到函式在記憶體的絕對地址。

但是如果作業系統打開了 ASLR(記憶體佈局隨機化),程式每次執行時動態庫的起始地址都會變化,也就無從確定庫內函式的絕對地址。在 ASLR 被關閉的前提下,我們可以通過除錯工具在執行程式過程中直接檢視 system() 的地址,也可以檢視動態庫在記憶體的起始地址,再在動態庫內檢視函式的相對偏移位置,通過計算得到函式的絕對地址。

padding2處的資料長度為4(32位機),對應呼叫 system() 時的返回地址。因為我們在這裡只需要開啟 shell 就可以,並不關心從 shell 退出之後的行為,所以 padding2 的內容可以隨意填充。

address of “/bin/sh”是字串 “/bin/sh” 在記憶體中的地址,作為傳給 system() 的引數。

關於ROP和hijack GOT我就不當文字的搬運工了,大家看這裡吧:
長亭科技牛逼!好想加入啊~加油加油加油~