文件上传绕过
文件上传简介
文件上传就是将客户端数据以文件形式封装,通过网络协议发送到服务器端。在服务器端解析数据,最终在服务端硬盘上作为真实的文件保存。
通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器收到请求并同意后,用户与Web服务器将建立连接,并传输数据。
何为文件上传漏洞?
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器端脚本语言未对上传的文件进行严格的验证和过滤,就容易造成上传任意文件的情况。
通常 Web 站点会有用户注册功能,而当用户登录之后大多数情况下会存在类似头像上传、附件上传之类的功能,这些功能点往往存在上传验证方式不严格的安全缺陷,导致攻击者通过各种手段绕过验证,上传非法文件,这是在web渗透中非常关键的突破口。
攻击者通过上传恶意文件传递给解释器去执行,然后就可以在服务器上执行恶意代码,进行数据库执行、服务器文件管理、命令执行等恶意操作。从而控制整个网站及服务器。 这个恶意的文件(php、asp、aspx、jsp等),又被称 WebShell 。
产生文件上传漏洞的原因:
1.服务器配置不当
2.文件上传限制被绕过
3.开源编辑器的上传漏洞
4.文件解析漏洞导致文件执行
5.过滤不严或被绕过
文件上传绕过姿势
在研究文件上传绕过姿势之前,我们首先要知道当前环境下,防守方通常是如何进行文件验证的,以下是目前的常见检测手段:
客户端JavaScript检测 (检测文件扩展名)
服务端MIME类型检测 (检测content-type内容)
服务端目录路径检测 (检测跟path参数相关的内容)
服务端文件扩展名检测 (检测跟文件extension相关的内容)
服务端文件内容检测 (检测内容是否合法是否含有恶意代码)
绕过前端客户端检测 - JS 检测
原理:通常在上传页面里含有专门检测文件上传的 JavaScript 代码,最常见的就是检测文件类型和扩展名是否合法。
方法:在本地浏览器客户端禁用Js即可;可使用火狐浏览器的Noscript插件、IE中禁用JS等方式实现,利用burpsuite可以绕过一切客户端检测。
方法一:浏览器禁用 JavaScript 代码解析(不推荐):
方法二:修改浏览器的前端 JavaScript 代码
方法三:Burpsuite 抓包修改传递给后端服务器的数据包
绕过服务器端检测 - 后端检测
服务端的代码通常检测三个点:MIME类型、文件内容、文件后缀
绕过MIME类型检测
MIME 检测原理:检测图片类型文件上传过程中http包的content-Type字段的值,来判断上传文件是否合法。
绕过方法:
使用 Burpsuite 修改返回 服务器端 的 content-Type 字段为正确字段(对的上 || 白名单)
以下是常见的 content-Type 字段:
超文本标记语言文本 .html text/html
普通文本 .txt text/plain
PDF文档 .pdf application/pdf
Microsoft word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,·jpg image/jpeg
au声音文件 .au audio/basic
MPEG文件 .mpg mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
PHP 文件格式 application/x-httpd-php
常见MIME类型 : https://www.runoob.com/http/mime-types.html
绕过文件后缀检测 - 黑名单
绕过前端的检测后在数据包中更改上传文件的后缀后可能会遇到如下情况(服务器端限制了可解析类文件的后缀)
这种情况就需要我们去准备同样可以被解析的其他同语言类型的替代可执行代码文件后缀(如php:php3、pht?、pHp4%00...)
常见绕过手段:
后缀大小写绕过:(.Php)
在对后缀的判断中,如果只是对字符串进行单独的比较来判断是不是限制文件,可以采用后缀名大小写绕过形式。
空格绕过:(.php)
如果黑名单没有对后缀名进行去空处理,可以通过在后缀名后加空进行绕过。
点绕过:(.php.)
如果黑名单没有对后缀名进行去.处理,利用Windows系统的文件名特性,会自动去掉后缀名最后的.,通过在文件名后加.进行绕过。
::$DATA 绕过
如果黑名单没有对后缀名进行去 ::$DATA 处理,利用Windows下NTFS文件系统的一个特性,可以在后缀名后加 ::$DATA ,绕过对黑名单的检测。
配合Apache解析漏洞
Apache解析有一个特点,解析文件时是从右往左判断,如果为不可识别解析再往左判断,如aa.php.owf.rar文件,Apache不可识别解析‘.owf’和‘.rar’这两种后缀,会解析成.php文件。
.htaccess 文件
配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测
.htaccess 文件(或者"分布式配置文件"),全称是Hypertext Access (超文本入口)。提供了针对目录改变配置的方法,即,在一个特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。
比如新建一个 .htaccess 文件:
<FilesMatch "as.png"> setHandler application/x-httpd-php </FilesMatch>
通过一个.htaccess文件调用php的解析器去解析一个文件名中只要包含"as.png"这个字符串的任意文件,所以无论文件名是什么样子,只要包含"as.png"这个字符串,都可以被以 php 的方式来解析,一个自定义的.htaccess 文件就可以以各种各样的方式去绕过很多上传验证机制。
// 小疑问求解答 -- 为何此处服务器上显示上传成功了但是访问不到
绕过文件后缀检测 - 白名单(00 截断)
白名单策略:文件扩展名不在白名单中为不合法。
绕过方法:服务端判断文件类型是从后往前判断,而对文件解析是从前往后解析,可以利用00截断的方式进行绕过,包括%00截断与0x00截断。php小于 5.3.29 且php配置 magic_quotes_gpc=Off 。
%00截断: url发送到服务器后被服务器解码,这时还没有传到验证函数,也就是说验证函数里接收到的不是%00字符,而是%00解码后的内容,即解码成了0x00。 0x00截断: 系统在对文件名进行读取时,如果遇到0x00,就会认为读取已经结束。但要注意是文件的十六进制内容里的00,而不是文件名中的00。
%00 截断(截断信息在 URL 当中):
0x00 截断 (阶段信息在请求包体内):
.htaccess 绕过
.htaccess文件是Apache服务器下的一个配置文件。其主要负责相关目录下的网页配置,即:在一个特定的文档目录中放置一个包含一个或多个指令的文件来对网页进行配置。
-- 即可以设定当前页面所处路径文件夹下的 某些/某类 文件可以被当作其他的 某类型 文件解析。
白名单也可以尝试
我们此处利用 .htaccess 的本质也就是利用这个特性实现类似于: .jpg 类型的文件全部被当作 .php 类型的文件所执行,文件中的信息可以被 php 所解析执行
下面是.htaccess文件的实例:
# 某一类文件全被被当作 某一类 文件解析
<ifModule mime_module>
AddHandler php5-script .jpg
# 将.jpg文件按照php代码进行解析执行
AddType application/x-httpd-php .jpg
# 将.jpg文件按照php代码进行解析执行
Sethandler application/x-httpd-php
# 将该目录及子目录下的文件均按照php文件解析执行
</ifModule>
# 该种匹配方式并不推荐,极易造成误伤
And
<FilesMatch "\.jpg$">
# 强制将jpg文件识别为PHP
SetHandler application/x-httpd-php
# 可选:关闭PHP错误输出(安全增强)
php_flag display_errors Off
</FilesMatch>
# 确保PHP解析引擎已启用
php_flag engine on
---
OR
---
# 匹配单一某文件被解析成某类型解析
<FilesMatch "gsl.jpg">
Sethandler application/x-httpd-php
# 将匹配到的 gsl.jpg 文件按照php解析执行
Addhandler php5-script .jpg
# 将匹配到的 gsl.jpg 文件按照php解析执行
</FilesMatch>
# 该种匹配方式较为精准,不会造成大批的误伤情况
And
# 更安全的实现方式(通过重写规则):
RewriteEngine On
# 仅允许特定jpg文件被解析为PHP(例如:safeimage.jpg)
RewriteCond %{REQUEST_URI} safeimage\.jpg$ [NC]
RewriteRule .* - [H=application/x-httpd-php]
# 其他jpg文件保持正常访问
绕过文件内容检测
一般通过检测文件内容来判断上传文件是否合法。
主要有两种检测方法:
通过检测上传文件内容开始处的文件幻数来判断。
通常情况下,通过判断前10个字节,基本就能判断出一个文件的真实类型。
主要是检测文件内容开始处的文件幻数
文件格式幻数(外语:magic number),它可以用来标记文件或者协议的格式,很多文件都有幻数标志来表明该文件的格式。
常见图片类型的文件幻数如下:
要绕过 jpg 文件幻数检测就要在文件开头写上下面的值:
Value = FF D8 FF E0 00 10 4A 46 49 46
要绕过 gif 文件幻数检测就要在文件开头写上下面的值:
Value = 47 49 46 38 39 61
要绕过 png 文件幻数检测就要在文件开头写上下面的值:
Value = 89 50 4E 47
然后在文件幻数后面加上自己的一句话木马代码就行了。
文件加载检测
一般是调用API或函数对文件进行加载测试。常见的是图像渲染测试,再严格点的甚至是进行二次渲染。
一般是调用API或函数去进行文件加载测试,我们常见的是图像渲染测试,严格的进行二次渲染。
对渲染/加载测试的攻击方式是代码注入绕过。
对二次渲染的攻击方式是攻击文件加载器自身。
1.对渲染/加载测试攻击-代码注入绕过
可以用图像处理软件对一张图片进行代码注入。
这类攻击的原理是:在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般是图片的注释区,这样能保证本身文件结构是完整的,对于渲染测试基本上都能绕过。
—— 就是在图片被后端重新渲染成为一个新文件的时候,我们要确保我们后门代码插入的地方不会被删除,还存在在重新渲染的新文件当中。
2.二次渲染的攻击方式-攻击文件加载器自身
这种情况下无法用代码注入绕过,二次渲染相当于吧原本属于图像数据的部分抓出来,在用自己的API或函数进行重新渲染,而非图像数据部分直接被隔离开了。
我们可以用溢出攻击对文件加载器进行攻击,上传自己的恶意文件后,服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode。