文件上传漏洞
文件上传漏洞
Wells概述
什么是文件上传漏洞
文件上传漏洞是指由于对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以向服务器上传恶意文件并进行执行,后获得执行服务端命令的能力。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。
产生文件上传漏洞的原因
- 不充分的文件验证:如果应用程序未能正确验证上传文件的类型(如MIME类型或文件扩展名)和内容,攻击者可能会上传执行恶意代码的文件。
- 不安全的文件存储:如果上传的文件存储在可通过Web直接访问的位置,且文件名可预测或未经过适当处理,攻击者可能会执行上传的恶意文件。
- 未对权限进行限制:权限上没有对于上传的文件目录设置不可执行权限。
例子
CTFHUB-技能树-WEB-文件上传-无验证
因为在上传文件后无验证文件信息以及设置动态脚本不可被执行,因此便可直接上传远程木马文件,
查看图片
上传后访问此网站路径下的/upload/shell.php
发现是空白界面,说明php文件可以被执行,此时通过冰蝎进行远程连接
查看图片教程
出现phpinfo页面,说明连接成功,即可获得主机部分权限,转到对应目录读取flag
查看图片
后端绕过-解析漏洞
解析漏洞通常指的是当应用程序或服务器在处理上传文件时,由于对文件类型的解析不当或不安全,导致攻击者能够上传恶意文件,从而执行不当操作或获取不当权限的安全问题。例如允许用户上传
.htaccess
文件导致用户可以设置任意文件格式的解析方式
.htaccess
绕过
.htaccess
简介
.htaccess
是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。通过.htaccess
可以做到:重写解析规则(如:将png
文件作为php
来进行解析等)、URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。
.htaccess
的作用范围
.htaccess
的生效范围为.htaccess
文件所在的当前目录。
.htaccess
利用前提
- 使用
Apache
服务器( 不适用于Nginx
服务器) - 能成功上传
.htaccess
文件的上传,且没有被重命名
.htaccess
使用模板
1 | #对于php |
例题:
CTFHUB-技能树-WEB-文件上传-.htaccess
查看页面源码可以发现页面后端源码
1 | <!DOCTYPE html> |
在 $blacklist = array("php", "php7", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf");
发现大多数的动态执行脚本文件后缀被禁止,但发现.htaccess
并没有被禁止,此时可以上传文件.htaccess
1 | AddType application/x-httpd-php .txt |
再上传含有shell的php代码的txt
文件,上传成功后,访问upload/shell.php.txt
,无内容显示,说明.txt
文件被作为php脚本执行成功,使用冰蝎连接
查看图片教程
成功获取phpinfo
页面,连接成功,读取flag
.user.ini
绕过
.user.ini
介绍
php.ini
是php的一个全局配置文件,对整个web服务起作用;而.user.ini
与.htaccess
类似,设置当前目录的配置信息。
详细参考信息:
PHP: .user.ini 文件 - Manual、php - 神秘的.user.ini文件
其中php
配置项中有两个配置可以起到文件包含的作用
1 | auto_prepend_file = <filename> //将指定文件包含在该目录中所有php脚本的文件头部 |
.user.ini
使用前提
- 能成功上传
.user.ini
文件的上传,且没有被重命名 - 此目录下已有一个任意的
.php
文件
.user.ini
作用范围
与.htaccess
文件相同,.user.ini
的生效范围为.user.ini
文件所在的当前目录。
.user.ini
使用方法
1.首先上传一个含有php
代码的任意符合后端检测的文件,以.jpg
为例:
文件名为info.jpg
,内容为
1 | <?php phpinfo();?> |
2.载上传入.user.ini
文件,内容为:
1 | auto_prepend_file = info.jpg |
注:info.jpg
需要自己上传问文件名来确定
3.访问文件上传目录下的任意.php
文件即可
例题:
数字后缀绕过
数字后缀简介
PHP 文件的标准后缀始终是 .php
,适用于所有版本的 PHP。然而,在某些特定场景或由某些开发者/系统中,使用.php3
、.php5
、.php7
等不是 PHP 语言的标准文件后缀,由于一些特殊的设置.php7
等后缀可被PHP解释器解析
使用条件:
Apache 的配置文件或目录下的.htaccess
文件有添加设置,如.php7
可被解析的配置为:
1 | AddHandler application/x-httpd-php .php7 |
利用中间件漏洞
中间件漏洞是指在计算机系统中使用的中间件软件中存在的安全漏洞。中间件是指位于操作系统和应用程序之间的软件组件,用于提供不同应用程序之间的通信和交互。常见的中间件包括数据库管理系统、Web服务器(如:
Apache
、Nginx
)等。
后端绕过-软件漏洞
利用PHP某些版本的BUG可以做到一些意想不到的效果。例如,
00
截断
PHP 00
截断绕过
00
截断利用条件
- php版本要小于5.3.4,5.3.4及以上已经修复该问题
- PHP的magic_quotes_gpc为OFF状态
- 用户可指定上传路径
00
绕过简介
ASCII中0作为特殊字符保留,表示字符串结束。
当用户传递文件上传路径包含00
,无论00
后存在任何内容文本(或后端直接对00
字符串进行拼接其他字符串),00
后的内容都会被截断,最后字符串留下00
前的内容且不包括00
。
以GET方式举例:
ASCII中的00
,无法直接显示,所以使用URL编码,ASCII中00
经过url编码后变为%00
页面源码为:
1 |
|
test.txt
的内容为
1 | <?php |
test.txt%00.2.txt
的内容为
1 | <?php |
实验1
此时通过GET传递参数,?file=test.txt%00.2.txt
查看图片教程
页面出现SUCCESS,说明include
的文件是test.txt
,此时file
被解析为test.txt
实验2:改变页面源码
1 |
|
此时通过GET传递参数,?file=test.txt%00
查看图片教程
页面还是出现SUCCESS,说明include
的文件是test.txt
,而不是test.txt.2.txt
,此时变量file
受$_GET['file']
中的影响,一同被截断
00
绕过方法
GET传参保存路径
后端对文件路径的处理类似为
1 | $des = $_GET['road'] . "/对文件名的处理操作......" . $ext; |
此时road
为我们可控的参数,可直接进行使用%00
截断
查看图片教程
由于使用00
截断,所以最后文件保存在/var/www/html/upload
,名为shell.php
,根据位置,访问/upload/shell.php
,即进入我们所在的页面,使用蚁剑连上后,可以找到我们成功截断的shell.php
查看图片教程
POST传参保存路径
与GET传参类似的的是:后端对文件路径的处理类似为
1 | $des = $_POST['road'] . "/对文件名的处理操作......" . $ext; |
此时road
为我们可控的参数,但与GET传参不同的是,http请求内包含文件时,POST参数不再被自动解码,所以POST传参需要使用BP使用查看16进制的请求详情,修改一个十六进制的为00
查看图片教程
步骤一:修改路径添加文件名,写入需要执行的代码语句
查看图片教程
步骤一:切换为十六进制模式,修改所需要替换为00
的位置
查看图片教程
由于使用00
截断,所以最后文件保存在/var/www/html/upload
,名为test.php
,根据位置,访问/upload/test.php
,即进入我们所在的页面,可以看到PHP的配置信息,00
截断成功
查看图片教程
例题:
CTFHUB-技能树-WEB-文件上传-00截断
查看页面源代码发现后端的源码
1 | if (!empty($_POST['submit'])) { |
抓包,修改GET参数为?road=/var/www/html/upload/shell.php%00
,使用00
截断,在传入文件的内容替换成需要执行的代码,如一句话等
查看图片教程
然后使用蚁剑连接进入,可以看到我们是成功使用00
截断写入的shell.php
查看图片教程
后端检测-修改绕过
通过抓包我们发送的请求,修改请求包中的部分内容,如修改文件名(黑名单双写,大小写替换),MIME,添加文件头等等操作,使之上传的木马符合后端的要求,使之成功上传。
双写绕过
双写绕过原理
有时候在检测时,后台会把敏感字符删除,这个时候,可以使用双写进行绕过。比如:将.php
改写为.pphphp
后端的代码类似为:
1 | $name = basename($_FILES['file']['name']); |
例题:
CTFHUB-技能树-WEB-文件上传-双写后缀
查看页面源码,发现这样一段内容
1 | <!-- |
这时候上传shell
文件,并抓包,将后缀名.php
改写为.pphphp
,再发包最后成功上传
大小写后缀绕过
大小写后缀绕过
后端在检测时,后台会检测敏感字符,如果并没有不区分大小写时,可以使用大小写进行绕过。比如:将.php
改写为.pHp
后端的代码类似为:
1 | $name = basename($_FILES['file']['name']); |
MIME检测绕过
MIME简介
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL。部分Web应用系统判定文件类型是通过content-type字段
,截取一个请求信息:
1 | POST / HTTP/1.1 |
其中Content-Type: application/octet-stream
和就是描述了上传文件的MIME 类型
MIME绕过方法
部分Web应用系统判定文件类型是通过content-type字段
,因此可以通过抓包,将content-type字段
改为常见的图片类型
,如image/gif
,从而绕过校验。
常见的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文档)
例题:
CTFHUB-技能树-WEB-文件上传-MIME绕过
尝试直接上传.htaccess
和php
shell文件时都上传失败,尝试修改MIME类型,抓包原始请求头
1 | POST / HTTP/1.1 |
将
1 | ------WebKitFormBoundary4BffHh31AMlHQtBd |
修改为
1 | ------WebKitFormBoundary4BffHh31AMlHQtBd |
再放行,最后发现shell.php
被成功上传,访问upload/shell.php
,无内容显示,说明.txt
文件被作为php脚本执行成功,使用冰蝎连接
查看图片教程
成功获取phpinfo
页面,连接成功,读取flag
文件头检测绕过
文件头检测绕过简介
文件头是在每一个文件(包括图片,视频或其他的非ASCII文件)的开头(十六进制表示)的一段数据,用于描述文件的属性和格式信息, 在进行文件头绕过时,我们可以把图片的文件头添加到我们的木马内容最前面,达到绕过文件头检测的目的。
常见的文件头
注意:文本形式请点击复制,不要做任何修改
GIF:
16进制模式:47 49 46 38 39 61
对应文本:
1 | GIF89a |
png:
16进制模式:89 50 4E 47 0D 0A 1A 0A
对应文本:
1 | ‰PNG |
JPG:
16进制模式:FF D8 FF E0 00 10 4A 46 49 46
对应文本:
1 | ÿØÿà |
文件头检测绕过条件
- 某些情况下,后端可能还会检测文件拓展名,此时需要结合解析漏洞或者文件包含才能实现执行木马
例题:
CTFHUB-技能树-WEB-文件上传-文件头检查
步骤一:直接选择木马文件进行上传,然后进行抓包
查看图片教程
以添加PNG请求头为例
方法一:在PHP代码前添加入任意八个字母,用于定位以及替换为PNG的文件头,后转HEX模式替换为PNG的文件头
查看图片教程
方法二:直接在PHP代码后插入PNG文件头对应的文本表示符号
查看图片教程
参考文章
参考腾讯云开发者社区博主「网络安全自修室」的文章