护网笔记(九)--文件上传漏洞
文件上传漏洞简介
本文所使用靶场:
upload-labs
上传文件的时候,如果服务器端脚本语言(PHP),未对上传的文件进行严格的验证和过滤,就有可能上传恶意的脚本文件,从而控制整个网站,甚至是服务器。
两个要求:
1. 你能上传
2. 服务器能按照你的要求解析,
比如你上传一个php脚本文件,服务器要能解析php文件才能执行
文件上传的危害
-
网站被控制,对文件增删改查、执行命令、链接数据库
-
如果服务器长久未更新,可以利用exp提权,导致服务器沦陷
-
同服务器的其它网站沦陷(旁站)
哪些地方存在文件上传漏洞?
有上传文件的功能
且上传到的目录,能够解析脚本语言(否则 405)
能够访问到上传的文件
就有可能存在文件上传漏洞
导致文件上传漏洞的原因
导致文件上传漏洞的原因较多,主要包括以下几类:
1)服务器配置不当(IIS 6.0 put 直接些文件)
2)本地文件上传限制被绕过(javascript验证)
3)服务端过滤不严格被绕过
4)文件路径截断(0x00)
5)文件解析漏洞导致文件执行(IIS、apache、nginx)
6)开源编辑器上传漏洞
(fckeditor自定义文件名,文件名结合IIS 6.0解析漏洞,杀伤力很高。
ewebeditor:可以登录后台,配置允许上传的文件类型.asp)
常见几种校验规则
客户端javascript校验--前端校验(第一关)
前端javascript脚本验证,判断文件后缀是否满足条件要求,如果不满足则不允许上传
// JS函数
function checkFile() {
//定义一个file变量,使用document.getElementsByName方法获取upload_file文件名
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义一个字符串,允许上传的文件类型,相当于白名单
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
//substring:提取字符串
//lastIndexof("."):以.这个位置开始向后取值
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
//indexof:如果要检索的字符串值没有出现,则该方法返回 -1
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}
前端校验思路:
首先准备一个1.php脚本文件,内容为phpinfo(),将1.php文件命名为1.jpg文件,符合前端校验要求,然后把数据包发送到burp suite,把1.jpg文件修改为2.php文件,可以成功上传,访问上传的2.php文件,可以正常解析phpinfo()
信息。
上传成功后右键图片,复制链接重新打开可见到如下配置文件。
绕过方法
1)利用burp suite抓包修改文件后缀名
2)修改webshell后缀类型为允许上传类型
3)抓包拦截将其后缀名修改为对应服务器可以解析的后缀名
服务器端MIME类型校验(第二关)
服务端MIME类型校验也就是校验Content-Type的内容
1、进入第二关,尝试上传1.php脚本文件
发现jpg正常上传,php不行。
使用bp抓包,
(本处其实采用Bp和第一关一样的方法似乎也能成功)
查看源码发现,发现仅仅判断content-type
,于是修改content-type
绕过:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}
修改此处。
本处不查看源码的话可以使用phpstrom
调试,
第二关总结
$_FILES['upload_file']['type']
在做代码审计的时候,碰到类似只校验type类型的,就可以修改type类型来达到绕过的目的,也就是说这个type类型是可控的,只校验type类型,是不安全的
基于黑名单(第三关)
黑名单的安全性比白名单的安全性低很多,攻击手法自然也比白名单多,一般有个专门的blacklist,里面包含常见的危险脚本文件。
绕过方法:
1)、文件名大小写绕过(Asp、pHp)
2)、黑白名单绕过(php、php2、php3、php5、phtml、asp、aspx、ascx、ashx、cer、asa、jsp、jspx)cdx,\x00hh\x46php
apache有兼容性,上传php可以解析,上传php2、php3、php5也可以解析
Windows:apache可以解析php2、php3、php5,不同的apache版本解析的后缀名不同
Linux:apache可以解析phtml
3)、特殊文件名绕过
修改数据包里的文件名为"test.php",或者"test.php "(文件后面有空格)由于这种命名方式在windows系统里是不允许的,所以在绕过上传后windows系统会自动去掉点和空格,Unix/linux系统没有这个特性
4)、NTFS硬盘格式特性绕过 ::$DATA
这里利用到了NTFS交换数据流(ADS),ADS是NTFS磁盘格式的一个特性,
在NTFS文件系统下,每个文件都可以存在多个数据流。
通俗的理解,就是其它文件可以“寄宿”在某个文件身上,
而在资源管理器中却只能看到宿主文件,找不到寄宿文件。
1.txt = 1.txt::$DATA
cmd: echo hello world >>1.txt
[相当于把hello world 写进1.txt]
cmd: echo hello world >>1.txt:a.txt[写进a.txt里面,a.txt寄宿在1.txt里面]
用cmd: notepad 1.txt:a.txt 可以打开寄宿文件 或者在cmd:dir /r 把寄宿文件显示出来
补充:
:: $ DATA的特性说明:上传了一个最后带点的文件
例如:“test.php.”,可以看到直接访问名称,回显Not
Found;在完整的名称后面加上::$DATA ,回显Forbidden 受限。
5)0x00截断绕过(5.2 C语言中将\0当作字符串的结尾)
6).htaccess 文件攻击(结合黑名单攻击)
7)解析绕过
服务端文件内容检测总结
文件检查项:前端js检查、后台代码检查(文件后缀名,文件内容特征)
如果文件内容检测设置的比较严格,那么上传攻击将变得比较困难,下面介绍一些基于文件内容检查的绕过方式。
前置知识点:
1、文件幻数检测:jpg(JFIF)gif(GIF89a) png(%PNG)
检测对象:检测文件内容开始处的文件幻数。
例如常见类型文件幻数如下:
文件类型 | 文件头 | 文件尾 |
---|---|---|
JPG | FF D8 FF E0 | FFD9 |
GIF | 47 49 46 38 | |
PNG | 89 50 4E 47 | AE 42 60 82 |
ZIP | 50 4B 03 04 | 50 4B |
MS Word/Excel (xls.or.doc) | D0 CF 11 E0 | |
RAR | 52 61 72 21 |
图片码
想让图片正常展示并且能够注入php代码,可以生成图片码。
语法格式:
copy /b 1.jpg+2.php 3.jpg
打开生成的文件,可以看到嵌入的php代码在最后面。
验证图片码是否可用:
将文件后缀改为php,然后放到服务器上,直接访问,查看是否能够解析
2、文件相关信息检测:文件头加一些图片信息中间夹杂攻击代码
3、文件加载检测:调用API或者函数进行加载测试 php的gd库。
服务器解析漏洞
可参考:
https://blog.csdn.net/weixin_34232617/article/details/92227949
本文来自作者:CK_0ff,转载请注明原文链接:https://www.cnblogs.com/Ck-0ff/p/15799877.html