


在复杂的软件系统中,代码审计是深入骨髓,发现并清除安全隐患的关键手段。本文将聚焦于Java环境下的Web Service,解析其常见漏洞模式与实战挖掘技巧。
Web Service简介
Web Service本质上是一种通过网络提供标准化服务的软件系统。它允许运行在不同平台、使用不同编程语言编写的应用程序相互通信和交换数据。
一、Web Service基础
通俗来讲,使用SOAP协议开发的接口对应的服务就是Web Service接口。它是通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。
Web Service有以下几个特点:
- 服务器端整出一些资源让客户端应用访问(获取数据)。
- 一个跨语言、跨平台的规范(抽象)。
- 多个跨平台、跨语言的应用间通信整合的方案(实际)。
而使用HTTP协议开发的接口对应的服务,我们通常叫HTTP Service。
Web Service交互的过程就是,Web Service遵循SOAP协议通过XML封装数据,然后由HTTP协议来传输数据。
二、Web Service分类
Web Service主要分为两类:
SOAP型Web Service:SOAP型Web Service允许使用XML格式与服务器进行通信。
REST型Web Service:REST型Web Service允许使用JSON格式(也可以使用XML格式)与服务器进行通信。与HTTP类似,该类型服务支持GET、POST、PUT、DELETE方法。不需要WSDL、UDDI。
SOAP
Web Service是基于SOAP协议传输数据,SOAP又是一种简单的基于XML的协议,它使应用程序通过HTTP来交换信息。
WSDL(Web Services Description Language)基于XML语言,用于描述Web Service及其函数、参数和返回值。它是Web Service客户端和服务器端能理解的标准格式。基于XML的,所以WSDL既是机器可阅读的,又是人可阅的,这将是一个很大的好处——可以视为接口文档。
SOAP使用HTTP来发送XML格式的数据,可以简单理解为:SOAP = HTTP + XML。
SOAP结构

- 必需的 Envelope 元素,可把此XML文档标识为一条SOAP消息。
- 可选的 Header 元素,包含头部信息。
- 必需的 Body 元素,包含所有的调用和响应信息。
- 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息。

REST
REST(Representational State Transfer,表征性状态转移)型Web Service。REST型Web Service允许我们使用JSON格式(也可以使用XML格式)与服务器进行通信。与HTTP类似,该类型服务支持GET、POST、PUT、DELETE方法。不需要WSDL, UDDI。
三、Web Service技术支持
XML
可扩展的标记语言(标准通用标记语言下的一个子集)是Web Service平台中表示数据的基本格式。
XSD数据类型
Web Service平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB. NET或C#)来构造一个Web Service时,为了符合Web Service标准,所有你使用的数据类型都必须被转换为XSD类型。
WSDL
WSDL(Web Services Description Language,网络服务描述语言)给出了SOAP型Web Service的基本定义,WSDL基于XML语言,描述了与服务交互的基本元素,说明服务端接口、方法、参数和返回值,WSDL是随服务发布成功,自动生成,无需编写。少数情况下,WSDL也可以用来描述REST型Web Service。SOAP也是基于XML(标准通用标记语言下的一个子集)和XSD的,XML是SOAP的数据编码方式。
文档结构

阅读方法
- 先看
service标签,看相应port的binding属性,然后通过值查找上面的binding标签。
- 通过
binding标签可以获得具体协议等信息,然后查看binding的type属性。
- 通过
binding的type属性,查找对应的portType,可以获得可操作的方法和参数、返回值等。
- 通过
portType下的operation标签的message属性,可以向上查找message获取具体的数据参数信息。
参数解析
Service:相关端口的集合,包括其关联的接口、操作、消息等。
Binding:特定端口类型的具体协议和数据格式规范。
portType: 服务端点,描述Web Service可被执行的操作方法,以及相关的消息,通过binding指向portType。
message: 定义一个操作(方法)的数据参数。
types: 定义Web Service使用的全部数据类型。
WSDL文档是从下往上阅读。
四、如何发现Web Service
通常可以通过以下方式发现Web Service:
- 使用Burp等代理软件,检查所捕获的数据。
- 使用Google语法进行搜索。
- 通过搜索引擎探测Web应用程序暴露的接口(比如目录遍历漏洞、LFI等)。
- 爬取并解压swf、jar等类似文件。
- 模糊测试。
例:使用Burp等代理软件检查捕获的数据
在BurpSuite中可以设定过滤规则,用来筛选抓包数据中的Web Service地址。可以通过搜索与表达式相匹配的数据,探测诸如“.dll?wsdl”、“.ashx?wsdl”、“.exe?wsdl”或者“.php?wsdl”等等的Web Service地址。

使用Google语法
inurl:(_vti_bin | api | webservice | ws )

