php变量覆盖漏洞

php变量覆盖漏洞学习
合上吧,没有新姿势。

全局变量覆盖

1
2
3
4
5
6
<?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

从 PHP » 4.2.0 版开始配置文件中 PHP 指令 register_globals 的默认值从 on 改为 off 了,自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。源自Register Globals

$ $导致的变量覆盖问题

这里在url中传值?name=test会将$name的值覆盖掉,变成test

举个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//?name=test
//output:string(4) “name” string(4) “test” string(4) “test” test
$name='hello';
foreach ($_GET as $key => $value)
$$key = $value;
var_dump($key);
echo "<br/>";
var_dump($value);
echo "<br/>";
var_dump($$key);
echo "<br/>";
echo $name;
?>

extract()变量覆盖

extract()函数的具体用法,函数的定义如下:

int extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] )

其中,第二个参数指定函数将变量导入符号表时的行为,最常见的两个值是EXTR_OVERWRITEEXTR_SKIP

如果没有指定 flags,则被假定为 EXTR_OVERWRITE,也就是默认情况下使用EXTR_OVERWRITE

第二个参数 含义
EXTR_OVERWRITE 如果有冲突,覆盖已有的变量。
EXTR_SKIP 如果有冲突,不覆盖已有的变量。
EXTR_PREFIX_SAME 如果有冲突,在变量名前加上前缀 prefix
EXTR_PREFIX_ALL 给所有变量名加上前缀 prefix
EXTR_PREFIX_INVALID 仅在非法/数字的变量名前加上前缀 prefix
EXTR_IF_EXISTS 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。 举个例子,以下情况非常有用:定义一些有效变量,然后从 $_REQUEST 中仅导入这些已定义的变量。
EXTR_PREFIX_IF_EXISTS 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
EXTR_REFS 将变量作为引用提取。这有力地表明了导入的变量仍然引用了 array 参数的值。可以单独使用这个标志或者在 flags 中用 OR 与其它任何标志结合使用。

举个简单的例子:

1
2
3
4
5
6
7
<?php
$flag = '0';
extract($_GET);
if($flag)
echo "get flag";
else
echo "try again";

extract()函数从用户可以控制的数组中导出变量时,可能发生变量覆盖。在这个例子里,extract()$_GET中导出变量,从而可以导致任意变量被覆盖。

这里构造payload:http://127.0.0.2:82/files/not_study_php/test.php?flag=2

impor_request_variables变量覆盖

impor_request_variables函数的具体用法,函数定义如下:

bool import_request_variables ( string $types [, string $prefix ] )

impor_request_variables()GET,POST,Cookie中的变量导入到全局,可以用字母‘G’‘P’‘C’分别表示 GETPOSTCookie。这些字母不区分大小写,所以你可以使用‘g’、‘p’和‘c’的任何组合。注意这些字母的顺序,当使用“gp”时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略。

适用php版本(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)

举个简单的例子:

1
2
3
4
5
6
7
<?php
$flag = '0';
import_request_variables('G');
if($flag == '1')
echo "get the flag";
else
echo "try again";

这里构造payload:http://127.0.0.2:82/files/not_study_php/test.php?flag=1

parse_str()变量覆盖

parse_str函数的具体用法,函数的定义如下:

void parse_str ( string $encoded_string [, array &$result ] )

举个简单的例子:

1
2
3
4
5
<?php

$flag = "this is flag";
parse_str($_SERVER['QUERY_STRING']);
echo $flag;

正常访问

url中参数可控

Reference

本文标题:php变量覆盖漏洞

文章作者:xianyu123

发布时间:2018年12月07日 - 21:25

最后更新:2019年05月11日 - 20:52

原始链接:http://0clickjacking0.github.io/2018/12/07/php变量覆盖漏洞/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------    本文结束  感谢您的阅读    -------------