本仓编译依赖固定在 deps/api/VERSION。先执行 ./scripts/install-api-deps.sh;该脚本会校验 SHA256SUMS 并安装下面的 Maven 坐标。不要把 deps/api/*.jar 复制进任何插件模块。
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<chains.api.version>2.0.0-beta7</chains.api.version>
</properties>
<dependency>
<groupId>org.vulhub</groupId>
<artifactId>java-chains-plugin-api</artifactId>
<version>${chains.api.version}</version>
<scope>provided</scope>
</dependency>只有确实使用公开 allowlisted helper 时才增加 java-chains-common,同样使用 provided。本仓同时分发该二进制,方便 IDE/编译,但这不表示 common 的所有实现包都对插件开放。
不要依赖或打包 java-chains-core、java-chains-server、java-chains-nodes、java-chains-all。
文件位置:src/main/resources/META-INF/chains-plugin.json。
{
"id": "demo",
"version": "1.0.0",
"apiVersion": "2.0.0-beta7",
"libraries": []
}version 是插件版本;apiVersion 是目标宿主 API 版本。
本地第三方 jar 可使用 system scope:
<dependency>
<groupId>local.demo</groupId>
<artifactId>demo-victim</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/demo-victim.jar</systemPath>
</dependency>这只解决编译。
<resource>
<directory>${project.basedir}/libs</directory>
<includes><include>demo-victim.jar</include></includes>
<targetPath>libraries/demo-victim</targetPath>
</resource>"libraries": [{
"id": "demo-victim",
"version": "1.0",
"isolation": "private",
"entries": ["libraries/demo-victim/demo-victim.jar"]
}]@GadgetMeta(id = "DemoLibraryGadget", libraries = {"demo-victim"}, ...)四步缺一不可。
victim jar 能编译不等于它在隔离 ClassLoader 中能独立执行。它可能在触发路径上引用未重定位的日志、代理、表达式或工具库。
- 把触发路径真正需要的间接 jar 作为独立文件放入同一
libraries/<setId>/,并加入 manifestentries。 - 不要把这些类 shade 进插件主 jar,也不要依赖它们恰好存在于宿主。
jdeps --missing-deps可以帮助发现候选缺口,但大型 victim jar 常含很多本链不会走到的可选代码,不能把全部not found都打包。- 最终判据是临时宿主 Reload 后,在真实插件 ClassLoader 中执行一次安全 generate;每次
NoClassDefFoundError都回到实际触发路径确认是必需还是可选分支。
private:优先使用当前 PluginUnit 自带 jar,通常是首选。shared:表达共享依赖意图;仍需验证目标宿主的解析顺序。
不要创建万能 shared classpath,也不要假设宿主应用的 Jackson、codec、Spring 等第三方库可见。
插件使用 ChildFirst 上下文和受限父加载器。执行 Gadget 时 TCCL 指向当前插件 ClassLoader。
Class<?> type = PluginClasses.forName("com.vendor.Victim");
ClassLoader loader = PluginClasses.contextLoader();常见失败:
- jar 只在
libs/,未打进libraries/<id>/。 - manifest id 与注解 id 不一致。
- entries 指向不存在的归档路径。
- 代理接口与实现来自不同 loader。
- plugin-api 被 shade,导致同名 Class 不相等。
./scripts/install-api-deps.sh
mvn clean verify
./build.sh
jar tf target/chains-plugin-*.jar应包含:manifest、插件类、nodes YAML、可选 preset、可选 LibrarySet。
不得包含:
org/vulhub/javachains/api/
org/vulhub/javachains/core/
org/vulhub/javachains/server/
BOOT-INF/
third-libs/
com/ar3h/
插件自己的 org/vulhub/javachains/plugins/ 包必须保留。
- 读取目标宿主的公开 plugin-api 版本。
- 同步 POM 依赖和 manifest
apiVersion。 - 插件行为变化时另行提升插件
version。 - 运行 clean verify、ClassLoader 测试和真实宿主冒烟。