五、Web Service渗透测试
很多人误以为Web Service没有界面,黑客就无法进行攻击。事实上,Web Service通常仅是对现有应用层功能进行了封装,其后台应用层代码如果存在安全漏洞,我们完全可以使用Web Service进行攻击。绝大多数情况下,我们可以通过查看WSDL从而了解Web Service可以提供的操作及SOAP消息格式,所以说,Web应用中所面临的安全威胁同样存在于Web Service中。
Web Service的漏洞分类可以分为2种:
1. Web应用安全漏洞:
- SQL注入
- XSS攻击
- 命令执行
- 越权
- LDAP注入
- 缓冲区溢出
- 逻辑漏洞
- 等等
2. XML相关的特殊安全漏洞:
- XPath注入
- XQuery注入
- 拒绝服务攻击(SOAP数组溢出、递归的XML实体声明、超大消息体)
- 信息泄漏(XML External Entity File Disclosure)
- 等等
SQL注入
Web Service中的SQL注入(SQLi)漏洞与普通Web渗透测试中漏洞并无区别。
XPath注入
XPath作为用来查询XML数据的语言,同样容易存在很多注入漏洞。某种程度上来说,XPath注入比SQL注入更简单,因为不同数据库产品的SQL语句有不同的语法,而XPath只有一个标准。我们假定某Web服务后台采用了这段代码来查询某XML数据文件中的记录。
存在注入漏洞的 XPath 查询
Stmt = "//users/user[username/text()='" + username+ "' and password/text()='" + password + "']/id/text()";
其中username和password是通过SOAP消息进行传输,如下文:
传递 XPath 查询参数的 SOAP 消息片段
<soap:Envelope xmlns:soap="">
<soap:Body>
<fn:PerformFunction xmlns:fn="">
<fn:uid>testuser</fn:uid>
<fn:password>testpassword</fn:password>
</fn:PerformFunction>
</soap:Body>
</soap:Envelope>
假如黑客利用SOAP传入username="admin", password="' or '1'='1",以上XPath查询就变为:
遭注入的 XPath 查询
Stmt="//users/user[username/text()='admin' and password/text()='' or '1'='1']/id/text()";
这样我们就可以访问到admin用户信息。
拒绝服务攻击
由于Web服务基于XML格式的协议进行通信(例如SOAP消息)。当SOAP消息到达Web服务器端时,服务器端会调用XML Parser解析XML数据(包括DTD声明),黑客可以利用大量的超大消息体或者递归的XML实体声明,让服务器端长时间解析XML数据,直至服务器资源耗竭,从而形成拒绝访问攻击,导致Web服务停止服务。
例如,SOAP消息中可以加入以下大量无意义的实体声明,导致SOAP消息解析缓慢。
SOAP 消息中无意义的实体声明示例
<!DOCTYPE root [
<!ENTITY ha "Ha !">
<!ENTITY ha2 "&ha; &ha;">
<!ENTITY ha3 "&ha2; &ha2;">
...
<!ENTITY ha127 "&ha126; &ha126;">
<!ENTITY ha128 "&ha127; &ha127;">
]>
信息泄漏
某些Web服务会返回客户端指定的资源信息时,如果服务器端防范不当,则可能存在信息泄漏隐患。举个简单的类似HelloWorld的例子,假设某个Web服务会接受用户传来的名字“Jeremy”,然后返回“Hello, Jeremy!”。但如果黑客传入如下参数:
SOAP 消息中声明外部文件引用
<!DOCTYPE root [
<!ENTITY myfile SYSTEM "file://c:/windows/win.ini">
]>
...
<name>&myfile;</name>
服务器端如果疏于参数校验及文件访问权限控制,该Web服务可能返回系统文件的内容。
六、使用SoapUI+Burp对Web Service渗透测试
我们可以对Web Service方法的具体参数进行Fuzz测试,挖掘其中存在的各种技术漏洞和逻辑漏洞。也可以使用一些专业工具对常见的Web Service进行渗透测试。一般我们是使用Burp和SoapUI联动进行对Web Service渗透测试。通过SoapUI访问Web Service,并将请求转发给BurpSuite。
SoapUI NG Pro:渗透测试流程的发起,通信报文的解析、集合payload之后通信报文的重新组装等。
Burp Suite:代理拦截,跟踪通信过程和结果,对通信进行重放和二次处理等。
首先启动SoapUI软件,然后设置代理。

填入Burp的代理IP和端口。

创建一个新的SOAP工程。在“Initial WSDL”一栏填入WSDL地址。

导入成功,SoapUI对给定的WSDL地址进行解析,以创建Web Service函数及请求。

接下来我们创建一个“Generate TestSuite”。

创建好了Generate TestSuite后,我们再来对其中一个接口来创建一个“New SecurityTest”。

例如:我们对AddCustomerNew TestCase接口进行SecurityTest(安全测试)。

Empty:空测试。
Automatic:默认安全测试,这个会默认对WebService接口加载SoapUI中的所有测试模块。
Full Control:可以自行选择测试模块。

我们来看看SoapUI中有哪些测试模块。

选择好要使用的测试模块后,我们就可以使用SoapUI执行自动测试。

扫描完成。

可以看到疑似漏洞,最终结果需要我们配合Burp手工去确认。
联动之后,我们可以在Burp中可以看到所有的SoapUI发送的测试数据包。

我们可以通过查看数据包和返回包来确认漏洞。
开发安全的Web服务是一项系统而复杂的工作。实际项目中Web服务的开发往往依赖于一些框架及中间件。因此如何开发安全的Web服务,需要结合各个框架和中间件进行具体分析。
总结
Web Service测试流程相对清晰,主要是根据接口定义进行针对性测试。而且大多数漏洞集中在未授权访问和SQL注入。
掌握Java代码审计技术可以帮助我们发现Java Web Service等应用中的潜在漏洞和安全风险,及时修复和加固系统,更好地保障程序的安全性、可靠性和稳定性。如果你想了解更多技术细节或与同行交流,可以访问云栈社区的相关板块。