引言
随着攻防对抗的强度越来越高,各大厂商流量分析、EDR等专业安全设备已广泛使用,对于Webshell的检测能力愈发成熟,对于攻击方来说,传统落地文件型的Webshell生存空间越来越小。如何在实战演练过程中完成高隐匿和持续性的Web权限维持,成为了Web对抗技术的研究重点,Webshell逐渐涌现出来一些新的利用方式。
Webshell 变迁
传统 Webshell 都是基于文件类型,攻击者可以通过文件上传、任意文件写入等漏洞将Webshell植入到目标机器的Web目录下,从而达到权限维持的目的,由于需要在目标机器上执行写入 *** 作,防守方可以通过静态检测的方式对文件中所使用的关键词、敏感函数、文件创建/修改时间、文件权限、文件所有者等多个维度的特征进行检测,传统Webshell生存空间被逐渐压缩,内存型Webshell应运而生。内存型 Webshell(MemWebshell)利用代码执行等方式,直接将恶意的代码注入到Web应用进程当中,具备无文件落地的特性更加符合OPSEC的原则,给检测带来巨大难度,适用于严苛的Web对抗场景。
MemWebshell 分类
MemWebshell 从注入方式和运行原理的角度上划分为两个大类:
-
基于Servlet规范利用:利用反序列化等具备任意代码执行能力的漏洞,动态注册符合Servlet规范的自定义恶意组件到Web容器的 Context 中,包括 Servlet、Filter、Listener 等,攻击者通过请求特定的路由实现与MemWebshell的通信;
-
基于 Java Instrumentation 利用:利用 Java Instrumentation 技术(JDK 5.0引入),动态修改 JVM 中Class 的字节码,包括类的属性、方法等内容,攻击者利用该技术 Hook 已有容器或 Servlet 代码逻辑,使用动态字节码 *** 作类库实现自定义恶意代码逻辑的插入或修改;
动态注册 MemWebshell
在日常项目开发当中有两种标准的注册方式,使用「XML配置文件」或「注解配置」,其本质是描述目标实例对象所需的配置信息,例如:路由信息、类信息等,最终底层都由 Web 容器来获取 XML 或者注解中的配置,完成 Servlet 实例对象的初始化,并注册到容器相应的 Context 中。其中,主要利用了 Servlet API 提供的动态注册机制,该机制是在 Servlet 3.0 中发布,为 Servlet、Filter、Listener 在 javax.servlet.ServletContext 接口中都提供了相应的注册方法,攻击者可利用该特性完成 MemWebshell 的动态注册。
注册 Filter MemWebshell
Filter 为过滤器,通过实现 javax.servlet.Filter 接口实现对目标请求的拦截,请求进入服务器后,先由 Filter 对请求进行预处理,通过配置 URL Pattern 实现对指定请求的拦截和过滤。
如何动态注册 Filter 到容器中?以 Tomcat 为例,断点调试自定义的 Servlet,可以看到 Filter 的调用核心是 ApplicationFilterChain 类,其中 filters 属性中存放着所有已经注册完成的 filter 实例,在 ApplicationFilterChain#internalDoFilter 方法中会循环获取 filters 属性中的过滤器实例,并调用过滤器的 doFilter 方法,实现对请求过滤逻辑的调用。如下图所示,filters 中已经存在一个容器自带的过滤器 WsFilter,跟踪该 Filter 来了解动态注册的方式。
通过调试分析可以发现在上层的 WsServerContainer 方法中,Tomcat 对 WsFilter 过滤器的注册,即 filters 属性中的默认过滤器。
WsServerContainer(ServletContext servletContext) {
…
// 动态注册 WsFilter 类
FilterRegistration.Dynamic fr = servletContext.addFilter(
“Tomcat WebSocket (JSR356) Filter”, new WsFilter());
fr.setAsyncSupported(true);
EnumSet types = EnumSet.of(DispatcherType.REQUEST,
DispatcherType.FORWARD);
// 绑定过滤器与URL映射关系
fr.addMappingForUrlPatterns(types, true, “
if (this.pos < this.n) { … }
…
}
已经具备了 Request 和 Response 实例,注入的 MemWebshell 实际就是类似于 Servlet 的代码逻辑,通过“密码”从请求中获取入参,经过Webshell处理后,使用 Response 输出流进行结果的返回。整个处理逻辑可以实现高度定制化的需求,例如:目前主流的冰蝎会在服务端实现自定义的 ClassLoader 类,利用 defineClass 方法还原客户端发送的字节码为 Class 类,在自定义的类中实现 Webshell 的功能代码,结合 MemWebshell 具备灵活度高、隐蔽性强的特点。
MemWebshell 总结
基于 Servlet MemWebshell 可以添加自定义的代码逻辑到内存中,充分的利用了 Servelet 3.0 ServletContext 的动态注册特性,类似的方式可以在 Weblogic、JBoss 等符合特性的其他容器中进行注册,除了基于Web容器,SpringBoot Controller 和 Intercepor 也能动态注册。动态注册MemWebshell整个过程中,具备无文件落地的特性,符合OPSEC的原则,给检测带来了巨大的难度。
Instrumentation MemWebshell 在运行过程中,不会在服务器上留下文件痕迹,有效的避开了主机安全设备的静态查杀过程,并且不启动额外端口、进程等特点,作为权限维持的手段受到攻击者的青睐。不过该种技术也存在一定的局限性,首先需要有目标服务器足够的控制权限,能够上传 Agent Jar 包并且运行 Java 命令实现功能代码的注入,而且由于需要修改 JVM 中加载的 Class 字节码,在原有的程序逻辑上具有一定的侵入性,一旦出现修改错误可能会导致目标服务 Crash 风险。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)