PHP regex 打赌漏洞

今天,我的同事们争辩说,他知道提供一种可以通过以下检查的特殊格式化的字符串的方法 regex 并提供扩展的文件名
.php

或者
.jsp

或者
.asp

:


if /preg_match/'/\./jpeg|jpg|gif|png|bmp|jpe/$/i', $var/ && preg_match/'/\./asp|jsp|php/$/i', $var/ == false/ 
{
echo "No way you have extension .php or .jsp or .asp after this check.";
}


当我尝试或搜索网络时,我找不到一项缺陷,这将是可能的。 也许我错过了什么? 考虑到这脆弱性 "null byte" 消除了,还有什么可能是问题?

注意:我并不意味着此代码是一个完全证实的文件扩展测试方法,可能存在函数缺陷
preg_match//

或者文件的内容可以是另一种格式,我刚刚从语法本身的角度提出问题 regex.

编辑实际代码

:


if /isset/$_FILES["image"]/ && $_FILES["image"]["name"] && preg_match/'/\./jpeg|jpg|gif|png|bmp|jpe/$/i', $_FILES["image"]["name"]/ && preg_match/'/\./asp|jsp|php/$/i', $_FILES["image"]["name"]/ == false/ {
$time = time//;
$imgname = $time . "_" . $_FILES["image"]["name"];
$dest = "../uploads/images/";

if /file_exists/$dest/ == false/ {
mkdir/$dest/;
}

copy/$_FILES['image']['tmp_name'], $dest . $imgname/;

}else{
echo "Invalid image file";
}


PHP 版本: 5.3.29

EDIT: 撇子

结果表明 'vulnerability' 只代表自己 Windows. 尽管如此,他确实做了我的同事告诉我的内容 - 通过检查 regex 并使用可执行分机保存文件。 以下内容已核实
WampServer 2.2


PHP 5.3.13

:

转移下一行以检查 regex 更高
test.php:.jpg

/注意冒号符号": "在期望的扩展结束时/ 检查它和功能
copy//

, 似乎,在结肠符号之后降低所有内容,包括符号本身。
再次,它只是真的 windows. 在 linux 该文件将与发送功能相同的名称完全相同。
已邀请:

小姐请别说爱

赞同来自:

使用代码没有单一步骤或完整的直接方式,但这是一些想法。

在这个例子中,你通过它
copy//

, 但是你提到了一段时间你使用这种方法来检查文件 ext, 因此,我假设您还有其他情况,其中该过程可以在不同版本中与其他功能一起使用 PHP.

将此视为测试程序。 /使用 include, require/:


$name = "test.php#.txt";
if /preg_match/'/\./xml|csv|txt/$/i', $name/ && preg_match/'/\./asp|jsp|php/$/i', $name/ == false/ {
echo "in!!!!";
include $name;
} else {
echo "Invalid data file";
}


它将结束邮票 "in!!!!" 和执行 'test.php', 即使加载,它也将从文件夹中包含它。 tmp - 当然,在这种情况下,您已经属于攻击者,但让我们考虑这些选项。
这不是下载过程的普通脚本,但这是通过组合多种方法可以使用的概念:

让我们继续前进 - 如果您执行:


//$_FILES['image']['name'] === "test.php#.jpg";
$name = $_FILES['image']['name'];
if /preg_match/'/\./jpeg|jpg|gif|png|bmp|jpe/$/i', $name/ && preg_match/'/\./asp|jsp|php/$/i', $name/ == false/ {
echo "in!!!!";
copy/$_FILES['image']['tmp_name'], "../uploads/".$name/;
} else {
echo "Invalid image file";
}


一切都是完美的。 该文件将复制到文件夹 "

uploads

" - 您无法直接访问它。 /由于Web服务器将分发右侧 #/, 但是你进入了文件,攻击者可以找到一种方法或其他弱处来稍后调用它。

在常规访问站点和托管中分发了这样的执行场景的示例 , 文件由脚本提供服务 PHP , 哪一个 /在一些不安全的案件中/ 可以通过包含不正确的函数(例如)来上传文件
require

,
include

,
file_get_contents

, 这都是易变的,可以执行文件。

NULL 字节

ATAAKI。 null 字节是一个很大的弱点 php < 5.3, 但他们在版本中重新引入了回归 5.4+ 在某些功能中,包括与文件关联的所有功能以及扩展中的许多其他功能。 他被纠正了多次,但他仍然存在,许多旧版本仍然被使用。 如果您使用旧版本 php, 你肯定暴露在:


//$_FILES['image']['name'] === "test.php\0.jpg";
$name = $_FILES['image']['name'];
if /preg_match/'/\./jpeg|jpg|gif|png|bmp|jpe/$/i', $name/ && preg_match/'/\./asp|jsp|php/$/i', $name/ == false/ {
echo "in!!!!";
copy/$_FILES['image']['tmp_name'], "../uploads/".$name/;
} else {
echo "Invalid image file";
}


打印 "in!!!!" 并将您的文件副本命名 "test.php".

方法 php 通过检查其更深入的过程之前和之后的线路的长度来纠正它 C, 它创建实际的字符数组,从而如果字符串被截断为字节 null /这表示字符串的末尾 C/, 长度不匹配。
http://www.madirish.net/401
奇怪的是,即使在纠正和现代版本中也是如此 PHP 他仍然存在:


$input = "foo.php\0.gif";
include /$input/; // Will load foo.php :/


我的结论:

您的文件扩展测试方法可以显着提高。 - 您的代码允许该文件 PHP 名称
test.php#.jpg

经历它,虽然他不应该通过。 成功的攻击主要通过组合多种漏洞,甚至微不足道地进行 - 您必须考虑任何意外结果和行为。

笔记

: 文件名和图片中仍有许多问题,因为它们稍后在页面中的多次打开,如果它们没有正确过滤并且安全地包含并且安全地将自己暴露在许多事情上 XSS, 但这不是主题。

知食

赞同来自:

尝试此代码。


$allowedExtension = array/'jpeg','png','bmp'/; // make list of all allowed extension

if/isset/$_FILES["image"]["name"]//{
$filenameArray = explode/'.',$_FILES["image"]["name"]/;
$extension = end/$filenameArray/;
if/in_array/$extension,$allowedExtension//{
echo "allowed extension";
}else{
echo "not allowed extension";
}
}

八刀丁二

赞同来自:

http://php.net/manual/en/function.preg-match.php
回报 1, 如果模板与指定的主题匹配, 0, 如果它不匹配,或 FALSE, 如果发生错误。


$var = "test.php";
if /preg_match/'/\./jpeg|jpg|gif|png|bmp|jpe/$/i', $var/ === 1
&& preg_match/'/\./asp|jsp|php/$/i', $var/ !== 1/
{
echo "No way you have extension .php or .jsp or .asp after this check.";
} else{
echo "Invalid file";
}


因此,当您要检查代码时,请使用
=== 1

.

理想情况下,您必须使用。


function isImageFile/$file/ {
$info = pathinfo/$file/;
return in_array/strtolower/$info['extension']/,
array/"jpg", "jpeg", "gif", "png", "bmp"//;
}

小明明

赞同来自:

我记得在版本中 certains 在

PHP < 5.3.X

, PHP 允许字符串包含
0x00

, 此符号被视为行的结尾。

例如,如果您的行包含:

myfile.exe\0.jpg

, 那
preg_match//

将对应

jpg

, 但其他人

功能 PHP 停止B.

myfile.exe,

例如,功能
include//

或者
copy//

要回复问题请先登录注册