PHP代碼審計筆記--變量覆蓋漏洞


   變量覆蓋指的是用我們自定義的參數值替換程序原有的變量值,一般變量覆蓋漏洞需要結合程序的其它功能來實現完整的攻擊。

   經常導致變量覆蓋漏洞場景有:$$,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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM