• 变量覆盖 学习笔记


    变量覆盖


    相关文章 & Source & Reference


    $$导致的变量覆盖问题

    $$介绍

    $$这种写法称为可变变量

    一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。

    1. $a = "hello";
    2. echo "$a"; //输出hello
    3. $a="world";
    4. echo "$a"; //输出hello
    5. echo "$$a"; //输出word
    6. echo "$a ${$a}"; //输出hello world
    7. echo "$a $hello"; //输出hello world
    8. ?>

    漏洞产生

    使用 foreach 来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。

    例如

    1. foreach ($_GET as $key => $value) {
    2. ${$key} = $value;
    3. }
    4. echo $a;
    5. ?>

    get 得到的数据 $key 和 $value, 关键第 3 行,${$key} 用 get 传进来的 $key 做为新的变量, 将 get 传进来的 $value 赋值给它。

    get ?a=1 第 3 行会解析为 $a=1。就造成了变量覆盖。


    extract()函数使用不当

    extract()函数从数组中将变量导入到当前的符号表。该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

    extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): int

    第一个参数是必须的,会不会导致变量覆盖漏洞由第二个参数决定,该函数有三种情况会覆盖已有变量。

    例如

    1. $a = 1; //原变量值为1
    2. $b = array('a' => '3');
    3. extract($b); //经过extract()函数对$b处理后
    4. echo $a; //输出结果为3
    5. ?>

    又例如

    1. $a = "0";
    2. extract($_GET);
    3. if ($a == 1) {
    4. echo "Hacked!";
    5. } else {
    6. echo "Hello!";
    7. }
    8. ?>

    ?a=1 就可以覆盖 a

    例题

    1. extract($_GET);
    2. if(isset($bdctf))
    3. {
    4. $content=trim(file_get_contents($flag)); //file_get_contents—将整个文件读入一个字符串
    5. if($bdctf==$content) //trim—去除字符串首尾处的空白字符(或者其他字符)
    6. { echo'bdctf{**********}'; }
    7. else
    8. { echo'这不是蓝盾的密码啊'; }
    9. }

    题目使用了 extract($_GET) 接收了 GET 请求中的数据,并将键名和键值转换为变量名和变量的值,然后再进行两个 if 的条件判断,所以可以使用 GET 提交参数和值,利用 extract() 对变量进行覆盖,从而满足各个条件。

    使 $bdctf 与 $content 都为空或者不存在就满足 $bdctf==$content

    get ?flag=&bdctf= 得到 flag


    parse_str()函数使用不当

    parse_str(string $string, array &$result): void

    如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。

    php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。

    parse_str 函数的作用就是解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量

    例如

    1. $a = 1; //原变量值为1
    2. parse_str('a=2'); //经过parse_str()函数后注册变量$a,重新赋值
    3. print_r($a); //输出结果为2
    4. ?>

    例题

    1. error_reporting(0);
    2. if(
    3. empty($_GET['id'])) { //empty()检查是否为空
    4. show_source(__FILE__); //highlight_file—语法高亮一个文件
    5. die(); //等同于exit—输出一个消息并且退出当前脚本
    6. } else {
    7. include (‘flag.php’);
    8. $a = "test";
    9. $id = $_GET['id'];
    10. @parse_str($id);
    11. if ($a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)) {
    12. echo $flag;
    13. } else {
    14. exit(‘其实很简单其实并不难!’);
    15. }
    16. }
    17. ?>

    PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

    这里其实利用了弱类型的知识点

    使用get请求 ?id=a[0]=s878926199a 得到flag


    mb_parse_str()变量覆盖

    mb_parse_str()函数用于解析GET/POST/COOKIE数据并设置全局变量,和parse_str()类似:

    1. $a = 'oop';
    2. mb_parse_str($_SERVER["QUERY_STRING"]);
    3. if ($a == 'test') {
    4. echo "Hacked!";
    5. } else {
    6. echo "Hello!";
    7. }
    8. ?>

    register_globals全局变量覆盖

    注:register_globals 已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

    php.ini 中有一项为 register_globals,即注册全局变量,当 register_globals=On 时,传递过来的值会被直接的注册为全局变量直接使用,而 register_globals=Off 时,我们需要到特定的数组里去得到它。

    当register_globals=On,变量未被初始化且能够用户所控制时,就会存在变量覆盖漏洞:

    1. echo "Register_globals: " . (int)ini_get("register_globals") . "
      "
      ;
    2. if ($a) {
    3. echo "Hacked!";
    4. }
    5. ?>

    通过 GET 和 POST 方式输入变量 a 的值都可以覆盖 a

    从 cookie 里也可以


    import_request_variables()使用不当

    import_request_variables 好像比较难见到了

    例如

    1. $auth='0';
    2. import_request_variables('G');
    3. if($auth== 1){
    4. echo"private!";
    5. }else{
    6. echo"public!";
    7. }
    8. ?>

    get auth=1时,网页上会输出private!

    import_request_variables('G')指定导入GET请求中的变量,从而导致变量覆盖
    点击关注,共同学习!安全狗的自我修养

    github haidragon

    https://github.com/haidragon

  • 相关阅读:
    基于RM编译码的协作MIMO系统误码率matlab仿真,对比不同RM编译码参数
    10、IOC 之类路径扫描和托管组件
    MatrixOne 支持多样化生态工具
    基于SSM的景点管理系统
    【爬虫】charles手机抓包环境设置(设置系统证书)
    阿里内部疯传的 2022年度Java面试总结手册「失传资料」
    2万字带你从0到1搭建一套企业级微服务安全框架
    YOLOv7+姿态估计Pose+tensort部署加速
    四.Kafka入门到精通-SpringBoot整合Kafka(Producer拦截器&Producer监听器)
    C++标准模板(STL)- 类型支持 (数值极限,is_modulo,digits,digits10)
  • 原文地址:https://blog.csdn.net/sinat_35360663/article/details/127617872