文件上传漏洞原理
文件上传漏洞通常是攻击者上传了可执行的文件到服务器并执行。上传的文件可以是木马,病毒,恶意脚本或者webshell等。
文件上传的先决条件
1,上传的文件能被web服务器当作脚本来解析执行(搭配文件包含和文件解析漏洞)
2,能访问到(能知道)上传文件的路径
服务器上传文件命令规则:
1,上传文件名和服务器命令一致
2,上传文件名和服务器命令不一致(随机,根据时间及日期等),后缀名一致
3,上传文件名和服务器命令不一致(随机,根据时间及日期等),后缀名不一致
文件上传的过滤法
前端过滤
#前端js检测,白名单限制上传格式为.jpg
<script type="text/javascript">
function selectFile(fnUpload){
var filename = fnUpload.value;
var mime = filename.toLowerCase().substr(filename.lastIndexOf("."));
if(mime!=".jpg")
{
alert("请选择JPG格式的文件进行上传");
fnUpload.outerHTML=fnUpload.outerHTML;
}
}
</script>
后端检测文件后缀名
#后端php检测
$info=pathinfo($_FILES["file"]["name"]);
$ext=$info['extension'];//得到文件扩展名
if(strtolower($ext) == "php"){ //黑名单检测,不允许上传php格式的文件
exit("不允许的后缀名");
}
后端基于Content-Type类型检测文件类型
#后端对上传文件的Content-Type类型进行检测,只允许上传image/gif,image/jpeg,image/pjpeg格式的文件
if(($_FILES["file"]["type"]!="image/gif") && ($_FILES["file"]["type"]!="image/jpeg") && ($_FILES["file"]["type"]!="image/pjpeg")){
exit($_FILES["file"]["type"]);
exit("不允许的格式");
}
文件上传绕过
前端检测绕过:
上传时使用bp拦截数据包,然后进行改包
后端绕过
1,windows系统解析漏洞
将test.php上传时经过bp修改为“test.php.”或者“.php ”,因为windows系统内是不允许文件以.或者空格结尾的,或者将php三个字母变换大小写(windows系统不区分大小写),如果是白名单检测,可以采用00截断绕过。在php<5.3.4版本中,存储文件时处理文件名的函数认为0x00时终止符。当函数读到0x00(%00)时,会认为文件已经结束。
例如:上传test.php%00.jpg,上传到后端时,后端判断文件名后缀的函数会认为其是一个.jpg格式的文件,可以躲过白名单检测。但是在保存文件的时候,处理文件名的函数在遇到%00字符认为这是终止符,于是丢弃了后面的.jpg,最终写入的文件为test.php。
2,bp抓包修改Content-Type类型
3,利用文件包含漏洞
4,apache服务器上传.htacess文件,将jpg类型的文件当作php解析
5,ngix服务器上传user.ini文件,将jpg文件的内容包含到php文件中去,相当于使用include()等包含文件的函数
6,有时服务器只对上传的第一个文件进行了检查,通过上传多个文件并将恶意文件参杂进其中也可以绕过服务器的过滤
7,拓展名绕过
ASP:asa,cer,cdx
Aspx:ashx,asmx,ascx
Php:php3,phtml
Jsp:jspx,jspf
同样,网站管理员可能会忽略.html格式的文件
文件上传的防御方法
1,前端js检测,对上传文件检测,包括文件大小,文件拓展名,文件类型等
2,服务端检测,对文件大小,文件路径,文件拓展名,文件类型,文件内容检测,文件重命名等
3,上传目录不设置可执行权限
4,审查文件解析漏洞和文件包含漏洞
5,将文件上传到单独的文件服务器,并且单独设置文件服务器的域名