php发展

首页 » 常识 » 预防 » 细说变量覆盖那些事
TUhjnbcbe - 2025/6/12 17:49:00

前言

最近在挖洞和看一些ctf题目中可以看到一些变量覆盖的知识点,之前对这个方面学习的有点不全面,虽然网上有这方面的文章,但是感觉讲的不是很全面,所以就决定写一篇文章来总结这方面的知识。

本文涉及相关实验:PHP安全之变量覆盖漏洞(通过该实验,详细了解PHP中变量覆盖漏洞相关的知识。如:$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等。)

漏洞原理

变量覆盖是指可以用自己的传参值代替程序原有的变量值。

漏洞寻找

例如下面的函数或者语法使用不当时就会出现漏洞。

$$extract()parse_str()import_request_variables()mb_parse_strregister_globals漏洞解析

这里先分析函数,再分析漏洞。

extract()

原理

extract()

函数从数组中将变量导入到当前的符号表。

例如

?php

$a=eeknight;

$my_array=array(a=C,b=T,c=F);

extract($my_array);

echo\$a=$a;\$b=$b;\$c=$c;

?

输出:

$a=C;$b=T;$c=F

攻击手段

这里先举个例子

?php

$a=echoeeknight;;

echo$a;

echo\n;

eval($a);

?

输出:

echoeeknight;

eeknight

在上面双引号包裹了单引号,然后通过eval去利用他,就可以直接输出单引号里的东西了。

为什么要说这个东西,因为当你单引号里的东西可以被利用,是不是就可以写什么执行什么了。

怎么利用呢,这时候刚才介绍的extract就发挥作用了。

把上面的例子简单改一下

?php

$a=echoeeknight;;

extract($_GET);

eval($a);

?

$$

原理

$$

产生的漏洞主要是因为foreach遍历数组的值,然后将获取的数组键名作为变量,数组中的值作为变量的值。

在这先简单介绍一下foreach和$$。

foreach循环只适用于数组,并用于遍历数组中的每个键/值对。

?php

$colors=array(red,green,blue,yellow);

foreach($colorsas$value){

echo$value\n;

}

?

输出:red

green

blue

yellow

$$

这里举个栗子

在PHP中,$var表示一个名为var的普通变量,它存储字符串、整数、浮点等任何值。而$$var是一个引用变量,用于存储$var的值。

在我看来就是套娃。

?php

$var=ee;

$$var=eeknight;

echo$var;

echo\n;

echo$$var;

echo\n;

echo$ee;

?

输出:ee

eeknight

eeknight

parse_str()

parse_str()

把查询字符串解析到变量中。

parse_str(string,array)

string必需。规定要解析的字符串。

array可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。

?php

parse_str(name=eeknightage=20);

echo$name.\n;

echo$age;

?

输出:eeknight

20

攻击方式

通过上面的例子,可以想到,如果parse_str()括号是GET,PSOT等之类的,我们是不是就可以直接执行我们要的函数。

mb_parse_str

mb_parse_str

—解析GET/POST/COOKIE数据并设置全局变量

具体的用法和上面的parse_str()一样。

这里就不多说明了。

import_request_variables()

import_request_variables()

函数将GET/POST/Cookie变量导入到全局作用域中。

?php

import_request_variables(gP,ee_);

echo$ee_knight;

?

攻击方式

只要利用了这个函数,就可以直接对里面的变量进行赋值。

register_globals

register_globals

的意思就是注册为全局变量

当php.ini中register_globals=On时,传递过来的值会被直接注册为全局变量,当为off时,需要到特定的数组中去得到

例子

?php

echoRegister_globals:.(int)ini_get(register_globals).br/;

if($auth){

echohello!;

}

?

ON

OFF

这里ON--OFF的转换时记得重启一下apache。

一些附加说明

为什么echo\$a=$a;\$b=$b;\$c=$c;这里要加上\呢解:这些斜杠的的意思就是,让后面的变量失去意义。那么写的是什么就是什么。parse_str()php.ini文件中的magic_quotes_gpc设置影响该函数的输出。如果已启用,那么在parse_str()解析之前,变量会被addslashes()转换。import_request_variables()该函数在最新版本的PHP中已经不支持。支持的版本:PHP4=4.1.0,PHP55.4.0。register_globalsregister_globals从php5.3.0起废弃,并从php5.4.0时移除。漏洞防御

addslashes()addslashes()在每个双引号()前添加反斜杠。使用原始变量,不进行变量注册;验证变量存在,如果一定要进行变量注册,可以在注册变量前先判断变量是否存在。

1
查看完整版本: 细说变量覆盖那些事