严苛Web对抗环境下的Webshell

引言

随着攻防对抗的强度越来越高,各大厂商流量分析、EDR等专业安全设备已广泛使用,对于Webshell的检测能力愈发成熟,对于攻击方来说,传统落地文件型的Webshell生存空间越来越小。如何在实战演练过程中完成高隐匿和持续性的Web权限维持,成为了Web对抗技术的研究重点,Webshell逐渐涌现出来一些新的利用方式。

Webshell 变迁

传统 Webshell
都是基于文件类型,攻击者可以通过文件上传、任意文件写入等漏洞将Webshell植入到目标机器的Web目录下,从而达到权限维持的目的,由于需要在目标机器上执行写入操作,防守方可以通过静态检测的方式对文件中所使用的关键词、敏感函数、文件创建/修改时间、文件权限、文件所有者等多个维度的特征进行检测,传统Webshell生存空间被逐渐压缩,内存型Webshell应运而生。内存型
Webshell(MemWebshell)利用代码执行等方式,直接将恶意的代码注入到Web应用进程当中,具备无文件落地的特性更加符合OPSEC的原则,给检测带来巨大难度,适用于严苛的Web对抗场景。

MemWebshell 分类

MemWebshell 从注入方式和运行原理的角度上划分为两个大类:

1. 基于Servlet规范利用:利用反序列化等具备任意代码执行能力的漏洞,动态注册符合Servlet规范的自定义恶意组件到Web容器的 Context
中,包括 Servlet、Filter、Listener 等,攻击者通过请求特定的路由实现与MemWebshell的通信;

2. 基于 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
来了解动态注册的方式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gEELFO2-1693066630979)(https://image.3001.net/images/20211207/1638859089_61af015118a87c91a616a.png!small?1638859090214)]

通过调试分析可以发现在上层的 WsServerContainer 方法中,Tomcat 对 WsFilter 过滤器的注册,即 filters
属性中的默认过滤器。

WsServerContainer(ServletContext servletContext) {  
...  
  
// 动态注册 WsFilter 类  
FilterRegistration.Dynamic fr = servletContext.addFilter(  
"Tomcat WebSocket (JSR356) Filter", new WsFilter());  
fr.setAsyncSupported(true);  
  
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST,  
DispatcherType.FORWARD);  
  
// 绑定过滤器与URL映射关系  
fr.addMappingForUrlPatterns(types, true, "/*");  
}

参照上述默认过滤器 WsFilter 类的注册,可以实现自定义过滤器的动态注册代码。通过请求任意路由的 cmd 参数即可执行任意命令。

1638859956_61af04b438c7df8ccf34b.png!small?1638859957309

调试 Tomcat 源码可以获知,每次请求的 ApplicationFilterChain#filters属性都是动态生成的,请求结束后,会调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值