一 文件上传漏洞介绍(理论)
文件上传漏洞是一种常见的web应用程序漏洞,允许攻击者向服务器上传恶意文件。这种漏洞可在没有恰当的安全措施的情况下,将任意类型的文件上传到服务器上,从而可能导致以下安全问题:
- 1.执行恶意代码:攻击者可以上传包含恶意代码的文件,如Webshell、病毒或木马程序,通过执行这些恶意文件,攻击者可以远程控制服务器,窃取敏感信息或进行其他恶意活动。
- 2.绕过访问控制:通过上传包含自己所需的权限和访问控制规则的文件,攻击者可以绕过系统的访问控制机制,访问他们本应该被禁止的资源。
- 3.拒绝服务攻击:攻击者可以上传大量大文件或无限制的文件,消耗服务器的存储空间和带宽,导致服务器资源耗尽,从而使服务不可用。
- 4.信息泄露:攻击者可以上传包含敏感信息的文件,如数据库备份文件、日志文件等,从而暴露敏感数据。
文件上传漏洞可以通过以下方式产生:
缺乏文件类型验证:服务器未对上传的文件进行类型验证,使得攻击者可以上传任意类型的文件。
缺乏文件名和路径验证:服务器未对文件名和路径进行有效的验证,使得攻击者可以使用恶意文件名和路径进行攻击。
不正确的访问控制:服务器未正确配置对上传文件的访问控制,使得攻击者可以上传到不受限制的目录中。
为了防止文件上传漏洞,开发人员应采取以下安全措施:
对上传的文件进行类型验证,只允许合法的文件类型上传。
对文件名和路径进行有效的验证,防止恶意文件名和路径的上传。
限制上传文件的大小和数量,避免服务器资源被耗尽。
将上传的文件保存在安全的目录中,不允许直接执行上传的文件。
对上传的文件进行病毒扫描,确保不会上传恶意文件。
对上传的文件进行访问控制,限制用户对上传文件的访问权限。
定期审查服务器上的上传文件,及时检测和删除恶意文件。
通过实施这些措施,可以有效减少文件上传漏洞的风险,并提高web应用程序的安全性。
二 基于靶场实操
2.1 认识靶场
上传(upload)是指将文件、数据或信息从本地计算机或设备发送到远程服务器或其他存储设备的过程。上传通常是通过互联网或局域网进行的,可用于分享文件、备份数据或将内容发布到网站或应用程序中。
在互联网上,上传通常是通过使用文件传输协议(FTP)或超文本传输协议(HTTP)等网络协议进行的。用户可以选择将单个文件或整个文件夹上传到指定的目标位置。上传的文件可以是各种格式,如文档、图片、音频、视频等。
上传过程包括以下步骤:
1. 选择要上传的文件或文件夹。
2. 连接到目标服务器或存储设备。
3. 将文件传输到服务器或设备。
4. 等待上传完成并验证文件是否成功。
上传的速度取决于多个因素,例如文件大小、网络连接速度和服务器的处理能力。较大的文件或较慢的网络连接可能需要较长的时间来完成上传。
上传功能已经成为许多网站和应用程序的基本功能之一,例如云存储服务、社交媒体平台和电子邮件附件。它为用户提供了方便快捷的方式来共享和传输文件,促进了信息的交流和共享。
2.3 闯关 实操 1-10
文件上传漏洞的本质 又是通过文件上传到对应的链接 让漏洞执行
JavaScript 教程 | 菜鸟教程
2.3.1 解题思路
前端校验上传文件的后缀名是否为.jpg|.png|.gif,屏蔽前段js代码运行,或者使用Burp Suite抓包拦截数据包并修改上传文件的后缀名,绕过前端的后缀名限制。
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; } }
2.3.2 解题策略
对文件MIME类型进行了验证判断,即请求数据中的Content-Type为image/jpeg|image/png|image/gif,在拦截请求包时修改该内容即可绕过上传限制。由于上传后文件后缀仍为php,服务器仍将该上传文件以php解析。
$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.'文件夹不存在,请手工创建!';
2.3.3 解题思路
黑名单判断,服务器端禁止上传'.asp','.aspx','.php','.jsp'后缀的脚本文件,可以上传例如php3, phtml后缀的文件绕过,前提是Apache配置文件(httpd.conf)中有如下配置:
AddType application/x-httpd-php .php .php3 .phtml
服务器会将php3, phtml后缀的文件当成php解析。
$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 . '文件夹不存在,请手工创建!'; } }
2.3.4 解题思路 更据下面禁止的文件后缀
$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.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
2.3.5 解题思路 后缀改为大写
本pass禁止上传.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|.htaccess后缀文件!
$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 = 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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
解题思路
黑名单判断加入.htaccess,但是源代码中没有$file_ext = strtolower($file_ext); //转换为小写这一行代码,可以使用大小写绕过。
$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 = 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 = '此文件类型不允许上传!';
}
} else {
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 = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
hif (!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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
pass03中php处理文件后缀的一个完整检查和处理
$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); //首尾去空
pass05 的处理
$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); //首尾去空
2.3.6 解题思路
$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 = $_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
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 = '此文件不允许上传';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
解题思路
源代码缺少$file_ext = trim($file_ext); //收尾去空,可以文件名后缀增加空格绕过
解题步骤
上传文件名info6.php
2.3.7 解题思路
解题思路
源代码缺少$file_name = deldot($file_name);//删除文件名末尾的点限制,可以文件名后缀增加.绕过,windows系统下会自动去掉后缀名中最后的.
解题步骤
上传文件名info7.php.
2.3.8 解题思路
解题思路
源代码缺少 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA限制,可以文件名后缀增加::$DATA绕过
- Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性 DATA 时,就是请求 a.asp 本身的数据,如果a.asp 还包含了其他的数据流,比如 a.asp:lake2.asp,请求 a.asp:lake2.asp::$DATA,则是请求a.asp中的流数据lake2.asp的流数据内容。
NTFS文件流实际应用
- NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$DATA。
解题步骤
上传文件名info8.php::$DATA,访问时去除后缀
2.3.9 解题思路
解题思路
由$img_path = UPLOAD_PATH.'/'.$file_name;得上传后文件的URL命名规则是由$file_name直接拼接而成
解题步骤
上传文件名info9.php. .
2.3.10 解题思路
解题思路
- $file_name = str_ireplace($deny_ext,"", $file_name);只对文件后缀名进行一次过滤,双写文件名绕过。
解题步骤
上传文件名改成info10.pphphp
upload-labs通关_数据处理专家的技术博客_51CTO博客