从代码看任意文件上传漏洞

admin 2025年5月5日14:10:35评论4 views字数 3013阅读10分2秒阅读模式

声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。

请大家关注公众号支持,不定期有宠粉福利

Part-01

    基础知识

任意文件上传漏洞属于 Web 应用系统中较为经典、同时也是危害较大的漏洞,在Web1.0 时代,恶意攻击者的主要攻击手法是将可执行脚本(WebShell)上传至目标服务器,以达到控制目标服务器的目的。那时人们的安全意识还不是很强,随着互联网的发展,开发人员的安全意识水平也越来越强,文件上传漏洞得到了明显改善。任意文件上传漏洞的本质是在进行文件上传操作时未对文件类型进行检测或检测功能不规范导致被绕过,从而使攻击者上传的可执行脚本(WebShell)被上传至服务器并成功
解析,如图所示。
从代码看任意文件上传漏洞
针对文件上传,我们在学习渗透测试时已经知道存在各类绕过方法,其中大部分绕过方法都和程序员编写习惯息息相关,本节我们将了解 Java 中各类错误写法引发的文件上传问题。
漏洞危害:获取 WebShell,攻击内网,破坏服务器数据等。

Part-02

文件上传漏洞发现方法

在 Java 开发中,文件上传的方式有多种,我们主要讲解以下三种:通过文件流的方式上传、通过ServletFileUpload 方式上传和通过 MultipartFile 方式上传。
1.通过文件流的方式上传
public String fileUpload(@RequestParam("file") CommonsMultipartFile file) throws IOException {  long startTime=System.currentTimeMillis(); System.out.println("fileName:"+file.getOriginalFilename()); try {  OutputStream os=new FileOutputStream("/tmp"+newDate().getTime()+file.getOriginalFilename());  InputStream is=file.getInputStream();  int temp;  while((temp=is.read())!=(-1))  {  os.write(temp);  }  os.flush();  os.close();  is.close();  } catch (FileNotFoundException e) {  e.printStackTrace();  }  return "/success"}
2.通过 ServletFileUpload 方式上传
String realPath = this.getServletContext().getRealPath("/upload"); String tempPath = "/tmp"File f = new File(realPath); if(!f.exists()&&!f.isDirectory()){  f.mkdir(); File f1 = new File(tempPath); if(!f1.isDirectory()){  f1.mkdir(); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository(f1); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); if(!ServletFileUpload.isMultipartContent(req)){ return; } List<FileItem> items =upload.parseRequest(req); for(FileItem item:items){  if(item.isFormField()){  String filedName = item.getFieldName();  String filedValue = item.getString("UTF-8");  }else String fileName = item.getName();  if(fileName==null||"".equals(fileName.trim())){ continue; }  fileName = fileName.substring(fileName.lastIndexOf("/")+1);  String filePath = realPath+"/"+fileName;  InputStream in = item.getInputStream();Ou tputStream out = new FileOutputStream(filePath);  byte b[] = new byte[1024];  int len = -1 while((len=in.read(b))!=-1){  out.write(b, 0, len);  }  out.close();  in.close();  try {  Thread.sleep(3000);  } catch (InterruptedException e) {  e.printStackTrace();  }  item.delete();
3.通过 MultipartFile 方式上传
public String handleFileUpload(@RequestParam("file") MultipartFile file) {  if (file.isEmpty()) {  return "请上传文件" }  // 获取文件名 String fileName = file.getOriginalFilename();  String suffixName = fileName.substring(fileName.indexOf("."));  String filePath = "/tmp" File dest = new File(filePath + fileName);  if (!dest.getParentFile().exists()) {  dest.getParentFile().mkdirs();  }  try {  file.transferTo(dest);  return "上传成功" } catch (IllegalStateException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }  return "上传失败"}
以上是常见的文件上传方式,类似的文件上传方式很多,这里不一一列举。文件上传漏洞的本质还是未对文件名做严格校验,常见的主要有如下几种情况:未对文件做任何过滤,仅在前端通过 js 检验,只判断了 Content-Type,后缀过滤不全,读取后缀方式错误等。

原文始发于微信公众号(锐鉴安全):从代码看任意文件上传漏洞

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月5日14:10:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从代码看任意文件上传漏洞https://cn-sec.com/archives/4029530.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息