taibeihacker
Moderator
WEB 容器安全
1 定义及原理
Web 服務器:提供Web 服務器的軟件或主機,即Web 服務器軟件或者裝有Web 服務器軟件的計算機。Web 中間件:提供系統軟件與應用軟件之間連接的軟件,Web 中間件是提供web 應用軟件和系統軟件連接的軟件的總稱。
Web 容器:容器是中間件的一種,它給處於其中的應用程序組件提供從一個環境,使應用程序直接與容器中的環境變量進行交互而不必關注其他的系統問題。 Web 容器用於給處於其中的應用程序組件提供一個環境。

2 Apache 安全
2.1 apache 配置错误
2.1.1 原理
AddHandler application/x-httpd-php .phpAddHandler 為相應的文件擴展名指定處理程序,上述的配置意味著將擴展名為.php 的文件交給x-httpd-php 程序處理
Apache 識別文件擴展名是從後往前的,如果遇到了無法識別的擴展名會接著往前識別,遇到第一個可以識別的擴展名作為該文件的擴展名
2.1.2 配置
2.1.2.1 修改 conf 文件

2.1.2.2 创建 .htaccess

2.1.3 漏洞复现
在有多個後綴的情況下,只要一個文件含有.php 後綴的文件即將被識別成PHP 文件,沒必要是最後一個後綴。利用這個特性,將會造成一個可以繞過上傳白名單的解析漏洞。環境運行後,訪問http://your-ip/uploadfiles/apache.php.jpeg 即可發現,phpinfo 被執行了,該文件被解析為php 腳本。
http://your-ip/index.php 中是一個白名單檢查文件後綴的上傳組件,上傳完成後並未重命名。我們可以通過上傳文件名為xxx.php.jpg 或xxx.php.jpeg 的文件,利用Apache 解析漏洞進行getshell。

2.2 apache 换行解析漏洞
漏洞編號:CVE-2017-15715影響版本:Apache 2.4.10 - 2.4.29
漏洞利用:文件上傳
漏洞名稱:換行解析漏洞
2.2.1 原理
其2.4.0~2.4.29 版本中存在一個解析漏洞,在解析PHP 時,1.php\x0A 將被按照PHP 後綴進行解析,導致繞過一些服務器的安全策略。
2.2.2 漏洞复现
12
3
4
5
6
7
8
9
?php
if(isset($_FILES['file'])) {
$name=basename($_POST['name']);
$ext=pathinfo($name, PATHINFO_EXTENSION);
if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'])) {
exit('bad file');
}
move_uploaded_file($_FILES['file']['tmp_name'], './' . $name);
}
在1.php 後面插入一個\x0A(注意,不能是\x0D\x0A,只能是一個\x0A),不再攔截:

訪問剛才上傳的/1.php%0a,發現能夠成功解析,但這個文件不是php 後綴,說明目標存在解析漏洞:

3 Nginx 安全
nginx 是一個高性能的HTTP 和反向代理Web 服務器,同時也提供了IMAP/POP3/SMTP 服務。中國大陸使用Nginx 網站用戶有:百度、京東、新浪、網易、騰訊等。
Nginx 可以在大多數Unix、 Linux 編譯運行,也有Windows 移植版。
3.1 nginx 配置错误
3.1.1 CRLF 注入
CRLF:就是CR 和LF,分別表示回車和換行,CR 命令讓打印頭回到左邊。 LF 命令讓紙前進一行。在HTTP 報文中,行與行之間使用CRLF 間隔。
攻擊者一旦向請求行或首部中的字段注入惡意的CRLF,就能注入一些首部字段或報文主體,並在響應中輸出,所以又稱為HTTP 響應分漏洞。
在Nginx 中配置文件中,有三個可以接受URL 的變量:
$URI
$DOCUMENT_URI
$REQUEST_URI
其中:
$URI - 獲取解碼後的請求路徑
$DOCUMENT_URI - 獲取解碼後的請求路徑
$REQUEST_URI - 沒有解碼的完整的URL
3.1.1.1 原理
Nginx會將$uri 進行解碼,導致傳入%0a%0d 即可引入換行符,造成CRLF 注入漏洞。錯誤的配置文件示例(原本的目的是為了讓http 的請求跳轉到https 上):
1
2
3
location/{
return 302 https://$host$uri;
}
3.1.1.2 漏洞复现
Payload: http://your-ip:8080/ Set-Cookie: a=1,可注入Set-Cookie 頭。

