php中的变量覆盖

php中的变量覆盖
J1Zh0n9变量覆盖常见函数
1 | ● register_globals |
$$导致的变量覆盖
给出一个例子
1 | foreach ($_GET as $key => $value) |
首先$$经常与foreach一起出现
这个遍历中出现$$key = $$value,这里将键和值又当做变量来使用。就这个题目来说,我们用get方法传递:_200=flag,经过$$key = $$value的处理后,就会变为$_200=$flag,这样就会将原来的$_200的值覆盖掉,换成$flag的值
第二个例子
1 | foreach ($_POST as $key => $value) |
这个遍历中出现$$key = $value,这里将只是将数组键当做下一个变量,将数组的值当做这个$$key的值。例如post方法传入flag=abc,则处理后变成$flag=abc。这样就造成将我们需要获取的flag的值给覆盖掉了。
引用BJDCTF2020]Mark loves cat的题
flag.php
1 |
|
index.php
1 |
|
其实就是一个变量覆盖,做法有三种分别是三种不同变量的覆盖
比如我们覆盖handsome
第一个if语句中输出变量$handsome,满足条件$_GET[‘flag’] == = $x && $x !=== ‘flag’
这个条件的意思是不能同时有flag的键值对
只需/?handsome=flag&flag=handsome
由于都是get传参所以在传入前者时相当于生成了$handsome=$flag
由于原本存在$flag=flag{xxxxxx}此时这个值就被赋给了$handsome这个变量
然后经过第二个参数把$handsome的值又赋给$flag
或者 ?handsome=flag&flag=b&b=flag
顺序不能反,不然flag的值就被handsome覆盖了
extract导致的变量覆盖
extract函数的作用就是从数组中将变量导入到当前的符号表。
用数组的键名作为变量名,键值作为变量值。
此处是以数组形式接收的
1 |
|
语法:
1 | extract($array, $extract_type, $prefix) |
1 |
|
parse_str函数导致的变量覆盖
首先这个要想实现需要打开配置
; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = On
然后要注意parse_str是函数必须要按照php代码执行不然不会起作用
例一:
1 |
|
此时parse_str是在php标签内部的所以肯定是起作用的
此时要想拿到flag
write-up
找到核心代码:
1 | @parse_str($b); |
因为这里用到了parse_str函数来传递b,if语句的条件是拿$a[0]来比较的,因为这里的变量a的值已经是固定的了。
整体代码乍看起来又不可能,但是利用变量覆盖函数的缺陷这里可以对a的变量进行重新赋值,后面的的if语句再利用本文前面提到的md5()比较缺陷进行绕过:
1 | http://localhost/?b=a[0]=240610708 |
例二:
1 | error_reporting(0); |
利用parse_str进行绕过
$_SERVER[‘argv’]的使用
?a=2+1+fl0g=flag_give_me
CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[2])
php 5.2.17里头为什么没有php.ini-development文件
.ini-recommended和php.ini-dist你把任意一个重命名为php.ini即可
这两个文件的区别是:
php.ini-recommended的安全等级比php.ini-dist高。默认是把display_errors 设置为 off,将 magic_quotes_gpc 设置为Off等等。而相对的php.ini-dist都是默认的配置。 所以说,如果你只是想进行web测试和普通开发,使用php.ini-dist,不然就是用php.ini-recommended。
register_globals()函数
register_globals全局变量覆盖。
这个特性已经在PHP5.3.0中废弃,并在5.4.0版本移除。
php.ini中有一项配置为register_globals,即注册全局变量。
当register_globals=On时,传递过来的值会被直接注册为全局变量,直接使用。所以此时,代码中的参数会被用户提交的参数覆盖掉。
1 |
|
payload:/?a=1
此时会覆盖掉$a的值,触发变量覆盖漏洞












