漏洞概述
VMware Tools没有正确的检查客户端请求的授权,导致包含一个本地权限提升漏洞,可以使虚拟机中的计算机账号由非管理员权限提升到管理员权限。
影响范围
Windows:
vm-tools:12.x.y,11.x.y 和10.x.y
Linux:
open-vm-tools:12.x.y,11.x.y和10.x.y
vm-tools:10.x.y
复现环境
操作系统:
Win7 sp1 32位操作系统,VMware Tools V11.3.5
分析工具:
IDA、OD、openssl、sigxml、procexp.exe
分析过程
根据官方公告,该提权漏洞是由VMware Tools导致的。VMwareTools是VMware客户机(guest)中安装的一套工具,可以提高虚拟机中安装的客户机操作系统性能并改善虚拟机管理。一般情况下,为了方便虚拟机中的客户机和真实主机(host)之间的交互,都会选择安装该工具。
既然是提权漏洞,应该和VMwareTools的高权限程序有关。先使用进程管理工具procexp.exe查看该工具安装后的常驻进程,可以看到与VMware相关的进程,有普通进程vmtoolsd.exe,服务进程 VGAuthService.exe、vm3dservice.exe和vmtoolsd.exe,其中服务进程均具有高权限,如下图所示:
同时,VMware开源了针对Linux系统的open-vm-tools工具的代码,可以看到,在补丁文件open-vm-
tools/vgauth/serviceImpl/proto.c中,增加了对公共管道请求的安全检查,只允许SessionRequest类型的请求通过,初步说明该提权漏洞与请求授权相关。如下图所示:
根据补丁文件proto.c代码,发现与服务进程VGAuthService.exe相关,该进程的服务名称为VGAuthService,显示名称为VMwareAlias Manager and TicketService。首先了解下VGAuthService.exe的大致功能,直接运行查看帮助,该程序的功能是针对VMware的产品,提供SAML令牌和票据身份验证。vm-tools安装后,该程序默认被安装为服务程序,如下图所示:
使用IDA打开VGAuthService.exe进行反编译,然后定位到补丁附近的代码。发现补丁代码是在一个名为Proto_SecurityCheckRequest(来自开源代码)的函数内部,该函数负责检查客户端请求的安全性。根据请求的类型,分别进行安全检查,检查通过后再调用对应的处理函数,处理完请求后返回结果,如下图所示:
那么究竟是什么请求导致了提权漏洞?
直接查看VGAuthService.exe的导入表和字符串,审计是否有提权相关的函数调用或者字符串。经过查找,发现权限相关的系统函数LsaLogonUser和字符串“SeTcbPrivilege”,如下图所示:
LsaLogonUser函数能够在不需要计算机账号密码的情况下,登录指定账号,登录成功后返回该账号的令牌(token),当然调用该函数的程序需要SeTcbPrivilege权限,该服务程序也拥有此权限。这似乎和提权漏洞密切相关,如果能够控制登录的账号,用管理员的账号登录,再创建指定进程,那么创建的进程将拥有管理员权限。
遗憾的是,该程序里并没有创建进程相关的函数调用。参考open-vm-
tools的开源代码以及逆向分析,发现该服务程序会将登录成功后的令牌复制给与自己通信的进程,如下图所示:
这似乎给提权又增加了一丝希望,那么剩下的问题是如何与这个服务程序进程通信,以及是否能控制LsaLogonUser函数的登录账号。
首先分析下如何与这个服务进程通信。可以从代码中看到,该程序中使用了管道“\\.\pipe\vgauth-
service”进行通信,并且没有权限限制,开源代码中称之为公共通道(public channel),与之相反的还有私有通道(privatechannel)。任何程序均可连接这个公共通道,连接成功后可以发送数据到该服务进程,也可以收到该服务程序返回的数据,如下图所示:
那么接下来分析如何控制LsaLogonUser函数登录的计算机账号。分析后发现,这个计算机账号来自于请求的数据中,是可以控制的。这个请求的名字为ValidateSamlBToken,对应的处理函数为ServiceProtoValidateSamlBearerToken。
为了控制LsaLogonUser函数登录的计算机账号,需要控制发送的请求数据,也就需要知道请求的数据格式。从处理请求的函数一步步倒着分析,找到读取和解析请求的函数,如下图所示:
从字符串比较函数中可以看到请求中的合法关键字,进一步分析发现,这些关键字需要组合成XML格式的请求数据。比如需要调用处理函数ServiceProtoValidateSamlBearerToken,请求的数据格式如下:
<?xml version="1.0" encoding="UTF-8" ?> <request> <sequenceNumber>【任意数字】</sequenceNumber> <requestName>ValidateSamlBToken</requestName> <samlToken>【samlToken数据】</samlToken> <userName>【计算机用户账号】</userName> <validateOnly>【是否只验证,不返回令牌】</validateOnly> </request>
其中request表示包含请求数据,sequenceNumber表示请求的序号,无校验,可以是任意数字;requestName表示请求的名称,不同的请求名称将调用不同的处理函数;剩下字段是请求的参数信息,不同的请求名称可能需要不同的参数。示例中的userName表示请求的计算机账号,也就是可能传递给LsaLogonUser函数的账号;validateOnly表示是否只验证,不返回Token,比如需要使用认证成功后的令牌,则需要设置该参数为1;samlToken表示认证需要的SAML格式的数据。
如果要获取到返回的令牌,该认证必须要验证通过,要想验证通过则必须要保证SAML数据正确,而且计算机账号必须是存在的。那么问题来了,传递什么样的SAML数据,才能通过这个认证,获取到返回的令牌数据?
那什么是SAML?
SAML是安全断言标记语言(Security Assertion Markup
Language),是一个基于XML的开源标准数据格式,用于交换身份验证和授权数据,经常应用于WEB系统的单点登录功能。详细的介绍和数据格式等问题读者可以自行搜索,这里主要分析该服务程序验证需要的一些SAML数据。
验证SAML数据的相关函数为SAML_VerifyBearerTokenAndChain。在该函数中,先使用函数VerifySAMLToken验证SAML格式的正确性,然后使用函数ServiceVerifyAndCheckTrustCertChainForSubject对证书和Subject的认证,如下图所示:
在函数VerifySAMLToken中,验证SAML格式的正确性。首先要满足SAML格式要求,比如需要有Subject,Conditions等关键字,还要有表示有效时间NotBefore,NotOnOrAfter关键字,如下图所示:
还需要有X509证书以及签名数据,X509证书可以借助开源工具openssl生成自签名的证书,但签名数据的计算可难住了笔者。在查阅了大量资料和尝试后,终于使用开源的signxml完成了SAML的签名计算,通过了该验证函数。一个有效的SAML数据如下图所示:
在函数ServiceVerifyAndCheckTrustCertChainForSubject中,会验证请求的计算机账号是否存在,存在后,再读取默认配置情况下的证书存储文件C:\ProgramData\VMware\VMware
VGAuth\aliasStore\user-【计算机账号】.xml或者C:\ProgramData\VMware\VMware
VGAuth\aliasStore\mapping.xml的内容,然后和请求的x509证书和Subject字段进行比较,如果相同,则通过验证;否则验证失败,如下图所示:
如果VerifySAMLToken和ServiceVerifyAndCheckTrustCertChainForSubject均通过了验证,则进入WinToken_GenerateTokenForUser使用LsaLogonUser登录请求的计算机账号,最后把登录成功的令牌复制给客户端程序,并将令牌数据作为请求的回应消息发送给客户端程序,如下图所示:
到现在为止,已经把可能产生提权漏洞的请求ValidateSamlBToken对应的处理函数ServiceProtoValidateSamlBearerToken分析完毕,是不是就可以利用漏洞了呢?
其实还有一个问题没有解决,那就是上面提到的保存x509证书和Subject数据的两个文件user-【计算机账号】.xml和mapping.xml是如何来的。如果没有这两个文件,认证是会失败的,必然也不会调用LsaLogonUser。那怎么才能产生这两个文件?经过交叉引用分析,这两个文件可以由另外一个请求AddAlias产生,其对应的处理函数为ServiceAliasAddAlias。这个请求的数据格式如下:
<?xml version="1.0" encoding="UTF-8" ?> <request> <sequenceNumber>【任意数字】</sequenceNumber> <requestName>AddAlias</requestName> <userName>【计算机用户账号】</userName> <addMappedLink>【是否生成xml文件,需要,则设置为1】</addMappedLink> <pemCert>【x509证书】</pemCert> <aliasInfo> <subject>【subject名字,需要与验证请求一致】</subject> <comment>【任意字符】</comment> </aliasInfo> </request>
在这个请求的处理函数ServiceAliasAddAlias中,首先会检查请求的计算机用户账号是否存在,如果存在,则再验证证书格式是否正确,正确后再将证书和Subject数据写入user-【计算机账号】.xml和mapping.xml文件中保存,以便认证时使用,如下图所示:
到现在为止,可以通过AddAlias请求添加证书文件user-【计算机账号】.xml和mapping.xml文件,然后再发送ValidateSamlBToken请求,认证刚才添加的证书文件,认证成功后使用LsaLogonUser登录,最后获取登录成功后的令牌,完成漏洞利用。
但是还忽略了一个问题,那就是请求中的计算机账号可以任意指定?
虽然请求中的计算机账号是可以控制的,但是别忘了在最开始分析的时候,补丁附近还有Proto_SecurityCheckRequest函数负责检查请求的安全性。在这个函数中,会检查连接是否来自公共通道,也就是是否来自管道“\\.\pipe\vgauth-
service”,这正是现在使用的管道,如下图所示:
如果是,则默认认为该连接是不安全的,并设置该管道的拥有者计算机账号为system,然后会增加额外的安全检查,在AddAlias请求的时候,如果请求的计算机账号名不是system,则会请求失败。也就是说目前只能添加system账号的证书数据,但是认证的时候使用LsaLogonUser登录system账号会失败,查询一番后发现不能使用system账号登录,导致漏洞利用失败。
那么怎么利用这个漏洞呢,还有哪些代码没分析清楚,可以导致提权漏洞的呢?
未完待续,敬请期待。
网络安全学习路线&资源
【----帮助网安学习,以下所有学习资料免费领!】
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)
![](https://i-blog.csdnimg.cn/blog_migrate/6324eb7f8d7ad2a016bbd1726229e9ff.png)
03网络安全的知识多而杂,怎么科学合理安排?
下面给大家总结了一套适用于网安零基础的学习路线,应届生和转行人员都适用,学完保底6k!就算你底子差,如果能趁着网安良好的发展势头不断学习,日后跳槽大厂、拿到百万年薪也不是不可能!
初级网工
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)
2、渗透测试基础(一周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等
3、操作系统基础(一周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)
4、计算机网络基础(一周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现
5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固
6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)
恭喜你,如果学到这里,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web 渗透、安全服务、安全分析等岗位;如果等保模块学的好,还可以从事等保工程师。薪资区间6k-15k
到此为止,大概1个月的时间。你已经成为了一名“脚本小子”。那么你还想往下探索吗?
7、脚本编程(初级/中级/高级)
在网络安全领域。是否具备编程能力是“脚本小子”和真正黑客的本质区别。在实际的渗透测试过程中,面对复杂多变的网络环境,当常用工具不能满足实际需求的时候,往往需要对现有工具进行扩展,或者编写符合我们要求的工具、自动化脚本,这个时候就需要具备一定的编程能力。在分秒必争的CTF竞赛中,想要高效地使用自制的脚本工具来实现各种目的,更是需要拥有编程能力.
零基础入门,建议选择脚本语言Python/PHP/Go/Java中的一种,对常用库进行编程学习; 搭建开发环境和选择IDE,PHP环境推荐Wamp和XAMPP, IDE强烈推荐Sublime; ·Python编程学习,学习内容包含:语法、正则、文件、 网络、多线程等常用库,推荐《Python核心编程》,不要看完; ·用Python编写漏洞的exp,然后写一个简单的网络爬虫; ·PHP基本语法学习并书写一个简单的博客系统; 熟悉MVC架构,并试着学习一个PHP框架或者Python框架 (可选); ·了解Bootstrap的布局或者CSS。
8、超级网工
这部分内容对零基础的同学来说还比较遥远,就不展开细说了,贴一个大概的路线。感兴趣的童鞋可以研究一下,不懂得地方可以【点这里】加我耗油,跟我学习交流一下。
网络安全学习路线&学习资源
扫描下方卡片可获取最新的网络安全资料合集(包括200本电子书、标准题库、CTF赛前资料、常用工具、知识脑图等)助力大家提升进阶!
![](https://i-blog.csdnimg.cn/blog_migrate/6324eb7f8d7ad2a016bbd1726229e9ff.png)
结语
网络安全产业就像一个江湖,各色人等聚集。相对于欧美国家基础扎实(懂加密、会防护、能挖洞、擅工程)的众多名门正派,我国的人才更多的属于旁门左道(很多白帽子可能会不服气),因此在未来的人才培养和建设上,需要调整结构,鼓励更多的人去做“正向”的、结合“业务”与“数据”、“自动化”的“体系、建设”,才能解人才之渴,真正的为社会全面互联网化提供安全保障。
特别声明:
此教程为纯技术分享!本书的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本书的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失!!!