變量覆蓋指的是用我們自定義的參數值替換程序原有的變量值,一般變量覆蓋漏洞需要結合程序的其它功能來實現完整的攻擊。
經常導致變量覆蓋漏洞場景有:$$,extract()函數,parse_str()函數,import_request_variables()使用不當,開啟了全局變量注冊等。
0×01 全局變量覆蓋
register_globals的意思就是注冊為全局變量,所以當On的時候,傳遞過來的值會被直接的注冊為全局變量直接使用,而Off的時候,我們需要到特定的數組里去得到它。
代碼示例1:
<?php //?id=1 echo "Register_globals: ".(int)ini_get("register_globals")."<br/>"; echo '$_GET["id"] :'.$_GET['id']."<br/>"; echo '$id :'.$id; ?>
當register_globals=Off的時候,下一個程序接收的時候應該用$_GET['id']來接受傳遞過來的值;
當register_globals=On的時候,下一個程序可以直接使用$id來接受值,也可以用$_GET['id']來接受傳遞過來的值。
tips:如果上面的代碼中,已經對變量$id賦了初始值,比如$id=0,那么即使在URL中有/test.php?id=1,也不會將變量覆蓋,id值為0
代碼示例2:
<?php echo "Register_globals: ".(int)ini_get("register_globals")."<br/>"; if (ini_get('register_globals')) foreach($_REQUEST as $k=>$v) unset(${$k}); print $a."<br/>"; print $_GET[b]; ?>
在register_globals=ON時,
提交/test.php?a=1&b=2 , 變量$a未初始化,$_GET[b]=2
提交/test.php??GLOBALS[a]=1&b=2,$a=1,$_GET[b]=2
tips: 從 PHP » 4.2.0 版開始配置文件中 PHP 指令 register_globals 的默認值從 on 改為 off 了,自 PHP 5.3.0 起廢棄並將自 PHP 5.4.0 起移除。源自 http://php.net/manual/zh/security.globals.php
0×02 $$導致的變量覆蓋問題
使用foreach來遍歷數組中的值,然后再將獲取到的數組鍵名作為變量,數組中的鍵值作為變量的值。因此就產生了變量覆蓋漏洞。請求?id=1 會將$id的值覆蓋,$id=1。
<?php
foreach (array('_COOKIE','_POST','_GET') as $_request) { foreach ($$_request as $_key=>$_value) { $$_key= $_value; } } $id = isset($id) ? $id : 2; if($id == 1) { echo "flag{xxxxxxxxxx}"; die(); } echo $id; ?>
0×03 extract()變量覆蓋
extract() 函數從數組中將變量導入到當前的符號表。該函數使用數組鍵名作為變量名,使用數組鍵值作為變量值。針對數組中的每個元素,將在當前符號表中創建對應的一個變量。源自:http://www.w3school.com.cn/php/func_array_extract.asp
代碼示例1:
將鍵值 "Cat"、"Dog" 和 "Horse" 賦值給變量 $a、$b 和 $c:
<?php $a = "Original"; $my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse"); extract($my_array); echo "\$a = $a; \$b = $b; \$c = $c"; ?> //運行結果:$a = Cat; $b = Dog; $c = Horse
代碼示例2:
<?php $id=1; extract($_GET); echo $id; ?> //提交:?id=123 //結果: 123
tips: 在調用extract()時使用EXTR_SKIP保證已有變量不會被覆蓋 extract($_GET,EXTR_SKIP);
0×04 parse_str()變量覆蓋
parse_str() 函數把查詢字符串解析到變量中,如果沒有array 參數,則由該函數設置的變量將覆蓋已存在的同名變量。
用法參考: http://www.w3school.com.cn/php/func_string_parse_str.asp
代碼示例一:
<?php parse_str("a=1"); echo $a."<br/>"; //$a=1 parse_str("b=1&c=2",$myArray); print_r($myArray); //Array ( [c] => 1 [b] => 2 ) ?>
tips:parse_str()類似的函數還有mb_parse_str(),用法基本一致。
0×05 import_request_variables變量覆蓋
import_request_variables 函數可以在 register_global = off 時,把 GET/POST/Cookie 變量導入全局作用域中。
<?php import_request_variables("g", "get_"); echo $get_id; ?> //提交:?id=111 //結構:111
關於我:一個網絡安全愛好者,致力於分享原創高質量干貨,歡迎關注我的個人微信公眾號:Bypass--,瀏覽更多精彩文章。
參考鏈接:
代碼審計|變量覆蓋漏洞 http://www.freebuf.com/column/150731.html
[web安全] 變量覆蓋漏洞 http://blog.csdn.net/hitwangpeng/article/details/45972099