AWD线下赛修复jar/war包一直手忙脚乱,此篇文章记录几种常用的Java jar包修复方法
反编译成Maven项目
对比于手动编译打包,反编译成Maven项目更加方便快捷(Maven其实也就是干这个事)
手动仅使用原始Java进行反编译并打包可以参考:AWD离线-Jar文件冷补丁
下面记录反编译成Maven项目并进行修复的步骤
- 反编译jar包,使用IDEA反编译插件还原源代码,反编译出来还是jar包,直接解压即可
1 | /Library/Java/JavaVirtualMachines/jdk-17.0.11.jdk/Contents/Home/bin/java -cp "/Applications/IntelliJ IDEA.app/Contents/plugins/java-decompiler/lib/java-decompiler.jar" org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true <jar_path> <output_path> |
最新版IDEA的反编译插件需要java17
- 导入源代码,创建一个空的Maven项目,然后将反编译后
/BOOT-INF/classes
下的源代码复制到/src/main/java
路径下。视check情况选择是否将resources
下资源文件一起导入
- 导入依赖库,将
BOOT-INF/lib
下的依赖复制到项目的lib文件文件夹下(没有这个文件夹,需要自己新建,一般在项目的第一级目录),在文件-项目结构-项目设置-库
中将lib文件夹添加为库文件夹,此步骤是解决在离线情况下缺少依赖的问题 - 用反编译出的
pom.xml
文件覆盖创建的Maven项目中的pom.xml
文件 - 修复代码并打包,修改Java源代码,或者根据漏洞点直接修改
pom.xml
文件中依赖的版本号,然后使用Maven进行打包,当然也可以直接在在IDEA中点点点。Springboot项目在pom.xml
内置了打包插件,所以选择Maven打包而不是构建成工件的jar
或者war
包的形式,需要根据实际情况选择如何打包
1 | mvn clean package |
以上展示的是打包一个完整的jar包的步骤,成功完成后会在/target
目录输出修复好的jar
包文件,直接-jar
运行即可,当然也可以直接选择使用压缩软件对编译好的class文件进行替换,看文章说Bandizip可以保证替换前后jar包和war包的可用性,使用Maczip测试确实出现如下报错
jar uf
更新class文件
那么除了使用Bandizip还有其他方法可以更新class文件而不影响jar包和war包的可用性呢,答案是肯定的,可以使用jar uf
命令来更新class文件
需要注意在jar包内class文件的真实包名,如下图,这里需要在包名前添加BOOT-INF/classes/
前缀
同时注意根据包名创建文件夹,IDEA中直接把target
目录改名为BOOT-INF
即可
命令示例
1 | jar uf vulnspringboot-1.0-SNAPSHOT.jar BOOT-INF/classes/org/example/controller/SCtfController.class |
Javassist修改jar包字节码
可以用以下项目作为脚手架:
非常便捷,在main
函数中指定要修改的jar包路径,然后在ExamplePatch
类的patch
方法中编写Javassist修改字节码逻辑即可,同样因为jar包结构问题,需要注意BOOT-INF/classes/
路径问题
修改jar包中class内容
1 | CtClass c1 = new PatchClass("org.example.controller.SCtfController", "BOOT-INF/classes/").getCtClass(); |
修改jar包中依赖的class
1 | PatchLibrary patchLibrary = new PatchLibrary("hessian-4.0.4.jar", "BOOT-INF/lib/"); |
同时也支持直接修改class,主要针对tomcat环境
1 | // we want to change /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/com/ctf/BoardServlet.class |
JarEditor修改jar包
比较推荐的方法,IDE插件直接修改jar包内容。对于外部包,右键jar包,Add Library
,就可以直接修改了
修改完成后,点击Save(Compile)
,编译并保存当前修改的java内容,最后点击Build Jar
,将编译保存的类文件写入Jar包中
经测试,目前好像没有修改未在jar包中class的功能,对于tomcat环境,可以将classes
文件夹压缩并修改为jar后缀即可修改
总结
几种方法优先推荐JarEditor修改jar包,其他思路比如JByteMod直接修改字节码因为普适性不高并没有做演示
同时也测试了arthas用于AWD修复jar包,但由于arthas采用agent原理,有些class并没有被jvm加载导致内存编译功能错误,还是更适用于应急响应以及bug诊断场景