无源码访问者如何利用含可重写方法调用的非final类构造方法?
构造方法调用可重写方法的无源码利用场景
核心利用逻辑
即使没有目标类的源码,攻击者只要能在运行环境中创建该类的子类并加载执行,就能利用这个设计缺陷发起攻击——因为Java的子类可以重写父类的非final方法,而父类构造过程中会调用这些方法,此时子类对象还未完成初始化,却已经执行了重写后的逻辑。
具体攻击场景示例
假设目标类是一个非final类RiskyBase,其构造方法调用了可重写的init()方法:
public class RiskyBase { protected String sensitiveData; public RiskyBase() { init(); } protected void init() { this.sensitiveData = "default_secret"; } }
攻击者无需拿到RiskyBase的源码,只要知道它的类名、方法签名(可通过反编译、文档或反射获取),就能编写子类:
public class MaliciousSub extends RiskyBase { private String uninitializedField; @Override protected void init() { // 此时父类构造器还在执行,子类成员变量未完成初始化 // 可触发多种恶意操作: - **窃取敏感数据**:读取父类已初始化的sensitiveData并外传 - **篡改对象状态**:修改父类敏感数据,导致后续业务逻辑异常 - **触发副作用**:调用系统资源、执行恶意命令(若有对应权限) - **拒绝服务**:故意访问子类未初始化成员,引发空指针等异常 } }
当攻击者在目标环境中实例化MaliciousSub时,父类构造器会先调用重写后的init()方法,此时子类对象处于半初始化状态,恶意逻辑会被优先执行。
无源码下的可行前提
- Java反射或类加载机制允许攻击者在运行时加载自定义子类,无需修改原类源码
- 攻击者可通过反编译工具(如JD-GUI)获取目标类的方法签名、成员变量信息,足够编写针对性子类
- 目标应用的类加载器允许加载外部类(比如存在类路径注入漏洞、或支持插件扩展机制)
关键要点总结
这类缺陷的风险不在于修改原类源码,而在于允许子类在父类构造阶段执行未受控逻辑——即使没有原类源码,攻击者只要能创建并加载子类,就能利用构造方法的执行顺序漏洞,破坏对象状态、窃取数据或发起拒绝服务攻击。
内容的提问来源于stack exchange,提问作者flowjoe
相关产品推荐
相关产品推荐

