1、概述
(1)什么是文件上传漏洞?
程序对文件的上传未作全面的限制,导致用户可以上传一些超越用户权限的文件,可以是木马,shell脚本,病毒等。
(2)危害
可以成为网站后门webshell获取权限
(3)漏洞的查找和判断
黑盒查找:扫描敏感文件获取上传地址;功能点测试;后台处的文件上传(后台权限不等于网站权限)
白盒查找:拿到网页源码后,通过代码分析是否有文件上传漏洞
判断:抓包或测试
注:文件上传类型的分析
2、常规文件上传地址获取
扫描网站敏感文件
工具:wwwscan、御剑、AWVS
搜索网站关键词site: URL upload
3、文件上传基础
(1)上传文件的格式不能混用,如果要求上传php文件,则一般不上传图片,因为要执行的话,要按照对应代码执行,除非有解析漏洞(搭建平台)
(2)文件上传的绕过:
抓包修改文件后缀(如果采用的全为js代码,在本地执行,没有用php接收可能抓不到包);
修改前端代码(对文件格式的过滤代码,因为将前端代码本地保存,所以最后需要添加action访问到图片对应上传的地址)
知道网站的CMS可以直接搜索XXXCMS上传漏洞,这种第三方插件的漏洞测试与常规不一样
(3)文件上传验证:
-
后缀名:类型,文件头等
-
后缀名:黑名单,白名单
黑名单:明确不让上传的格式后缀(asp php jsp aspx cgi war
)
白名单:明确可以上传的格式后缀(jpg png zip rar gif
)
- 文件类型:MIME信息
媒体类型,用来表示文档、文件或字节流的性质和格式。
由类型/子类型组成(无空格,一般是小写,不敏感)
text image audio:音频 video:视频 application:二进制
burpsuit:Content-Type:image/jpeg
- 文件头:内容头信息
方法:查看源码,抓包修改信息
(5)常用函数
_FILES
函数
$_FILES['myFile']['name'] :文件的原名称
$_FILES['myFile']['type'] :文件的MIME 类型
$_FILES['myFile']['size'] :已上传文件的大小,单位为字节
$_FILES['myFile']['tmp_name'] :文件被上传后在服务端储存的临时文件名,一般是系统默认
$_FILES['myFile']['error'] :该文件上传相关的错误代码
实例:$_FILES['upload_file'] name="upload_file"
相同才能上传
<?php
$name=$_FILES['upload_file']['name'];
echo $name;
?>
<form enctype="xxxx" method="post" action="">
<p>上传图片:</p>
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="上传"/>
</form>
trim()
函数
移除字符串两侧的空白字符或其他预定义字符
strrchr()
函数
查找字符串在另一个字符串中最后出现的位置,并返回从该位置到字符串结尾的所有字符
<?php
echo strrchr("hello world! what a beautiful day!",what);
?>
what a beautiful day!
4、黑名单绕过
(1)::$DATA
:不检测文件后缀
针对Windows上的PHP源文件,若文件名+::$DATA
后,会把::$DATA
后的数据当做文件流处理,不会检测文件后缀且保持原文件名
1.php::$DATA
(2).htaccess
文件解析漏洞
From:https://blog.csdn.net/weixin_44032232/article/details/108998564
- 环境:
服务器没有禁止此文件的上传,且服务商允许用户自定义此文件
- 原理:
.htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法:在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
- .htaccess文件内容:
第一种:好用,但容易误伤其他正常文件,易被发现
<IfModule mime_module>
AddHandler php5-script .gif #在当前目录下,只针对gif文 件会解析成Php代码执行
SetHandler application/x-httpd-php #在当前目录下,所有文件都会 被解析成php代码执行
AddType application/x-httpd-php .gif
</IfModule>
第二种:精确控制能被解析成PHP代码的文件,不易被发现
<FilesMatch "evil.gif">
SetHandler application/x-httpd-php #在当前目录下,如果匹配到 evil.gif文件,则被解析成PHP代码执行
AddHandler php5-script .gif #在当前目录下,如果匹配到 evil.gif文件,则被解析成PHP代码执行
</FilesMatch>
- 漏洞利用
将准备好的.htaccess(文件名为此)文件上传,再上传木马即可
若.htaccess上传后被重命名则无法利用此漏洞
(3)空格或点
deldot($file_name) 删除文件名末尾的点
trim($file_ext) 收尾去空
当在源码中没有这些过滤,我们可以尝试在数据包中文件名+空格/点,再发送数据包进行绕过
(4)MIME信息
修改数据包中MIME的文件格式信息,再发送数据包即可
(5)过滤
一次过滤
a.php--a.
a.pphphp--a.php
循环过滤
a.php--a.
a.pphphp--a.
5、白名单绕过
(1)函数
strrpos(string,find,start)
:查找字符串在另一字符串最后一次出现的位置
start(可选),规定在何处开始搜索;区分大小写
(2)MIME信息绕过
(3)00截断
%00,0x00,/00,\0
From:https://blog.csdn.net/weixin_44840696/article/details/90581104
- 环境:
PHP版本小于5.3.4
magic_quotes_gpc = Off
- 原理
截断的是路径
无论0x00还是%00,最终被解析后都是一个东西:chr(0),对应的就是NUT字符(NULL),也就是空字符。
当一个字符串中存在空字符(不是空格)的时候,在被解析的时候会导致空字符后面的字符被丢弃。
- 漏洞利用
前端:
在文件名中插入空字符
用Burp抓包后,在文件名插入一个空格,然后再HEX中找到空格对应的16进制编码“20”,把它改成00
1.php.0x00.jpg--1.php
后端:
上传条件:
后缀检测,合格则进行上传路径拼接
拼接路径和文件名,组成文件上传路径
文件路径可控:
比如可以修改路径拼接的path,抓的数据包存在path: uploads/
就可以直接把路径构造成uploads/xxx.php%00
- 区别
0x00
:代表16进制的空字符00,需要在HEX中改为00,进行截断
%00
:URL解码之前的字符,可以用在URL中如xx.php?filename=test.php%00.txt
,也可以直接插在Burp包中的路径中,如path=shell.jsp%00.txt
POST因为不会自动解码(GET会自动解码),所以需要将%00进行URL编码