Ghidra 从 XXE 到 RCE
作者:腾讯安全玄武实验室 tomato, salt
0x00 背景
Ghidra是 NSA 发布的一款反汇编工具,它的发布引起了安全研究人员的极大兴趣。
有研究人员发现Ghidra在加载工程时会存在XXE,基于笔者之前对XXE漏洞利用研究发现,攻击者可以利用Java中的特性以及Windows操作系统中NTLM认证协议的缺陷的组合来完成RCE。
0x01 技术细节
Java在使用内置类 sun.net.www.protocol.http.HttpURLConnection
发送HTTP请求遇到状态码为401的HTTP返回头时,会判断该页面要求使用哪种认证方式,若采用的NTLM认证则会自动使用当前用户凭据进行认证。
其根本原因在于Windows下的Java默认启用了透明NTLM认证,并且将所有由外部传入的URL地址都认为是可信的。如下面代码段所示
sun.net.www.protocol.http.AuthScheme#NTLM
1 | if (tryTransparentNTLMServer) { |
再跟入NTLMAuthenticationProxy.isTrustedSite
方法
1 | public static boolean isTrustedSite(URL url) { |
通过反射调用了sun.net.www.protocol.http.ntlm.NTLMAuthentication
中的isTrustedSite
方法,在此方法中将所有外部传入的URL都判定为可信的。
攻击者通过搭建基于NTLM认证的HTTP Server即可获取到当前用户的Net-NTLM Hash。
我们再来看NTLM认证协议的缺陷。NTLM认证协议中存在一种很古老的攻击的技术,被称作为NTLM Relay攻击。此攻击的原理网上已经有很多文章进行说明,在此不再赘述。
但在此次漏洞利用方式中我们使用的凭据反射攻击,即为攻击者将受害者的Net-NTLM Hash再次Relay给受害者,达到以彼之道还施彼身的效果。
下面来看看这个过程的具体实现,攻击者首先搭建基于NTLM认证的恶意HTTP Server,然后通过XXE/SSRF等漏洞使受害者向恶意的HTTP Server进行NTLM认证。
值得注意的是,NTLM认证分为两个版本NTLMv1和NTLMv2,在进行NTLMv1类型认证时攻击将获取到的Net-NTLM Hash直接Relay给受害者的SMB服务即可,但是在使用NTLMv2类型认证时,攻击者在Relay时需要将NTLM认证中Type 2 Message的Negotiate Flags进行修改,将Negotiate Always Sign与Negotiate 0x00004000 两个标志位从设置改为不设置,这其中具体代表的含义为让此次认证被认作在网络上(Relay给本机会被当做是一次本地认证)进行以及将认证中的签名进行去除。
为完成该攻击过程,笔者已经编写好脚本。
0x03 复现步骤
受害者环境 Oracle JDK 8u161、Win10、Administrator账户
攻击者环境 Ubuntu16.04 IP为192.168.130.136
首先在局域网内另一台机器上运行前面提到的脚本
1 | python ultrarelay.py -ip 192.168.130.136 -smb2support |
脚本将会在80端口开启HTTP服务。然后回到Win10中新建一个Ghidra工程,修改工程中的project.prp,插入XXE攻击代码,如下图所示
再次使用Ghidra打开此恶意工程,攻击者就能获取到受害者机器的NTLM Hash,也可通过脚本中的参数在受害者机器上执行任意命令。
0x04 防御措施
1.开启Windows防火墙,禁止外部请求访问SMB服务
2.若要提供SMB服务 则建议开启SMB Sign
3.升级JDK至最新版本