PHP
文件上传漏洞的浅析。
文件上传简介
在一个正常的网站中,通常都会存在一些允许用户上传文件的地方。但是有一些上传功能的地方没有对用户上传的内容进行过滤,导致会上传木马到服务器并执行命令,甚至控制服务器的权限。
文件上传实现
前端代码。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>File uploads</title>
</head>
<body>
<form action="dofile.php" method="post" enctype="multipart/form-data">
请选择上传的文件:
<input type="file" name="myfile" /><br/>
<input type="submit" value="上传文件" />
</form>
</body>
</html>
服务器端代码。
<?php
// 通过$_FILES文件上传变量接收上传文件信息
header('content-type:text/html;charset=utf-8');
$fileinfo = $_FILES['myfile'];
$filename = $fileinfo['name'];
$type = $fileinfo['type'];
$tmp_name = $fileinfo['tmp_name'];
$size = $fileinfo['size'];
$error = $fileinfo['error'];
//判断错误号
if($error==UPLOAD_ERR_OK){
if(move_uploaded_file($tmp_name,"uploads/".$filename)){
echo '文件'.$filename.'上传成功';
}else{
echo '文件'.$filename.'上传失败';
}
}
上面是实现文件上传的测试代码,对上传文件没有进行任何的限制,可以进行任意文件的上传,比如以下上传一个php
文件。
上传一个php文件,会显示文件test.php上传成功。然后访问该文件。
上面是只是一个理想的测试环境,来实现一下由于文件上传存在的一些漏洞。可能在实际环境中有多种的限制,比如对上传文件黑/白名单的限制、上传后文件名的重命名、可写目录没有执行权限等。
接下来复现phpCollab 2.5.1
任意文件上传的漏洞,学习一下其中的原理。
phpCollab 2.5.1 - Arbitrary File Upload
下载对应的版本,安装。登录后台里面。在客户–>客户组织–>标志处,上传文件的地方存在任意文件上传漏洞。
在标志处可以进行任意文件上传,我们上传一个php
后缀的文件,然后通过前端调试分析,可知上传后的文件路径以及名字。
最后,可以访问到上传后的文件。
其中漏洞点在/clients/editclient.php
文件的第63~70行。
$extension = strtolower( substr( strrchr($_FILES['upload']['name'], ".") ,1) ); // 后缀名字 substr(string,start,length)
if(@move_uploaded_file($_FILES['upload']['tmp_name'], "../logos_clients/".$id.".$extension"))
//move_uploaded_file() 函数将上传的文件移动到新位置。
{
chmod("../logos_clients/".$id.".$extension",0666);
$tmpquery = "UPDATE ".$tableCollab["organizations"]." SET extension_logo='$extension' WHERE id='$id'";
connectSql("$tmpquery");
}
从代码中可以看到没有对上传的文件进行任何的验证,直接通过move_uploaded_file
来完成上传操作,并保存在logos_clients
文件夹下。
接下来翻译一篇关于文件上传安全测试的文章,来具体学习一下如何来进行测试。
(技术翻译)文件上传
Web应用程序中的允许用户上传文件的函数处,有时候没有对上传内容其进行严格的过滤和验证,可能会导致攻击者利用此漏洞进行攻击。本文进行概述利用文件上传的功能进行渗透测试,将会介绍一些小技巧来绕过黑名单的过滤和一些实用的检测方法。
寻找上传点
文件上传功能非常容易验证和利用,一般在个人信息图片、文件上传和文件导入处。当你测试的时候,Burp被动扫描也会去验证存在上传功能的入口。
测试文件上传类型
一般的Web应用程序都会设置一个黑名单来过滤和验证用户上传的内容,但是有时候百密一疏,一些其他的后缀名会绕过黑名单。另外一种是白名单,只允许用户上传特定的文件。
这个时候需要测试一下允许上传的文件后缀名。
使用Burp 测试文件上传类型
- 手工测试一个请求,该请求会收到拒绝上传此类型之类等错误响应。
- 发送这个请求到Burp intruder模块
清除其中默认的选项
选择文件上传类型的点
选择不同的文件名,比如php.jpg,asp.jpg等
在选项中,配置grep匹配在第一步中响应出现的字符串。
开始进行测试,那些没有匹配到错误响应字符串的后缀,需要进一步的验证和测试,是否可以上传成功。
关键点
使用Burp Intruder测试所有的后缀,使用Grep功能处理结果
一些不常见的后缀名可能会绕过黑名单,比如.php,.php5,.phtml
使用Burp测试文件上传的Content-Type
识别那些文件上传的Content-Type
能被应用程序接受
和测试上传文件后后缀一样,同样是使用Burp Intruder进行爆破。这次修改的是Content-Type
字段。参考上面的7个步骤即可。
关键点
使用Burp Intruder测试所有的Content-Type,使用Grep功能处理结果
尝试将Content-Type更改为支持的文件类型,但是其中包含Web服务器/Web应用程序要处理的后缀名
一些不常见Content-Type可能会绕过黑名单
文件名和扩展模糊测试
文件名和扩展应该在输入验证时测试,当文件的名字为XSS
,SQLi
,LDAP
或者一个命令注入载荷的时候会发生什么。
还是使用Burp Intruder
进行测试,原理和测试文件上传类型类似,可以参考上面的七个步骤。
文件上传黑名单绕过
Windows IIS 文件上传黑名单绕过
1:配合服务器解析漏洞,在黑名单加一个分号以及正常的文件名,例如shell.asp;.jpg
2:目录解析。folder.asp\file.txt,其中asp文件夹里面的任何扩展名文件都被IIS当作asp文件来执行。
3:环境是IIS,PHP时,< > 和 . 可以转换为 ? * .
4:使用可以替换文件的字符。比如>>可以替换 web.config
5:尝试在文件名后面使用空格或点。比如 foo.asp…. .. . . . .
6:file.asax:.jpg
7:尝试在文件名中加入禁止的字符,| %< * ? “,来得到错误信息。
Windows Apache 环境黑名单绕过
1:Windows8.3 一个特征允许短文件名替换已经存在的文件。比如
web.config
可以被web~config.con
替代,或者.htaccess
可以被HTACESS~1
替代。2:尝试上传
a.file
,如果上传函数的根目录在www/uploads
,将会创建一个uploads
文件在上述目录。
其他绕过技术
1:确定那些字符被过滤了。使用
Burp
在特定位置插入元字符表。2:确保你的列表中包括一些不常见的扩展名,比如
.php5
,.php3
,.phtml
3:测试防御机制。如果是过滤一些文件名,可能会被绕过。比如
shell.ph.phpp
,如果是过滤了php
,之后名字后缀可能会变成.php
4:使用%00截断。比如
shell.php%00.jpg, shell.php%0delete0.jpg
。5:双扩展名:如果应用程序过滤或者重命名扩展名。如果给它两个扩展名会发生什么?比如
shell.php.php
或者shell.txt.jog.png.asp
。6:尝试上传一个超长文件名,比如
supermassivelongfileeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeename.php
7:尝试上传
test.asp\
,test.asp.\
。8:上传flash XSS攻击载荷,然后命名a.jpg
9:尝试以前的技术,但使用PDF或Silverlight代替
10:同样,尝试滥用
crossdomain.xml
或clientaccesspolicy.xml
文件。11:尝试使用编码绕过。比如URL,HTML,Unicode或者双重编码
12:结合以上所有的绕过技术。
13:尝试替换HTTP请求方法。使用
POST
替换PUT
或者GET
(反之亦然)。14:确保所有的输入点进行模糊测试。
绕过文件上传白名单
1:枚举出白名单并测试允许的扩展名来利用
2:测试文件内容正在验证中
3:测试扩展重命名技术,如
shell.php.png
绕过文件大小上传机制
恶意文件内容
测试上传任何文件上传的内容是否被应用程序处理。比如你可以将XSS载荷写入到Excel
,CSV
,txt
文件中,稍后看是否会由应用程序呈现。使用Burp repwater
和intruder
尝试在文件导入和上传功能函数中注入各种的载荷,测试应用程序的响应。
图像数据
可以在图像EXIF数据内注入反向shell吗?
在Kali
安装
apt-get install exiftool
在图像文件中注入代码后,只需上传文件,并使用校验和验证文件是否相同(以下是详细步骤)
用Burp注入请求
这是与上述EXIF方法类似的技术,但是你要将代码直接粘贴到打包请求中。
1:使用burp上传一个合法的图片,且验证上传成功
2:发送之前的请求到
repeater
模块3:在请求中的合法图像数据之后,尝试注入有效载荷(注入有效载荷或反向shell)
4:提交这个请求
5:从目标服务器上下载上传的我呢件,验证它是否包含有效的载荷。是否在目标服务器上能成功执行。
验证上传文件
不管你在上一步使用什么方法(EXIF或修改Burp请求),校验一个本地上传的和上传到目标服务器的文件,是否匹配。
服务器端命令执行技术
如果能成功上传一个shell
到目标的web服务器上,你可以尝试以下技术来执行上传的shell
。
1:Apache MIME Types: 尝试上传重命名文件,比如
shell.php.jpg
或者shell.asp;.jpg
,并且评估一下Web服务器是否会利用Apache MIME types。2:空子节:使用一个空子节
%00
在文件名末尾,或者这样,shell.php%0delete0.jpg
。观察应用程序的响应。3:可以上传点文件。如果可以上传
.htaccess
文件,利用AddType
:AddType application/x-httpd-php .foo
。4:注意上传文件的任何处理 比如:可以在稍后由后端备份脚本,处理的文件名中使用命令注入?
5:注意服务器处理的上传文件。如果压缩文件允许上传,应用程序是否会提取其中的内容。反之亦然。
6:服务器防病毒是否处理上传了文件?尝试上传压缩文件类型如.zip,.rar等,如果服务器端防病毒易受攻击,可以利用并获得命令执行。
任意文件上传防御
- 对上传文件格式限制,只允许某些格式文件上传。使用白名单
- 对文件格式进行校验,前端和服务器端都需要校验。
- 将上传文件的目录,设置权限。一般上传的都是静态文件,所以需要对其目录设置禁止执行权限。
- 将上传的文件的名字进行随机命名。
参考
https://www.aptive.co.uk/blog/unrestricted-file-upload-testing/