記一次完整的PHP程式碼審計——yccms v3.4審計

2023-02-21 21:00:23

一、環境搭建與使用工具

(一)環境搭建

  1. 開啟原始碼檢視安裝要求

     

  2. PHP 5.4+,Mysql 5.0.*,直接使用phpstudy設定即可

  3. 檢視原始碼目錄結構,發現是mvc模式的,那麼我們重點關注的就是controller、public、model下的檔案

     

     

(二)使用工具

  1. 整合網站環境搭建:phpstudy

  2. 程式碼靜態掃描:Fortify、seay原始碼審計系統

  3. 程式碼偵錯:phpstorm

  4. 抓包:BurpSuite

  5. 瀏覽器測試外掛:Hackbar

二、靜態程式碼掃描

  1. Fortify的掃描情況

  2. 再使用seay原始碼審計系統掃描一下,方便後面程式碼函數跟進

     

三、程式碼審計過程

(一)程式碼執行

  1. public/class目錄下的Factory.class.php檔案,檔案類名為Factory

  2. 使用setModel方法呼叫self::getA()方法獲取a引數進行跳轉檢查操作,通過file_exists()函數判斷檔案路徑是否存在,然後通過eval()函數範例化a引數執行程式碼

  3. 這裡想要利用eval()執行程式碼,則必須繞過file_exists()函數的檢查,該函數允許路徑中存在特殊字元,且遇到/../的時候會返回到上級目錄,可以利用以下形式嘗試繞過

     ?a=Factory();phpinfo();//../

  4. 成功繞過。發現eval函數中存在對a引數的範例化,把前面的執行程式碼phpinfo()改成system('whoami')後,出現報錯,報錯資訊中出現了一個範例化路徑config/run.inc.php

  5. 在專案中搜尋Factory,找到的唯一的有效範例化也是config/run.inc.php

     

  6. config/run.inc.php檔案無法直接存取,繼續找包含了這個檔案的其他可用檔案,找到admin/index.php、config/count.php、search/index.php三個檔案,也就是說需要通過這三個檔案對Factory()進行範例化呼叫才可以利用此處的程式碼執行漏洞。由於index.php是預設的首頁檔案,所以通過admin/index.php進行利用時可以省略index.php

  7. 構造webshell,使用蟻劍嘗試連線成功

     ?a=Factory();@eval($_POST[1]);//../

(二)無需登入任意檔案檔案刪除

  1. seay中提示controller目錄下有三處檔案刪除,但是隻有PicAction.class.php檔案中沒有對路徑獲取檔名進行校驗,另外三個都存在對檔案路徑或檔名的校驗

  2. 先看controller/PicAction.class.php,檢視程式碼如下,發現是一處刪除圖片的功能點,且沒有檢驗檔案路徑和檔名

  3. 先隨便傳張圖片上去,或者放一張圖片到upload目錄下,到後臺的圖片管理抓個包看一下

    封包如下,body部分的引數為pid[1]=xxx.png&send=刪除選中圖片

  4. 在網站根目錄下新建一個1.txt檔案,瀏覽器中退出管理員賬號,hackbar構造poc嘗試刪除該檔案

  5. 執行後發現網站根目錄下的1.txt檔案被刪除了

     

(三)無需登入任意文章刪除

  1. 第二處檔案刪除在controller/ArticleAction.class.php,檢視程式碼如下,以get方法接收id引數,先連線資料庫查詢該id是否存在,若存在則刪除該id所對應的文章,因此這裡無法刪除任意檔案,只能刪除文章

  2. 還是先退出登入,使用hackbar構造poc測試,嘗試刪除id為2446的文章

  3. 登入後臺檢視,發現id為2446的文章確實被刪除了

(四)任意檔案上傳一

  1. public/class/LogoUpload.class.php檔案,檢視程式碼

  2. 先到後臺檢視一下這處上傳點

  3. 嘗試前臺不登陸存取上傳點,發現可以直接存取

  4. 嘗試上傳一個webshell,先正常選擇上傳一個png圖片,然後burpsuite抓包修改成一句話木馬再傳送,如下

     

  5. 再檢視原始碼,發現LogoUpload.class.php檔案中還有一個上傳後的校驗,重新命名檔名為logo,驗證上傳目錄,校驗檔案型別是否為png圖片

     

  6. 根據上述規則,上傳的shell.php檔案應該被重新命名為了logo.php,找到logo上傳目錄view/index/images/,發現裡面有一個logo.php檔案,使用蟻劍嘗試連線成功

     

(五)任意檔案上傳二

  1. 第二處檔案上傳點public/class/FileUpload.class.php,檢視程式碼如下,邏輯跟上面那一處上傳差不多,但是檔名以時間+100到1000之間的亂數進行重新命名

  2. 抓包測試一下

     

  3. 到uploads目錄下看一下,發現多了一個20230221165059459.php檔案,檔名被通過時間進行了重新命名

  4. 嘗試使用蟻劍連線成功,這一處上傳點同樣可以前臺不登陸直接存取,不過有js校驗

     

(六)驗證碼複用漏洞

  1. 這個都不需要看程式碼,直接測就行,驗證碼不會變,可以重複使用