变量覆盖
前言
变量覆盖指的是可以用我们自定义的参数值替换程序原有的变量值。
变量覆盖漏洞大多数由函数使用不当导致,经常引发变量覆盖漏洞的有:extract(),parse_str()和import_request_variables()函数,以及”$$”。
$$
$$这种写法称为可变变量
一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。
1 | <?php |
1 | <?php |
题目分析
$_SERVER[‘REQUEST_METHOD’]为访问页面时的请求方法
foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。
有两种语法:
1 | foreach (array_expression as $value) // 遍历给定的 array_expression 数组。每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。 |
源码包含了flag.php文件,并且需要满足3个if里的条件才能获取flag,题目中使用了两个foreach并且也使用了$$.两个foreach中对 $$key的处理是不一样的,满足条件后会将$flag里面的值打印出来,所以$flag是在flag.php文件文件中的。
但是由于第7,11-14行间的代码会将flag的值给覆盖掉了,所以需要先将flag的值赋给_200或_403变量,然后利用die(_200)或die(_403)将flag打印出来。
解题方法
由于第7,11-14行间的代码会将$flag的值给覆盖掉,所以只能利用第一个foreach先将$flag的值赋给$_200,然后利用die($_200)将原本的flag值打印出来。
extract()函数
extract(array,extract_rules,prefix)
参数 | 描述 |
---|---|
array | 必需。规定要使用的数组。 |
extract_rules | 可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。 |
prefix | 可选。请注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。 |
1 | <?php |
题目分析
题目要求使用POST提交数据,extract($_POST)会将POST的数据中的键名和键值转换为相应的变量名和变量值,利用这个覆盖$pass和$thepassword_123变量的值,从而满足pass==thepassword_123这个条件。
解题方法
使用POST请求提交pass=1&thepassword_123=1, 然后extract()会将接收到的数据将$pass和$thepassword_123变量的值覆盖为空,便满足条件了。
PAYLOAD:pass=1&thepassword_123=1
parse_str()函数
void parse_str ( string $encoded_string [, array &$arr ] )
参数 | 描述 | ||
---|---|---|---|
encoded_string | 必需。规定要解析的字符串。 | ||
arr | 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。 | ||
|
1 | <meta charset="utf-8"> |
题目分析
首先要求使用GET提交id参数,然后parse_str($id)对id参数的数据进行处理,再使用判断a[0] != ‘QNKCDZO’ && md5(a[0]) == md5(‘QNKCDZO’)的结果是否为真,为真就返回flag,md5(‘QNKCDZO’)的结果是0e830400451993494058024219903391。
解题方法
使用GET请求id=a[0]=240610708,这样会将a[0]的值覆盖为240610708,然后经过md5后得到0e462097431906509019562988736854与md5(‘QNKCDZO’)的结果0e830400451993494058024219903391比较都是0 所以相等,满足条件,得到flag。
import_request_variables()
bool import_request_variables ( string $types [, string $prefix ] )
将 GET/POST/Cookie 变量导入到全局作用域中。
参数 | 描述 | ||
---|---|---|---|
types | 指定需要导入的变量。可以用字母‘G’、‘P’和‘C’分别表示 GET、POST 和 Cookie。这些字母不区分大小写,所以你可以使用‘g’、‘p’和‘c’的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序,当使用“gp”时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略。 | ||
prefix | 为变量名的前缀,置于所有被导入到全局作用域的变量之前。虽然 prefix 参数是可选的,但如果不指定前缀,或者指定一个空字符串作为前缀,你将获得一个 E_NOTICE 级别的错误。 | ||
|