最新消息:图 床

Nday 漏洞從挖掘到利用

COOL IAM 230浏览 0评论

作者: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是我們可控數據且沒有做大小檢查,a3outputStruct地址,也就是說如果我們進入memcpy分支,同樣可以做到一個信息泄漏。

0x01.漏洞利用

這裡我用來做提權的有兩個漏洞,queryCompletion我們可以通過參數來控制越界call,這個的利用就比較簡單,直接通過堆噴構造數據然後泄漏kslide做ROP即可,但是我們在10.13上需要尋找新的gadget,上一次還用的是project-zeropwn4fun上用的一個,一開始我的思路有問題,總想着有這樣一個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的undefinecode來找到我們需要的gadget,這樣的話很快就能找到了,但是我因為思路問題卡了兩天。

接下來就是需要一個info leak來泄漏kslide了。

我一開始找到的一個infoleakReadRegister32,但是這個限制比較多,只能從一個很靠後的地址往後讀,後面基本沒有什麼有效信息了,也不會有對象來給我們計算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的分支:

  1. v5有效
  2. *(v5+0x1dc)不為0
  3. *(v5 + 0x3f70 )是一個有效內核地址
  4. *(*(v5 + 0x3f70 ) + 0x100 )為0

並且要想泄漏kslide還需要滿足一個條件,那就是從(v5 + 0x2170)(v5 + 0x2170 + 0x1d8)的地址上存在着有效數據供我們使用。

我剛一看,就有兩個想法:

就地解決

在這個對象內部來找,看看有沒有合適的,這是最簡單的一種做法,後來我在一次實驗中在偏移0x1398處找到了符合條件的,當時十分高興:

mac OS X internals 第九章


转载请注明:IAMCOOL » Nday 漏洞從挖掘到利用

0 0 vote
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x