迷你天猫商城代码审计
一、项目简介
迷你天猫商城是一个基于Spring Boot的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认收货,评价等一系列操作。 作为迷你天猫商城的核心组成部分之一,天猫数据管理后台包含商品管理,订单管理,类别管理,用户管理和交易额统计等模块,实现了对整个商城的一站式管理和维护。
二、第三方组件漏洞审计
本项目是基于Maven构建的。对于Maven项目,我们首先从 pom.xml 文件开始审计引入的第三方组件是否存在漏洞版本,然后进一步验证该组件是否存在漏洞点。本项目引入的组件以及组件版本整理如下。
组件名称 组件版本
SpringBoot 2.1.6.RELEASE 开发框架
Mysql 5.1.47 数据库
Druid 1.1.19 数据源监控
Fastjson 1.2.58 开源JSON解析库
Taglibs 1.2.5 标签库
Mybatis 3.5.1 持久层框架
Log4j 2.10.0 日志记录库
经过搜索查询,发现Fastjsonj、Mybatis、Log4引入的版本是存在漏洞的。
1)Fastjson 反序列化漏洞
-
① 本项目引入的Fastjson版本为1.2.58,该版本存在反序列化漏洞。
-
② 已确定了Fastjson版本存在问题,进一步寻找触发Fastjson的漏洞点。反序列化过程中会使用这两个函数 JSON.parse() 和 JSON.parseObject() (parseObject() 相比parse()多执行了 JSON.toJSON(obj),在处理过程中会调用反序列化目标类的所有 setter 和 getter 方法。)全局搜索两个关键字,发现本项目存在 JSON.parseObject() ,如下图所示:
-
③ 双击进入 ProductController.java 文件,问题代码出现在了 第151行 ,使用
JSON.parseObject() 方法反序列化了 propertyJson 参数。如下图所示:
-
④ 我们向上追踪propertyJson 参数,该参数是 添加产品信息 接口中 产品属性JSON 字段。如下图所示:
-
⑤ 通过代码审计,找到了Fastjson反序列化漏洞点。我们通过渗透测试进一步验证。访问管理后台,发现漏洞输入点位于 所有产品-添加一件产品 功能下。
-
⑥ 点击添加一件产品后,使用BurpSuite抓包拦截记录请求数据包,发现请求地址为admin/product ,并且产品属性信息为 propertyJson 字段参数,如下图所示:
-
⑦ 对 propertyJson 参数值进行URL解码,发现为JSON格式字符串,如下图所示:
-
⑧ 访问在线DNSlog地址,点击获取一个子域名,如下图所示:
-
⑨ 我们构造漏洞验证POC:{"@type":"java.net.Inet4Address","val":"65qezy.dnslog.cn"},将其粘贴到 propertyJson 字段中。击发送数据包后,稍等一小会,能看到获取到回显信息,成功触发了Fastjson漏洞。如下图所示:
-
⑩ 或者去到访问NDSLog地址,点击 Refresh Record ,也可以看到获取到回显信息。
2)Mybatis 远程命令执行漏洞
- ① 本项目引入的Mybatis版本为3.5.1,该版本存在远程命令执行漏洞。
在满足以下三个条件的时候,攻击者可以触发远程代码执行:
1、用户启用了内置的二级缓存(默认不开启,需手动配置)
2、用户未设置JEP-290过滤器
3、攻击者找到了一种修改私有Map字段条目的方法,即修改
org.apache.ibatis.cache.impl.PerpetualCache.cache有效的缓存密钥
二级缓存:将查询结果放到缓存中,下次查询时结果相同的话直接从缓存中获取结果。
Mybatis开启二级缓存语句
<setting name = "cacheEnabled" value = "true" />
- ② 经过查找在 src\main\resources\mybatis 下面的配置文件,本项目并 未开启 二级缓存。不满足该漏洞的触发条件,所有该漏洞可忽略。
3)Log4j远程代码执行漏洞
-
① 本项目引入的Log4j版本为2.10.0,该版本存在远程代码执行漏洞。
-
② 该组件漏洞主要发生在引入的 log4j-core(源码),log4j-api(接口) 是不存在该问题的。
-
③ 寻找漏洞触发点。全局搜索关键字logger.info (也可用logger.error查看)。发现多处日志记录拼接了变量参数,让我们看看这些参数是否是从前端传来的。如下图所示:
-
④ 双击进入该代码文件,位于\src\main\java\com\xq\tmall\controller\fore\ForeUserController.java。
-
⑤ 对上述代码进行分析。触发漏洞点的代码为77行的 logger.info("获取图片原始文件名:{}", originalFileName); 向上追踪,发现通过file.getOriginalFilename(); 获取file的文件名后赋值给 originalFileName; 在向上追踪,file参数来自 user/uploadUserHeadImage 接口,通过注释我们可以知道此处为 用户头像上传 功能。将文件名改为攻击语句,即可触发Log4j漏洞。
三、单点漏洞审计
对组件是否存在漏洞进行验证后,我们针对功能单点代码审计,发现存在的漏洞。对于单点功能代码审计除了特定漏洞存在特定代码审计方法,一般先去看一遍Controller层代码,了解基本功能。再从功能出发进行代码。
1)SQL注入漏洞代码审计
-
① 本项目使用了Mybatis,来定义SQL。我们主要查看Myabatis中 xxxMapper.xml 文件中是否存在使用 $ 拼接SQL语句的情况。使用 $ 是直接拼接SQL语句的,未进行转义。
全局搜索关键字 $ ,确实存在几处 order by 使用了 $ 拼接SQL语句,因为 order
by 是没办法使用 #{} 的。搜索结果如下图所示:
-
② 双击进入 UserMapper.xml 文件,第70行存在问题。向上查看根据 select id
追踪该dao层的代码文件。如下图所示:
-
③ 点击绿色箭头跳转到dao层代码文件,可以看到select函数中存在 orderUitl 参数,我们继续逆向追踪,看看参数值从何而来。
-
④ 键盘按住 ctrl 键后鼠标左击 select ,查看谁使用该函数,如下图所示:
-
⑤ 可以看到有两个文件使用了该函数方法,点击 UserServiceImpl.java 文件,定位到37行。如下图所示:
-
⑥ 从上图可以看出。 getList 方法中需要 orderUtil 参数,我们继续逆向追踪,看看orderUtil又是从何而来。首先看看谁使用了 getList 方法,键盘按住 ctrl 键后鼠标左击 getList ,如下图所示:
-
⑦ 可以看到 UserController.java 使用了该方法,且第170行中传入了orderUtil 值,进入文件查看具体代码,如下图所示:
-
⑧ 针对上述文件进行分析,先看161行实例化OrderUitl工具类,该类需要两个参数
(orderyBy和isDesc )。点击进入查看该类的代码,该类文件位于
src\main\java\com\xq\tmall\util\OrderUtil.java 。通过注释了解该类用于 排序/倒序 字段。如下图所示:
-
⑨ 此时应该追踪 orderBy 参数是从何而来。从下图可以看到,该值通过
admin/user/{index}/{count} 接口传过来的。通过注释可以看出来该接口用于按
条件查询用户,如下图所示:
-
⑩ 整个流程串下来,确定了漏洞点为 orderby 参数,该参数值来源于 按条件查询用
户 。 -
⑪ 既然接口找到了,我们可以使用BurpSuite来构造请求,然后进一步攻击验证。通过注释我们了解到该接口为查询用户,我们访问后台寻找功能点,发现用户管理翻页查询会向该接口发送请求数据包,如下图所示:
-
⑫ 点击翻页时,使用BurpSuite抓取数据包,可以看到发送数据包中存在orderby字段,如下图所示:
-
⑬ 给orderBy赋值1,发送出去,可以看到排序在第一的数据信息
-
⑭ 给orderBy赋值99,发送出去时。出现异常。因为只有十几个用户。
-
⑮ 在浏览器那边也可查看到相应数据,如下图所示:
-
⑯ 至此,确定了用户管理功能翻页查询数据处存在SQL注入漏洞。
-
⑰ 该项目还存在多处相同注入点的SQL注入就不一一列出了。
2)管理员头像任意文件上传漏洞
对于代码审计任意文件上传漏洞来说,首先是看看是否存在文件上传功能,然后
进一步审计是否存在任意文件上传漏洞。或者搜索相关关键字,文件上传关键字如下:
File
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest
-
① 在做Log4j漏洞代码审计时,我们发现 管理员头像上传 存在文件上传功能,对于该功能,我们审计一下是否存在任意文件上传漏洞。相关代码如下图所示:
-
② 发现并没有相关过滤恶意后缀名的代码。本项目中filter层也没有相关过滤代码。经过分析确定该位置存在任意文件上传漏洞。
-
③ 在管理员后台的管理员帐户里直接上传.php文件的话上传不了,因为前端 accept=”image/*”做了过滤处理,只能上传图片类的文件。
-
④ 我们先上传正常的图片,然后进行抓包,如下图所示:
-
⑤ 把filename的地方改成2.jsp,点击发送,收到上传成功的信息,如图所示:
3)产品分类添加分类文件任意上传漏洞
-
① 再全局搜索file,发现还有其他功能点疑似有漏洞。如下图所示:
-
② 双击进入 产品分类 相应的代码CategoryController.java,如下图所示:
-
③ 全程看下来发现和管理员头像处的做法一样,没有过滤处理。在后台找到该功能点位置,如下图所示:
-
④ 上传正常的图片,然后进行抓包,如图所示:
-
⑤ filename处改为 ”1.php”,点击发送,可以看到发送成功的信息,如图所示:
4)所有产品添加产品处任意文件上传漏洞
-
① 全局搜索file,发现在 所有产品 添加一个产品处疑似有漏洞,如图所示:
-
② 查看代码,发现除了 465行 判断上传的图片是单张还是图集,没有发现其他过滤处理。找到后台功能点处,如图所示:
-
③ 上传图片,然后抓包,在把filename处的值改为”2.php”,点击发送,可看到上传成功的信息,如图所示:
5)用户头像任意文件上传漏洞
-
① 全局搜索file,发现在 用户头像 处疑似有漏洞,如图所示:
-
② 查看代码后,没有发现有过滤处理。找到前台功能点处,如图所示:
-
③ 上传正常的图片,进行抓包,在修改filename的值为“2.php”(tips:因为是Java项目,所以本应该上传jsp的一句话木马才比较合理,因为上面有案例了就懒得再弄了),点击发送,即可看到上传成功的信息,如图所示:
6)管理员昵称处XSS漏洞
从开发视觉来看防护XSS漏洞,大多是过滤/转义用户的输入和输出。对于开发人员来
说,不可能对每一个输入和输出点进行过滤/转义。一般常使用filter层(过滤器)或拦截器进行统一过滤。或者所使用的前端框架自带防XSS机制。
-
① 所以,我们审计XSS漏洞第一步看看filter层是否存在XSS过滤代码。对本项目审计发现filter层并没有关于防护XSS的代码,如下图所示:
-
② 第二步,我们看看使用的前端框架是什么,版本是多少,以及是否存在防XSS漏洞机制。经过一番查找,发现pom.xml和webapp文件下,都表明使用了传统的JSP。JSP大多配合Filter进行XSS防护,上述我们发现filter层并没有XSS防护机制。所以本项目存在XSS漏洞。
-
③ 我们在管理员昵称处键入XSS漏洞验证
POC: <img src=1 onerror=alert(1) />
,点击保存。如下图所示:
-
④ 每次登录管理员后台就会触发XSS弹框,如下图所示:
7)前台搜索栏XSS漏洞
- ① 在前台的搜索栏键入XSS漏洞验证
POC: <svg onload=alert(1)>
,也能触发XSS弹框,如下图所示:
8)所有产品的添加产品处XSS漏洞
-
① 在添加一个产品的产品标题键入XSS漏洞验证
POC:<svg onload=alert(2)>
,如下图所示:
-
② 在前台搜索后,点击产品也能触发弹框,如下图所示:
前台用户登录处,管理后台登录处均没有图形验证码,以及其他防暴力破解措施。可以
对账号进行爆破破解。