【愚公系列】2024年08月 《CTF实战:从入门到提升》 008-Web安全入门(PHP变量覆盖漏洞)
🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
🚀前言
PHP变量覆盖漏洞是一种安全漏洞,发生在PHP代码中。它可以允许攻击者通过覆盖一个或多个变量的值来绕过身份验证或控制程序的执行流程。
具体来说,当PHP代码中的某个变量没有经过正确的输入验证或过滤时,攻击者可以通过提交恶意数据来覆盖该变量的值。这可能导致程序执行不受控制的行为,例如绕过身份验证、窃取敏感数据或执行恶意代码。
PHP变量覆盖漏洞通常与其他漏洞一起利用,例如未经验证的用户输入、弱密码或不安全的文件上传功能。避免这类漏洞的最佳做法是始终对用户输入进行验证和过滤,并确保所有使用的变量都是安全的。
🚀一、PHP变量覆盖漏洞
当PHP开发者在编写代码时,很多时候为了方便会直接完全信任用户的输入,不做校验地赋值到自己程序的变量中。如果这时变量被传到了某些危险函数上,就会产生一些意想不到的后果。
🔎1.PHP变量覆盖的概念
<?php
$cmd="echo hello";
//一些能够覆盖变量 cmd的逻辑
system ($cmd);
简单地解读一下,上面这部分代码定义了变量cmd,之后会被带入system执行这个变量中所记载的命令,如这里就是echo hello。但如果中间逻辑中$cmd可控,那么就可以操控$cmd,随心所欲地在目标机器上执行我们想要执行的命令了。这里$cmd被直接赋值:如果在system中多了一个能覆盖变量的函数,例如,能将$cmd的值改成whoami,就会造成下面system执行的是whoami这个命令,那么这就是一个变量覆盖漏洞。
变量覆盖漏洞的危害在于它能更改变量的值,一般都是配合其他函数/漏洞“打组合拳”。
🔎2.PHP变量覆盖的函数
在PHP中有如下几种变量覆盖的方
- PHP语法导致的变量覆盖
<?php
$a= "want_to_be_a_cat";
$b = "miaow";
$test =$a;
$$test = $b;
var_dump($want_to_be_a_cat);//输出miaow
这段代码使用了PHP的变量变量特性和变量赋值操作。让我一步一步解释:
-
定义了两个变量
$a和$b,分别赋值为字符串 “want_to_be_a_cat” 和 “miaow”。 -
创建了一个新变量
$test,它的值与变量$a相同,即 “want_to_be_a_cat”。 -
使用变量变量的特性,将
$b的值 “miaow” 赋值给$want_to_be_a_cat变量。这里$$test表示将变量$test的值作为变量名,并将其赋予$b的值。 -
使用
var_dump()函数打印变量$want_to_be_a_cat的值,输出为 “miaow”。因为变量$want_to_be_a_cat被赋值为 “miaow”。
所以,这段代码的最终输出是 “miaow”。

2) PHP函数导致的变量覆盖(extract、parse_str、mb_parse_str、import_request_variables)
<?php
$a="want_a_cat";
$b="miao";
extract([$a =>$b]);
var_dump($want_a_cat);//输出miao
//parse_str("want_a_cat=miao");//只在PHP5.2 中出现
//var_dump($want_a_cat);//输出 miao
//mb_parse_str("want_a_cat=miao");//只在 PHP5.2 中出现
//var_dump($want_a_cat);//输出miao
//import_request_variables ("p","");
//var_dump($want_a_cat);//传人want_a_cat=miao,输出miao
这段代码使用extract()函数将变量$a作为键名,变量$b作为键值来创建一个新的变量$want_a_cat。然后使用var_dump()函数输出变量$want_a_cat的值,结果为"miao"。
注释部分的代码演示了其他几种方式来实现类似的功能,但它们可能只在特定版本的PHP中可用。parse_str()函数可以将字符串解析为变量,mb_parse_str()函数是parse_str()函数的多字节字符版本。import_request_variables()函数可以将请求的GET、POST和COOKIE参数导入到全局命名空间中。
请注意,这些函数中的一些在较新的PHP版本中已被弃用或移除,因此最好不要使用它们。
3) PHP配置项导致变量覆盖(register_globals: php.ini中的一个配置项,配置为true之后传入GET/POST参数都会被赋成变量)。
<?php
var_dump($want_to_be_a_cat);//传人want_to_be_a_cat=miao,输出miao
🔎3.PHP变量覆盖漏洞的利用方法
下面来看一下PHP语法导致的变量覆盖漏洞,PHP有种语法叫可变变量:可以动态设置和使用变量,代码如下:
<?php
$test='abc';
$$test=' success ';
echo $abc;
//输出 success

