转自先知社区 https://xz.aliyun.com/t/2443

0x00前言

通常网站后台可以配置允许上传附件的文件类型,一般登录后台,添加php类型即可上传php文件getshell。但是,随着开发者安全意识的提高,开发者可能会在代码层面强制限制php等特定文件类型的上传,有时会使用unset函数销毁删除允许上传文件类型的索引数组,如:Array('gif','jpg','jpeg','bmp','png','php'),不过错误地使用unset函数并不能到达过滤限制的效果。

0x01问题详情

问题描述:

最近在审计某CMS代码过程中,发现后台限制文件上传类型的代码如下:

$ext_limit = $ext_limit != '' ? parse_attr($ext_limit) : '';
foreach (['php', 'html', 'htm', 'js'] as $vo) {
unset($ext_limit[$vo]);
}

其目的是实现:获取配置中的允许上传文件类型$ext_limit并转换为数组,无论后台是否添加了php等类型文件,均强制从允许上传文件类型的数组中删除php,html,htm,js等类型。

但是由于unset函数使用不当,导致其代码无法达到该目的。具体地,执行如下代码:

$ext_limit =  Array('gif','jpg','jpeg','bmp','png','php');
var_dump($ext_limit);
foreach (['php', 'html', 'htm', 'js'] as $vo) {
unset($ext_limit[$vo]);
}
var_dump($ext_limit);

得到输出为如下,可以看到php并没有被删除

D:\wamp\www\test.php:15:
array (size=6)
0 => string 'gif' (length=3)
1 => string 'jpg' (length=3)
2 => string 'jpeg' (length=4)
3 => string 'bmp' (length=3)
4 => string 'png' (length=3)
5 => string 'php' (length=3) D:\wamp\www\test.php:19:
array (size=6)
0 => string 'gif' (length=3)
1 => string 'jpg' (length=3)
2 => string 'jpeg' (length=4)
3 => string 'bmp' (length=3)
4 => string 'png' (length=3)
5 => string 'php' (length=3)

问题分析:

unset函数的使用说明可以参考php官网,简单理解就是:unset可以销毁掉一个变量;或者根据传入的key值,销毁数组类型中指定的键值对。
针对PHP 索引数组,调用unset时必须调用其对应的数字索引才能销毁指定的键值对。所以如果传入unset函数的参数不是索引,而是其值的情况(如此处unset('php')),无法销毁删除对应为php的键值对。

0x03修复办法

修改以上存在缺陷的代码为如下,主要是枚举索引数组为key=>value的形式,根据value进行比较,满足条件时将对应的key传入unset函数,从而销毁删除。

$ext_limit =  Array('gif','jpg','jpeg','bmp','png','php');
var_dump($ext_limit);
foreach (['php', 'html', 'htm', 'js'] as $vo) {
foreach($ext_limit as $key=>$value){
if($value===$vo){
unset($ext_limit[$key]);
}
}
}
var_dump($ext_limit);

输出结果如下(php对应的键值对已被删除):

D:\wamp\www\test.php:15:
array (size=6)
0 => string 'gif' (length=3)
1 => string 'jpg' (length=3)
2 => string 'jpeg' (length=4)
3 => string 'bmp' (length=3)
4 => string 'png' (length=3)
5 => string 'php' (length=3) D:\wamp\www\test.php:23:
array (size=5)
0 => string 'gif' (length=3)
1 => string 'jpg' (length=3)
2 => string 'jpeg' (length=4)
3 => string 'bmp' (length=3)
4 => string 'png' (length=3)

0x04小结

使用索引数组时,如果要使用unset销毁删除指定的键值对,切记采用枚举索引数组为key=>value的形式,根据value进行比较,满足条件时将对应的key传入unset函数

ps:安全问题的分析与挖掘就是一个开发者与hacker攻防较量的过程,对抗的点就是哪一方考虑的更加周全。