3.1.2 目录穿越漏洞
Nginx 在配置別名(Alias)的時候,如果忘記加/,將造成一個目錄穿越漏洞。錯誤的配置文件示例(原本的目的是為了讓用戶訪問到/home/目錄下的文件):
1
2
3
location /files {
alias /home/;
}
Payload:http://your-ip:8081/files./,成功穿越到根目錄:

3.2 Nginx 越界读取缓存漏洞
漏洞編號:CVE-2017-7529影響版本:Nginx 0.5.6 - 1.13.2
漏洞危害:敏感信息洩露
3.2.1 原理
3.2.1.1 HTTP Range
HTTP 的Range,允許客戶端分批次請求資源的部分,如果服務端資源較大,可以通過Range 來並發下載;如果訪問資源時網絡中斷,可以斷點續傳Range 設置在HTTP 請求頭中,它是多個byte-range-spec(或suffix-range-byte-spec)的集合
示例
Range:bytes=0-1024 表示訪問第0 到第1024 字節
Range:bytes=500-600,601-999,-300 表示分三塊訪問,分別是500 到600 字節,601 到600 字節,最後的300 字節;

3.2.1.2 HTTP-Cache
Nginx 可以作為緩存服務器,將Web 應用服務器返回的內容緩存起來。如果客戶端請求的內容已經被緩存,那麼就可以直接將緩存內容返回,而無需再次請求應用服務器。由此,可降低應用服務器的負載並提高服務的響應性能。Cache 文件內容:

3.2.1.3 原理分析
Nginx 對Range 的支持包括header 處理和body 處理,分別用來解析客戶端發送過來的Range header 和裁剪返回給客戶端的請求數據Bodyngx_http_range_header_filter_module 負責對header 數據的處理
ngx_http_range_body_filter_module 負責對body 數據的處理
解析過程:

在ngx_http_range_parse 函數中有這樣一個循環
這段代碼是要把“-”兩邊的數字取出分別賦值給start 和end 變量,字符串指針p 中即為bytes=後面的內容。

在上面這段代碼中存在cutoff 和cutlim 閾值限定了從字符串中讀取時不會讓start 或end 為負值
所以這裡需要進入suffix=1 的分支,因此使用Range: bytes=-xxx,即省略初始start 值的形式。
start 等於content_length 減去end 值,所以如果傳入的end 比實際長度還要長,就可以使start 變為負數。最終end 的值會被設定為content_length - 1
通過上面的設定後,這塊range 的總長度就超過了content-length。而Nginx對range 總長度會有檢查,但是注意到size 的值是multipart 的全局range 長度相加得到
因此,一個range 是不夠的,至少需要兩個range,其長度之和溢出為負數,就可以繞過總長度的檢查了。
for 循環是一個無條件的循環,有一個退出條件為=,支持range 的值為start1 - end1, start2 - end2 的形式構造range: bytes=-x, -y。一大一小兩個end 值,只需要控制前面一個end 值小而後一個end 值大,從而實現star t值和size 值皆為負數,控制start 值負到一個合適的位置,那麼就能成功讀到緩存文件頭部了。
3.2.2 漏洞复现

可見,越界讀取到了位於「HTTP返回包體」前的「文件頭」、「HTTP返回包頭」等內容。
3.3 Nginx 文件名逻辑漏洞
漏洞編號:CVE-2013-4547漏洞危害:文件上傳、繞過目錄限制
影響版本:0.8.41 ~ 1.4.3/1.5.0 ~ 1.5.7
3.3.1 原理
非法字符空格和截止符\0 會導致Nginx 解析URI 時的有限狀態機混亂,危害是允許攻擊者通過一個非編碼空格繞過後綴名限制。舉個例子,假設服務器上存在文件:file.aaa[空格],注意文件名的最後一個字符是空格。則可以通過訪問:http://127.0.0.1/file.aaa \0.bbb,讓Nginx 認為文件file.aaa 的後綴為.bbb。
3.3.2 漏洞复现
3.3.2.1 解析漏洞
Nginx 匹配到.php 結尾的請求,就發送給fastcgi 進行解析,常用的寫法如下:1
2
3
4
5
6
7
8
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
正常情況下(關閉pathinfo 的情況下),只有.php 後綴的文件才會被發送給fastcgi 解析。
而存在CVE-2013-4547 的情況下,我們請求1.gif[0x20][0x00].php,這個URI 可以匹配上正則\.php$,可以進入這個Location 塊;但進入後,Nginx 卻錯誤地認為請求的文件是1.gif[0x20],就設置其為SCRIPT_FILENAME 的值發送給fastcgi。
fastcgi 根據SCRIPT_FILENAME 的值進行解析,最後造成了解析漏洞。
所以,我們只需要上傳一個空格結尾的文件,即可使PHP 解析之。
該漏洞利用條件有兩個:
Nginx 0.8.41 ~ 1.4.3/1.5.0 ~ 1.5.7
php-fpm.conf 中的security.limit_extensions 為空,也就是說任意後綴名都可以解析為PHP
vulhub 環境啟動後,訪問http://your-ip:8080/即可看到一個上傳頁面。
這個環境是黑名單驗證,我們無法上傳php後綴的文件,需要利用CVE-2013-4547。我們上傳一個1.gif,注意後面的空格:

