文件上传(下)
· 阅读需 11 分钟
服务器命名规则
第一种类型:上传文件名和服务器命名一致
第二种类型:上传文件名和服务器命名不一致(随机,时间日期命名等)
上传漏洞总结
- 任意文件上传 (没有任何校验)
- 绕过js校验上传 (校验发生在前端)
- 绕过后端校验上传 (校验发生在后端)
- 绕过文件类型校验
- 绕过扩展名校验
- 绕过文件头校验
- 结合解析漏洞上传 (中间件解析漏洞造成)
- 其他类型
文件上传检测类型
1.客户端 javascript检测(通常为检测文件扩展名)
2.服务端文件头检测
3.服务端MIME类型检测(检测Content-Type内容)
4.服务端目录路径检测 (检测跟path参数相关的 内容)
5.服务端文件扩展名检测
6.服务端文件内容检测 (检测内容是否合法或含有恶意代码)
客户端javascript检测
- 首先判断是否为 JS 本地验证
如果浏览器页面没有刷新或者打开burp抓包没有抓到包就已经有验证结果即可证明为前端JS本地验证。
服务端文件头检测
- 什么是文件头:
文件头就是为了描述一个文件的一些重要的属性,比如图片的长度、宽度、像素尺寸等,当程序打开文件时读取这些属性对文件进行处理。
getimagesize()函数
getimagesize()函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回FALSE并产生一条错误信息。
语法:
getimagesize( string filename )例子:
<?php $array = getimagesize("images/flower_1.jpg"); print_r($array); \?>浏览器显示如下:
浏览器显示如下:
Array ([0] => 350 [1]=> 318[2]=>2[3] => width="350" height="318"[bits] =>8 [channels] => 3 [mime] => image/jpeg)返回结果说明
索引О给出的是图像宽度的像素值
索引1给出的是图像高度的像素值
索引2给出的是图像的类型,返回的是数字,其中1= GIF,2 = JPG,3= PNG,4 = SWF,5= PSD,6= BMP,7= TIFF(intel byte order),8=TIFF(motorola byte order),9= JPC,10=JP2,11=JPX,12=JB2,13= swc,14 =IFF,15 = WBMP,16= XBM
索引3给出的是一个宽度和高度的字符串,可以直接用于HTML的<image>标签
索引 bits给出的是图像的每种颜色的位数,二进制格式
索引channels给出的是图像的通道值,RGB图像默认是3
索引mime给出的是图像的MIME信息,此信息可以用来在HTTPContent-type头信息中发送正确的信息,如: header("Content-type:image/jpeg");
绕过文件头检测
Web应用程序在校验文件类型、文件扩展名的同时,也会校验文件头,从而进一步确定文件的类型。针对这种情况,可以通过在上传的一句话木马文件的开头加入特定的文件头从而绕过这种校验方式。
| 文件类型 | 对应的文件头 |
|---|---|
| jpeg | JPGGraphic File |
| jpg | JPGGraphic File |
| png | JPGGraphic File |
| gif | GIF 89A |
| zip | Zip Compressed |
| doc | MS Compound Document v1 or Lotus APProach APRfile |
| xls | MS Compound Document v1 or Lotus APProach APRfile |
| xlt | MS Compound Document v1 or Lotus APProach APRfile |
| ppt | MS Compound Document v1 or Lotus APProach APRfile |
| apr | MS Compound Document v1 or Lotus APProach APRfile |
服务端MIME类型检测(Content -Type)
- MIME的作用和定义目录
使客户端软件,区分不同种类的数据,例如WEB浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件。
WEB服务器使用MIME来说明发送数据的种类,WEB客户端使用MIME来说明希望接收到的数据种类。
Tomcat的安装目录\conf\web.xml中定义了大量的MIME类型。
Apache的安装目录\conf\mime.types中定义了大量的MIME类型,httpd.conf中也定义了一些特殊的MIME类型。
- 常见的MIME类型
text/plain(纯文本)
text/html (HTML文档)
text/javascript(js代码)
application/xhtml+xml (XHTML文档)
image/gif (GIF图像)
image/jpeg (JPEG图像)│
image/png ( PNG图像)
video/mpeg (MPEG动画)
application/octet-stream (二进制数据)
application/pdf (PDF文档)
- 绕过方法:
例: burp抓包后修改content-Type:image/gif
或更改为其他的图片格式。因为图片格式往往是准许上传的。 I

服务端文件扩展名检测
- 黑名单检测--安全性比白名单低很多,攻击手法也比白名单多。
绕过方式:
(1)文件名大小写绕过
例如 AsP,pHp
(2)名单列表绕过
用名单列表里没有的名单进行攻击,比如黑名单里没有asa或cer之类
(3)特殊文件名绕过
比如发送的http包里把文件名改成test.asp.或test.asp_(下划线为空格),这种命名方式在windows系统里是不被允许的,所以需要在burp进行修改,然后绕过验证后,会被windows系统自动去掉后面的.和空格,但要注意unix/linux系统没有这个特性。
(4)0x00截断绕过
是test.asp .jpg(asp后面为Ox00) ,type=gettype(name) //而在gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg, if(type==jpg)
(5).htaccess文件攻击 配合名单列表绕过。上传一个自定义的.htaccess
(6)解析调用/漏洞绕过
这类漏洞直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞
(7) apache的配置文件httpd.conf中AddType application/x-httpd-php .php .phtml开启,这样phtml也可以当成php解析。
- 白名单检测―一相对难过很多,但是也不一定绝对安全。
绕过方式:
(1)0x00截断绕过
用像test.asp%00.jpg的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击。
00截断
0x00,%00,/00之类的截断,都是一样的,只是不同表示而已
在url中%00表示ascll码中的0,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束
0x开头表示16进制,0在十六进制中是00,0x00就是%00解码成的16进制用burp抓包,在需要截断的位置添加了一个空格,空格是为了占位,方便修改00。然后打开hex,(空格的16进制为0x20)修改16进制内容,把20改成00即可。
- 00截断限制条件
- 1.php版本小于5.3.4
- 2.php的magic_quotes_gpc为OFF状态
::$data
必须是windows,必须是php
1.php
php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持"::$DATA"之前的文件名
他的目的就是不检查后缀名
解析调用/漏洞绕过
这类漏洞直接配合上传一个代码注入过的白名单文件即可,再利用解析调用/漏洞
.htaccess文件攻击,通过一个.htaccess文件调用php的解析器去解析任意文件,无论文件名是什么样子,都可以被以php的方式来解析。建一个.htaccess文件,里面的内容如下
SetHandler application/x-httpd-php
- .htaccess
<FileMatch "1">
SetHandler application/x-httpd-php
</FileMatch>
服务端文件文件检测
- (检测内容是否合法或含有恶意代码)
如果文件内容检测设置的比较严格,那么上传攻击将变得非常困难,也可以说它是再代码层检测的最后一道关卡,如果它被突破了,就算没有代码层的漏洞,也给后面利用应用层的解析漏洞带来了机会。
一般用图片马,有waf要求一句话代码能过waf。
绕过二次渲染
绕过二次渲染:
1.攻击函数本身,通过上传不完整图片让其渲染函数暴露,然后攻击之。
2.对文件加载器进行溢出攻击。
怎么看是否被二次渲染:上传一张图片马,下载到本地,打开看看如果代码还在就没有被二次渲染