Nginx升級加固SSL/TLS協議資訊洩露漏洞(CVE-2016-2183)
漏洞說明
// 基於Nginx的https網站被掃描出SSL/TLS協議資訊洩露漏洞(CVE-2016-2183),該漏洞是在安裝Nginx時build的Openssl版本問題導致的漏洞,
// 需要重新編譯安裝Nginx並指定版本的Openssl(可以不升級系統的openssl,編譯過程中只要指定新的openssl路徑即可)。
加固方法和步驟
檢查當前Nginx安裝過程使用的openssl版本
[root@server ~]# nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
下載新版本Openssl
cd /tmp
wget https://www.openssl.org/source/openssl-1.1.0k.tar.gz
tar zxvf openssl-1.1.0k.tar.gz -C /usr/local
下載安裝原始碼Nginx
yum install -y gcc gcc-c++ openssl-devel pcre-devel make zlib-devel wget
wget http://nginx.org/download/nginx-1.14.2.tar.gz
cd /root/nginx-1.14.2
./configure --prefix=/usr/local/nginx1.14 --with-http_ssl_module --with-http_stub_status_module --with-openssl=/usr/local/openssl-1.1.0k
make && make install
我之前make時如果將openssl放到root目錄可能會編譯報錯,/usr/local就沒報錯,沒報錯就不要改下面檔案了
# 錯誤資訊
/bin/sh: line 2: ./config: No such file or directory
make[1]: *** [/usr/local/ssl/.openssl/include/openssl/ssl.h] Error 127
make[1]: Leaving directory `/usr/local/src/nginx-1.9.9'
make: *** [build] Error 2
解決方法
# 開啟nginx原始檔下的/usr/local/src/nginx-1.9.9/auto/lib/openssl/conf檔案:
vi /root/nginx-1.14.2/auto/lib/openssl/conf
# 找到以下程式碼,差不多三四十行
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
# 修改成以下程式碼
CORE_INCS="$CORE_INCS $OPENSSL/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
驗證Nginx使用Openssl版本
[root@JD sbin]# ./nginx -V
nginx version: nginx/1.14.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.1.0k 28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx1.14 --with-http_ssl_module --with-http_stub_status_module --with-openssl=/usr/local/openssl-1.1.0k
HTTP伺服器的預設banner
能讓攻擊者瞭解遠端系統型別和遠端HTTP Server資訊以便進行下一步的攻擊
Nginx
一般Nginx我們都會隱藏版本號
# 在http{}裡面加上
http {
include mime.types;
default_type application/octet-stream;
server_tokens off;
# 隱藏php版本只需要在php.ini配置檔案修改expose_php = On改為expose_php=Off
# 但是我們訪問時候還是能看到關鍵資訊,讓人竊取到你使用的是nginx
[root@JD nginx-1.14.2]# curl localhost -I
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 09 Sep 2020 13:36:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 09 Sep 2020 13:08:03 GMT
Connection: keep-alive
ETag: "5f58d3b3-264"
Accept-Ranges: bytes
由於Nignx沒有提供相關配置項改變預設banner,所以我們需要修改原始碼,隱藏Nginx軟體名
# 我們可以隱藏掉server資訊也可以製造假的server迷惑攻擊者
# 修改第一個配置檔案為nginx.h
ls /usr/local/src/nginx-1.12.2/
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
# 我們找到當初make之前的那個原始碼包
cd /usr/local/src/nginx-1.12.2/src/
vim core/nginx.h # 修改下面三行
#define nginx_version 1012002
#define NGINX_VERSION "7.0"
#define NGINX_VER "IIS/" NGINX_VERSION
#ifdef NGX_BUILD
#define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD NGINX_VER
#endif
#define NGINX_VAR "IIS"
# OR
#define nginx_version 1014002
#define NGINX_VERSION ""
#define NGINX_VER "UNKNOW/" NGINX_VERSION
#ifdef NGX_BUILD
#define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD NGINX_VER
#endif
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
#endif /* _NGINX_H_INCLUDED_ */
# 修改第二個配置檔案為ngx_http_header_filter_module.c,49行
grep IIS http/ngx_http_header_filter_module.c
static u_char ngx_http_server_string[] = "Server:IIS" CRLF;
# OR
static u_char ngx_http_server_string[] = "" CRLF;
static u_char ngx_http_server_full_string[] = "" NGINX_VER CRLF;
static u_char ngx_http_server_build_string[] = "" NGINX_VER_BUILD CRLF;
# 修改第三個配置檔案為ngx_http_special_response.c,對外頁面報錯時,他會控制是否展示敏感資訊,修改如下列
21 static u_char ngx_http_error_full_tail[] =
22 "<hr><center>IIS</center>" CRLF
23 "</body>" CRLF
24 "</html>" CRLF
25 ;
26
27
28 static u_char ngx_http_error_build_tail[] =
29 "<hr><center>IIS</center>" CRLF
30 "</body>" CRLF
31 "</html>" CRLF
32 ;
# OR
static u_char ngx_http_error_full_tail[] =
"<hr><center>" NGINX_VER "</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
static u_char ngx_http_error_build_tail[] =
"<hr><center>" NGINX_VER_BUILD "</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
# nginx -V 檢視原來編譯的引數,從新編譯並且make && make install 才會生效,如果原始碼修改錯誤會編譯不過去.如果編譯前服務是啟動的哪怕編譯成功也是不生效的,需要重啟服務.
# 編譯,重啟請看上面,接下來我們訪問看下效果
[root@JD nginx1.14]# curl localhost -I
HTTP/1.1 200 OK
[root@JD nginx1.14]#
還有一種辦法比較另類,我沒試過
sub_filter '<hr><center>nginx</center>' '<hr><center>ws</center>';
Tomcat
1)我們可以編輯Tomcat(安裝目錄)/conf/server.xml 檔案 ,找到我們應用程式埠對應的元素,新增 server="自定義" 屬性,覆蓋掉原來的server屬性。
2) 重啟服務即可