一、自行搭建靶场

Github项目地址:https://gitee.com/project_team/Tmall_demo
访问地址:
前台地址:ip:8088/tmall
后台地址:ip:8088/tmall/admin
模拟天猫商城代码审计 - 图1
模拟天猫商城代码审计 - 图2

二、代码审计漏洞挖掘

1、第三方组件审计

本项目是基于Maven构建的。对于Maven项目,我们首先从pom.xml文件开始审计引入的第三方组件是否存在漏洞版本,然后进一步验证该组件是否存在漏洞点。
本项目引入的组件以及组件版本整理如下。

组件名称 组件版本
SpringBoot 2.1.6.RELEASE
Fastjson 1.2.58
Mysql 5.1.47
Druid 1.1.19
Taglibs 1.2.5
Mybatis 3.5.1
Log4j 2.10.0

经判断该组件存在:Fastjson反序列化漏洞,Log4j漏洞,Mybatis版本漏洞。

Fastjson漏洞代码审计

序列化操作和反序列化所用到的函数

函数 功能
JSON.toJSONString(Object) 将对象序列化成json格式
JSON.toJSONString(Object,SerializerFeature.WriteClassName) 将对象序列化成json格式,并且记录了对象所属的类的信息
JSON.parse(Json) json格式返回为对象(但是反序列化类对象没有@Type时会报错)
JSON.parseObject(Json) 返回对象是com.alibaba.fastjson.JSONObject
JSON.parseObject(Json, Object.class) 返回对象会根据json中的@Type来决定
JSON.parseObject(Json, User.class, Feature.SupportNonPublicField); 会把Json数据对应的类中的私有成员也给还原

进一步确定漏洞点,主要关注函数有JSON.parse()和JSON.parseObject()两个函数。
通过全局搜索JSON.parseObject()函数如下图所示
模拟天猫商城代码审计 - 图3
双击进入ProductController.java文件,问题代码出现在了第151行,使用JSON.parseObject()方法反序列化了propertyJson参数,我们向上追踪propertyJson参数,该参数是`添加产品信息接口中产品属性JSON字段。
如下图所示:
模拟天猫商城代码审计 - 图4
经判断,该漏洞位于地址为admin/product位置,触发参数为propertyJson
模拟天猫商城代码审计 - 图5

Fastjson漏洞验证

通过其他函数查询对比发现该漏洞位置位于:
所有产品->添加一件产品
通过抓包发现位置准确并加以验证
模拟天猫商城代码审计 - 图6
通过构建payload发现DNS回显判断该漏洞存在
模拟天猫商城代码审计 - 图7

Log4j漏洞代码审计

该组件漏洞主要发生在引入的`og4j-core,log4j-api是不存在该问题的。
log4j-core是源码,log4j-api是接口
pom.xml文件引入Log4j组件情况如下图所示,引入了log4j-core,以及版本为2.10.0。
模拟天猫商城代码审计 - 图8
基本确定存在问题,验证还需进一步寻找能触发的漏洞点。

全局搜索关键字logger,如下图可以看出,本项目使用logger.info级别记录日志方式居多。
模拟天猫商城代码审计 - 图9
发现有几处 日志记录拼接了变量参数
判断这些参数是否由前端传参
模拟天猫商城代码审计 - 图10
对上述代码进行分析。触发漏洞点的代码为65行的logger.info(“获取图片原始文件名:{}”, originalFileName);。向上追踪,发现通过file.getOriginalFilename();获取file的文件名后赋值给originalFileName。在向上追踪,file参数来自admin/uploadAdminHeadImage接口,通过注释我们可以知道此处为管理员头像上传功能。
模拟天猫商城代码审计 - 图11

Log4j漏洞验证

模拟天猫商城代码审计 - 图12
判断dnslog存在回显,故该漏洞存在

Mybatis漏洞代码审计

Mybatis版本为3.5.1,该版本存在远程命令执行漏洞
Mybatis < 3.5.6存在远程代码执行漏洞,CVE编号为CVE-2020-26945。
在满足以下三个条件的时候,攻击者可以触发远程代码执行:
1、用户启用了内置的二级缓存(默认不开启,需手动配置)
2、用户未设置JEP-290过滤器
3、攻击者找到了一种修改私有Map字段条目的方法,即修改org.apache.ibatis.cache.impl.PerpetualCache.cache有效的缓存密钥
经过探索src\main\resources\mybatis下面的配置文件,本项目并未开启二级缓存。

Mybatis开启二级缓存语句

关键条件被否定,即不存在该漏洞,故忽略。

2、SQL注入漏洞

本项目使用了Mybatis,来定义SQL。我们主要查看Myabatis中xxxMapper.xml文件中是否存在使用$拼接SQL语句的情况。使用$是直接拼接SQL语句的,未进行转义。
通过全局搜索$进行查询,发现ORDER BY 使用了$拼接SQL语句。因为Myabatis中ORDER BY无法使用#{}进行防注入。

