作者:腾讯安全玄武实验室 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
2
3
4
5
6
7
8
9
10
11
if (tryTransparentNTLMServer) {
tryTransparentNTLMServer =
NTLMAuthenticationProxy.supportsTransparentAuth;
/* If the platform supports transparent authentication
* then check if we are in a secure environment
* whether, or not, we should try transparent authentication.*/
if (tryTransparentNTLMServer) {
tryTransparentNTLMServer =
NTLMAuthenticationProxy.isTrustedSite(url);
}
}

再跟入NTLMAuthenticationProxy.isTrustedSite方法

1
2
3
4
5
6
7
8
9
public static boolean isTrustedSite(URL url) {
try {
return (Boolean)isTrustedSite.invoke(null, url);
} catch (ReflectiveOperationException roe) {
finest(roe);
}

return false;
}

通过反射调用了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至最新版本

0x05 参考资料

https://twitter.com/sghctoma/status/1103392091009413120

https://conference.hitb.org/hitbsecconf2018dxb/materials/D2T2%20-%20NTLM%20Relay%20Is%20Dead%20Long%20Live%20NTLM%20Relay%20-%20Jianing%20Wang%20and%20Junyu%20Zhou.pdf