CMS目錄結構分析
我們首先可以使用window下自帶的tree命令生成文件目錄。
tree /f>tree.txt
我們分析主目錄文件的功能:
——admin //后台文件
——css //css文件
——files //功能函數文件
——images //圖片
——index.php //主目錄文件
——install //安裝文件
——seacmseditor //編輯器
——template //模板文件
——upload //文件上傳目錄
我們使用RIPS或SEAY進行掃描。
一、安裝流程中存在SQL注入
漏洞位置:/install/index.php
RIPS審計出現sql注入,跟進文件比對審計結果。
通讀代碼發現代碼邏輯如下:
1.檢測是否生成了InstallLock.txt文件
2.執行sql語句
審計發現這里sql語句確實沒有經過過濾,直接插入update的sql語句,導致sql注入。
漏洞演示:
payload:
1' extractvalue(1,concat(0x7e,(select @@version),0x7e))#
1.根據源碼可知,我們首先需要刪除安裝目錄下的installLock.txt文件(如果網站上存在一個任意文件刪除漏洞)
2.刪除后我們重新進入安裝界面。
在管理賬號一欄輸入我們的payload,也就是我們常見的報錯注入方法,
之后我們提交:
發現在修改錯誤一欄發現爆出我們的Mysql版本,證明漏洞存在。
二、主目錄存在文件包含
跟進文件
<?php
//單一入口模式 error_reporting(0); //關閉錯誤顯示 $file=addslashes($_GET['r']); //接收文件名 $action=$file==''?'index':$file; //判斷為空或者等於index include('files/'.$action.'.php'); //載入相應文件 ?>
代碼邏輯大概為,通過GET型傳參傳入r,並將值經過一個addslashes()
函數操作,然后一個三元運算符判斷要載入的文件,直接進入include
函數包含。
include('files/'.$action.'.php');
這條語句包含了file目錄下的文件。
語法為:條件表達式?表達式1:表達式2
問號前面的位置是判斷的條件,判斷結果為bool型,為true是調用表達式1,為false時調用表達式2.
由代碼邏輯可知,代碼限制了我們訪問的目錄為file。
Bypass:可用../
進行目錄跳轉。
漏洞演示
然后我們在本地訪問index.php添加如下參數。即可正確解析phpinfo界面
因為此處代碼會自動在文件名后添加.php,所以我們不添加后綴名,否則無法正常解析。
三、前台多處SQL注入
結合RIPS掃描結果可發現多處sql注入漏洞,該CMS采用過濾方式大多是通過addslashes()
函數過濾。
單純使用addslashes()
函數會造成兩個問題:
- 是否采用GBK(寬字節注入)
- sql語句是否采用了單引號閉合。
software.php
漏洞位置:files/software.php
第13行,where后字句忘記加單引號保護。
$query = "UPDATE download SET hit = hit+1 WHERE id=$id";
content.php
漏洞位置:files/content.php
第19行,where后字句忘記加單引號保護。
$query = "UPDATE content SET hit = hit+1 WHERE id=$id";
submit.php
首先可看見 過濾和傳參
$type=addslashes($_GET['type']);
$name=$_POST['name']; $mail=$_POST['mail']; $url=$_POST['url']; $content=$_POST['content']; $cid=$_POST['cid']; $ip=$_SERVER["REMOTE_ADDR"]; $tz=$_POST['tz']; if ($tz==""){$tz=0;} $jz=$_POST['jz'];
只對type
參數進行了過濾,因此其他參數涉及到sql語句的可能存在sql注入。
漏洞位置:files/submit.php
第66行
$query = "SELECT * FROM interaction WHERE( mail = '$mail')";
漏洞位置:files/submit.php
第121-147行
$query = "INSERT INTO interaction (
type, xs, cid, name, mail, url, touxiang, shebei, ip, content, tz, date ) VALUES ( '$type', '$xs', '$cid', '$name', '$mail', '$url', '$touxiang', '$shebei', '$ip', '$content', '$tz', now() )";
漏洞位置:files/submit.php
第176行
$query = "SELECT * FROM content WHERE( id= $cid)";
漏洞位置:files/submit.php
第206行
$query = "SELECT * FROM download WHERE( id= $cid)";
四、XSS漏洞
反射型XSS
漏洞位置:files/contact.php
第12~15行
$page=addslashes($_GET['page']);
if ($page<>""){ if ($page<>1){ $pages="第".$page."頁 - ";
經過一次addslashes
函數處理就直接帶入頁面。
我們訪問網址的聯系功能,找到了代碼對於的page參數,其實就是留言列表的頁數。
我們嘗試插入一個簡單XSS payload
page=<img src=x onerror=alert(/xss/);>
漏洞利用成功。
存儲型XSS
漏洞位置:files/content.php
<div class="manageinfo">
<ul>
<div class="lou">回復 #<?php echo $pinglun['id']?> 樓</div>
<?php
$query2 = "SELECT * FROM manage";
$resul2 = mysql_query($query2) or die('SQL語句有誤:'.mysql_error());
$manage2 = mysql_fetch_array($resul2);
if ($manage2['img']==""){
$touxiang="images/manage.jpg";
} else{
$touxiang=$manage2['img'];
}
?>
<img src="<?php echo $touxiang?>">
<strong><?php echo $manage2['name']?><span>認證站長</span></strong>
<li>位置:<a><?php echo $pinglun['rip']?></a></li>
<li>時間:<a><?php echo tranTime(strtotime($pinglun['rdate']))?></a></li>
<li>來自:<a><?php echo $pinglun['rshebei']?></a></li>
</ul>
</div>
這里是從$pinglun這個變量中取出其中的信息,隨后插入存儲信息的interaction
表
在/files/submit.php
中將content內容給過濾。
$content=addslashes(strip_tags($content)); //過濾HTML
在評論處可以提交昵稱、郵箱、網址、評論內容,但是顯示評論和留言的地方有昵稱,所以只有昵稱處有存儲型XSS。
五、越權
漏洞位置:inc/checklogin.php
<?php
$user=$_COOKIE['user'];
if ($user==""){
header("Location: ?r=login");
exit;
}
?>
該處的代碼邏輯存在問題,直接從COOKIE
處賦值給$user
如果 $user
為空就跳轉至登錄界面
反之如果不為空就可以訪問,因此存在越權訪問。
漏洞利用:
我們首先從admin中進入使用之前的賬號登錄后台。然后找到一個發布內容的頁面:參數為?r=newwz
之后我們退出登錄,回到登錄界面。查看頁面的cookie
發現在cookie里確實沒有user值,我們嘗試直接跳轉剛才登錄后的發布頁面,發現會自動跳轉到登錄界面。
根據代碼邏輯,我們可以嘗試在cookie中添加一個user,因為代碼沒有判斷user的具體值,所以填入任意數值即可。
發現沒有登錄,我們也成功進入了后台頁面。
六、后台萬能密碼登錄
漏洞位置:admin/files/login.php
<?php
ob_start();
require '../inc/conn.php';
$login=$_POST['login'];
$user=$_POST['user'];
$password=$_POST['password'];
$checkbox=$_POST['checkbox'];
if ($login<>""){
$query = "SELECT * FROM manage WHERE user='$user'";
$result = mysql_query($query) or die('SQL語句有誤:'.mysql_error());
$users = mysql_fetch_array($result);
if (!mysql_num_rows($result)) {
echo "<Script language=JavaScript>alert('抱歉,用戶名或者密碼錯誤。');history.back();</Script>";
exit;
}else{
$passwords=$users['password'];
if(md5($password)<>$passwords){
echo "<Script language=JavaScript>alert('抱歉,用戶名或者密碼錯誤。');history.back();</Script>";
exit;
}
//寫入登錄信息並記住30天
if ($checkbox==1){
setcookie('user',$user,time()+3600*24*30,'/');
}else{
setcookie('user',$user,0,'/');
}
echo "<script>this.location='?r=index'</script>";
exit;
}
exit;
ob_end_flush();
}
?>
萬能密碼登錄有兩個點:
1.user未經過過濾直接拼接進入數據庫查詢
2.password的md5對比可繞過
payload:
user:1' union select 1,2,'test','c4ca4238a0b923820dcc509a6f75849b',5,6,7,8#
password:1
此處md5(1)=c4ca4238a0b923820dcc509a6f75849b
我們進入后台,在賬號一欄中填入payload,密碼輸入mad5加密的1即可成功登錄。
漏洞分析
我們登錄我們的mysql數據庫,查詢xhcms庫下的manage表
我們使用聯合查詢的方法,發現結果在數據庫下添加一行新的參數,而添加的值我們是可控的。
所以我們的payload就是通過傳入新的md5加密后的password,從而達到繞過驗證,直接登錄的目的。
總結
這個cms和bluecms用來入門代碼審計還是不錯的,但是現在大多數cms應該都不會有這種很低級的sql注入或文件包含了。。。。。用來學習審計思路還是挺好的。