0x00 背景
OWASP Zed Attack Proxy 简称 ZAP,是一个开源的安全测试工具,功能和 Burpsuite 基本一样,它们同样使用 Java 语言编写,本人也曾有用过一段时间 ZAP,它完全可以替代 Burpsuite,不过也可能是由于先入为主的观念还是觉得 Burpsuite 用着更顺手。
自从 2021.12 月的 log4j2 JNDI 漏洞出现,ZAP 官方也随之更新了关于 ZAP 受到 log4j2 漏洞影响的公告,详情参见ZAP and Log4Shell
公告提到用户需升级到目前最新的 2.11.1 版本才会免于该漏洞的影响。
First the good news - ZAP does not typically log strings that could be used to exploit this vulnerability out of the box, so the exposure to this vulnerability should be limited.
If you have not changed the default ZAP Log4j settings and have not exposed the ZAP API to untrusted addresses (which we do not advise) then at this stage we believe that you will not be vulnerable.
同时还提到 ZAP 一般不会记录可以导致漏洞触发的日志,且如果没有打开 ZAP API 那就不太容易被攻击。
实际上经过我的测试发现他对此现象的描述是不正确的。我不止发现了 ZAP API 一处触发点,所以即使手动关闭了 ZAP API 同样能够触发。
0x01 主动反制
我下载了一个 2.11.0 版本的 ZAP,它和 Burpsuite 一样,都是默认监听本地 8080 代理端口,也同样会在默认情况下开启 WEB API。
Burpsuite 的是 http://burp/
或是http://127.0.0.1:8080/
ZAP 的是 http://zap/
或是http://127.0.0.1:8080/
访问 ZAP 的 WEB UI页面,它有提供一个本地 API 的功能。
点进去是一些 ZAP 开放出去的 API 接口。
随便选择一个组件,它需要填写一个 API Key,这个地方正常是要填写 ZAP 在”应用程序编程接口“中的那串随机密钥的。
但如果这里密钥输错了,程序就会把密钥打印在日志中。
只要在这里输入 log4j2 的测试代码,就能够触发了。
那么利用起来也很简单,只要通过 JS 向 ZAP API 接口发送一个 log4j POC 就能够触发了。
http://zap/JSON/acsrf/view/optionPartialMatchingEnabled/?apikey=${upper:AAAA}
0x02 被动反制
前面公告中也写到,解决方法之一就是不把ZAP API暴露给不信任的地址,如果直接关闭了 API 功能,又该怎么去触发。
我想到的主要有三个思路。
- 从主程序的源码中按照关键字寻找可控输入点。
- 从 ZAP 自带的插件中找日志可控输入点
ZAP 在它的 plugin 目录里自带了几个以 .zap 扩展名为结尾的官方插件。
把他改成 .zip 就能当成压缩包解压出来。
- 通过对一个各种场景齐全的网站扫描来观察 ZAP 的日志打印情况,再把可控输入点挨个测试一遍。
以 pscanrules 为例,我找到了一个可以把请求头Authorization
中的内容打印在日志的地方。
当打印 error 或 info 级别的日志时就会触发。
也就是说,尽管 ZAP 没有开启 API,只要开着 ZAP 的代理来访问带有反制代码的网页就会触发漏洞,从而执行代码。
另外,如果 ZAP 用的是高版本 JDK 的话也是可以绕过的。因为它的第三方库中有使用了 commons-collections 和 commons-beanutils,可以通过 LDAP 返回一个序列化 Gadget。
最后建议正在使用 OWASP ZAP 的红队升级到 2.11.1 或最新版本,可以真正免于此漏洞的影响。