JEECG代码审计之文件上传

0x01 简述

JEECG(J2EE Code Generation)是一款基于代码生成器JEE的智能开发平台。引领新的开发模式(Online Coding->代码生成器->手工MERGE智能开发),可以帮助解决Java项目90%的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省人力成本,同时又不失灵活性。

0x02 环境搭建

mysql5.7

idea、java7、tomcat7

jeecg3.8:https://github.com/chen-tj/jeecg3.8

  1. 下载源码,导入maven项目,刷新maven下载依赖

  2. 导入数据库,配置数据库文件(需要手动创建jeecg数据库)

  1. 配置tomcat启动

0x03 路由简介

JEECG快速开发平台基于spring MVC 框架

@Controller将一个类声明为控制器类,再通过@RequestMapping配置路由映射。

简单举例说明:

项目中src/main/java/com/jeecg/demo/controller/MultiUploadController.java文件

@RequestMapping("/multiUploadController")
@RequestMapping(params = "list")

对应的url地址为:http://localhost:8080/multiUploadController.do?list

访问http://localhost:8080/multiUploadController.do?list

RequestMapping的params参数: 指定request中必须包含某些参数值时,才让该方法处理。

因此访问:

http://localhost:8080/multiUploadController.do?list和

http://localhost:8080/multiUploadController.do?list=112313312都是一样的

0x04 漏洞复现

登陆后台后

访问:http://192.168.120.140:8080/jeecgFormDemoController.do?commonUpload

上传文件,抓包改名

返回包图片地址

成功访问

0x05 漏洞分析

通过url地址http://192.168.120.140:8080/jeecgFormDemoController.do?commonUpload寻找控制器

定位src/main/webapp/webpage/common/upload/uploadView.jsp

ModelAndView返回到视图文件system/commonupload/commonUploadFile

双击shift查找

分析代码,弹出了个div窗口,通过onclick事件调用了commonUpload函数

查看systemController控制器

传递到了common/upload/uploadView文件,层层寻找终于找到cgUploadController为最终的上传控制器

上传文件没有判断文件名后缀,导致直接getshell

/src/main/java/org/jeecgframework/web/cgform/controller/upload/CgUploadController.java

	/**
* 自动上传保存附件资源的方式
* @return
*/
@RequestMapping(params = "ajaxSaveFile")
@ResponseBody
public AjaxJson ajaxSaveFile(MultipartHttpServletRequest request) {
AjaxJson ajaxJson = new AjaxJson();
Map<String, Object> attributes = new HashMap<String, Object>();
try {
Map<String, MultipartFile> fileMap = request.getFileMap();
String uploadbasepath = ResourceUtil.getConfigByName("uploadpath");
// 文件数据库保存路径
String path = uploadbasepath + "/";// 文件保存在硬盘的相对路径
String realPath = request.getSession().getServletContext().getRealPath("/") + "/" + path;// 文件的硬盘真实路径
realPath += DateUtils.getDataString(DateUtils.yyyyMMdd) + "/";
path += DateUtils.getDataString(DateUtils.yyyyMMdd) + "/";
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();// 创建文件时间子目录
}
if(fileMap != null && !fileMap.isEmpty()){
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile mf = entity.getValue();// 获取上传文件对象
String fileName = mf.getOriginalFilename();// 获取文件名
String swfName = PinyinUtil.getPinYinHeadChar(oConvertUtils.replaceBlank(FileUtils.getFilePrefix(fileName)));// 取文件名首字母作为SWF文件名
String extend = FileUtils.getExtend(fileName);// 获取文件扩展名
String noextfilename=DateUtils.getDataString(DateUtils.yyyymmddhhmmss)+StringUtil.random(8);//自定义文件名称
String myfilename=noextfilename+"."+extend;//自定义文件名称
String savePath = realPath + myfilename;// 文件保存全路径CgUploadController
write2Disk(mf, extend, savePath);
TSAttachment attachment = new TSAttachment();
attachment.setId(UUID.randomUUID().toString().replace("-", ""));
attachment.setAttachmenttitle(fileName.substring(0,fileName.lastIndexOf(".")));
attachment.setCreatedate(new Timestamp(new Date().getTime()));
attachment.setExtend(extend);
attachment.setRealpath(path + myfilename); String globalSwfTransformFlag = ResourceUtil.getConfigByName("swf.transform.flag");
if("true".equals(globalSwfTransformFlag) && !FileUtils.isPicture(extend)){
attachment.setSwfpath( path + FileUtils.getFilePrefix(myfilename) + ".swf");
SwfToolsUtil.convert2SWF(savePath);
} systemService.save(attachment);
attributes.put("url", path + myfilename);
attributes.put("name", fileName);
attributes.put("swfpath", attachment.getSwfpath());
attributes.put("fileid", attachment.getId()); }
}
ajaxJson.setAttributes(attributes);
} catch (Exception e) {
e.printStackTrace();
ajaxJson.setSuccess(false);
ajaxJson.setMsg(e.getMessage());
}
return ajaxJson;
}
					MultipartFile mf = entity.getValue();// 获取上传文件对象
String fileName = mf.getOriginalFilename();// 获取文件名
String swfName = PinyinUtil.getPinYinHeadChar(oConvertUtils.replaceBlank(FileUtils.getFilePrefix(fileName)));// 取文件名首字母作为SWF文件名
String extend = FileUtils.getExtend(fileName);// 获取文件扩展名
String noextfilename=DateUtils.getDataString(DateUtils.yyyymmddhhmmss)+StringUtil.random(8);//自定义文件名称
String myfilename=noextfilename+"."+extend;//自定义文件名称
String savePath = realPath + myfilename;// 文件保存全路径CgUploadController
write2Disk(mf, extend, savePath);

