任意文件寫入
這個 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=<?php phpinfo();?>
即可
可以看到已經成功 rce
任意文件讀取
我們再順着fileedit
這個方法往下瞅瞅,發現還有一個file_get_contents
,他的參數也是$rootpath
,所以這裏也是我們可控的,不同的是進入這個 else 分支我們用 get 傳參即可
我們直接傳入../../index.php
,發現已經成功把index.php
讀取出來了
反序列化漏洞
上面兩個漏洞是利用了file_get_contents
和file_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'.'<?php __HALT_COMPILER();?>');//設置stub
可以看到已經成功上傳了,同時記住下面那個路徑
最後我們在scanFilesForTree
這裏觸發我們的phar
文件就可以了
總結
本篇的漏洞已經全部上交cnvd,這個 cms 總的來說比較適合練手,主要的切入點還是通過白盒通過尋找一些危險的函數,再想方設法的去控制它的參數變量
本文涉及相關實驗:任意文件下載漏洞的代碼審計 (過本節的學習,瞭解文件下載漏洞的原理,通過代碼審計掌握文件下載漏洞產生的原因以及修復方法。)