任意文件寫入

這個 cms 是基于 thinkphp5.1 的基礎開發的,一般我們挖 cms 如果想 rce 的話,可以在 application 文件夾直接搜索file_put_content等危險函數,如下圖,我們直接全局定位到這個fileedit方法里面的file_put_content

我們看到第一個參數$rootpath,他是被拼接了這么一段路徑

$rootpath = Env::get('root_path') . 'theme' . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $path;

其中$path是我們可控的,那么一般就可以考慮下是否存在路徑穿越的問題

再看到第二個參數htmlspecialchars_decode(Request::param('html')也是我們可控的

所以這里就比較清晰了,我們只需要../就可以進行路徑穿越,htmlspecialchars_decode也對我們寫入 php 代碼沒有什么影響,所以我們直接 post 傳參 path=../../index.php&html=即可

可以看到已經成功 rce

任意文件讀取

我們再順著fileedit這個方法往下瞅瞅,發現還有一個file_get_contents,他的參數也是$rootpath,所以這里也是我們可控的,不同的是進入這個 else 分支我們用 get 傳參即可

我們直接傳入../../index.php,發現已經成功把index.php讀取出來了

反序列化漏洞

上面兩個漏洞是利用了file_get_contentsfile_put_content,這兩個函數都是涉及了 IO 的操作函數,也就是說可以進行操作 phar 反序列化漏洞,但是他們的路徑并不是完全可控的,只是后面一小部分可控,所以這條路走不通,所以接下來的思路就是搜索有沒有可以操作phar的函數

我們直接全局搜索is_dir,一個一個分析是否可以利用

這里我的運氣比較好,映入眼簾的是scanFilesForTree這個方法,他的$dir是直接可控的,文章的開頭說了這個 cms 是基于 thinkphp5.1 二次開發的,所以我們可以直接利用這個漏洞生成 phar 文件來進行 rce

我們首先看看能不能上傳 phar 文件,在后臺一處發現可以上傳文件

我們先抓個包試試水,發現提示非法圖片文件,應該是寫了什么過濾

我們找到upload這個函數發現對圖片的類型和大小進行了一些驗證

public function upload($file, $fileType = 'image')
    {
        // 驗證文件類型及大小
        switch ($fileType)
        {
            case 'image':
                $result = $file->check(['ext' => $this->config['upload_image_ext'], 'size' => $this->config['upload_image_size']*1024]);
                if(empty($result)){
                    // 上傳失敗獲取錯誤信息
                    $this->error = $file->getError();
                    return false;
                }
                break;
        $result =  $this->uploadHandler->upload($file);
        $data   =  array_merge($result, ['site_id' => $this->site_id]);
        SiteFile::create($data);
        return $data;
    }

然后嘗試加了GIF89a頭就可以上傳了,看來多打CTF還是有用的,于是直接上傳我們的 phar 文件就好了

這里要記得生成 phar 文件的時候要要加入GIF89a頭來繞過,如下

$phar->setStub('GIF89a'.'');//設置stub

可以看到已經成功上傳了,同時記住下面那個路徑

最后我們在scanFilesForTree這里觸發我們的phar文件就可以了

總結

本篇的漏洞已經全部上交cnvd,這個 cms 總的來說比較適合練手,主要的切入點還是通過白盒通過尋找一些危險的函數,再想方設法的去控制它的參數變量