一、自行搭建靶场
Github项目地址:https://gitee.com/project_team/Tmall_demo
访问地址:
前台地址:ip:8088/tmall
后台地址:ip:8088/tmall/admin
二、代码审计漏洞挖掘
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()函数如下图所示
双击进入ProductController.java文件,问题代码出现在了第151行,使用JSON.parseObject()方法反序列化了propertyJson参数,我们向上追踪propertyJson参数,该参数是`添加产品信息接口中产品属性JSON字段。
如下图所示:
经判断,该漏洞位于地址为admin/product位置,触发参数为propertyJson
Fastjson漏洞验证
通过其他函数查询对比发现该漏洞位置位于:
所有产品->添加一件产品
通过抓包发现位置准确并加以验证
通过构建payload发现DNS回显判断该漏洞存在
Log4j漏洞代码审计
该组件漏洞主要发生在引入的`og4j-core,log4j-api是不存在该问题的。
log4j-core是源码,log4j-api是接口
pom.xml文件引入Log4j组件情况如下图所示,引入了log4j-core,以及版本为2.10.0。
基本确定存在问题,验证还需进一步寻找能触发的漏洞点。
全局搜索关键字logger,如下图可以看出,本项目使用logger.info级别记录日志方式居多。
发现有几处 日志记录拼接了变量参数
判断这些参数是否由前端传参
对上述代码进行分析。触发漏洞点的代码为65行的logger.info(“获取图片原始文件名:{}”, originalFileName);。向上追踪,发现通过file.getOriginalFilename();获取file的文件名后赋值给originalFileName。在向上追踪,file参数来自admin/uploadAdminHeadImage接口,通过注释我们可以知道此处为管理员头像上传功能。
Log4j漏洞验证
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时一定使用$符号!因为使用错误也不会报错,因此可能不容易发现。
*
以UserMapper.xml文件为例,进行逆向追踪。
- 进入UserMapper.xml文件发现第70行存在问题。
- 跳转到dao层代码文件,可以看到select函数中存在orderUitl参数,我们继续逆向追踪,看看参数值从何而来。
3.键盘按住ctrl键后鼠标左击select,查看谁使用该函数,如下图所示
4.进入UserServiceImpl.java,定位到37行,如下图所示
5.从上图可以看出。getList方法中需要orderUtil参数,我们继续逆向追踪,看看orderUtil又是从何而来。首先看看谁使用了getList方法
如下图所示:
6.可以看到UserController.java使用了该方法,且第170行中传入了orderUtil值,进入文件查看具体代码。
如下图所示:
7、通过对代码进行分析,161行实例化OrderUitl工具类,该类需要两个参数即,orderyBy和isDesc
点击进入查看该类的代码,该类文件位于
src\main\java\com\xq\tmall\util\OrderUtil.java中
过注释了解该类用于排序/倒序字段。如下图所示:
8、此时追踪orderBy函数从何而来
从下图可以看到,该值通过 接口admin/user/{index}/{count} 传入
通过注释可以看出来该接口用于按条件查询用户
如下图所示:
确定了漏洞点为orderby参数,该参数值来源于按条件查询用户。
SQL注入漏洞验证
orderBy=10回显正常
orderBy=11回显错误
故存在sql注入。
3、XSS漏洞
1、看看filter层是否存在XSS过滤代码。对本项目审计发现filter层并没有关于防护XSS的代码,如下图所示:
2、看使用的前端框架是什么,版本是多少,以及是否存在防XSS漏洞机制。经过一番查找,发现pom.xml和webapp文件下,都表明使用了传统的JSP。JSP大多配合Filter进行XSS防护,上述我们发现filter层并没有XSS防护机制。
经上述验证,本项目存在XSS漏洞。我们从渗透测试实战角度进一步验证。
3、XSS漏洞验证
4、任意文件上传漏洞
在做前面的审计时发现存在上次图片位置。或者通过搜索以下关键字来判断是否存在任意文件上传漏洞
File
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest
但对于SpingBoot项目来说,想要SpringBoot内嵌的Tomcat对JSP解析,一定要引入相关依赖。如下图所示:
已知引入了对JSP解析的依赖,审计管理员头像上传功能的关键代码,看看能否上传JSP木马。代码如下图
1、通过对管理员头像上传功能,进行代码审计
代码审计分析:
- 、第62行,通过@RequestMapping注解,我们得到如下几个信息:
1.上传接口为admin/uploadAdminHeadImage
2.上传方法为POST
3.produces = “application/json;charset=UTF-8,定义了返回格式为JSON
关键信息为接口地址
②、第63行,uploadAdminHeadImage方法接受绑定的file参数和session参数,我们主要关注file参数。
、第64行,获取到文件名称后赋值给originalFileName。
、第67行,是获取文件后缀名,先看括号内originalFileName.lastIndexOf(‘.’),获取originalFileName字符串最后一次出现 . 的地方。然后通过substring截取子串的方式得到文件后缀名,赋值给变量extension。也就是说,尽管出现.jsp.jsp.jsp这种形式后缀名,最后得到的结果也只有.jsp。
⑤、第69行,随机命名文件,采用UUID+extension方式,并赋值给fileName参数。
⑥、第71行,获取上传路径,赋值给filePath。
⑦、第76到80行,上传文件关键代码,创建文件流将文件上传到filePath路径中,上传成功后,会返回该文件的文件名。
至此,上传流程代码审计结束。整个流程串下来,我们发现并没有相关过滤恶意后缀名的代码。本项目中filter层也没有相关过滤代码。