Tomcat - Security Vulnerability
Recently, I am focusing on dealing with the vulnerabilities which found by a security scan. Most of them are related with Web Server, especially with Tomcat. I will record how to verify and fix the these vulnerabilities.
Expired/Untrusted/Self-signed Certificate:
Verify:
$ openssl s_client -connect localhost:7004 CONNECTED(00000003) depth=0 C = US, ST = VA, L = VVV, O = xxx, OU = yyy, CN = zzz.prod.xxx.edu -->> verify error:num=18:self signed certificate verify return:1 depth=0 C = US, ST = VA, L = VVV, O = xxx, OU = yyy, CN = zzz.prod.xxx.edu -->> verify error:num=10:certificate has expired -->> notAfter=Mar 29 12:45:03 2017 GMT verify return:1 depth=0 C = US, ST = VA, L = VVV, O = xxx, OU = yyy, CN = zzz.prod.xxx.edu notAfter=Mar 29 12:45:03 2017 GMT verify return:1 ……… No client certificate CA names sent --- SSL handshake has read 1052 bytes and written 589 bytes --- New, TLSv1/SSLv3, Cipher is AES128-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : AES128-SHA Session-ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxx Session-ID-ctx: Master-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxx Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None Start Time: 1544020132 Timeout : 300 (sec) -->> Verify return code: 10 (certificate has expired) --- read:errno=0
Fix:
Generate a request, the password of the old keystore is needed.
Normally, the password is on Tomcat server.xml, if cannot find, create a new one instead.
$ keytool -genkey -alias tara -keyalg RSA -keysize 2048 -keystore ./tara $ keytool -certreq -alias tara -keyalg RSA -file ./tara.csr -keystore ./.keystore -ext SAN=dns:tara.pprd.yyy.edu
Send the content in tara.csr to CA to sign
After get the feedback from CA, download tara.cer and import
$ keytool -import -alias tara -file tara.cer -keystore ./.keystore
If recreate keystore, the new name / password should be changed on server.xml
Weak Cipher suite
Verify:
Do it from a windows client
>nmap -sV --script ssl-enum-ciphers -p 7004 128.82.96.201 Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-05 09:26 Eastern Standard Time Nmap scan report for homer.prod.odu.edu (128.82.96.201) Host is up (0.0010s latency). ……... | ssl-enum-ciphers: | TLSv1.2: | ciphers: | TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A | compressors: | NULL | cipher preference: client | warnings: | 64-bit block cipher 3DES vulnerable to SWEET32 attack |_ least strength: C ……
Or, use openssl, when we use MEDIUM, it should be not working, only HIGH can be accepted
$ openssl s_client -connect 127.0.0.1:4903 -cipher MEDIUM CONNECTED(00000003) 139781540525968:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:769: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 171 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None Start Time: 1544157174 Timeout : 300 (sec) Verify return code: 0 (ok) ---
Or, we can use the following script:
#!/usr/bin/env bash # OpenSSL requires the port number. SERVER=$1 DELAY=1 ciphers=$(openssl ciphers 'ALL:eNULL' | sed -e 's/:/ /g') echo Obtaining cipher list from $(openssl version). for cipher in ${ciphers[@]} do echo -n Testing $cipher... result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1) if [[ "$result" =~ ":error:" ]] ; then error=$(echo -n $result | cut -d':' -f6) echo NO \($error\) else if [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher :" ]] ; then echo YES else echo UNKNOWN RESPONSE echo $result fi fi sleep $DELAY done
Unfortunately, not every cipher suite you are using can be listed.
Fix:
Remove motioned cipher suites from server.xml for specific connector
Do it on the test machine at first to make sure the client can still access the web server.
The cipher suites which Tomcat supports are determinded by JAVA. It would be better to use update-to-date JDK
TLS1.0 / 1.1 / SSLv3 is supported
Verfiy:
if not supported, you can see the following information, otherwise, like the verify in “Expired/Untrusted/Self-signed Certificate:”
$ openssl s_client -connect localhost:8441 -tls1_1
CONNECTED(00000003)
140204650911560:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:339:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
-->> Secure Renegotiation IS NOT supported <<--
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1544026583
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
Fix:
Specify sslProtocol=”TLSv1.2” for connector in server.xml of Tomcat.