Codebase list tlssled / fdf0832
Imported Upstream version 1.3 Mati Aharoni (Kali Linux Developer) 10 years ago
2 changed file(s) with 757 addition(s) and 321 deletion(s). Raw diff Collapse all Expand all
+0
-321
TLSSLed_v1.2.sh less more
0 #!/usr/bin/env bash
1 #
2 # Tool: TLSSLed.sh
3 #
4 # Description:
5 # Script to extract the most relevant security details from a
6 # target SSL/TLS HTTPS implementation by using sslscan & openssl.
7 #
8 # Author: Raul Siles (raul _AT_ taddong _DOT_ com)
9 # Taddong SL (www.taddong.com)
10 # Date: 2011-10-18
11 # Version: 1.2
12 #
13 # - New in version 1.2:
14 # - Mac OS X support: sed regex switch changed - by [ anonymous ].
15 # - Test if target service speaks SSL/TLS - by Abraham Aranguren (AA).
16 # For performance reasons, this test has been merged with the SSL/TLS
17 # renegotiation test.
18 # - Optimizations by removing cat usage in grepping for findings - by AA.
19 # - New initial tests to check for the tool prerequisites: openssl & sslscan.
20 # - Test for TLS v1.1 and v1.2 support (CVE-2011-3389 aka BEAST).
21 # The tests also include checking for SSLv3 and TLSv1 support.
22 # - Log files names changed from host:port to host_port and ":" removed
23 # from the time portion of the date command, to be able to copy them
24 # to Windows based file systems:
25 # (In Windows ":" is not allowed in a filename, while "_" is).
26 #
27 # - New in version 1.1:
28 # - Cert public key length, subject, issuer, and validiy period.
29 # - Test HTTP(S) secure headers: Strict-Transport-Security (STS), and
30 # cookies with and without the secure flag.
31 # - NOTE: openssl output is now saved to files too.
32 #
33 # - Current SSL/TLS tests: (version 1.0)
34 # SSLv2, NULL cipher, weak ciphers -key length-, strong ciphers -AES-,
35 # MD5 signed cert, and SSL/TLS renegotiation.
36 #
37 #
38 # Requires:
39 # - sslscan
40 # https://sourceforge.net/projects/sslscan/
41 # - openssl
42 # http://www.openssl.org
43 #
44 # Credits:
45 # - Version 1.0 based on ssl_test.sh by Aung Khant, http://yehg.net.
46 # - Abraham Aranguren (AA) - http://securityconscious.blogspot.com (v1.2)
47 #
48
49 #
50 # /**************************************************************************
51 # * Copyright 2011 by Taddong SL (Raul Siles) *
52 # * *
53 # * This program is free software; you can redistribute it and/or modify *
54 # * it under the terms of the GNU General Public License as published by *
55 # * the Free Software Foundation; either version 3 of the License, or *
56 # * (at your option) any later version. *
57 # * *
58 # * This program is distributed in the hope that it will be useful, *
59 # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
60 # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
61 # * GNU General Public License for more details. *
62 # * *
63 # * You should have received a copy of the GNU General Public License *
64 # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
65 # * *
66 # **************************************************************************/
67 #
68
69 VERSION=1.2
70
71 # This script does not filter the input from certain commands, hence it might
72 # be vulnerable to local input command manipulation, such as in uname.
73
74 # v1.2: Mac OS X (Darwin) support.
75 # sed regexes in Linux use the -r switch, and in non-GNU systems the -E switch.
76 SED_ARG_REGEX=-r
77 if [ "$(uname)" == "Darwin" ] ; then
78 SED_ARG_REGEX=-E
79 fi
80
81 echo ------------------------------------------------------
82 echo " TLSSLed - ($VERSION) based on sslscan and openssl"
83 echo " by Raul Siles (www.taddong.com)"
84 echo ------------------------------------------------------
85
86 if [ -z `which openssl` ] ;then echo; echo "ERROR: openssl command not found!"; exit; fi
87 if [ -z `which sslscan` ] ;then echo; echo "ERROR: sslscan command not found!"; exit; fi
88
89 OPENSSLVERSION=$(openssl version)
90 SSLSCANVERSION=$(sslscan --version | grep version | sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")
91
92 echo + openssl version: $OPENSSLVERSION
93 echo + $SSLSCANVERSION
94 echo ------------------------------------------------------
95 echo
96
97 if [ $# -ne 2 ]; then
98 echo Usage: $0 HOSTNAME_or_IP PORT
99 exit
100 fi
101
102 HOST=$1
103 PORT=$2
104
105 echo [-] Analyzing SSL/TLS on $HOST:$PORT ..
106 echo
107
108 # Run sslcan once, store the results to a log file and
109 # analyze that file for all the different tests:
110 DATE=$(date +%F_%R:%S | sed 's/://g')
111 TARGET=$HOST\_$PORT
112 LOGFILE=sslscan\_$TARGET\_$DATE.log
113 ERRFILE=sslscan\_$TARGET\_$DATE.err
114 RENEGLOGFILE=openssl\_RENEG\_$TARGET\_$DATE.log
115 RENEGERRFILE=openssl\_RENEG\_$TARGET\_$DATE.err
116 HEADLOGFILE=openssl\_HEAD\_$TARGET\_$DATE.log
117 HEADERRFILE=openssl\_HEAD\_$TARGET\_$DATE.err
118
119 # Check if the target service speaks SSL/TLS (& check renegotiation)
120 (echo R; sleep 5) | openssl s_client -connect $HOST:$PORT > $RENEGLOGFILE 2> $RENEGERRFILE &
121 pid=$!
122 sleep 5
123
124 SSL_HANDSHAKE_LINES=$(cat $RENEGLOGFILE | wc -l)
125
126 if [ $SSL_HANDSHAKE_LINES -lt 5 ] ; then
127 # SSL handshake failed - Non SSL/TLS service
128 # If the target service does not speak SSL/TLS, openssl does not
129 # terminate
130 kill -s SIGINT ${pid}
131
132 echo "[+] ERROR: The target service $HOST:$PORT does not seem"
133 echo " to speak SSL/TLS or is not available!!"
134 echo
135 exit
136 else
137 # SSL handshake succeded - Continue
138 echo "[*] The target service $HOST:$PORT seems to speak SSL/TLS..."
139 echo
140 fi
141
142
143 echo
144 echo [-] Running sslscan on $HOST:$PORT...
145 sslscan $HOST:$PORT > $LOGFILE 2> $ERRFILE
146
147 echo
148 echo [*] Testing for SSLv2 ...
149 grep "Accepted SSLv2" $LOGFILE
150 echo
151 echo [*] Testing for NULL cipher ...
152 grep "NULL" $LOGFILE | grep Accepted
153 echo
154 echo [*] Testing for weak ciphers \(based on key length\) ...
155 grep " 40 bits" $LOGFILE | grep Accepted
156 echo
157 grep " 56 bits" $LOGFILE | grep Accepted
158 echo
159 echo [*] Testing for strong ciphers \(AES\) ...
160 grep "AES" $LOGFILE | grep Accepted
161
162 echo
163 echo [*] Testing for MD5 signed certificate ...
164 #cat $LOGFILE | grep -E 'MD5WithRSAEncryption|md5WithRSAEncryption'
165 grep -i 'MD5WithRSAEncryption' $LOGFILE
166
167 echo
168 echo [*] Testing for certificate public key length ...
169 grep -i 'RSA Public Key' $LOGFILE
170
171 echo
172 echo [*] Testing for certificate subject ...
173 grep -i 'Subject:' $LOGFILE
174
175 echo
176 echo [*] Testing for certificate CA issuer ...
177 grep -i 'Issuer:' $LOGFILE
178
179 echo
180 echo [*] Testing for certificate validity period ...
181 NOW=$(date -u)
182 echo " Today: $NOW"
183 grep -i 'Not valid' $LOGFILE
184
185 echo
186 echo [*] Checking preferred server ciphers ...
187 # v1.1:
188 # cat $LOGFILE | sed '/Prefered Server Cipher(s):/,/^$/!d' | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
189 #
190 cat $LOGFILE | sed '/Prefered Server Cipher(s):/,/^$/!d' | sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
191
192 echo
193 echo
194 echo [-] Testing for SSLv3/TLSv1 renegotiation vuln. \(CVE-2009-3555\) ...
195 #echo [*] echo R \| openssl s_client -connect $HOST:$PORT \| grep "DONE"
196 #
197 # Renegotiation details go to stderr (2>)
198 #
199 # if $OPENSSLVERSION is updated (version?) it supports RFC5746 and will print:
200 # Secure Renegotiation IS NOT supported
201 # Secure Renegotiation IS supported
202 #
203
204 # Executed as the first step to check if target service supports SSL/TLS:
205 #
206 # (echo R; sleep 5) | openssl s_client -connect $HOST:$PORT > $RENEGLOGFILE 2> $RENEGERRFILE
207
208 echo
209 echo [*] Testing for secure renegotiation ...
210 grep -E "Secure Renegotiation IS" $RENEGLOGFILE
211
212
213 echo
214 echo
215 echo [-] Testing for TLS v1.1 and v1.2 \(CVE-2011-3389 aka BEAST\) ...
216
217 # Test for SSLv3 and TLSv1 support first (from sslscan)
218 echo
219 echo [*] Testing for SSLv3 and TLSv1 support first ...
220 grep "Accepted SSLv3" $LOGFILE
221 grep "Accepted TLSv1" $LOGFILE
222
223 #
224 # Connection details go to stderr (2>) and, therefore, to a variable:
225 #
226 # if $OPENSSLVERSION is updated (version >= 1.0.1-stable) it supports
227 # TLS v1.1 & v1.2, if not, the openssl help is displayed in the command output
228 #
229 # Example of server that supports all SSL and TLS versions:
230 # tls.woodgrovebank.com:443 (Microsoft) (20111012)
231
232 OUTPUT_TLS1_1=$((sleep 5; echo QUIT) | openssl s_client -tls1_1 -connect $HOST:$PORT 2>&1)
233 OUTPUT_TLS1_2=$((sleep 5; echo QUIT) | openssl s_client -tls1_2 -connect $HOST:$PORT 2>&1)
234
235 # if "DONE": TLS v1.x supported
236 # else if "wrong version number": TLS v1.x not supported
237 # else if "unknown option": OpenSSL does not support TLS v1.1 or v1.2
238
239 echo
240 echo [*] Testing for TLS v1.1 support ...
241
242 if grep -q DONE <<<$OUTPUT_TLS1_1; then
243 echo "TLS v1.1 IS supported"
244 elif grep -q "wrong version number" <<<$OUTPUT_TLS1_1; then
245 echo "TLS v1.1 IS NOT supported"
246 elif grep -q "unknown option" <<<$OUTPUT_TLS1_1; then
247 echo "The local openssl version does NOT support TLS v1.1"
248 else
249 echo "UNKNOWN"
250 fi
251
252 echo
253 echo [*] Testing for TLS v1.2 support ...
254
255 if grep -q DONE <<<$OUTPUT_TLS1_2; then
256 echo "TLS v1.2 IS supported"
257 elif grep -q "wrong version number" <<<$OUTPUT_TLS1_2; then
258 echo "TLS v1.2 IS NOT supported"
259 elif grep -q "unknown option" <<<$OUTPUT_TLS1_2; then
260 echo "The local openssl version does NOT support TLS v1.2"
261 else
262 echo "UNKNOWN"
263 fi
264
265 echo
266 echo
267 echo [-] Testing for SSL/TLS HTTPS security headers ...
268 #
269 #
270 #
271 (echo -e "HEAD / HTTP/1.0\n\n"; sleep 5) | openssl s_client -connect $HOST:$PORT > $HEADLOGFILE 2> $HEADERRFILE
272
273 echo
274 echo [*] Testing for Strict-Transport-Security \(STS\) header ...
275 grep -i 'Strict-Transport-Security' $HEADLOGFILE
276
277 echo
278 echo [*] Testing for cookies with the secure flag ...
279 grep -i 'Set-Cookie' $HEADLOGFILE | grep -i 'secure'
280
281 echo
282 echo [*] Testing for cookies without the secure flag ...
283 grep -i 'Set-Cookie' $HEADLOGFILE | grep -v -i 'secure'
284
285
286 echo
287 echo
288 echo [-] New files created:
289 ls -l $LOGFILE
290 ls -l $HEADLOGFILE
291 ls -l $RENEGLOGFILE
292
293 # Delete all empty error files:
294 # It could potentially delete other .err zero-size files not created by TLSSLed
295 # find . -size 0 -name '*.err' -delete
296
297 if [ ! -s $ERRFILE ]; then
298 # Error file is empty
299 rm $ERRFILE
300 else
301 ls -l $ERRFILE
302 fi
303 if [ ! -s $RENEGERRFILE ]; then
304 # Renegotiation error file is empty
305 rm $RENEGERRFILE
306 else
307 ls -l $RENEGERRFILE
308 fi
309 if [ ! -s $HEADERRFILE ]; then
310 # Openssl HEAD error file is empty
311 rm $HEADERRFILE
312 else
313 ls -l $HEADERRFILE
314 fi
315
316 echo
317 echo
318 echo [-] done
319 echo
320
0 #!/usr/bin/env bash
1 #
2 # Tool:
3 # TLSSLed.sh
4 #
5 # Description:
6 # Script to extract the most relevant security details from a
7 # target SSL/TLS HTTPS implementation by using sslscan & openssl.
8 #
9 # URL:
10 # http://www.taddong.com/en/lab.html#TLSSLED
11 #
12 # Author:
13 # Raul Siles (raul _AT_ taddong _DOT_ com)
14 # Taddong SL (www.taddong.com)
15 #
16 # Date: 2013-01-31
17 # Version: 1.3
18 #
19
20 #
21 # /**************************************************************************
22 # * Copyright 2011-2013 by Taddong SL (Raul Siles) *
23 # * *
24 # * This program is free software; you can redistribute it and/or modify *
25 # * it under the terms of the GNU General Public License as published by *
26 # * the Free Software Foundation; either version 3 of the License, or *
27 # * (at your option) any later version. *
28 # * *
29 # * This program is distributed in the hope that it will be useful, *
30 # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
31 # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
32 # * GNU General Public License for more details. *
33 # * *
34 # * You should have received a copy of the GNU General Public License *
35 # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
36 # * *
37 # **************************************************************************/
38 #
39
40 #
41 # - TODO:
42 # - Add a new command line argument to define the specific URL to test in
43 # the target server. E.g. $ ./TLSSLed.sh HOSTNAME_or_IP-ADDRESS PORT [URL]"
44 #
45 # By default the URL should be "/".
46 # This check should use HTTP/1.1 (instead of 1.0) and a valid Host header.
47 # (Right now this only applies to the HTTP header tests at the end)
48 #
49 #
50 # - New in version 1.3:
51 # - All file output goes to a single directory (same filenames as in
52 # previous versions) instead of to the working local directory.
53 # - Change in the date format used for log files:
54 # From: 2011-12-30_105055 - To: 20111230-105055
55 # - Test if SSL/TLS renegotiation is enabled (NEW check) and if the target
56 # service supports secure renegotiation (already in previous versions).
57 # If secure renegotiation is not supported, we must check renegotiation
58 # by usin legacy renegotiation (two new log files are used).
59 # - New test to check for legacy renegotiation even when secure
60 # renegotiation is supported, just in case the target service supports
61 # both.
62 # - Test if client certificate authentication is required by the target
63 # service. If so, identify the number of CAs accepted and save the
64 # list of CAs to a file.
65 # - New test to check for HTTP headers using HTTP/1.0 (previous
66 # versions) as well as HTTP/1.1 and a valid Host header. New log
67 # files created for this.
68 # - New error handling code for the initial SSL/TLS verification.
69 # - Optimizations in the openssl delays (sleep timers).
70 # - New DELAY variable to control sleep timers (by default 3 seconds -
71 # it was 5 before).
72 # - New output indentation.
73 # - New output code set for findings: - (negative), + (positive), . (info),
74 # * (group of checks) or ! (error/warning).
75 # - LOGFILE changed to SSLSCANLOGFILE & ERRFILE changed to SSLSCANERRFILE.
76 # - RENEGLEGACY???FILE(s) included in the final listing and removal
77 # process.
78 # - Several changes to the output messages for the different findings.
79 # - Duplication of "Prefered Server Cipher" output message removed.
80 # - New check to test for RC4 in the prefered chiper(s) regarding BEAST.
81 # - Use of openssl "-prexit" option for some weird target scenarios (CSA).
82 # - Added the date and time at the beggining of the output.
83 #
84 # - New in version 1.2:
85 # - Mac OS X support: sed regex switch changed - by [ anonymous ].
86 # - Test if target service speaks SSL/TLS - by Abraham Aranguren (AA).
87 # For performance reasons, this test has been merged with the SSL/TLS
88 # renegotiation test.
89 # - Optimizations by removing cat usage in grepping for findings - by AA.
90 # - New initial tests to check for the tool prerequisites: openssl &
91 # sslscan.
92 # - Test for TLS v1.1 and v1.2 support (CVE-2011-3389 aka BEAST).
93 # The tests also include checking for SSLv3 and TLSv1 support.
94 # - Log files names changed from host:port to host_port and ":" removed
95 # from the time portion of the date command, to be able to copy them
96 # to Windows based file systems:
97 # (In Windows ":" is not allowed in a filename, while "_" is).
98 #
99 # - New in version 1.1:
100 # - Cert public key length, subject, issuer, and validiy period.
101 # - Test HTTP(S) secure headers: Strict-Transport-Security (STS), and
102 # cookies with and without the secure flag.
103 # - NOTE: openssl output is now saved to files too.
104 #
105 # - Current SSL/TLS tests: (version 1.0)
106 # SSLv2, NULL cipher, weak ciphers -key length-, strong ciphers -AES-,
107 # MD5 signed cert, and SSL/TLS renegotiation.
108 #
109 #
110 # Requires:
111 # - sslscan
112 # https://sourceforge.net/projects/sslscan/
113 # - openssl
114 # http://www.openssl.org
115 #
116 # Credits for ideas and feedback:
117 # - Version 1.0 based on ssl_test.sh by Aung Khant, http://yehg.net.
118 # - Abraham Aranguren (AA) - http://securityconscious.blogspot.com (in v1.2)
119 #
120
121 # New output codeset (between square brackets) for the findings:
122 # [-] Negative finding (insecure)
123 # [+] Positive finding (secure)
124 # [.] Informational finding
125 # [*] Group of checks
126 # [!] Error or warning message
127
128 # Variables
129
130 # Version
131 VERSION=1.3
132
133 # Manage sleep time for openssl connections (in seconds)
134 DELAY=3
135
136 # DATE (pre v1.3):
137 # DATE=$(date +%F_%R:%S | sed 's/://g')
138 # DATE (post v1.3+):
139 DATE=$(date +%Y%m%d-%H%M%S)
140
141 # Some SSL/TLS target services require some extra options to work:
142 # E.g. -prexit: Print out info even when the SSL/TLS connection fails.
143 # http://www.openssl.org/docs/apps/s_client.html
144 # For some scenarios where client certificates are required.
145 OPENSSLOPTIONS="-prexit"
146
147 # Default openssl protocol: By default this variable is empty so that the
148 # protocol is automatically selected by the openssl version available:
149 OPENSSLPROTOCOLVERSION=""
150 # The default backward compatible protocol version in case of errors: TLS1
151 BACKWARDPROTOCOL="false"
152 OPENSSLBACKWARDPROTOCOLVERSION="-tls1"
153 #
154 # See NOTE (openssl protocol version glitches) below.
155 #
156 # openssl 1.x might require the "-tls1" or "-ssl3" openssl command line
157 # arguments on some target sites, as openssl 1.x uses TLS protocol version
158 # 1.2 by default in the Client Hello message, and if not supported by the
159 # target server, it never sends the Server Hello message back.
160 #
161
162 # *** SECURITY DISCLAIMER ***
163 # This script does not filter the input for certain commands, hence it
164 # might be vulnerable to local input command manipulation, such as in uname.
165 # *** SECURITY DISCLAIMER ***
166
167 # Functions ()
168
169 reviewlogfiles () {
170 echo
171 echo "[.] Review the files within the output directory for more info."
172 echo " [.] Output directory: $DIRECTORY ..."
173 echo
174 }
175
176 # Function to initially test if the target service speaks SSL/TLS
177 test_if_service_speaks_SSLTLS () {
178
179 (echo R; sleep $DELAY) | \
180 openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
181 $OPENSSLOPTIONS > $DIRECTORY/$RENEGLOGFILE 2> $DIRECTORY/$RENEGERRFILE &
182 pid=$!
183 sleep $DELAY
184
185 SSL_HANDSHAKE_LINES=$(cat $DIRECTORY/$RENEGLOGFILE | wc -l)
186 #
187 # NOTE: openssl protocol version glitches
188 #
189 # This check does not work with openssl 1.0.1-dev on some target sites,
190 # and it requires the "-tls1" or "-ssl3" openssl command line arguments;
191 # here, and in all openssl instances within this script.
192 #
193 # The reason is openssl 1.0.1-dev uses TLS protocol version 1.2 in the
194 # Client Hello message, and the server never sends the Server Hello
195 # message. The otput simply shows:
196 # CONNECTED
197 #
198 # If the -tls1_1 switch is used in these target services, they properly
199 # reply back with a "wrong version number" message.
200 #
201 # v1.3: Added new code to accommodate this scenario:
202 # If (-lt 5) but CONNECTED, then use the -tls1 (backward protocol
203 # version) switch in all openssl executions...
204 # ... or (select the right option based on the openssl version, but this
205 # might change): if openssl 1.0.1-dev or +, use -tls1...
206
207 #
208 # There is a specific case where the target service can refuse the
209 # connection but the port still speaks SSL/TLS. In that case the error
210 # log contains the following messages, although the handshake log is >
211 # than 5 lines:
212 # connect: Connection refused
213 # connect:errno=22
214 #
215
216 ERR_SSL=$(cat $DIRECTORY/$RENEGERRFILE)
217
218 if grep -q "connect: Connection refused" <<<$ERR_SSL; then
219 # Target service speaks SSL/TLS but refuses the connection
220 echo
221 echo "[!] ERROR: The target service $HOST:$PORT might speak SSL/TLS"
222 echo " but refuses the connection."
223 reviewlogfiles
224 exit
225 fi
226
227 if [ $SSL_HANDSHAKE_LINES -lt 5 ] ; then
228 # SSL handshake failed - Non SSL/TLS service or error:
229 # - If the target service does not speak SSL/TLS, openssl does not
230 # terminate, so kill it.
231 # - However, if the target speaks SSL/TLS but the connection fails
232 # (e.g. "sslv3 alert bad certificate") then the connection
233 # finishes.
234 kill -s SIGINT ${pid} 2>/dev/null
235
236 # Check if it failed because of an error or lack of SSL/TLS support
237 #ERR_SSL=$(cat $DIRECTORY/$RENEGERRFILE)
238 if grep -q "ssl handshake failure" <<<$ERR_SSL; then
239 echo
240 echo "[!] ERROR: The target service $HOST:$PORT speaks SSL/TLS"
241 echo " but returned an error: ssl handshake failure."
242 echo " E.g. Client certificate mandatory?"
243 elif [ $BACKWARDPROTOCOL == "true" ]; then
244 echo
245 echo "[!] ERROR: The target service $HOST:$PORT does not seem"
246 echo " to speak SSL/TLS even when using the SSL/TLS backward"
247 echo " protocol version: $OPENSSLPROTOCOLVERSION"
248 elif grep -q "CONNECTED" <<<$ERR_SSL; then
249 # The local openssl tool tried by default a protocol version not
250 # supported by the target server. Switching back to a more
251 # conservative protocol version (OPENSSLBACKWARDPROTOCOLVERSION).
252 OPENSSLPROTOCOLVERSION=$OPENSSLBACKWARDPROTOCOLVERSION
253 # Set we already tried a backward option
254 BACKWARDPROTOCOL="true"
255 echo
256 echo "[.] WARNING: Trying connection again with SSL/TLS protocol version:"
257 echo " $OPENSSLPROTOCOLVERSION"
258 #echo
259 mv $DIRECTORY/$RENEGLOGFILE $DIRECTORY/$RENEGLOGFILE.1st-try
260 mv $DIRECTORY/$RENEGERRFILE $DIRECTORY/$RENEGERRFILE.1st-try
261 # Repeat initial test with a potentially different
262 # $OPENSSLPROTOCOLVERSION
263 test_if_service_speaks_SSLTLS
264 else
265 echo
266 echo "[!] ERROR: The target service $HOST:$PORT does not seem"
267 echo " to speak SSL/TLS or it is not reachable!!"
268 fi
269 reviewlogfiles
270 exit
271 else
272 # Specific case where server returns "reason(1000)" cause it requires a
273 # client certificate, and SSLv3 was used by default. Force it to switch
274 # to the OPENSLLBACKWARDPROTOCOLVERSION and try again:
275 # Error:
276 # 3073591496:error:140773E8:SSL routines:SSL23_GET_SERVER_HELLO:\
277 # reason(1000):s23_clnt.c:724:
278 # Another error: (!= openssl version)
279 # 13531:error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate:s3_pkt.c:1093:SSL alert number 42
280
281 if grep -q "SSL23_GET_SERVER_HELLO:reason(1000)\|sslv3 alert bad certificate" <<<$ERR_SSL; then
282 echo
283 echo "[!] ERROR: The target service $HOST:$PORT speaks SSL/TLS"
284 echo " but returned an error."
285 echo " Check the output and try manually other SSL/TLS versions."
286 echo " E.g. Client certificate mandatory?"
287 reviewlogfiles
288 exit
289 else
290 # SSL handshake succeded - Continue...
291 # VERBOSE
292 echo " [.] The target service $HOST:$PORT seems to speak SSL/TLS..."
293 echo
294 echo " [.] Using SSL/TLS protocol version: $OPENSSLPROTOCOLVERSION"
295 echo " (empty means I'm using the default openssl protocol version(s))"
296 echo
297 fi
298 fi
299 }
300
301
302 # MAIN:
303
304 # v1.2:
305 # Mac OS X (Darwin) support:
306 # sed regexes in Linux use the -r switch, while in non-GNU systems (like
307 # Mac OS X) they use the -E switch.
308 #SED_ARG_REGEX=-r
309 #if [ "$(uname)" == "Darwin" ] ; then
310 # SED_ARG_REGEX=-E
311 #fi
312 #
313 # Used for the old check below required to remove terminal output formatting
314
315 echo ------------------------------------------------------
316 echo " TLSSLed - ($VERSION) based on sslscan and openssl"
317 echo " by Raul Siles (www.taddong.com)"
318 echo ------------------------------------------------------
319
320 if [ -z `which openssl` ] ;then echo; echo "[!] ERROR: openssl command not found!"; echo; exit; fi
321 if [ -z `which sslscan` ] ;then echo; echo "[!] ERROR: sslscan command not found!"; echo; exit; fi
322
323 OPENSSLVERSION=$(openssl version)
324 #SSLSCANVERSION=$(sslscan --version | grep version | \
325 #sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")
326 # v1.3:
327 # Works with the old sslscan 1.8.2 and the new 1.8.3rc3 fork
328 SSLSCANVERSION=$(sslscan --version | grep version | \
329 sed "s/^.*sslscan/sslscan/")
330
331 echo " openssl version: $OPENSSLVERSION"
332 echo " $SSLSCANVERSION"
333 echo ------------------------------------------------------
334 echo " Date: $DATE"
335 echo ------------------------------------------------------
336 echo
337
338 if [ $# -ne 2 ]; then
339 echo "[!] Usage: $0 <hostname or IP_address> <port>"
340 echo
341 exit
342 fi
343
344 HOST=$1
345 PORT=$2
346
347 echo "[*] Analyzing SSL/TLS on $HOST:$PORT ..."
348
349 # Run sslcan once, store the results to a log file and
350 # analyze that file for all the different tests:
351 TARGET=$HOST\_$PORT
352 DIRECTORY=TLSSLed\_$VERSION\_$TARGET\_$DATE
353 SSLSCANLOGFILE=sslscan\_$TARGET\_$DATE.log
354 SSLSCANERRFILE=sslscan\_$TARGET\_$DATE.err
355 # Same idea for openssl - save results to files and analyze
356 # them to verify different tests:
357 RENEGLOGFILE=openssl\_RENEG\_$TARGET\_$DATE.log
358 RENEGERRFILE=openssl\_RENEG\_$TARGET\_$DATE.err
359 RENEGLEGACYLOGFILE=openssl\_RENEG\_LEGACY\_$TARGET\_$DATE.log
360 RENEGLEGACYERRFILE=openssl\_RENEG\_LEGACY\_$TARGET\_$DATE.err
361 HEADLOGFILE=openssl\_HEAD\_$TARGET\_$DATE.log
362 HEADERRFILE=openssl\_HEAD\_$TARGET\_$DATE.err
363 HEAD1LOGFILE=openssl\_HEAD\_1.0\_$TARGET\_$DATE.log
364 HEAD1ERRFILE=openssl\_HEAD\_1.0\_$TARGET\_$DATE.err
365 CASFILE=CAs-client-cert\_$TARGET\_$DATE.txt
366
367
368 # Just in case...
369 if [ -z "$DIRECTORY" ]; then
370 echo
371 echo "[!] ERROR: Output directory is not defined! Aborting execution!"
372 echo
373 exit
374 fi
375
376 # VERBOSE
377 echo " [.] Output directory: $DIRECTORY ..."
378 if [ -d "$DIRECTORY" ]; then
379 echo
380 echo "[!] ERROR: Output directory already exist! Aborting execution!"
381 echo
382 exit
383 fi
384 echo
385 mkdir -p $DIRECTORY
386
387 # Check if the target service speaks SSL/TLS (& check renegotiation)
388 echo "[*] Checking if the target service speaks SSL/TLS..."
389
390 test_if_service_speaks_SSLTLS
391
392 # This initial check is required because sslscan works pretty slow & badly
393 # on non-SSL/TLS services, such as HTTP (without S):
394
395 echo "[*] Running sslscan on $HOST:$PORT ..."
396 sslscan $HOST:$PORT > $DIRECTORY/$SSLSCANLOGFILE \
397 2> $DIRECTORY/$SSLSCANERRFILE
398
399 echo
400 echo " [-] Testing for SSLv2 ..."
401 grep "Accepted SSLv2" $DIRECTORY/$SSLSCANLOGFILE
402 echo
403 echo " [-] Testing for the NULL cipher ..."
404 grep "NULL" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
405 echo
406 echo " [-] Testing for weak ciphers (based on key length - 40 or 56 bits) ..."
407 grep " 40 bits" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
408 grep " 56 bits" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
409 echo
410 echo " [+] Testing for strong ciphers (based on AES) ..."
411 grep "AES" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
412
413 echo
414 echo " [-] Testing for MD5 signed certificate ..."
415 #cat $DIRECTORY/$SSLSCANLOGFILE | grep -E 'MD5WithRSAEncryption|md5WithRSAEncryption'
416 grep -i 'MD5WithRSAEncryption' $DIRECTORY/$SSLSCANLOGFILE
417
418 echo
419 echo " [.] Testing for the certificate public key length ..."
420 grep -i 'RSA Public Key' $DIRECTORY/$SSLSCANLOGFILE
421
422 echo
423 echo " [.] Testing for the certificate subject ..."
424 grep -i 'Subject:' $DIRECTORY/$SSLSCANLOGFILE
425
426 echo
427 echo " [.] Testing for the certificate CA issuer ..."
428 grep -i 'Issuer:' $DIRECTORY/$SSLSCANLOGFILE
429
430 echo
431 echo " [.] Testing for the certificate validity period ..."
432 NOW=$(date -u)
433 echo " Today: $NOW"
434 grep -i 'Not valid' $DIRECTORY/$SSLSCANLOGFILE
435
436 echo
437 echo " [.] Checking preferred server ciphers ..."
438 # v1.1:
439 # cat $DIRECTORY/$SSLSCANLOGFILE | sed '/Prefered Server Cipher(s):/,/^$/!d' | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
440 #
441 PREFERED_CIPHERS=$(cat $DIRECTORY/$SSLSCANLOGFILE | \
442 sed '/Prefered Server Cipher(s):/,/^$/!d' | \
443 sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | \
444 grep -v "Prefered Server Cipher" | grep -v "^$")
445 echo "$PREFERED_CIPHERS"
446
447 # Extra empty line above removed with the last grep
448
449 #
450 # SSL/TLS RENEGOTIATION TESTS:
451 # -----------------------------
452 #
453 # Before testing for client initiated renegotiation, we need to check if
454 # we must use the secure (RFC5746) or the insecure (legacy) mode.
455 #
456 # Renegotiation details will go to stderr (2>).
457 #
458 # If $OPENSSLVERSION is updated (0.9.8m+) it supports RFC5746 and will print
459 # the details based on the analysis of the new RI extension:
460 # - Secure Renegotiation IS NOT supported
461 # - Secure Renegotiation IS supported
462 #
463 # Command executed initially to check if target service supports SSL/TLS:
464 #
465 # (echo R; sleep $DELAY) | openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT > \
466 # $DIRECTORY/$RENEGLOGFILE 2> $DIRECTORY/$RENEGERRFILE
467 #
468 # v1.3:
469 # First of all, check if secure renegotiation is supported. Based on the
470 # results, check if client initiated renegotiation is enabled by using
471 # openssl defaults (secure) or the use the "-legacy_renegotiation" flag
472 # (insecure).
473 #
474 # It is important to differentiate between having client initiated
475 # renegotiation enabled, and having support for secure renegotiation.
476 # There are four possible options or combinations.
477 #
478 # If secure renegotiation is NOT supported, we need to use the legacy flag
479 # to test for SSL/TLS legacy renegotiation. If it IS supported, the default
480 # command (initially executed) works fine.
481 #
482 # Additionally, even if secure renegotiation IS supported, we can check if
483 # the target service also accepts insecure renegotiations (legacy).
484 # Therefore, in any case we test for SSL/TLS renegotiation using the legacy
485 # mode.
486 #
487
488 # The text can appear two times, hence we use "uniq":
489 SECURE_RENEG=$(grep -E "Secure Renegotiation IS" $DIRECTORY/$RENEGLOGFILE | \
490 uniq)
491
492 echo
493 echo "[*] Testing for SSL/TLS renegotiation MitM vuln. (CVE-2009-3555) ..."
494 echo
495 echo " [+] Testing for secure renegotiation support (RFC 5746) ..."
496 echo " $SECURE_RENEG"
497
498 # Check for SSL/TLS renegotiation using legacy mode in any case
499 LEGACY_RENEG="-legacy_renegotiation"
500 (echo R; sleep $DELAY) | \
501 openssl s_client $LEGACY_RENEG $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
502 > $DIRECTORY/$RENEGLEGACYLOGFILE 2> $DIRECTORY/$RENEGLEGACYERRFILE
503
504 echo
505 echo "[*] Testing for SSL/TLS renegotiation DoS vuln. (CVE-2011-1473) ..."
506 echo
507
508 if grep -q NOT <<<$SECURE_RENEG; then
509 # Secure renegotiation IS NOT supported: show legacy mode results
510 SECURE_RENEG_STATE="No"
511 ERR_RENEG=$(cat $DIRECTORY/$RENEGLEGACYERRFILE)
512 echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (insecure)..."
513 else
514 # Secure renegotiation IS supported: RFC5746
515 # The default option in openssl (assuming 0.9.8m+) is not to use any
516 # special flag, that is, use secure renegotiation by default
517 SECURE_RENEG_STATE="Yes"
518 ERR_RENEG=$(cat $DIRECTORY/$RENEGERRFILE)
519 echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (secure)..."
520 fi
521
522 # - If SSL/TLS renegotiation is enabled you will get:
523 # ...
524 # verify return:0
525 # DONE
526 #
527 # The DONE message is on the error output, not on the standard output, and
528 # only when the "echo R & sleep" method is used (not in interactive mode).
529
530 if grep -q DONE <<<$ERR_RENEG; then
531 echo " (CI) SSL/TLS renegotiation IS enabled"
532 # Client certificate might be required:
533 elif grep -q "sslv3 alert bad certificate" <<<$ERR_RENEG; then
534 echo " UNKNOWN: Client certificate might be required (sslv3 alert bad certificate)"
535 # Client certificate might be required:
536 # "sslv3 alert unexpected message" in openssl-1.0.1-dev
537 elif grep -q "sslv3 alert unexpected message" <<<$ERR_RENEG; then
538 echo " UNKNOWN: Client certificate might be required (sslv3 alert unexpected message)"
539 # Different error behaviors when reneg. is not enabled:
540 elif grep -q "no renegotiation" <<<$ERR_RENEG; then
541 echo " (CI) SSL/TLS renegotiation IS NOT enabled (no renegotiation)"
542 elif grep -q "ssl handshake failure" <<<$ERR_RENEG; then
543 echo " (CI) SSL/TLS renegotiation IS NOT enabled (ssl handshake failure)"
544 else
545 echo " UNKNOWN"
546 fi
547
548 # Additionally, if secure renegotiation is supported, check if it still
549 # allows renegotiation using legacy mode (insecure):
550 if [ "$SECURE_RENEG_STATE" == "Yes" ]; then
551 echo
552 echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (insecure)..."
553 ERR_RENEG=$(cat $DIRECTORY/$RENEGLEGACYERRFILE)
554
555 # REPEAT:
556 if grep -q DONE <<<$ERR_RENEG; then
557 echo " (CI) SSL/TLS renegotiation IS enabled"
558 # Client certificate might be required:
559 elif grep -q "sslv3 alert bad certificate" <<<$ERR_RENEG; then
560 echo " UNKNOWN: Client certificate might be required (sslv3 alert bad certificate)"
561 # Client certificate might be required:
562 # "sslv3 alert unexpected message" in openssl-1.0.1-dev
563 elif grep -q "sslv3 alert unexpected message" <<<$ERR_RENEG; then
564 echo " UNKNOWN: Client certificate might be required (sslv3 alert unexpected message)"
565 # Different error behaviors when reneg. is not enabled:
566 elif grep -q "no renegotiation" <<<$ERR_RENEG; then
567 echo " (CI) SSL/TLS renegotiation IS NOT enabled (no renegotiation)"
568 elif grep -q "ssl handshake failure" <<<$ERR_RENEG; then
569 echo " (CI) SSL/TLS renegotiation IS NOT enabled (ssl handshake failure)"
570 else
571 echo " UNKNOWN"
572 fi
573 fi
574
575 # Check if client certificate autentication is required by the target
576 # service.
577 #
578 # NOTE: If client certificate authentication is being requested, it would be
579 # possible to test for it using a client digital certificate using openssl:
580 # $ openssl s_client $OPENSSLPROTOCOLVERSION -connect www.example.com:443 \
581 # -cert client.pem -key client.key
582 #
583
584 LOG_RENEG=$(cat $DIRECTORY/$RENEGLOGFILE)
585
586 echo
587 echo "[*] Testing for client authentication using digital certificates ..."
588 echo
589 if grep -q "Acceptable client certificate CA names" <<<$LOG_RENEG; then
590 echo " SSL/TLS client certificate authentication IS required"
591
592 # Check the list and number of accepted CAs
593 # Save CAs list to file
594 # The LOG_RENEG variable does not have the original break lines to parse
595 # the output properly, so read the file again
596 cat $DIRECTORY/$RENEGLOGFILE | \
597 sed '/Acceptable client certificate CA names/,/^---$/!d' | \
598 grep -v "\-\-\-" | grep -v "Acceptable client certificate CA names" | \
599 grep -v "^$" > $DIRECTORY/$CASFILE
600
601 # Number of CAs
602 CAS=$(cat $DIRECTORY/$CASFILE | wc -l)
603 echo " The target service accepts $CAS Certification Authorities (CAs)"
604
605 elif grep -q "No client certificate CA names sent" <<<$LOG_RENEG; then
606 echo " SSL/TLS client certificate authentication IS NOT required"
607 else
608 echo " UNKNOWN"
609 fi
610
611
612 echo
613 echo "[*] Testing for TLS v1.1 and v1.2 (CVE-2011-3389 vuln. aka BEAST) ..."
614
615 # Test for SSLv3 and TLSv1 support first (from sslscan)
616 echo
617 echo " [-] Testing for SSLv3 and TLSv1 support ..."
618 grep "Accepted SSLv3" $DIRECTORY/$SSLSCANLOGFILE
619 grep "Accepted TLSv1" $DIRECTORY/$SSLSCANLOGFILE
620
621 # Test for RC4 in the list of prefered ciphers (from sslscan previously)
622 echo
623 echo " [+] Testing for RC4 in the prefered cipher(s) list ..."
624 echo "$PREFERED_CIPHERS" | grep "RC4"
625
626 #
627 # Connection details go to stderr (2>) and, in this case, to a variable:
628 #
629 # If $OPENSSLVERSION is updated (version >= 1.0.1-stable) it supports
630 # TLS v1.1 & v1.2, if not, the openssl help is displayed in the command
631 # output.
632 #
633 OUTPUT_TLS1_1=$((echo Q; sleep $DELAY) | \
634 openssl s_client -tls1_1 -connect $HOST:$PORT 2>&1)
635 OUTPUT_TLS1_2=$((echo Q; sleep $DELAY) | \
636 openssl s_client -tls1_2 -connect $HOST:$PORT 2>&1)
637
638 # if "DONE": TLS v1.x supported
639 # else if "wrong version number": TLS v1.x not supported
640 # else if "unknown option": OpenSSL does not support TLS v1.1 or v1.2
641
642 echo
643 echo " [.] Testing for TLS v1.1 support ..."
644
645 if grep -q DONE <<<$OUTPUT_TLS1_1; then
646 echo " TLS v1.1 IS supported"
647 elif grep -q "wrong version number" <<<$OUTPUT_TLS1_1; then
648 echo " TLS v1.1 IS NOT supported"
649 elif grep -q "ssl handshake failure" <<<$OUTPUT_TLS1_1; then
650 echo " TLS v1.1 IS NOT supported (ssl handshake failure)"
651 elif grep -q "unknown option" <<<$OUTPUT_TLS1_1; then
652 echo " The local openssl version does NOT support TLS v1.1"
653 else
654 echo " UNKNOWN"
655 fi
656
657 echo
658 echo " [.] Testing for TLS v1.2 support ..."
659
660 if grep -q DONE <<<$OUTPUT_TLS1_2; then
661 echo " TLS v1.2 IS supported"
662 elif grep -q "wrong version number" <<<$OUTPUT_TLS1_2; then
663 echo " TLS v1.2 IS NOT supported"
664 elif grep -q "ssl handshake failure" <<<$OUTPUT_TLS1_2; then
665 echo " TLS v1.2 IS NOT supported (ssl handshake failure)"
666 elif grep -q "unknown option" <<<$OUTPUT_TLS1_2; then
667 echo " The local openssl version does NOT support TLS v1.2"
668 else
669 echo " UNKNOWN"
670 fi
671
672 echo
673 echo "[*] Testing for HTTPS (SSL/TLS) security headers using HTTP/1.0 ..."
674
675 (echo -e "HEAD / HTTP/1.0\n\n"; sleep $DELAY) | \
676 openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
677 > $DIRECTORY/$HEAD1LOGFILE 2> $DIRECTORY/$HEAD1ERRFILE
678
679 echo
680 echo " [+] Testing for HTTP Strict-Transport-Security (HSTS) header ..."
681 grep -i 'Strict-Transport-Security' $DIRECTORY/$HEAD1LOGFILE
682
683 echo
684 echo " [+] Testing for cookies with the secure flag ..."
685 grep -i 'Set-Cookie' $DIRECTORY/$HEAD1LOGFILE | grep -i 'secure'
686
687 echo
688 echo " [-] Testing for cookies without the secure flag ..."
689 grep -i 'Set-Cookie' $DIRECTORY/$HEAD1LOGFILE | grep -v -i 'secure'
690
691
692 echo
693 echo "[*] Testing for HTTPS (SSL/TLS) security headers using HTTP/1.1 & Host ..."
694
695 (echo -e "HEAD / HTTP/1.1\nHost: $HOST\n\n"; sleep $DELAY) | \
696 openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
697 > $DIRECTORY/$HEADLOGFILE 2> $DIRECTORY/$HEADERRFILE
698
699 echo
700 echo " [+] Testing for HTTP Strict-Transport-Security (HSTS) header ..."
701 grep -i 'Strict-Transport-Security' $DIRECTORY/$HEADLOGFILE
702
703 echo
704 echo " [+] Testing for cookies with the secure flag ..."
705 grep -i 'Set-Cookie' $DIRECTORY/$HEADLOGFILE | grep -i 'secure'
706
707 echo
708 echo " [-] Testing for cookies without the secure flag ..."
709 grep -i 'Set-Cookie' $DIRECTORY/$HEADLOGFILE | grep -v -i 'secure'
710
711
712 echo
713 echo "[*] New files created:"
714 echo " [.] Output directory: $DIRECTORY ..."
715 echo
716
717 # Moved to bottom:
718 #ls -l $DIRECTORY/$SSLSCANLOGFILE
719 #ls -l $DIRECTORY/$RENEGLOGFILE
720 #ls -l $DIRECTORY/$RENEGLEGACYLOGFILE
721 #ls -l $DIRECTORY/$HEAD1LOGFILE
722 #ls -l $DIRECTORY/$HEADLOGFILE
723
724 # Delete all empty error files:
725 # $ find . -size 0 -name '*.err' -delete
726 # This could potentially delete other .err zero-size files not created by
727 # TLSSLed.
728
729
730 if [ ! -s "$DIRECTORY/$SSLSCANERRFILE" ]; then
731 # SSLscan error file is empty
732 rm "$DIRECTORY/$SSLSCANERRFILE"
733 fi
734 if [ ! -s "$DIRECTORY/$RENEGERRFILE" ]; then
735 # Renegotiation error file is empty
736 rm "$DIRECTORY/$RENEGERRFILE"
737 fi
738 if [ ! -s "$DIRECTORY/$RENEGLEGACYERRFILE" ]; then
739 # Legacy renegotiation error file is empty
740 rm "$DIRECTORY/$RENEGLEGACYERRFILE"
741 fi
742 if [ ! -s "$DIRECTORY/$HEAD1ERRFILE" ]; then
743 # Openssl HEAD 1.0 error file is empty
744 rm "$DIRECTORY/$HEAD1ERRFILE"
745 fi
746 if [ ! -s "$DIRECTORY/$HEADERRFILE" ]; then
747 # Openssl HEAD 1.1 error file is empty
748 rm "$DIRECTORY/$HEADERRFILE"
749 fi
750
751 ls $DIRECTORY
752
753 echo
754 echo [*] done
755 echo
756