一、概述
任意文件上传(Arbitrary File Upload) 是一种网络安全漏洞,漏洞源于应用程序对用户上传文件的不当处理。当系统未能正确验证文件类型、内容或路径时,攻击者便有机可乘,上传携带恶意代码的文件,如Webshell,进而执行任意命令、窃取数据或发起进一步攻击。
大多数网站都有文件上传的接口,但如果在后台开发时并没有对上传的文件进行安全考虑或采用了有缺陷的措施,导致攻击者可以通过一些手段绕过安全措施从而上传一些恶意文件,从而通过该恶意文件的访问来控制整个后台。
二、使用pikachu靶场环境学习测试
1、客户端前端校验(client check):
客户端实施文件类型检查:
客户端校验,允许的文件扩展名.jpg, .png, 和 .gif:
<script>
function checkFileExt(filename)
{
var flag = false; //状态
var arr = ["jpg","png","gif"];
//取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
//比较
for(var i=0;i<arr.length;i++)
{
if(ext == arr[i])
{
flag = true; //一旦找到合适的,立即退出循环
break;
}
}
//条件判断
if(!flag)
{
alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>
##var arr = ["jpg","png","gif"];
##创建一个数组arr,包含允许的文件扩展名,即.jpg, .png, 和 .gif。
通过修改后缀名重新上传成功:(.php改为.jpg文件后缀名)
选择文件--lan.jpg--文件上传-抓包改回文件后缀名-放包-上传成功:
lan.php上传成功
客户端前端校验说明:
前端校验(Client-Side Validation)是Web应用程序中用于在用户提交数据到服务器之前验证用户输入的一种机制。以下是一些前端校验的主要特征和目的:
-
实时反馈:前端校验可以立即显示错误信息,提高用户体验,因为用户不需要等待服务器响应就能看到其输入是否有效。
-
减少服务器负担:通过在客户端进行初步验证,可以减少无效请求到达服务器,从而降低服务器的处理压力和带宽使用。
-
基本验证规则:前端校验通常包括对数据类型、长度、格式的检查,例如:
- 必填字段检查
- 邮箱格式验证
- 电话号码或身份证号码格式检查
- 数字范围验证
- URL、日期和时间格式验证
- 文件类型和大小限制(如在文件上传中)
-
增强可用性:良好的前端验证可以指导用户正确填写表单,减少提交失败的概率,提高表单完成率。
-
可视化提示:通过使用红色错误消息、字段高亮或其他视觉提示,帮助用户快速识别和修正错误。
-
兼容性:前端验证需要考虑到不同的浏览器和设备,确保在各种环境下都能正常工作。
-
可定制性:前端验证库(如jQuery Validate、React Formik、Vue Form Validation等)通常提供丰富的自定义选项,允许开发者根据应用需求定制验证逻辑和错误消息。
-
安全性补充:尽管前端校验是必要的,但它不能替代服务器端验证,因为客户端的代码是可以被用户绕过的,所以重要数据和关键逻辑的安全验证应始终在服务器端进行。
-
性能优化:使用异步验证可以改善用户体验,例如在用户输入时实时验证,而不仅仅是提交表单时。
-
响应式设计:随着移动设备的普及,前端校验需要考虑不同屏幕尺寸和输入方式,确保在各种设备上都能正常工作。
前端校验是Web开发中的重要组成部分,它结合了用户体验、性能和安全性等多个方面,旨在提供一个流畅且安全的用户交互流程。
三、upload-labs靶场环境测试学习
一个帮你总结所有类型的上传漏洞的靶场;是指用于练习和测试文件上传漏洞的在线平台或本地模拟环境。
文件上传靶机下载地址:https://github.com/c0ny1/upload-labs
运行环境
操作系统:推荐windows(除了Pass-19必须在linux下,其余Pass都可以在windows上运行)
php版本:推荐5.2.17(其他版本可能会导致部分Pass无法突破)
php组件:php_gd2,php_exif(部分Pass需要开启这两个组件)
apache:以moudel方式连接
PS:可下载Windows下集成环境,解压即可运行靶机环境。
实验用小马
Pass-01
绕过方式
源代码
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;
}
}
1.前端禁用JS,直接上传Webshell
2.把以.php结尾的小马改为以.jpg|.png|.gif结尾,用burpsuite抓包,在把.jpg|.png|.gif改回.php即可上传成功
详细步骤:
1.php改为lan.jpg进行上传,利用bp抓包拦截请求
在bp上将lan.jpg改为lan.php然后放包
上传完成:
----------------
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类型进行了验证判断
截断上传数据包,修改Content-Type为image/gif,然后放行数据包
查看目标主机1.php上传成功
-----------
Pass-03
源代码
$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 . '文件夹不存在,请手工创建!';
}
}
方式一:上传php3,php5...等这样可以被服务器解析的后缀名
1.这里是黑名单验证(‘.asp‘,‘.aspx‘,‘.php‘,‘.jsp‘),我们可上传php3,php5...等这样可以被服务器解析的后缀名
用阅览器打开文件地址
图像链接:
http://10.0.0.101:90/upload/upload/202405100357171894.php3
上传的文件成功未被解析执行:
phpstudy无法解析php2、php3、phtml等文件解决方法
2、打开配置文件
点击其他选项菜单---->打开配置文件---->httpd-conf
修改配置文件,将红框前面的注释删掉,后面可以加想解析的文件类型,php2、php3等
重启phpstudy即可
重新用阅览器打开文件地址
http://10.0.0.101:90/upload/upload/202405100357171894.php3
文件上传成功1.php小马文件被解析执行:
方式二、尝试上传Apache服务器中的.htaccess
文件绕过:
.htaccess
文件是Apache服务器的一个配置文件,用于控制目录级别的权限和重定向等操作
(只要和 .htaccess 文件同目录下就会被当成脚本解析)
文件内容:
<FilesMatch "">
SetHandler application/x-httpd-php
</FilesMatch>
##这段代码的作用是将所有请求的文件都作为PHP文件处理,但这可能会导致所有文件(包括非PHP文件)都被尝试用PHP解析,可能导致错误或者不必要的资源消耗。在实际部署中,通常会指定特定的文件扩展名,如.php,以确保只有PHP文件被正确处理
查看上传情况:
上传的.htaccess文件被重命名无法执行)
上传成功无法被解析执行(文件被重命名)
---------------------
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 . '文件夹不存在,请手工创建!';
}
}
方式一:尝试上传Apache服务器中的.htaccess
文件
选择.htaccess文件
点击上传-用bp工具进行抓包,
发到Repeater查看相应情况:
成功上传.htaccess文件
或文件右击-复制图像链接
http://10.0.0.101:90/upload/upload/.htaccess
阅览器打开:(意味着服务器已经识别出了该文件,并且正在尝试应用其中的规则。)
只要和.htaccess文件同目录下就会被当成脚本解析:
上传1.php文件:
将1.php改成照片格式后缀名后上传
上传成功
复制上传文件的图像链接:
图像链接粘贴到Web管理工具;输入小马密码实现远程操控:
方式二:利用PHP 和 Windows环境的叠加特性
以下符号在正则匹配时的相等性:
双引号" = 点号.
大于符号> = 问号?
小于符号< = 星号*
1、先上传一个名为4.php:.jpg的文件,上传成功后会生成4.php的空文件,大小为0KB.
将1.php小马文件重命名为4.jpg
上传4.jpg用bp抓包拦截,拦截的请求发送到重发器
将4.jpg文件改为4.php:.jpg发送(绕过方式)
查看目标主机上传的4.php文件0kb大小
(因中间件bp发送4.php:.jpg对文件格式不限制,win系统文件名称符号限制(:等符号)4.php:.jpg会自动改为4.php)
\ / : * ? " < > |
2、然后将文件名改为4.<或4.<<<或4.>>>或4.>><后再次上传,重写4.php文件内容,Webshell代码就会写入原来的4.php空文件中。
用bp重发器将4.php:.jpg重命名为4.<后再次发送
文件已成功上传并写入内容
最后关闭bp拦截请求
------------------------
Pass-05
源代码
$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); //转换为小写 这一句没有了,我们就可以使用文件名后缀大小写混合绕过,把1.php改为5.phP...来上传
1、先把1.php小马文件改为1.jpg上传
用bp抓包拦截改为5.phP进行绕过-放包:
文件上传成功:
尝试利用上传的小马远程控制目标主机:
http://10.0.0.101:90/upload/upload/202405100947417058.phP
填写目标主机地址及密码:
成功控制目标主机:
声明:
- 此文章只做技术研究,谨遵守国家相关法律法规,请勿用于违法用途,如果您对文章内容有疑问,可以尝试留言私信,如有侵权请联系小编处理。
- 在进行任何渗透测试或漏洞利用之前,请确保你有合法授权,遵守所有适用法律和道德规范