0x00 前言php
這段時間就一直在搞代碼審計了。針對本身的審計方法作一下總結,記錄一下步驟。html
審計沒他,基礎要牢,思路要清晰,姿式要多且正。前端
下面是本身審計的步驟,正在逐步調整,尋求效率最高。web
0x01 關於 XiaoCmssql
XiaoCms 企業建站版基於 PHP+Mysql 架構 是一款小巧、靈活、簡單、易用的輕量級 cms。能知足各類企業站 博客 等中小型站點。(此cms貌似已經中止更新了)shell
01. 支持自定義內容模型數據庫
經過自定義內容模型和自定義字段能夠輕鬆簡單的定製出各類內容模型 如新聞模塊、產品模塊、下載模塊、圖片模塊。
02. 支持自定義會員模型。
經過自定義會員模型能夠擴展各類會員模型 如 我的、企業。
03. 支持自定義表單模型。
經過自定義表單模型能夠擴展內容評論、 在線留言、 報名、產品訂購、等各類提交表單。
04. 支持自定義表。
05. 區塊管理功能。
06. 支持手機版。
07. 支持url僞靜態 生成靜態 動態 三種模式。
08. 支持遊客投稿。
09. 支持會員投稿,會員模塊單獨分離可選不安裝。
10. 簡單易用的後臺操做管理方式,小白也懂得怎麼用。
11. 靈活的模板標籤語言 讓製做模板更容易更省時間。
12. 系統開源二次開發簡單。
13. 自定義推薦位。
14. 採用pdo數據庫驅動提升安全性。
15. 先後臺完全分離,支持更改後臺目錄。
16. XiaoCms不只僅是企業建站cms,更是輕量級的萬能建站CMS數組
(摘自官網)安全
(從官網簡介咱們知道數據庫使用了pdo預處理)cookie
下載好源碼解壓,安裝好程序。
0x02 初識XiaoCms
目錄結構
├─admin //後臺
│ ├─controller //控制器
│ ├─img //後臺圖片
│ └─template //後臺模板
├─core //核心模塊
│ ├─controller //控制器
│ ├─img //圖片
│ │ ├─calendar
│ │ │ └─skins
│ │ │ └─default
│ │ ├─js
│ │ ├─kindeditor
│ │ │ ├─lang
│ │ │ ├─plugins
│ │ │ │ ├─autoheight
│ │ │ │ ├─baidumap
│ │ │ │ ├─clearhtml
│ │ │ │ ├─code
│ │ │ │ ├─filemanager
│ │ │ │ │ └─images
│ │ │ │ ├─flash
│ │ │ │ ├─image
│ │ │ │ │ └─images
│ │ │ │ ├─insertfile
│ │ │ │ ├─lineheight
│ │ │ │ ├─link
│ │ │ │ ├─media
│ │ │ │ ├─multiimage
│ │ │ │ │ └─images
│ │ │ │ ├─pagebreak
│ │ │ │ ├─plainpaste
│ │ │ │ ├─quickformat
│ │ │ │ └─wordpaste
│ │ │ └─themes
│ │ │ ├─common
│ │ │ ├─default
│ │ │ └─simple
│ │ ├─message
│ │ ├─uploadify
│ │ └─watermark
│ └─library //一些輔助庫
├─data //存放數據
│ ├─bakup
│ ├─cache
│ ├─config
│ ├─install
│ ├─models
│ ├─tplcache
│ └─upload
│ └─image
└─template
├─default
│ └─images
└─mobile
從目錄文件名定義,咱們大概能夠猜想系統使用的是MVC模式。
藉助工具phpstorm,從index.php跟一下程序。瞭解程序是怎麼運行的,作了什麼過濾。(也就是當咱們第一次訪問index.php的執行過程)
跟進xiaocms.php
展開xiaocms類看一下類的具體方法:
不一一細看,主要看一下run函數
run方法的主要做用是解析傳來的 controller,action 等參數,隨之加載相應的控制器類,調用相應的方法。驗證了咱們以前的猜想,這個系統確實是MVC模式。
其中在包含控制器的代碼中,只是判斷文件是否存在,就直接包含了文件。
在php5.3以前是能夠用%00截斷進行目錄穿越,形成任意文件包含的。
但仔細閱讀,會發現其實前面parse_request已經進行了過濾,因此此路不通。有一點須要注意的是,當咱們沒有傳入c和a參數時,會默認調用index 控制器下的index方法。
在看完了這個xiaocms.php以後,咱們再去看一下,以前加載的幾個類。
進入global.function.php,這是一個公共函數庫,各類輔助方法。(仔細閱讀,就不詳解了)
隨後就是version.php,只是簡單定義一下版本常量而已。
以後是Base.class.php,這是一個基礎的類庫,不少類都是繼承於它。
先看看構造函數,balbla的加載了不少東西,而後就是把該設置的設置,渲染好頁面返回給前端。
總結一下:
當咱們訪問index.php時,系統先去訪問index.php ,index.php又包含了xiaocms.php,xiaocms.php又包含了global.functions.php,base.class.php等文件,設置了相應的配置,先是運行了base.class.php的構造函數,實例化了數據庫,session等對象,渲染好了基礎頁面。隨之運行run方法,解析傳輸過來的url,調用對應的控制器和方法。
程序的運行過程是大概瞭解了,可是不太清楚是否作了過濾?咱們訪問一下文章,帶入點參數。
由於沒有傳輸c和a參數,因此程序默認調用的是index控制器下index方法
找到控制器index.php。
index 方法
傳入的是id,在else if下面.跟進get方法
對get輸入進行了過濾,轉義了雙引號和左尖括號,右尖括號。
其中post方法也是同樣的。
至此,咱們大概瞭解了整個程序的運行路線,以及輸入過濾等。
0x03 黑盒白盒結合審計
先瀏覽一下網站,看一下前臺有什麼功能,後臺有什麼功能。主張以功能點驅動審計。
先看一下前臺有什麼功能,大概總結一下有四個功能點(頁面瀏覽,留言,評論,搜索)
會產生這些問題
首先看一下頁面瀏覽方面是否會產生sql注入的問題。
由於使用了pdo預編譯,注入概率很小,但也不能說絕對,也有pdo照顧不到的地方
(1)參數佔位符不能用於指定查詢中的表和列的名稱。
(2)參數佔位符不能用於查詢的其餘部分,好比ORDER BY子句中的ASC或者DESC關鍵詞等。
搜索一下參數爲 id 或者 catid 的輸入有沒有作整型過濾
幾經測試,發現此路不通。
由於作了pdo,且通過了實體化過濾,單引號,雙引號,<,>都是沒戲的了。
那麼前臺的幾個功能點算是被堵死了。
再來看一下後臺
先看登錄
因爲用的是session跟cookie沒啥關係了,而驗證碼也是繞不過去。
惟一有點欣慰的是能夠繞過鎖定15分鐘的限制,驗證碼也比較簡單,能夠經過第三方庫來識別。
能夠對後臺進行爆破。
登錄進去後臺首頁
後臺功能點繁多就不一一截圖了。
既然已經進入後臺了,那麼咱們就能夠看看有沒有什麼方法能夠getshell。
1,配置文件??
來到系統配置頁面
咱們看看config.ini.php正常情況下是怎樣子的?
用的是單引號,由於只是過濾了雙引號,那麼咱們是否是能夠經過單引號逃出,形成代碼執行呢?
測試一下
發現配置文件變成這樣子了。
哪裏來的單引號?
跟蹤代碼發現,只有剛開始的過濾,都沒有其餘過濾啊。
惟一奇怪的可能就只有var_export這個函數了。
看一下手冊,發下果真是它搞的鬼。
那麼此路不通。
2,文件上傳看一下??
找到文件上傳相關代碼,發現了這麼一個方法
其中這行代碼設置了upload相關配置
$result = $upload->set_limit_size(1024*1024*$size)->set_limit_type($type)->upload($_FILES[$fields],XIAOCMS_PATH.$filenpath); //設置上傳文件的大小,上傳文件的類型,設置上傳文件存儲的路徑
跟進到upload.class.php看一下上傳代碼。
先是設置上傳的限制類型
而後調用upload函數進行上傳。
跟進parse_init。判斷上傳的文件名是否在可上傳數組內。而這個可上傳後綴名數組是咱們可控的。
那麼就形成了任意文件上傳。
看一下有誰調用了upload方法,發現了兩個地方,其中第二個是可控的。
跟進uploadify_uploadAction方法
能夠看到沒有任何限制。
那麼這個請求應該是這樣子的。
http://127.0.0.1/xiaocms/admin/index.php?c=uploadfile&a=uploadify_upload&type=php&size=1000
post參數 submit,file。
本地構造一個上傳頁面
頁面代碼以下:
<html> <body> <form action="http://127.0.0.1/xiaocms/admin/index.php?c=uploadfile&a=uploadify_upload&type=php&size=1000" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="hidden" name="submit" value="submit"/> <input type="submit" value="submit" /> </form> </body> </html>
上傳一個php試一下
成功getshell。
固然這裏是咱們可以進入後臺的前提。
若是咱們沒有進入後臺的話,能夠利用csrf,由於這個程序後臺的請求都是存在csrf的。
但還有一個問題就是文件名。
那麼徹底是能夠經過csrf來getshell的。(有前臺留言和評論功能)
update,在後臺數據庫恢復處發現了一個任意目錄刪除漏洞
根據代碼咱們能夠能夠知道paths,沒有作任何過濾,直接帶進去刪除。
代碼首先判斷了path 是否存在 以及$dir.$path是不是一個目錄,這裏咱們能夠經過不發送path參數進行繞過。
最終的請求應該是這樣子的。
POST /xiaocms/admin/index.php?c=database&a=import HTTP/1.1 Host: 127.0.0.1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Referer: http://127.0.0.1/xiaocms/admin/index.php?c=database Accept-Language: zh-CN,zh;q=0.8 Cookie: PHPSESSID=fgcbjs2jerab54cm70on37grh2 Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 29 submit=submit&paths[]=
首先在data目錄下新建一個test文件夾做爲測試文件夾
發送請求包
查看一下目錄
成功刪除test文件夾。
update
審另外一套cms的時候,想起了p神以前的分享,說到了一個叫會話固定的漏洞。
發現此cms也是存在的。
看代碼 \core\library\session.class.php
會話初始時會接受外部參數,設置session_id。
起初我覺得必須網站管理員在尚未打開這個網站的時候可使用,也就是尚未初始化session的時候,實驗發現。就算已是初始化了session,也是經過一個連接,讓管理員設置session id 爲咱們控制的session_id。
想到的一個場景就是,網站管理員在收到留言的時候,點擊了咱們的連接,而後種下了咱們設置的session_id。
咱們就能夠利用這個session_id直接登錄後臺,再經過以前的任意文件上傳漏洞,直接getshell。
poc代碼:
<html> <body> <form action="http://127.0.0.1/xiaocms/" method="post"> <input type="hidden" name="session_id" value="testxiaocms"> <input type="submit" > </form> </body> </html>
0x04 總結
經過此次審計,算是熟練了本身審計的思路和步驟吧。
總的來講這套cms,問題不是不少。如今僅發現了一個後臺爆破和後臺getshell。
但由於這套cms已經好久沒有更新了,且都是後臺的問題,並不會有什麼影響。
還有不少想寫的,待之後再說吧。