Mybatis中如果使用#符引用参数,会自动在参数值两端加引号,导致排序失效,因此Mybatis中使用Order By时一定使用$符号!因为使用错误也不会报错,因此可能不容易发现。
*

模拟天猫商城代码审计 - 图13
以UserMapper.xml文件为例,进行逆向追踪。

  1. 进入UserMapper.xml文件发现第70行存在问题。
  2. 跳转到dao层代码文件,可以看到select函数中存在orderUitl参数,我们继续逆向追踪,看看参数值从何而来。

模拟天猫商城代码审计 - 图14
3.键盘按住ctrl键后鼠标左击select,查看谁使用该函数,如下图所示
模拟天猫商城代码审计 - 图15
4.进入UserServiceImpl.java,定位到37行,如下图所示
模拟天猫商城代码审计 - 图16
5.从上图可以看出。getList方法中需要orderUtil参数,我们继续逆向追踪,看看orderUtil又是从何而来。首先看看谁使用了getList方法
如下图所示:
模拟天猫商城代码审计 - 图17
6.可以看到UserController.java使用了该方法,且第170行中传入了orderUtil值,进入文件查看具体代码。
如下图所示:
模拟天猫商城代码审计 - 图18

7、通过对代码进行分析,161行实例化OrderUitl工具类,该类需要两个参数即,orderyBy和isDesc
模拟天猫商城代码审计 - 图19
点击进入查看该类的代码,该类文件位于
src\main\java\com\xq\tmall\util\OrderUtil.java中
过注释了解该类用于排序/倒序字段。如下图所示:
模拟天猫商城代码审计 - 图20
8、此时追踪orderBy函数从何而来
从下图可以看到,该值通过 接口admin/user/{index}/{count} 传入
通过注释可以看出来该接口用于按条件查询用户
如下图所示:
模拟天猫商城代码审计 - 图21
确定了漏洞点为orderby参数,该参数值来源于按条件查询用户。

SQL注入漏洞验证

orderBy=10回显正常
模拟天猫商城代码审计 - 图22
orderBy=11回显错误
模拟天猫商城代码审计 - 图23
故存在sql注入。

3、XSS漏洞

1、看看filter层是否存在XSS过滤代码。对本项目审计发现filter层并没有关于防护XSS的代码,如下图所示:
模拟天猫商城代码审计 - 图24
2、看使用的前端框架是什么,版本是多少,以及是否存在防XSS漏洞机制。经过一番查找,发现pom.xml和webapp文件下,都表明使用了传统的JSP。JSP大多配合Filter进行XSS防护,上述我们发现filter层并没有XSS防护机制。
模拟天猫商城代码审计 - 图25
经上述验证,本项目存在XSS漏洞。我们从渗透测试实战角度进一步验证。

3、XSS漏洞验证

模拟天猫商城代码审计 - 图26

4、任意文件上传漏洞

在做前面的审计时发现存在上次图片位置。或者通过搜索以下关键字来判断是否存在任意文件上传漏洞
File
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest
但对于SpingBoot项目来说,想要SpringBoot内嵌的Tomcat对JSP解析,一定要引入相关依赖。如下图所示:
模拟天猫商城代码审计 - 图27
已知引入了对JSP解析的依赖,审计管理员头像上传功能的关键代码,看看能否上传JSP木马。代码如下图
模拟天猫商城代码审计 - 图28
1、通过对管理员头像上传功能,进行代码审计
代码审计分析:

  1. 、第62行,通过@RequestMapping注解,我们得到如下几个信息:

1.上传接口为admin/uploadAdminHeadImage
2.上传方法为POST
3.produces = “application/json;charset=UTF-8,定义了返回格式为JSON
关键信息为接口地址
②、第63行,uploadAdminHeadImage方法接受绑定的file参数和session参数,我们主要关注file参数。

  1. 、第64行,获取到文件名称后赋值给originalFileName。

  2. 、第67行,是获取文件后缀名,先看括号内originalFileName.lastIndexOf(‘.’),获取originalFileName字符串最后一次出现 . 的地方。然后通过substring截取子串的方式得到文件后缀名,赋值给变量extension。也就是说,尽管出现.jsp.jsp.jsp这种形式后缀名,最后得到的结果也只有.jsp。

⑤、第69行,随机命名文件,采用UUID+extension方式,并赋值给fileName参数。

⑥、第71行,获取上传路径,赋值给filePath。

⑦、第76到80行,上传文件关键代码,创建文件流将文件上传到filePath路径中,上传成功后,会返回该文件的文件名。

至此,上传流程代码审计结束。整个流程串下来,我们发现并没有相关过滤恶意后缀名的代码。本项目中filter层也没有相关过滤代码。

经过分析确定该位置存在任意文件上传漏洞。

任意文件上传漏洞验证

http://192.168.8.147:8088/tmall/res/images/item/adminProfilePicture/9d80e779-1bef-4a0d-aa5e-75cb615860cd.jsp
模拟天猫商城代码审计 - 图29