PHP索引数组+unset使用不当导致的问题的更多相关文章

  1. 关于PHP索引数组unset某key后json_encode相关问题踩坑记录

    <?php $a = [1,2,3]; var_dump(json_encode($a)); #string(7) "[1,2,3]" unset($a[0]); var_d ...

  2. Bash : 索引数组

    Bash 提供了两种类型的数组,分别是索引数组(indexed array)和关联数组(associative array).本文主要介绍索引数组的基本用法. 索引数组的基本特点 Bash 提供的数组 ...

  3. WPF--Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析

    原文地址: http://www.tuicool.com/articles/F7reem http://blog.csdn.net/yl2isoft/article/details/11711833 ...

  4. JS 索引数组、关联数组和静态数组、动态数组

    JS 索引数组.关联数组和静态数组.动态数组 数组分类: 1.从数组的下标分为索引数组.关联数组 var ary1 = [1,3,5,8]; //按索引去取数组元素,从0开始(当然某些语言实现从1开始 ...

  5. SELinux配置不当导致vsftpd系统用户不能登陆

    1.测试是否是SELinux配置不当导致的: setenforce 0 再次登陆ftp,正常,说明是SELinux配置不当导致.还原配置 setenforce 1 2.查看配置: getsebool ...

  6. Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析

    原文:Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析 前段时间,公司同事开发了一个小工具,在工具执行过程中,UI界面一直处于卡死状态. 通过阅读代码发现,主要是 ...

  7. CCLuaObjcBridge调Objective-C方法传索引数组报invalid key to &#39;next&#39;错调试

    CCLuaObjcBridge是cocos2d-x系列引擎与Objective-C进行交互的"桥梁",老廖的quick-cocos2d-x在其framework进行了简单了封装,封 ...

  8. numpy 数组索引数组

    在numpy中,数组除了可以被整数索引,还可以被数组索引. a[b]就是已数组b的元素为索引,读取数组a的值. 当被索引数组a是一维数组,b是一维或则多维数组时,结果维度维度与索引数组b相同. a = ...

  9. js 索引数组转JSON为空

    let a = [] a.a = 1 console.log(a) // [a: 1] console.log(JSON.stringify(a)) // [] 当然js根本没索引数组一说,这是php ...

随机推荐

  1. HDU1506 Largest Rectangle in a Histogram(算竞进阶习题)

    单调栈裸题 如果矩形高度从左到右是依次递增,那我们枚举每个矩形高度,宽度拉到最优,计算最大面积即可 当有某个矩形比前一个矩形要矮的时候,这块面积的高度就不能大于他本身,所以之前的所有高于他的矩形多出来 ...

  2. C/C++ 程序库

    C/C++ 程序库 // --------------------------------------------- 来几个不常见但是很变态的库吧: bundle: 把几乎所有常见的压缩库封装成了一个 ...

  3. hiho1259 A Math Problem (数位dp)

    题目链接:http://hihocoder.com/problemset/problem/1259 题目大意:g(t)=(f(i)%k=t)的f(i)的个数 求所有的(0-k-1)的g(i)的异或总值 ...

  4. 爬虫_淘宝(selenium)

    总体来说代码还不是太完美 实现了js渲染网页的解析的一种思路 主要是这个下拉操作,不能一下拉到底,数据是在中间加载进来的, 具体过程都有写注释 from selenium import webdriv ...

  5. Hdoj 1879.继续畅通工程 题解

    Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计 ...

  6. [leetcode]Weekly Contest 68 (767. Reorganize String&&769. Max Chunks To Make Sorted&&768. Max Chunks To Make Sorted II)

    766. Toeplitz Matrix 第一题不说,贼麻瓜,好久没以比赛的状态写题,这个题浪费了快40分钟,我真是...... 767. Reorganize String 就是给你一个字符串,能不 ...

  7. SRM 600 div 2 T 1

      贪心+枚举 #include <bits/stdc++.h> using namespace std; class TheShuttles { public: int getLeast ...

  8. 同一台机器安装多个zabbix-agentd

    先来看一zabbix-agentd rpm包安装生成的文件   有的机器之前安装过老版本的,我这边就直接将这些配置文件打包到一个文件夹,然后上传到对应的机器上解压一下修改配置文件就ok啦 改一下启动脚 ...

  9. ImageMagick - 智能的灰度空间(GRAYColorspace)让人窒息

    今天在处理一张 gray.jpg 图片时,发现生成的图片色彩空间是: GRAYColorspace 可我在代码中明明设置了: MagickWand * mw = NewMagickWand (); M ...

  10. numpy学习之前的必要数学知识:线性代数

    行列式 主要内容 1.行列式的定义及性质 2.行列式的展开公式 一.行列式的定义 1.排列和逆序 排列:由n个数1,2,…,n组成的一个有序数组称为一个n级排列,n级排列共有n!个 逆序:在一个排列中 ...