加入收藏 | 设为首页 | 会员中心 | 我要投稿 武陵站长网 (https://www.50888.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

第二十天php变量覆盖

发布时间:2023-03-04 10:34:12 所属栏目:PHP教程 来源:未知
导读: register_globals导致的变量覆盖问题
默认在5.4中废弃

register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们

register_globals导致的变量覆盖问题

  默认在5.4中废弃

register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。COOKIE,_COOKIE,C?OOKIE,_POST,$_GET全部会注册为全局变量.

在这里插入图片描述

漏洞原理

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

漏洞寻找

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

$$
extract()
parse_str()
import_request_variables()
mb_parse_str
register_globals

$$

原理

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

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

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

<

?php 
$colors = array("red","green","blue","yellow"); 
foreach ($colors as $value) {
   echo "$value n";
}
?>
输出:red
 green
 blue
 yellow 

$$这里举个例子

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

在我看来就是套娃。 先来个简单的

 $a = "b";
 $$a = "123"
echo $b;
结果 : 123

<?php
$var = "ee";
$$var = "eeknight";
echo $var ;
echo "n";
echo $$var;
echo "n";
echo "$ee";
?>
输出:ee
     eeknight
  eeknight

php中的数组

通过数组可以一次性定义一组变量.

数组有多个元素组成,每个元素相当于一个变量

每一个元素是一个"键值对" (key => value) , 键是变量的名字, 值是变量中的数据.

<?php
      $a[1] = "bihuo";
      $a[2] = "lisi";
      $a[3] = 123;
      print_r($a);
      echo"
"
; var_dump($a);

在这里插入图片描述

在这里插入图片描述

foreach函数遍历数组

.foreach函数有两种语法格式:

·foreach(array asvalue),循环读取数组中元素的值并赋值给变量value),循环读取数组中元素的值并赋值给变量value),循环读取数组中元素的值并赋值给变量value。。

·foreach(array askey=>key=>key=>value),循环读取数组中元素的键赋值给变量key,元素的值赋值给变量key,元素的值赋 值给变量key,元素的值赋值给变量value。

$users=array("01"=>"zhangsan","02"=>"1isi","03"=>123);
$colors = array("red","green","blue");
foreach($users as $value) {
    echo $value . "
"
; } foreach($colors as $key=>$value) { echo "$key=>$value" . "
"
; }

在这里插入图片描述

来看一个例题

foreach 配合$$

<?php
//可变变量
//$a = 'b';
//$$a = 'hello';
//echo $b;
foreach (array('_GET', '_POST', '_COOKIE') as $item) {  
    foreach ($$item as $k => $v) { //$$item = $_GET as $k=>$v   这里可变变量 $_GET
        $$k = $v;  //$$k = $XDEBUG_SESSION_START = PHPSTORM   
    }              //数值定义变量 $a = " bihuo.cn"
}
if (!isset($a)) {   
    $a = 100;        //  bihuo.cn
}

if ($a == 'bihuo.cn') {
    echo 'ok';
}

在这里插入图片描述

举个例子

php
<?php
include'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_GET as $x => $y){ //get传值
    $$x = $$y;  //漏洞在这里  比如输入 yds=flag 相当于 $yds=$flag
}
foreach($_GET as $x => $y){ 
    if($_GET['flag'] === $x && $x !== 'flag'){ //判断get传进来的值等不等于flag 如果等于flag则跳过
        exit($handsome);
    }
}
//检测get是否为flag 或者post是否为flag  必须两方都为假  否则输出$yds
//通过这里我们就可以结合前面的来构造 既然要输出$yds所以我们想办法让$flag的值赋值给$yds  
//构造yds=flag GET传输 在经过第一个foreach的时候进行了赋值 等于进行了这样的一个操作$yds=$flag  
//所以这个条件为真就可以输出flag了。
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
    
}
//
//检测POST flag是否为flag  或者get 是否为flag   //至少有一个为真则为真
if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}
echo "the flag is: ".$flag;
?>

parse_str() 解析字符串 目前用的很多

将字符串中的值注册为全局变量表中的变量

默认的话 就是将str中的值注册为全局变量

例如

<?php
$str = $_GET['str'];
parse_str($str);
if ($name === 'bihuo.cn'){
    echo 'success';
}
else{
    echo 'fail';
}

在这里插入图片描述

在这里插入图片描述

<?php
$str = $_GET['str'];
parse_str($str);
if ($name === 'bihuo.cn' && $age === '18'){
    echo 'success';
}
else{
    echo 'fail';
}

parse_str能够解析多个变量

在这里插入图片描述

需要%26编码

在这里插入图片描述

在这里插入图片描述

在看这一个例题

<?php error_reporting(0);
$a = "www.bihuo.cn";
$id = $_GET['id'];
@parse_str($id);
var_dump($a);
if ($a[0] != "QNKCDZO" && md5($a[0]) == md5("QNKCDZO")) {
    echo "success";
} else {
    exit("failure");
}

在这里插入图片描述

传一个数组 md5弱类型

在这里插入图片描述

注意点 将变量导入到指定的数组中

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

extract() 转换独立的变量

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

extract()

原理

extract()函数可以将数组中的元素转换切多个独立的变量

他使用数组键名作为变量名,使用数组值作为变量值

例如 这是本来的使用

<?php
$a ="roda";

$my_array = array("a" => "123","b" => "456", "c" => "567");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
echo "
"
; echo "$a";

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果要避免覆盖原有的变量,可以在extract()函数中加上EXTR_PREFIX SAME参数。

·这样如果有冲突,就在变量名前加上前缀,当然前缀也需要由我们来指定。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这里先举个例子

<?php
$a="echo 'eeknight';";
echo $a;
echo "n";
eval($a);
?>
输出:
echo 'eeknight';
eeknight

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

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

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

把上面的例子简单改一下

<?php
$a="echo 'eeknight';";
extract($_GET);
eval($a);
?>

在这里插入图片描述

例题

<?php $flag = 'flag.php';
extract($_GET);
if (isset($ceshi)) {
    $content = trim(file_get_contents($flag));
    if ($ceshi == $content) {
        echo 'flag{bihuo.cn}';
    } else {
        echo 'Oh.no';
    }
} ?>

在这里插入图片描述

<?php
include 'flag.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    extract($_POST);
    if ($pass == $bihuo){
        echo 'now this is the flag:{bihuo.cn}';
    }
}

在这里插入图片描述

<?php
include  'flag.php';
$status_403 = 'denied';
$status_200 = 'ok';
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    if (!isset($_POST['flag'])){
        exit($status_403);
    }
    foreach ($_GET as $k=>$v){
        $$k = $$v;
    }
    foreach ($_POST as $k=>$v){
        $$k = $v;
    }
    if ($_POST['flag'] !== $flag){
        exit($status_403);
    }
    echo 'now the flag is '.$flag;
}

在这里插入图片描述

import_request_variables变量覆盖

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

参考

(编辑:武陵站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!