JEECG代碼審計之文件上傳


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下載依賴

    1617254610527

  2. 導入數據庫,配置數據庫文件(需要手動創建jeecg數據庫)

1617254655062

  1. 配置tomcat啟動

    1617254720707

1617254752442

1617254847745

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

1617256733462

訪問http://localhost:8080/multiUploadController.do?list

1617256856986

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

1617262473738

上傳文件,抓包改名

返回包圖片地址

1617265563283

成功訪問

1617264881783

0x05 漏洞分析

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

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

1617266413760

ModelAndView返回到視圖文件system/commonupload/commonUploadFile

雙擊shift查找

1617266565416

分析代碼,彈出了個div窗口,通過onclick事件調用了commonUpload函數

1617266600611

1617267165760

查看systemController控制器

1617267215852

傳遞到了common/upload/uploadView文件,層層尋找終於找到cgUploadController為最終的上傳控制器

1617267547752

1617267523669

上傳文件沒有判斷文件名后綴,導致直接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文件輸出流

image-20210401174422706

image-20210401174808446


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM