前言
php的变量问题是php代码审计中的一部分,相对php反序列化来说较为简单。再此总结一下这类相关内容。
特殊的变量
可变变量
我们知道php都是用$符号来定义变量的,那么可变变量的定义符号为$$。主要原理是将一个变量的内容作为另一个变量的名称。我们来举个例子:
<?php
$a = "123";
$b = "age";
$age = "qwe";
print_r($b);
//输出字符串"age"
print_r($$b);
//输出字符串"qwe"
?>
超全局变量
比较常用的是$GLOBALS变量,它引用全局作用域中可用的全局变量,任何地方都可以使用。通过数组的形式输出,变量名为键名,内容为键值。有时flag隐藏在某个变量中,我们可以通过超全局变量将他打印出来。(小写的global是定义全局变量的,实现在函数内不需要传参就可以访问该变量)
变量覆盖
extract函数:从数组中将变量导入到当前的符号表。(官方语言)该函数使用数组键名作为变量名,数组键值作为变量值。extract函数将检查数组键值是否为合法的变量名,同时也检查符号表中已存在的变量名是否冲突,如果冲突,就覆盖已有的变量值。
来看一个例子:
<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan)) {
$content=trim(file_get_contents($flag));
if($shiyan==$content) { echo'flag{xxx}'; }
else { echo'Oh.no'; } }?>
进行简单的代码审计,我们需要让$shiyan和$content相等,题目中用extract函数接收GET请求中的数据,将键名和键值作为变量名和变量值,我们不知道$flag的值到底是什么?那么就要用到变量覆盖了。我们可以将$shiyan和$flag都赋值为空,extract函数会将覆盖原有同名的变量值。从而达到两个变量相等。
构造payload:?shiyan=&flag=
prase_str函数也具有变量覆盖漏洞。它的作用就是将字符串注册成变量。
基本语法:prase_str(string,array) string参数:要解析的字符串 array参数:储存变量的数组名称(可选)若没有这个array参数,则该函数设置的变量就覆盖掉已存在的同名变量。
<?php
$a = "gou";
parse_str("a=mao");
print_r($a);
?>
//打印出猫
<?php
$a = "gou";
parse_str("a=mao",$arr);
print_r($a);
//打印mao
echo "\n";
print_r($arr);
/*Array
(
[a] => mao
)*/
?>
这就是有无array参数的区别。用parse_str函数也可以做到变量的覆盖。
结语
了解php变量是php代码审计的基础