内容纲要

前言

今早刷帖子看到有位师傅整理了关于 SSII( Server-Side-Includes Injection , 服务器端包含注入 ) 的笔记 , 恰好我之前没有接触过该漏洞 , 所以也学习一下~


SSII ( Server-Side-Includes Injection )


SSI 是什么? 有什么用?

SSI ( Server-Side-Includes , 服务器端包含 ) , 是一种基于服务器端的网页制作技术 .

SSI 是嵌入到 HTML 页面中的指令 , 在页面被提供时由服务器进行运算 , 产生相应的 HTML 代码 , 对现有的 HTML 页面增加动态生成的内容 .

一般来说 , 要完成比较复杂的任务( 比如构建在线聊天室 ) , 就必须设计专门的 CGI 或 ASP 程序 . 但如果只是想给网页添加一些简单的功能( 比如显示一篇文件 , 显示 Web 文档相关信息 , 显示用户 IP 地址等 ) , 只需要使用 SSI 就可以了

SSI 是由 Web 服务器解析执行的 , 仅需要 Web服务器开启相关支持即可 , 对客户端没有限制 , 不会因为浏览器的不同而产生不同的观看效果 .


SSI 相关语法

.shtml ( Server-Parsed HTML ) 页面就是应用 SSI 技术的 HTML 文档 , 除此之外还有 .stm 页面 , .shtm 页面 . 该类页面在返回到客户端前 , 其中的 SSI 指令会被服务器解析 , 在最终返回给客户端的页面中是不包含 SSI 指令的 , 即使某些 SSI 指令没有被解析 , 浏览器也会将其作为普通的 HTML 注释处理 .

SSI 的语法格式必须是以 <!-- 开头 , 然后紧跟 # 号和 SSI 指令 . 其中不能存在任何空格 .

  • 显示服务器端环境变量 <!--#echo>

    1. 显示当前文档名称

      <!--#echo var="DOCUMENT_NAME"-->

    2. 显示当前时间

      <!--#echo var="DATE_LOCAL"-->

    3. 显示对端IP地址

      <!--#echo var="REMOTE_ADDR"-->

  • 将文本内容直接插入到文档中 <!--#include>

    1. file 包含的文件可以在同一级目录下或其子目录中

      <!--#include file="demo.html"-->

    2. virtual 包含的文件可以是 Web 站点上的虚拟目录的完整路径

      <!--#include virtual="/virtual.html"

      注意这里的 " / " 是指 Web 根目录 .

  • 显示 Web 文档的相关信息 <!--#flastmod--> , <!--#fsize-->

    1. 显示文档最近的更新日期

      <!--#flastmod file="demo.html"-->

    2. 显示当前文件的大小

      <!--#fsize file="demo.html"-->

  • 直接执行服务器上的可执行程序或者 CGI 应用 , 并显示执行输出内容 <!--#exec>

    1. 执行服务器上的脚本文件

      <!--#exec cmd="test.sh"-->

      另外这里我有个疑问哈~ 很多帖子给出了 <!--#exec cmd='cat /etc/passwd'--> 这个例子 , 但是 cmd 参数是使用 /bin/sh 执行指定字符串 , 而 cat 命令是编译后的二进制文件 , /bin/sh 怎么能执行二进制文件呢 ? 不明白哈==

    2. 执行服务器上的 CGI 脚本

      <!--#exec cgi="/cgi-bin/somefile.cgi"-->

  • 修改 SSI 默认设置 <!--#config errmsg-->

    参数有 errmsg , timefmt , sizefmt , 分别用于修改默认错误信息 , 设置时间与日期的显示格式 , 设置文件大小单位 . 这些就不详细说明了 .

  • 高级 SSI 可设置变量使用 if 条件语句


SSII 原理

那么到底什么是 SSII ( Server-Side Includes Injection , 服务端包含注入) 呢 ?

.stm , .shtm , shtml 等 Web 页面中 , 如果用户可以从外部输入 SSI 标签 , 且输入的内容会被服务器处理并返回到 Web 页面上 , 就可能导致攻击者注入恶意脚本来执行任意代码 .

是不是很像 XXS 这类 HTML 代码注入漏洞 ? 事实上 , 存在 XSS 的页面有很大概率存在 SSI 注入漏洞 , 如果攻击者输入的 Payload 不是 XSS 代码而是 SSI 标签 , 而服务器又恰好开启了 SSI 支持 , 那么就会存在 SSI 注入漏洞 .

综上所述 , SSI 注入漏洞的原理就是攻击者通过外部输入恶意 SSI 标签到 Web 页面 , 来动态执行代码 .

