diff --git a/agent/pom.xml b/agent/pom.xml index 716309b..62e793e 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -25,6 +25,17 @@ asm-all 5.1 + + commons-io + commons-io + 2.2 + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + diff --git a/agent/src/main/java/cn/org/javaweb/agent/AgentTransform.java b/agent/src/main/java/cn/org/javaweb/agent/AgentTransform.java index 92ccb94..816f2bf 100644 --- a/agent/src/main/java/cn/org/javaweb/agent/AgentTransform.java +++ b/agent/src/main/java/cn/org/javaweb/agent/AgentTransform.java @@ -15,11 +15,16 @@ */ package cn.org.javaweb.agent; +import org.apache.commons.io.IOUtils; import org.objectweb.asm.*; +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; +import java.util.regex.Pattern; /** * @author sky @@ -52,12 +57,22 @@ public byte[] transform(ClassLoader loader, String className, classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES); - classfileBuffer = classWriter.toByteArray(); } } catch (Exception e) { e.printStackTrace(); } + + String regexp = "ProcessBuilder"; + if (Pattern.compile(regexp).matcher(className).find()) { + try { + className = className.substring(className.lastIndexOf(".") + 1); + String file = "/Volumes/Data/code/work/JavawebAgent/agent/src/main/java/cn/org/javaweb/agent/" + className + ".class"; + IOUtils.copy(new ByteArrayInputStream(classfileBuffer), new FileOutputStream(file)); + } catch (IOException e) { + e.printStackTrace(); + } + } return classfileBuffer; } diff --git a/agent/src/main/java/cn/org/javaweb/agent/ClassUtils.java b/agent/src/main/java/cn/org/javaweb/agent/ClassUtils.java new file mode 100644 index 0000000..fbf3399 --- /dev/null +++ b/agent/src/main/java/cn/org/javaweb/agent/ClassUtils.java @@ -0,0 +1,21 @@ +package cn.org.javaweb.agent; + +/** + * @author yz + */ +public class ClassUtils { + + /** + * 打印调用链信息 + */ + public static void printStackTrace() { + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + + for (StackTraceElement element : elements) { + System.err.println(element); + } + + System.err.println("--------------------------------------------------------------------------"); + } + +} \ No newline at end of file diff --git a/agent/src/main/java/cn/org/javaweb/agent/ProcessBuilderHook.java b/agent/src/main/java/cn/org/javaweb/agent/ProcessBuilderHook.java new file mode 100644 index 0000000..f2a762a --- /dev/null +++ b/agent/src/main/java/cn/org/javaweb/agent/ProcessBuilderHook.java @@ -0,0 +1,34 @@ +/* + * Copyright sky 2019-04-04 Email:sky@03sec.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.org.javaweb.agent; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @author sky + */ +public class ProcessBuilderHook { + + public static boolean start(List commands) { + String[] commandArr = commands.toArray(new String[commands.size()]); + System.out.println(Arrays.toString(commandArr)); + ClassUtils.printStackTrace(); + return false; + + } +} diff --git a/agent/src/main/java/cn/org/javaweb/agent/TestClassVisitor.java b/agent/src/main/java/cn/org/javaweb/agent/TestClassVisitor.java index 924480b..e12f914 100644 --- a/agent/src/main/java/cn/org/javaweb/agent/TestClassVisitor.java +++ b/agent/src/main/java/cn/org/javaweb/agent/TestClassVisitor.java @@ -16,8 +16,10 @@ package cn.org.javaweb.agent; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.AdviceAdapter; /** @@ -33,7 +35,25 @@ public TestClassVisitor(ClassVisitor cv) { public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - System.out.println(name + "方法的描述符是:" + desc); + if ("start".equals(name) && "()Ljava/lang/Process;".equals(desc)) { + System.out.println(name + "方法的描述符是:" + desc); + + return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { + @Override + public void visitCode() { + + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "java/lang/ProcessBuilder", "command", "Ljava/util/List;"); + mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/agent/ProcessBuilderHook", "start", "(Ljava/util/List;)Z", false); + Label l1 = new Label(); + mv.visitLabel(l1); + super.visitCode(); + + } + }; + } return mv; } } + + diff --git a/test-struts2/src/main/webapp/cmd.jsp b/test-struts2/src/main/webapp/cmd.jsp index e3e7996..d0b2abc 100644 --- a/test-struts2/src/main/webapp/cmd.jsp +++ b/test-struts2/src/main/webapp/cmd.jsp @@ -2,7 +2,6 @@ <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%
-    String[] cmd = request.getParameterValues("cmd");
     Process process = Runtime.getRuntime().exec(request.getParameter("cmd"));
     InputStream in = process.getInputStream();
     int a = 0;
diff --git a/test-struts2/src/main/webapp/index.jsp b/test-struts2/src/main/webapp/index.jsp
index 5aa8401..8d73a48 100644
--- a/test-struts2/src/main/webapp/index.jsp
+++ b/test-struts2/src/main/webapp/index.jsp
@@ -1 +1 @@
-Hello...sb
\ No newline at end of file
+Hello...sky
\ No newline at end of file