作者:Peterpan0927@360 nirvan team
博客:https://peterpan980927.cn
use two vul and heap srpay twice
0x00.漏洞挖掘
這算是我的一個小練手吧,寫的不是很好,主要是思路分享
queryCompletion in AVEBridge
由於com.apple.AVEBridge
這個模塊中的函數比較少,於是我就寫了一個比較小的C語言腳本來Fuzz
一下,這個比較簡單,所以一下子就找到了:
mov rdi, [rdi+rsi*8+168]
...
call qword ptr [rax+0x1c8]
這裡rsi
是我們可控的一個參數,這裡相當於我們可以劫持控制流做ROP
進行提權,但還需要一個信息泄漏作為配合。
ReadRegister32
這是我在另一個模塊AppleIntelFramebufferAzul
中找到的一個漏洞,因為我的目的很明確,就是需要信息泄漏,所以我就從有類似特徵的函數進行入手了,如函數名位Readxxx
,有memcpy
類似的函數。
這個函數也十分簡單:
__int64 __fastcall AppleIntelAzulController::ReadRegister32(...){
...
return *(a2 + a3);
}
通過逆向和調試我找到了這個函數的最上級調用是從IntelFBClientControl::actionWrapper
函數開始的,通過調試我們發現傳到ReadRegister32
的參數a3
是用戶空間可控的,且沒有做任何邊界檢查,也就是說這個是一個越界讀,並且在它的上級函數中發現:
case 0x852:
*(a5+2) = AppleIntelAzulController::ReadRegister32(*(this+2), *a3);
而這個a5
正好是IOConnectCallMethod
中要傳回用戶空間的那個outputStruct
的地址,也就是說這是一個信息泄漏
getDisplayPipeCapability
這也是一個信息泄漏的問題,同樣在AppleIntelFramebufferAzul
中,首先來看看一部分代碼:
//a1是this指針
v5 = *(a1+ 8 * *a2 + 0xf60);
if ( v5 ){
if( *( v5 + 0x1dc ) && ( ! *(*(v5 + 0x3f70 ) + 0x100 ) ) ){
memcpy(a3, (v5 + 0x2170), 0x1d8);
*v3 = *v4
result = 0;
}
else{
...
}
}
else{
...
}
return result;
其中a2
是我們可控數據且沒有做大小檢查,a3
是outputStruct
地址,也就是說如果我們進入memcpy
分支,同樣可以做到一個信息泄漏。
0x01.漏洞利用
這裡我用來做提權的有兩個漏洞,queryCompletion
我們可以通過參數來控制越界call,這個的利用就比較簡單,直接通過堆噴構造數據然後泄漏kslide
做ROP即可,但是我們在10.13
上需要尋找新的gadget
,上一次還用的是project-zero
在pwn4fun
上用的一個,一開始我的思路有問題,總想着有這樣一個pattern
...
push rax
...
...
;... is no pop
pop rsp
...
...
;... didn't change rsp
ret
但是這樣毫無疑問是自己把自己給框住了,事實上可以存在這樣的一種pattern
...
push rax
pop rsp
...
...
;... didn't change rsp
ret
而且我們的出發點可以放在二進制搜索上,直接從切入一段機器碼,不需要理會其上下文,比如我們可以在ida中搜索:
50 5c
然後通過ida的undefine
和code
來找到我們需要的gadget
,這樣的話很快就能找到了,但是我因為思路問題卡了兩天。
接下來就是需要一個info leak來泄漏kslide
了。
我一開始找到的一個infoleak
是ReadRegister32
,但是這個限制比較多,只能從一個很靠後的地址往後讀,後面基本沒有什麼有效信息了,也不會有對象來給我們計算kslide
。所以我在嘗試了一段時間後放棄了
後來我又找到了一個,這個的利用條件相對來說也比較苛刻(我們可以控制*a2):
//a1是this指針
v5 = *(a1+ 8 * *a2 + 0xf60);
if ( v5 ){
if( *( v5 + 0x1dc ) && ( ! *(*(v5 + 0x3f70 ) + 0x100 ) ) ){
memcpy(a3, (v5 + 0x2170), 0x1d8);
*v3 = *v4
result = 0;
}
else{
...
}
}
else{
...
}
return result;
從上面可以看到我們需要滿足以下幾個條件才可以進入memcpy
的分支:
v5
有效*(v5+0x1dc)
不為0*(v5 + 0x3f70 )
是一個有效內核地址*(*(v5 + 0x3f70 ) + 0x100 )
為0
並且要想泄漏kslide
還需要滿足一個條件,那就是從(v5 + 0x2170)
到(v5 + 0x2170 + 0x1d8)
的地址上存在着有效數據供我們使用。
我剛一看,就有兩個想法:
就地解決
在這個對象內部來找,看看有沒有合適的,這是最簡單的一種做法,後來我在一次實驗中在偏移0x1398
處找到了符合條件的,當時十分高興:
mac OS X internals 第九章
转载请注明:IAMCOOL » Nday 漏洞從挖掘到利用