赞
踩
作者:Longofo@知道创宇404实验室
日期:2021年2月26日
Apache Axis分为Axis1(一开始就是Axis,这里为了好区分叫Axis1)和Axis2,Axis1是比较老的版本了,在Axis1官方文档说到,Apache Axis1现在已经很大程度被Apache Axis2,Apache CXF和Metro取代,但是,Axis1仍与以下类型的项目相关:
需要使用JAX-RPC的项目。该API只有两种开源实现:Axis和Sun的参考实现。
需要使用或公开使用SOAP编码的Web服务的项目。SOAP编码已被弃用,现代Web服务框架不再支持。但是,仍然存在使用编码类型的旧式服务。
使用Axis构建的现有项目,使用现代Web服务框架重写它们的投资回报将太低。
之前遇到过几个应用还是在使用Axis1,Axis1依然存在于较多因为太庞大或臃肿而没那么容易被重构的系统中。
后面记录下Axis1和Axis2相关内容。各个WebService框架的设计有区别,但是也有相通之处,熟悉一个看其他的或许能省不少力气。
1. Apache Axis1
1.1 搭建一个Axis项目
如果一开始不知道配置文件要配置些什么,可以使用Intellij idea创建axis项目,idea会自动生成好一个基础的用于部署的server-config.wsdd配置文件以及web.xml文件,如果手动创建需要自己写配置文件,看过几个应用中的配置文件,用idea创建的server-config.wsdd中的基本配置参数在看过的几个应用中基本也有,所以猜测大多开发Axis的如果没有特殊需求一开始都不会手动去写一些基本的参数配置,只是往里面添加service。
1.1.1 使用idea创建Axis项目
新建项目,选择WebServices
选择Apache Axis
如果你不知道axis开发要依赖些什么,就选择下载(默认会下载Axis1的最新版1.4版本);你知道的话就可以选择之后自己设置依赖
完成之后,idea生成的结构如下:
主要是会自动帮我们生成好基础的wsdd配置文件和web.xml中的servlet
1.1.2 访问WebService
搭建完成之后,和通常的部署web服务一样部署到tomcat或其他服务器上就可以了访问测试了。idea默认生成的web.xml中配置了两个web services访问入口:
/services
/servlet/AxisServlet
还有一种是.jws结尾的文件,也可以作为web service,.jws里面其实就是java代码,不过.jws只是作为简单服务使用,不常用,后续是只看wsdl这种的。
后续要用到的示例项目代码传到了github。
1.2 基本概念
1.2.1 wsdd配置文件
大体基本结构如下,更详细的可以看idea生成的wsdd文件:
http://xml.apache.org/axis/wsdd/
value="adam.bp.workflow.webservice.test.WebServicesTest"/>
后续对于漏洞利用需要关注的就是中的几个parameter,qs:list、qs:wsdl、qs:method。这些在后面会逐步看到。
1.2.2 Service Styles
在官方文档一共提供了四种Service方式:
RPC
Document
Wrapped
Message,上面wsdd中的AdminService就属于这类service,,它配置的是java:MSG
后续内容都是基于RPC方式,后续不做特别说明的默认就是RPC方式,也是Axis作为WebService常用的方式,RPC服务遵循SOAP RPC约定,其他三种方式暂不介绍(Message Service在1.2.3.4小节中会有说明)。
1.2.3 wsdl组成
访问AdminService的wsdl来解析下wsdl结构:
wsdl主要包含5个部分:
types
messages
portType
binding
service
结合AdminService的代码来更好的理解wsdl:
public class Admin {
protected static Log log;
public Admin() {
}
public Element[] AdminService(Element[] xml) throws Exception {
log.debug("Enter: Admin::AdminService");
MessageContext msgContext = MessageContext.getCurrentContext();
Document doc = this.process(msgContext, xml[0]);
Element[] result = new Element[]{doc.getDocumentElement()};
log.debug("Exit: Admin::AdminService");
return result;
}
...
}
1.2.3.1 types
types是对于service对应的类,所有公开方法中的复杂参数类型和复杂返回类型的描述。如:
AdminService方法的参数和返回值中都有复杂类型,表示AdminService方法的Element[]参数,是一个Element类型的数组,不是基本类型(基本类型可以看1.2.4节),如果没有配置该类的对应的序列化器和反序列化器(在后续可以看到),在wsdl中就会写成type="xsd:anyType"。就是AdminService方法的返回值,同理。
1.2.3.2 messages
messages是对于service对应的类,每个公开方法每个参数类型和返回类型的描述。如:
就是AdminService方法入参,它是一个复杂类型,所以用element="impl:AdminService"引用上面types中的。同理表示。
1.2.3.3 portType
portType是service对应的类,有哪些方法被公开出来可被远程调用。如:
这个service的AdminService方法被公开出来可以调用,他的输入输出分别是impl:AdminServiceRequest和impl:AdminServiceResponse,也就是上面messages对应的两个定义。
1.2.3.4 binding
binding可以理解成如何通过soap进行方法请求调用的描述。如:
这个binding的实现是impl:Admin,就是portType中的Admin。
POST /axis/services/AdminService HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 473
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
这里soap没有方法名(即AdminService),也没有参数类型。可能这里会好奇,这个
最后,我们到达“Message”样式的服务,当您希望Axis退后一步,让您的代码以实际的XML而不是将其转换为Java对象时,应使用它们。Message样式服务方法有四个有效签名:
public Element [] method(Element [] bodies);
public SOAPBodyElement [] method (SOAPBodyElement [] bodies);
public Document method(Document body);
public void method(SOAPEnvelope req, SOAPEnvelope resp);
前两个将传递DOM元素或SOAPBodyElements的方法数组-数组将为信封中中的每个XML元素包含一个元素。
第三个签名将为您传递一个表示的DOM文档,并且期望得到相同的结果。
第四个签名为您传递了两个表示请求和响应消息的SOAPEnvelope对象。如果您需要查看或修改服务方法中的标头,则使用此签名。无论您放入响应信封的内容如何,返回时都会自动发送回给呼叫者。请注意,响应信封可能已经包含已由其他处理程序插入的标头。
1.2.3.5 service
这个标签对于我们调用者其实没什么作用,也就说明下这个service的调用url为http://localhost:8080/axis/services/AdminService:
可以看出service包含了binding,binding包含了portType,portType包含了messages,messages包含了types。看wsdl的时候倒着从service看可能更好一点,依次往上寻找。
1.2.3.6 说明
对于多个参数的方法,含有复杂类型的方法,可以看demo项目中的HelloWord的wsdl,我将那个类的方法参数改得更有说服力些,如果能看懂wsdl并且能猜测出这个service公开有哪些方法,每个方法的参数是怎样的,就基本没有问题了。
Axis文档中说到,1.2.3小节的每一部分在运行时都会动态生成对应的类去处理,不过我们不需要关心它怎么处理的,中间的生成代码对于该框架的漏洞利用也没有价值,不必去研究。
其实有工具来帮助解析wsdl的,例如soap ui,我们也可以很方便的点击,填写数据就能调用。大多数时候没有问题,但是有时候传递复杂数据类型出现问题时,你得直到问题出在哪,还是得人工看下types,人工正确的构造下再传递;或者你自己绑定的恶意类不符合bean标准时,soap ui其实生成的不准确或不正确,也要自己手动修改构造。
1.2.4 wsdl types与java基础类型的对应
文档中列出了下面一些基本类型:
xsd:base64Binary
byte[]
xsd:boolean
boolean
xsd:byte
byte
xsd:dateTime
java.util.Calendar
xsd:decimal
java.math.BigDecimal
xsd:double
double
xsd:float
float
xsd:hexBinary
byte[]
xsd:int
int
xsd:integer
java.math.BigInteger
xsd:long
long
xsd:QName
javax.xml.namespace.QName
<Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。