• PHP变量覆盖漏洞试验随笔


    其实顾名思义,变量覆盖漏洞就是原先服务端定义好的变量,原设定不能由用户随意更改、查看的变量,可以被我们用一些方法去更改、读取。

    先贴一下之前做的有关php可变变量的复习和foreach导致变量覆盖的试验

    得再了解一下php可变变量

    由下面的试验,应该是如果同时存在$a和

    a$a" role="presentation">a$a
    a本身的值就不重要了,它的值会变成那个重名变量的值,而如果那个重名变量不存在,$a和
    a" role="presentation" style="text-align: center; position: relative;">a
    a的值

    简单来说:

    1-$hello存在,$$a的值变成$hello的值

    2-$hello不存在,$hello的值变成$$a的值

     

    1. $a='hello';
    2. $$a=1;            //这里再定义$$a,$$a=1应该就相当于$hello=1,可以看到$$a和$hello输出是一样的
    3. echo $$a.'
      '
      ;
    4. echo $hello.'
      '
      ;
    5. ------------------------------
    6. 1
    7. 1

    1. $a='hello';
    2. $$a='2';
    3. $hello='3';
    4. echo $a;
    5. echo $$a;
    6. echo $hello;
    7. --------------------------------
    8.    hello
    9.    3
    10.    3
    11.    //之后我突然发现,如果$$a='2';$hello='3'这两行代码交换了位置,echo $hello会输出2
    1. $a='hello';
    2. $$a='2';
    3. #$hello='3';
    4. echo $a;
    5. echo $$a;
    6. echo $hello;
    7. --------------------------------
    8.    hello
    9.    2
    10.    2

    另外说一下${}这样的,${}会获取内部的值并把它当作一个变量来解析

    1. $a='1';
    2. $$a='2';
    3. echo $1;  //这么写会报错的,数字不能做变量名
    4. echo ${1};   //这样写就和上面的利用规则一样了
    5. --------------------------------------
    6. 报错  2

    简单复习一下可变函数,当我们在一个变量后面加上括号,php就会尝试把它当作一个函数来解析

    1.    function test(){
    2.    echo "hello";
    3. }
    4. $a='test';
    5. $a();
    6. -------------------------------------
    7. hello

    那么,下面这个foreach到底是怎么完成变量覆盖的?

    这里我发现foreach遍历的时候它内部的$x这种带一个$符号的就是我们get传的键值对,带两个$$的是这俩分别对应的值

    1. foreach($_GET as $x => $y){
    2.    $$x = $$y;
    3. }

     

    1. $hello='123';
    2. $flag="flag{hhh}";
    3. $_GET=array();
    4. $_GET['hello']="flag";
    5. var_dump($_GET);
    6. echo $hello.'
      '
      ;
    7. echo $$flag.'
      '
      ;
    8. foreach($_GET as $x => $y){
    9.    echo $x.'<--$x_first_$y-->'.$y.'
      '
      ;
    10.    echo $$x.'<--$$x_second_$$y-->'.$$y.'
      '
      ;
    11.    echo $hello.'
      '
      ;
    12.    $$x = $$y;
    13.    echo $hello.'
      '
      ;
    14. }
    15. echo $hello.'
      '
      ;
    16. -----------------------------------------
    17. C:\wamp64\www\test\ppp.php:12:
    18. array (size=1)
    19.  'hello' => string 'flag' (length=4)
    20. 123
    21. hello<--$x_first_$y-->flag
    22. 123<--$$x_second_$$y-->flag{hhh}
    23. 123
    24. flag{hhh}
    25. flag{hhh}

    extract

    1. $a = "1";
    2. $my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
    3. extract($my_array);
    4. echo "\$a = $a; \$b = $b; \$c = $c";
    5. ?>
    6. 运行结果:$a = Cat; $b = Dog; $c = Horse
     
    

    例题

    1. $test=*****;
    2. extract($_GET);
    3. if(isset($gift)){
    4.    $content=trim($test);
    5.    if($gift==$content){
    6.        echo 'flag is:'.$flag;
    7.   }else{
    8.        echo 'nonono';
    9.   }
    10. }

    parse_str() 函数

    1. parse_str("name=gyy&&age=60");   // test=123&gift=123
    2. echo $name."
      "
      ;
    3. echo $age;
    4. ?>
    5. 输出了gyy和60
    ​$$

    不仅仅是函数会导致变量覆盖,有些特殊符号的特殊搭配也会引起变量覆盖漏洞,比如$$。

    $$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值,因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。

    做一下规律总结,foreach里面

    $$x = $y; 我们可以以类似flag=xxx的形式把任意变量覆盖为xxx

    x=" role="presentation" style="text-align: center; position: relative;">x=
    y; 若已知存在$a和$b两个变量,以a=b的形式,可以把$b的变量赋值给$a,比如把$flag赋值给一个无关紧要的变量,然后输出这个无关紧要的变量

    除了这两种利用方式,别的好像是造成不了实际影响的,可以这么理解,上面说过

    1. $a='hello';
    2. $$a=1;           //这里再定义$$a,$$a=1应该就相当于$hello=1,可以看到$$a和$hello输出是一样的

    或许可以这么记,虽然不知道啥原理,左边的得借助$$进到这个变量的$xxx才能进行传值,右边的不需要进到$xxx

    1-当$$x=$y,事先有$x=xxx,

    $$x=$xxx=$y,覆盖

    2-当

    x=" role="presentation" style="text-align: center; position: relative;">x=
    y,事先存在$x=xxx,$y=hhh

    x=$xxx=" role="presentation" style="text-align: center; position: relative;">x=$xxx=
    y=$hhh,覆盖

    3-当$x=$$y,左边进不到$xxx,没法传值

    1. $a = 1;
    2. foreach(array('_COOKIE','_POST','_GET') as $_request) {       // $_request只是一个普通的变量名
    3. foreach($$_request as $_key=>$_value)
    4. {$$_key=addslashes($_value);}}
    5. echo $a;
    6. ?>
  • 相关阅读:
    Java中的多线程概述、多线程实现、线程类常见的方法与线程安全问题详细使用(多线程上篇含Lock锁同步方法同步代码块)
    Redis实战 - 17 Redis事务和乐观锁实现缓存登录图片验证码功能
    Spring5应用之AOP切入点详解
    云计算【第一阶段(14)】Linux的目录和结构
    部署Redis集群
    wxpython分页
    生成器高级用法
    多商户商城系统功能拆解24讲-平台端分销会员
    计算机毕业设计Java奥利给共享自习室系统(源码+系统+mysql数据库+lw文档)
    【Java】Java对象的上转型对象与下转型
  • 原文地址:https://blog.csdn.net/qq_61778128/article/details/126877145