extract()函数和get&post上传的个人见解

定义

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

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

该函数返回成功设置的变量数目。

说大白话就是:将导入extract里面的数组的键名作为变量,值作为变量的值导入到当前的符号表。来个简单的demo:

<?php
$love=array('name'=>'lxrhe');
extract($love);
echo $name;
?>
#输出:lxrhe

 就如上面所言,键作为了变量,值作为了变量值!

应用

看完了定义直接来看看应用!

创建变量

demo:

比如说这道题就是让你使用extract()函数创建一个变量,这里直接post提交,这里还利用了php的非法传参谈一谈PHP中关于非法参数名传参问题_php非法传参-CSDN博客,即参数里面的空格和[和+和点都会被转化成_。所以直接提交pass word=ctfshowvip或者pass+word=ctfshowvip(这个不知道为什么没成功)。这里主要是涉及了post上传的机制问题,即以数组形式储存数据的,即

$_POST = ['pass_word' => 'ctfshowvip'];

覆盖变量

demo:

<?php
$love='rufeii';
extract($_POST);
?>
#如果我们上传love=lxrhe那么根据extract函数的定义
就会导入到当前的符号表,如果已经存在了就会实行覆盖!
一个稍为复杂的问题
 <?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
} 

代码审计:定义了一个filter函数用于过滤,还有个$_SESSION数组,数组里面有三个键值对!还有个我们今天的主角extract($_POST)!逻辑就是通过extract实行变量覆盖,user,function使它们变为可控,然后打字符串减少逃逸!不过不是主线任务!我们直接看payload

POST: _SESSION[user]=flagflagflagflagflagphp

&_SESSION[function]=";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"2";}

这里主要是理解_SESSION[user],之前没考虑post上传数据的储存机制,导致难以理解,那么现在我们进行分析即可!

php对上传的数据进行解析!主要看数组上传!

<?php
$_POST['love'];
?>
简单数组上传:
post提交love[]=1,php会解析成你上传的变量a是一个数组
即a=[1],$_POST={'love'=>{[0]=>1}};
数组的嵌套上传:
post提交love[name]=lxrhe,那么解析成
$_POST={'love'=>{['name']=>'lxrhe'}};当然还可以嵌套更多逻辑都是一样的

那么对payload进行分析:覆盖变量$_SESSION(它是一个数组),$_POST = ['_SESSION' =>['user' => 'flagflagflagflagflagphp','function'=>'";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"2";}'];所以这里可以覆盖变量并且修改值,而且post和get上传好像是不需要考虑是不是字符串,因为它会自动识别!

### 关于 `extract` 函数的实现与用法 #### PHP 中 `extract` 的定义功能 PHP 提供了一个名为 `extract()` 的内置函数,用于将数组中的键作为变量名导入到当前符号表中,并赋予相应的值。此操作可以简化数据访问过程,但也可能带来安全隐患[^1]。 #### 使用示例 假设存在如下关联数组 `$arr`: ```php $arr = array( 'var_a' => 'value a', 'var_b' => 'value b' ); ``` 调用 `extract($arr)` 后,在脚本范围内会创建两个新变量 `$var_a` `$var_b` 并分别设置它们等于 `'value a'` `'value b'`[^3]。 #### 安全隐患分析 当从外部输入源(如 URL 参数、POST 请求体等)获取的数据未经严格验证就被传递给 `extract()` 时,则可能导致意外覆盖已存在的局部或全局作用域内的同名变量的情况发生。这不仅会影响程序逻辑正常执行还容易引发安全风险,比如信息泄露甚至远程代码执行漏洞[^2]。 例如,如果页面中有预先设定好的变量 `$gift='default gift';` ,而攻击者通过 GET 方式提交请求 `/page.php?gift=hacked&content=malicious code` 。此时服务器端代码里如果有类似下面这样的语句就会出现问题: ```php // 假设这里已经有一个默认礼物变量 $gift = "default gift"; // 如果开发者不小心使用了 extract() extract($_GET); // 此处原本应该显示 default gift,但是由于 $_GET['gift'] 被提取出来并覆盖掉了原来的 $gift 变量, echo $gift; ``` 上述情况下最终输出将是 `"hacked"` 而不是预期中的 `"default gift"` , 更严重的是后续可能会被执行恶意内容 `$content="malicious code";`. 为了防止此类问题的发生,建议开发人员遵循以下最佳实践: - 尽量避免直接对不可信来源的数据应用 `extract()`. - 对传入的数据进行严格的过滤校验. - 明确指定要导出哪些字段而不是全部.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值