要想 SSI 注入成功 , 至少需要满足如下几个条件 .

  • Web中间件支持并且开启了 SSI

  • Web应用程序在返回 HTML 页面时 , 拼接了用户输入的内容

  • 用户在外部输入的数据没有通过有效的 SSI 标签过滤

其实 , 如今大多数 Web 应用程序已经不再使用 SSI 了 , 只有某些比较古老的站点还在使用 , 因此 , SSII 漏洞往往只能作为一种思路 , 很难利用成功 .


SSII 漏洞利用实例

这里使用 bWAPP 作为实验环境 , 来看一看 SSII 漏洞究竟如何利用的~

Low 级别

先来看一看最低级别的利用 .

这里可以填写 firstnamelastname , 然后页面会返回该用户的 IP 地址 . 随便输入信息然后提交 .

可以看到该页面是 shtml 页面 , 且在回显信息中拼接了用户的输入数据 . 我们可以先看下这里是否存在 XSS 漏洞 , 随便写个 POC 就可以弹窗成功 .

发现了一个反射型 XSS 漏洞 , 并且当前页面又是 xhtml 页面 , 且猜测服务器开启了 SSI , 这里的 IP 地址是通过 <!--#echo var="REMOTE_ADDR"--> 呈现给用户的 . 因此直接注入执行系统命令的 SSI 标签 .

Payload : <!--#exec cmd="uname -a"-->

成功执行系统命令 !


Medium 级别

还是这个界面

输入前面使用的 XSS POC , 查看回显信息 , 会发现依旧触发弹窗 , 说明这个反射型 XSS 还在 .

继续输入刚才 SSI Payload , 查看是否可以执行系统命令 .

Payload : <!--#exec cmd="uname -a" -->

发现并没有命令执行的回显 , 这里 SSI 漏洞没有成功利用 . 于是换一个 Payload 再试一次 .

Payload : <!--#exec cmd=id -->

这里系统命令执行成功了 , 因此猜测这里过滤或者编码了双引号 , 经过测试单引号也被过滤了 , 不过我们还可以使用反引号 " ` " 来执行系统命令 .

成功执行系统命令 .


High 级别

一样的页面 , 先验证之前的反射型 XSS 漏洞是否还存在

然后发现不再出现弹窗 , 而是将用户输入的信息直接输出 . 查看页面源代码发现所有的敏感字符都被编码成 HTML 实体了

而且连左右尖括号都被编码了 , SSII 漏洞利用的关键就是引入标签 , 现在都不能插入新的标签了 , 自然也就无法利用 SSII 漏洞 .

由此也看出来了 SSII 漏洞利用的局限性 , 非常依赖标签的引入 . 能防御 XSS 的输出编码完全可以防御 SSII 攻击 .


源码分析

查看 bWAPP 目录下 ssii.php 文件

这里写的很清楚 , 一共有三个可选项 , 跟进 no_check() 函数 , 该函数定义如下

该函数没有对用户的输入数据进行任何过滤 , 继续跟进 xss_check_4() 函数

addslashes() 函数会对用户输入中的所有单引号 , 双引号 , 反斜杠进行了转义 , 但是该函数并不能防御 XSS , 所以也不能防御 SSI .

继续跟进 xss_check_4() 函数

htmlspecialchars() 函数会将 XSS 攻击时常用的敏感字符转换成 HTML 实体 , 因此常常被用于防御 XSS 攻击 . 同时也可以用于防御 SSI 攻击 .


检测和防御

  1. 先搜索目标站点下是否存在 .stm , shtm , shtml 等文件 .

  2. 若存在则进一步判断目标站点是否支持并开启了 SSI

  3. 若开启了则进一步分析上述后缀的文件中是否存在用户输入内容未经过有效过滤就反射输出到页面中( 即检测是否存在反射型 XSS )

若判断结果满足以上三点 , 则目标站点很有可能存在 SSII 漏洞 .

防御的话 , 就是尽量不要开启 SSI 功能 . 如果非要使用 , 则必须对用户输入的数据进行严格的过滤 .


总结

SSII 漏洞的原理和利用方式都非常简单 , 而且作为一个比较老的漏洞 , 可利用的机会实在不多 , 很多情况下有就是碰碰运气

本文简单的记录了 SSII 的相关知识 , 内容很少 , 以后做测试时可以作为一个参考~

另外我还是不明白 <!--#exec cmd='cat /etc/passwd'--> 这行代码 , 为什么 /bin/sh 能执行二进制程序呢 ? 我的 Nginx 环境会始终有 [an error occurred while processing the directive] 这个报错 . 如果您知道原因 , 欢迎留言~

最后修改日期:2020年3月9日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。