write2Disk函数用的是FileOutputStream文件输出流

JEECG代码审计之文件上传的更多相关文章

  1. 2020/1/30 PHP代码审计之文件上传漏洞

    0x00 漏洞简介 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.这种攻击是最为直接和有效的,"文件上传"本身是没有问题,有问题的是 ...

  2. 代码审计之XiaoCms(后台任意文件上传至getshell,任意目录删除,会话固定漏洞)

    0x00 前言 这段时间就一直在搞代码审计了.针对自己的审计方法做一下总结,记录一下步骤. 审计没他,基础要牢,思路要清晰,姿势要多且正. 下面是自己审计的步骤,正在逐步调整,寻求效率最高. 0x01 ...

  3. [代码审计]eyoucms前台未授权任意文件上传

    0x00 背景 来公司差不多一年了,然而我却依旧没有转正.约莫着转正也要到九月了,去年九月来的,实习,转正用了一年.2333 废话不多说了,最近有其他的事要忙,很久没有代码审计了.难的挖不了,浅的没意 ...

  4. [代码审计]XiaoCms(后台任意文件上传至getshell,任意目录删除,会话固定漏洞)

    0x00 前言 这段时间就一直在搞代码审计了.针对自己的审计方法做一下总结,记录一下步骤. 审计没他,基础要牢,思路要清晰,姿势要多且正. 下面是自己审计的步骤,正在逐步调整,寻求效率最高. 0x01 ...

  5. 【代码审计】XYHCMS V3.5文件上传漏洞分析

      0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...

  6. 【代码审计】UKCMS_v1.1.0 文件上传漏洞分析

      0x00 环境准备 ukcms官网:https://www.ukcms.com/ 程序源码下载:http://down.ukcms.com/down.php?v=1.1.0 测试网站首页: 0x0 ...

  7. 【代码审计】JTBC(CMS)_PHP_v3.0 任意文件上传漏洞分析

      0x00 环境准备 JTBC(CMS)官网:http://www.jtbc.cn 网站源码版本:JTBC_CMS_PHP(3.0) 企业版 程序源码下载:http://download.jtbc. ...

  8. 【代码审计】QYKCMS_v4.3.2 任意文件上传漏洞分析

      0x00 环境准备 QYKCMS官网:http://www.qykcms.com/ 网站源码版本:QYKCMS_v4.3.2(企业站主题) 程序源码下载:http://bbs.qingyunke. ...

  9. 【代码审计】BootCMS v1.1.3 文件上传漏洞分析

      0x00 环境准备 BootCMS官网:http://www.kilofox.net 网站源码版本:BootCMS v1.1.3  发布日期:2016年10月17日 程序源码下载:http://w ...

随机推荐

  1. 探究Presto SQL引擎(1)-巧用Antlr

    一.背景 自2014年大数据首次写入政府工作报告,大数据已经发展7年.大数据的类型也从交易数据延伸到交互数据与传感数据.数据规模也到达了PB级别. 大数据的规模大到对数据的获取.存储.管理.分析超出了 ...

  2. TCP 才不傻!

    大家好,我是小林. 之前收到个读者的问题,对于 TCP 三次握手和四次挥手的一些疑问: 第一次握手,如果客户端发送的SYN一直都传不到被服务器,那么客户端是一直重发SYN到永久吗?客户端停止重发SYN ...

  3. 自动化可用到的Java读取Excel文件指定的行列数据

    前言 在做接口自动化的时候,通常会遇到数据取用及存放的问题,一般有三种方式可选择 1.数据库存取 2.表格存取 3.项目配置文件存取 这里仅展示下第二种方式表格取数据的 示例 import org.a ...

  4. [TensorFlow2.0]-学习率 激活函数 损失函数

    本人人工智能初学者,现在在学习TensorFlow2.0,对一些学习内容做一下笔记.笔记中,有些内容理解可能较为肤浅.有偏差等,各位在阅读时如有发现问题,请评论或者邮箱(右侧边栏有邮箱地址)提醒. 若 ...

  5. SaToken学习笔记-04

    SaToken学习笔记-04 如果有问题,请点击:传送门 角色认证 在sa-token中,角色和权限可以独立验证 // 当前账号是否含有指定角色标识, 返回true或false StpUtil.has ...

  6. 记客户端出现Connect reset问题排查。

    客户访问我们地址出现Connect reset. 网上查询说是服务端关闭,客户端还在读,就会出现Connect reset. 我们就排查为什么服务端会关闭. 网络的同事说收到了客户端的信息,但是被服务 ...

  7. iOS开发之蜂窝布局—Swift

    前言 最近项目中用到了类似蜂窝的六边形布局,在这里分享出来抛砖引玉,供大家参考学习.本文提供了2种思路实现效果,第一种方式使用UICollectionView实现,第二种方式使用UIScrollVie ...

  8. reduce使用技巧

    一.使用reduce同时执行map(循环)和filter(过滤) 例如,将数组中的项的值加倍,然后只选择那些大于50的项 const numbers = [10, 20, 30, 40]; const ...

  9. 地球坐标系(WGS-84)转火星坐标系(GCJ)

    /** * 单点坐标纠偏 */ var pi = 3.14159265358979324; var a = 6378245.0; var ee = 0.00669342162296594323; va ...

  10. 【java虚拟机】分代垃圾回收策略的基础概念

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6602166.html 一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一 ...