訪問http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php,即可發現PHP 已被解析:

注意,[0x20]是空格,[0x00]是\0,這兩個字符都不需要編碼。
3.3.2.2 绕过目录限制
比如很多網站限制了允許訪問後台的IP:1
2
3
4
location /admin/{
allow 127.0.0.1;
deny all;
}
通過請求如下URI:/test[0x20]/./admin/index.php,這個URI 不會匹配上location 後面的/admin/,也就繞過了其中的IP 驗證
但最後請求的是/test[0x20]/./admin/index.php 文件,也就是/admin/index.php,成功訪問到後台。
(這個前提是需要有一個目錄叫test:這是Linux 系統的特點,如果有一個不存在的目錄,則即使跳轉到上一層,也會報文件不存在的錯誤, Windows 下沒有這個限制)
3.4 Nginx 解析漏洞
漏洞危害:文件上傳影響版本:
Nginx 1.x 最新版
PHP 7.x 最新版
3.4.1 原理
nginx 把以.php 結尾的文件交給fastcgi 處理,為此可以構造http://ip/uploadfiles/test.png/.php,其中test.png 是我們上傳的包含PHP 代碼的圖片文件。fastcgi 在處理.php 文件時發現文件並不存在,這時php.ini 配置文件中cgi.fix_pathinfo=1 發揮作用,這項配置用於修復路徑,如果當前路徑不存在則採用上層路徑。為此這裡交由fastcgi 處理的文件就變成了/test.png。
最重要的一點是php-fpm.conf 中的security.limit_extensions 配置項限制了fastcgi 解析文件的類型(即指定什麼類型的文件當做代碼解析),此項設置為空的時候才允許fastcgi 將.png 等文件當做代碼解析。
3.4.2 漏洞复现
該漏洞與Nginx、php 版本無關,屬於用戶配置不當造成的解析漏洞。訪問http://your-ip/uploadfiles/nginx.png 和http://your-ip/uploadfiles/nginx.png/.php 即可查看效果。
4 Tomcat 安全
Tomcat 是Apache 軟件基金會的Jakarta 項目中的一個核心項目,由Apache、Sun 和其他一些公司及個人共同開發而成。Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬於輕量級應用服務器,在中小型系統和並發訪問用戶不是很多的場合下被普遍使用。
實際上Tomcat 是Apache 服務器的擴展,但運行時它是獨立運行的,所以當你運行Tomcat 時,它實際上作為一個與Apache 獨立的進程單獨運行的。
4.1 Tomcat 配置错误
漏洞編號:CVE-2017-12615影響版本:Apahce Tomcat 7.0.0 - 7.0.79
漏洞說明:當Tomcat 運行在Windows 主機上,且啟用了HTTP PUT 請求方法,攻擊者將有可能可通過精心構造的攻擊請求向服務器上傳包含任意代碼的JSP 文件。之後,JSP 文件中的代碼將能被服務器執行。
漏洞本質Tomcat 配置了可寫(readonly=false),導致我們可以往服務器寫文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
servlet
servlet-namedefault/servlet-name
servlet-classorg.apache.catalina.servlets.DefaultServlet/servlet-class
init-param
param-namedebug/param-name
param-value0/param-value
/init-param
init-param
param-namelistings/param-name
param-valuefalse/param-value
/init-param
init-param
param-namereadonly/param-name
param-valuefalse/param-value
/init-param
load-on-startup1/load-on-startup
/servlet
雖然Tomcat 對文件後綴有一定檢測(