上述代码就是可变变量,首先定义了$test,其值是abc,然后$$test这个语法先把$test解析成abc,继续解析就成了$abc=‘success’,至此多了一个abc变量,造成变量覆盖。${$test}也是同理,会优先解析台内的变量,然后$i$test}==${abc}==$abc。
对于PHP函数导致的变量覆盖漏洞,来看下面这样一段代码:
<?php
extract(array('test'=>'b '));
echo $test;
extract函数可以接受三个参数:
-
第一个参数(必需):类型为数组,分为键和值。键是变量名,值是变量值。如果没有定义值,则默认为NULL。
-
第二个参数:一些可选的配置项,如EXTR_OVERWRITE。如果变量已经存在,将会覆盖该变量。具体的参数可以参考PHP文档。
-
第三个参数:前缀。只有当第二个参数为EXTR_PREFIX_SAME、EXTR_PREFIX_ALL、EXTR_PREFIX_INVALID或EXTR_PREFIX_IF_EXISTS时才生效。该参数会自动为变量添加前缀。
再来看下面这段parse_str的代码:
<?php
parse_str("test=b");
echo $test;
parse_str函数可以接受两个参数:
-
第一个参数必需,类型为字符串,格式为"变量名=变量值&变量名=变量值",使用"&“作为分割符。注意,此函数会自动进行URL解码。例如,我们想把
$test覆盖成”$",而"$“刚好是变量分隔符,这里可以使用”%26"进行URL编码转义。 -
第二个参数为可选,类型为数组。加上这个选项后,不会生成新的变量,而是将变量存放进指定的数组。
同样的逻辑也适用于mb_parse_str函数。
“函数import request variables在PHP 5.4版本已经被淘汰,并且基本不再使用。为了解决PHP配置项导致的变量覆盖问题,需要在php.ini文件中设置register globals=On。请注意,这个配置项在PHP5.3.0起已经废弃,并且在PHP5.4.0起被移除。该配置项的作用是自动将请求的GET/POST参数注册为变量。例如,如果请求中携带了GET参数a=1,则相当于执行了$a=1操作。”
🔎4.案例解析[BJDCTF2020]Mark loves cat
看看案例[BJDCTF2020]Mark loves cat打开之后页面如图所示

访问靶机地址,那么第一件事就是信息搜集。找到漏洞点,查看源代码搜索.php没有什么发现,接着扫描敏感文件。当访问/.git/时,返回403Forbidden,说明存在/.git信息泄露,如图所示

使用git_extract获取源码,发现只有两个php文件:flag.php和index.php。
下面是flag·php的内容

index.php的内容如下

代码中if较多。遇到这种题目,就直接看关键字。最后有echo $flag,并且前面有$$,经典的变量覆盖问题。由于$flag在flag·php中定义了,并且在开头就包含了文件,是否可以利用变量覆盖漏洞把$yds的值覆盖成$flag?当前可以了。
直接使用GET传递yds=flag,遇到以下的变量覆盖时:

就成了$yds=$flag,成功把$flag赋值给了$yds,然后不传递flag参数,让程序退出,输出$yds,拿到flag。
🚀感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”
- 点赞
- 收藏
- 关注作者
评论(0)