安全测试多种多样,先来浅谈文件上传漏洞利用

发表于:2020-12-25 10:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:book4yi    来源:简书

分享:
  实习工作以后,我才发现自己对于渗透测试还没形成自己的测试体系,对于一些常见的漏洞测试方法了解得不够全,更加认识到知识积累的重要性。总而言之,一入安全深似海~
  文件上传漏洞利用条件:
  1、上传的文件能被Web服务器当做脚本来执行
  2、我们能够访问到上传文件的路径
  代码审计基础:
  关于 PHP 中 $_FILES 数组的使用方法:
  $_FILES['file']['name'] # 客户端文件名称
  $_FILES['file']['type'] # 文件的 MIME 类型
  $_FILES['file']['size'] # 文件大小单位字节
  $_FILES['file']['tmp_name'] # 文件被上传后在服务器端的临时文件名,可以在 php.ini 中指定
  防御函数:
$file_name = trim($_FILES['upload_file']['name'])`;
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');//查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
  文件上传常见校验方式:
  服务端校验:
  ·文件头 content-type 字段校验
  ·文件内容头校验(GIF89a)
  ·后缀名黑名单校验
  ·后缀名白名单校验
  ·自定义正则校验
  ·WAF设备校验(根据不同的 WAF 产品而定)
  ·客户端 javascript 校验(一般只校验后缀名)
  常见绕过方式:
  PUT 方法:
  WebDAV 是一种基于 HTTP 1.1 协议的通信协议.它扩展了 HTTP 1.1,在 GET、POST、HEAD 等几个 HTTP 标准方法以外添加了一些新的方法。使应用程序可直接对 Web Server 直接读写,并支持写文件锁定 (Locking) 及解锁 (Unlock),还可以支持文件的版本控制。
  当 WebDAV 开启 PUT,MOVE,COPY,DELETE 方法时,攻击者就可以向服务器上传危险脚本文件。
  PUT:由于PUT方法自身不带验证机制,利用PUT方法可以向服务器上传文件,所以恶意攻击者可以上传木马等恶意文件。
  DELETE:利用DELETE方法可以删除服务器上特定的资源文件,造成恶意攻击。
  OPTIONS:将会造成服务器信息暴露,如中间件版本、支持的HTTP方法等。
  TRACE:可以回显服务器收到的请求,主要用于测试或诊断,一般都会存在反射型跨站漏洞。
  我们可以将请求方法设置为OPTIONS,来查看服务器支持的请求方法。有些网站开启了WebDAV,并且管理员配置不当,导致支持危险的HTTP方法:
  JavaScript 校验:
  客户端 JS 验证通常做法是验证上传文件的扩展名是否符合验证条件。
  示例代码如下:
<?php
//文件上传漏洞演示脚本之js验证
$uploaddir = 'uploads/';
if (isset($_POST['submit'])) {
if (file_exists($uploaddir)) {
if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) {
echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n";
}
} else {
exit($uploaddir . '文件夹不存在,请手工创建!');
}
//print_r($_FILES);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gbk"/>
<meta http-equiv="content-language" content="zh-CN"/>
<title>文件上传漏洞演示脚本--JS验证实例</title>
<script type="text/javascript">
function checkFile() {
var file = document.getElementsByName('upfile')[0].value;
if (file == null || file == "") {
alert("你还没有选择任何文件,不能上传!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//alert(ext_name);
//alert(ext_name + "|");
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" +     ext_name;
alert(errMsg);
return false;
}
}
</script>
<body>
<h3>文件上传漏洞演示脚本--JS验证实例</h3>
<form action="" method="post" enctype="multipart/form-data" name="upload" onsubmit="return     checkFile()">
<input type="hidden" name="MAX_FILE_SIZE" value="204800"/>
请选择要上传的文件:
<input type="file" name="upfile"/>
<input type="submit" name="submit" value="上传"/>
</form>
</body>
</html>
  直接通过 F12 修改 js 代码绕过验证:
  或者使用 burp 抓包直接提交,绕过 js 验证。
  服务器端校验之文件头 content-type 字段校验(服务端 MIME 类型检测):
  MIME type 的缩写为 (Multipurpose Internet Mail Extensions) 代表互联网媒体类型 (Internet media type),MIME 使用一个简单的字符串组成,最初是为了标识邮件 Email 附件的类型,在 html 文件中可以使用 content-type 属性表示,描述了文件类型的互联网标准。
  Response 对象通过设置 ContentType 使客户端浏览器,区分不同种类的数据,并根据不同的 MIME 调用浏览器内不同的程序嵌入模块来处理相应的数据。
  MIME类型格式:
# 类别/子类别; 参数
Content-Type: [type]/[subtype]; parameter
  MIME 主类别:
  text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
  Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
  Application:用于传输应用程序数据或者二进制数据;
  Message:用于包装一个 E-mail 消息;
  Image:用于传输静态图片数据;
  Audio:用于传输音频或者音声数据;
  Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
  常见MIME类型:
  示例代码:
<?php
if($_FILE['userfile']['type'] != "image/gif"){ //检测content-type
echo "sorry,we only allow uploading GIF images";
exit;
}
else
{
echo "Upload success!";
}
?>
  绕过手段:
  通过burp修改MIME type,抓包修改content-type为允许的上传类型:
  image/jpeg、image/png、image/gif等等。
  后缀名黑名单校验:
  后端脚本检测文件扩展名,数据提交到后端,后端的函数对上传文件的后缀名进行检测,比如黑名单检测不允许上传 .php 、.asp 后缀格式的文件。
  示例代码:
#后端php检测
$info=pathinfo($_FILES["file"]["name"]);
$ext=$info['extension'];// 得到文件扩展名
if (strtolower($ext) == "php") {   #黑名单检测,不允许上传php格式的文件
exit("不允许的后缀名");
}
# 或者
<?php
$type = array("php","php3");
//判断上传文件类型
$fileext = fileext($_FILE['file']['name']);  # fileext函数用于获取文件名的后缀
if(!in_array($fileext,$type)){
echo "upload success!";
}
else{
echo "sorry";
}
?>
  服务端基于文件头检测:
  不同的图片文件都有不同文件头,如:
  jpg:FF D8 FF E0 00 10 4A 46 49 46
  png: 89 50 4E 47 0D 0A 1A 0A 00 00
  gif: 47 49 46 38 39 61 26 02 6F 01
  绕过方式:绕过这个检测只需要在恶意脚本前加上允许上传文件的头标识。
GIF89a
<?php phpinfo(); ?>
  补充:jpg 格式图片头部是 JFIF ,gif头部是GIF89a,png头部是%PNG。
  条件竞争上传:
  原理:
  上传文件时,服务器获取文件,先把它保存到临时文件中(不是网站根目录),然后再上传到网站根目录,最后才进行判断检测(即先上传后进行判断与删除)。
  利用思路:
  利用一个时间差,使用多线程并发的访问上传的文件,总会有一次在上传文件到删除文件这个时间段内访问到上传的 php 文件,一旦我们成功访问到了上传的文件,那么它就会向服务器写一个 shell
  利用代码:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["cmd"]);?>');?>
  绕过技巧小结:
  上传不符合 windows 文件命名规则的文件名
  大小写绕过:针对对大小写不敏感的系统如 windows:test.pHp
  空格绕过:用burp截断,后在文件名末尾添加空格:test.php(空格)
  在 windows 下,下划线是空格,保存文件时下划线被吃掉剩下 test.php:test.php_
  点号绕过:用burp截断,后在文件名末尾添加.:test.php.
  路径拼接绕过:最后一个点前有空格,适用于上传的文件名没有被修改:test.php. .
  特殊符合绕过:test.php::$DATA
  上传以上文件名会被 windows 系统自动去掉不符合规则符号后面的内容。
  00截断:
  php5.3之前会把0x00当做结束符,绕过白名单:
  php版本小于5.3.4时,可通过%00截断文件后缀名,如:filename="123.php%00.png"
  基于拓展名的绕过:
  Asp:asa、cer、cdx
  Aspx:ashx、asmx、ascx
  Php:php2、php3、php5、phtml、pht
  Jsp:jspx、jspf
  利用 NTFS ADS 特性:
  配合解析漏洞:
  解析漏洞一般配合图片马进行利用:
  制作图片马:
copy a.jpg /b + shell.php /a webshell.jpg
  超长文件名截断上传:windows 258byte | linux 4096byte
  配合 .user.ini 配置文件本地包含文件
  配合 Apache 的 .htaccess 文件上传解析漏洞(测试失败,待解决)
  htaccess文件是Apache服务器中的一个配置文件,负责相关目录下的网页配置。它可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
  利用前提:
  要在Apache中启动执行.htaccess,必须在http.conf中设置AllowOverride All(默认为None),并且启动Rewrite模块。
  编写.htaccess,内容编辑为:
AddType application/x-httpd-php .jpg
  .htaccess 文件里的代码可以让 .jpg 后缀名文件格式的文件名以 php 格式解析
  上传 HTML 文件:
  很多网站采用黑名单的过滤机制,但是他们忘记了过滤 html 文件,这就造成了上传html文件形成存储型XSS或者利用html文件进行钓鱼。
  防御手段:
  客户端检测,使用 js 对上传图片检测,包括文件大小、文件扩展名、文件类型等。
  服务端检测,对文件大小、文件路径、文件扩展名、文件类型、文件内容检测、对文件重命名等。
  服务器端上传目录设置不可执行权限。
  检查网站有没有文件解析漏洞和文件包含漏洞。
  将文件上传到单独的文件服务器,并且单独设置文件服务器的域名。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号