Difference between revisions of "SSL testing"

From Noah.org
Jump to navigationJump to search
m
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
 
[[Category:Engineering]]
 
[[Category:Engineering]]
 +
__FORCETOC__
  
 
The '''sslscan''' tool is useful. Openssl can also be used.
 
The '''sslscan''' tool is useful. Openssl can also be used.
Line 141: Line 142:
 
</pre>
 
</pre>
  
== SSL Testing Script ==
+
== SSL Testing Scripts ==
 +
 
 +
This checks that the SSL certificate is valid and has no problems.
 +
<pre>
 +
#!/bin/sh
 +
# FIXME: This does not handle star certs (*.example.com).
 +
# if echo "${CERT_SUBJECT_CN}" | grep -q -v "*"; then
 +
######################################################################
 +
#
 +
# This checks SSL certificates for problems.
 +
#
 +
# SYNOPSIS
 +
#
 +
#    check_ssl_cert HOSTNAME
 +
#
 +
# DESCRIPTION
 +
#
 +
#    This checks SSL certificates for problems.
 +
#
 +
# EXAMPLES
 +
#
 +
#    check_ssl_cert hostname.example.com
 +
#
 +
# EXIT STATUS
 +
#
 +
#    This exits with status 0 on success or non-zero on error.
 +
#
 +
# AUTHOR
 +
#
 +
#    Noah Spurrier noah@noah.org
 +
#
 +
# LICENSE
 +
#
 +
#    This license is OSI and FSF approved as GPL-compatible.
 +
#    This license identical to the ISC License and is registered with and
 +
#    approved by the Open Source Initiative. For more information vist:
 +
#        http://opensource.org/licenses/isc-license.txt
 +
#
 +
#    Copyright (c) 2014, Noah Spurrier
 +
#
 +
#    Permission to use, copy, modify, and/or distribute this software for any
 +
#    purpose with or without fee is hereby granted, provided that the above
 +
#    copyright notice and this permission notice appear in all copies.
 +
#
 +
#    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 +
#    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 +
#    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 +
#    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 +
#    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 +
#    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 +
#    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 +
#
 +
#
 +
# VERSION
 +
#
 +
#    Version 1
 +
#
 +
######################################################################
 +
 
 +
SSL_HOSTNAME=$1
 +
 
 +
NOW=$(date "+%s")
 +
CERT_INFO=$(openssl s_client -connect ${SSL_HOSTNAME}:443 </dev/null 2>/dev/null | openssl x509 -text -noout)
 +
CERT_EXPIRATION_DATE=$(echo "${CERT_INFO}" | sed -n 's/.*Not After.*: \(.*\)/\1/p')
 +
CERT_EXPIRATION_SECONDS=$(date '+%s' --date "${CERT_EXPIRATION_DATE}")
 +
CERT_EXPIRATION_DAYS=$(( ( $CERT_EXPIRATION_SECONDS - ${NOW} ) / 60 / 60 / 24))
 +
CERT_ISSUER=$(echo "${CERT_INFO}" | sed -n 's/.*Issuer.*: \(.*\)/\1/p')
 +
CERT_ISSUER_CN=$(echo "${CERT_INFO}" | sed -n 's/.*Issuer.*:.*CN=\(.*\)/\1/p')
 +
CERT_SUBJECT=$(echo "${CERT_INFO}" | sed -n 's/.*Subject.*: \(.*\)/\1/p')
 +
CERT_SUBJECT_CN=$(echo "${CERT_INFO}" | sed -n 's/.*Subject.*:.*CN=\(.*\)/\1/p')
 +
 
 +
if [ "${CERT_SUBJECT_CN}" != "${SSL_HOSTNAME}" ]; then
 +
    # Ignore star certs. They match everything.
 +
    # FIXME I should at least check that the domain names are the same.
 +
    if ! printf '%s' "${CERT_SUBJECT_CN}" | egrep -q '\*'; then
 +
        echo "ERROR: SSL hostname does not match Subject CN in the cert." >&2
 +
        echo "SSL_HOSTNAME: ${SSL_HOSTNAME}" >&2
 +
        echo "CERT_SUBJECT_CN: ${CERT_SUBJECT_CN}" >&2
 +
        exit 1
 +
    fi
 +
fi
 +
 
 +
if [ ${CERT_EXPIRATION_DAYS} -lt 0 ]; then
 +
        echo "ERROR: Certificate has expired." >&2
 +
        echo "CERT_EXPIRATION_DATE: ${CERT_EXPIRATION_DATE}" >&2
 +
        exit 1
 +
fi
 +
#####################################################################
 +
# END
 +
#########1#########2#########3#########4#########5#########6#########7
 +
#j
 +
#    __________________            _-_
 +
#    \___=NCC-1701= __))  ____.---'---`---.____
 +
#                \_ \    \----._________.----'
 +
#                  \ \    / /    `-_-'
 +
#              __,--`-`---'-'-.
 +
#              /}___          )(-
 +
#                  `--.____,-'
 +
#
 +
# vim: set ft=sh sr et ts=4 sw=4 : See help 'modeline'
 +
</pre>
  
 
This show the default cipher used to connect to a remote host and it lists all the client ciphers that the remote host supports.
 
This show the default cipher used to connect to a remote host and it lists all the client ciphers that the remote host supports.
 
 
<pre>
 
<pre>
 
#!/bin/bash
 
#!/bin/bash

Latest revision as of 09:02, 21 July 2017


The sslscan tool is useful. Openssl can also be used.

openssl

This starts an interactive connection with a service sitting behind an SSL/TLS layer. The following command will connect to a remote HTTPS client and establish a connection. After you enter this command it will print some output and then wait for your input. It works more or less like telnet at this point. One of the more interesting lines to look for is the cipher: line, which shows the cipher algorithm that was negotiated and in use.

openssl s_client -showcerts -connect www.example.com:443

You can check if a specific cipher is allowed. The cipher: line should show that the given cipher is in use.

openssl s_client -showcerts -connect www.example.com:443 -cipher RC4

It's a bit like testing an unsecure HTTP server with telnet. Now you can type in manual requests. Remember, you have to enter two line feeds after the GET request. Note that some servers require the host: header, some do not. If you get an HTTP 400 Bad Request then you probably need to add the host: header.

GET / HTTP/1.1
host: www.example.com


A full test session might look like the following. In this example a redirect is returned as a response to GET / HTTP/1.1.

CONNECTED(00000003)
depth=0 C = US, ST = California, O = "Exemplar, Inc.", OU = IT Department, CN = www.example.com, emailAddress = itteam@example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, O = "Exemplar, Inc.", OU = IT Department, CN = www.example.com, emailAddress = itteam@example.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = US, ST = California, O = "Exemplar, Inc.", OU = IT Department, CN = www.example.com, emailAddress = itteam@example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/O=Exemplar, Inc./OU=IT Department/CN=www.example.com/emailAddress=itteam@example.com
   i:/C=US/ST=California/L=San Francisco/O=Exemplar, Inc./OU=IT Department/CN=lb_test_root_CA_1/emailAddress=itteam@example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGRTCCBC2gAwIBAgICAVIwDQYJKoZIhvcNAQEFBQAwgbExCzAJBgNVBAYTAlVT
MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRow
GAYDVQQKExFTcXVhcmVUcmFkZSwgSW5jLjEWMBQGA1UECxMNSVQgRGVwYXJ0bWVu
dDEaMBgGA1UEAxQRbGJfdGVzdF9yb290X0NBXzExJTAjBgkqhkiG9w0BCQEWFml0
dGVhbUBzcXVhcmV0cmFkZS5jb29wHhcNMTIwOTEzMjMzMTIwWhcNMTUwNjEwMjMz
MTIwWjCBpDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGjAYBgNV
BAoMEVNxdWFyZVRyYWRlLCBJbmMuMRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MSUw
IwYDVQQDDBx3d3ctbXVoYW1tYWQuc3F1YXJldHJhZGUuY29tMSUwIwYJKoZIhvcN
AQkBFhZpdHRlYW1Ac3F1YXJldHJhZGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEApFz500fjWy0DfAvqm+H+Ol8sOp4ip12C5PZDh+CRVoAGGYvl
tStfMojTeDSluAr5s49qdypjb3rOgL43NNATMBvNq8tS8XhTdnq+wd4WDTPe5TPL
wE1Q67NVeEfFi33Zjt8VvcuPZSMU/JKL/7z96AxFdOFkYctPC6xGYAqywTZywT8+
Xshd3AILV5b4JqPzTjxSJZxRFDuWjp0gCHX/ATFIuoBoLoAdBISr/RAjn9qWxS+h
3xGH24SHLc5Js1oXu1Vlgnu9SLTYW14QmTYpNHByRUdWIPkrpAITCqjaUWUB7KJO
82aNCw+6LtF3UX6/t9hQmid9XWXHQTu+P/O05wIDAQABo4IBcDCCAWwwCQYDVR0T
BAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoG
CCsGAQUFBwMBMDgGCWCGSAGG+EIBDQQrFilTcXVhcmVUcmFkZSAtIFdhcnJhbnRp
ZXMgdGhhdCBtYWtlIHNlbnNlITAdBgNVHQ4EFgQUR9nBJsa0o9mYhWB54zX98vU7
HR0wgdAGA1UdIwSByDCBxaGBt6SBtDCBsTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAYBgNVBAoTEVNx
dWFyZVRyYWRlLCBJbmMuMRYwFAYDVQQLEw1JVCBEZXBhcnRtZW50MRowGAYDVQQD
FBFsYl90ZXN0X3Jvb3RfQ0FfMTElMCMGCSqGSIb3DQEJARYWaXR0ZWFtQHNxdWFy
ZXRyYWRlLmNvbYIJAOkVdZRJpqb+MA0GCSqGSIb3DQEBBQUAA4ICAQAphQ/SF3EP
8MS7hB1Cm2ntV9HUZD3DdLVIEBpujZhty9GsqPSExRGeU+uDnWYF8j+z7ZbhYHjd
VcVfxszHn9VzX2HyQm9kFs2dry3qGJgILVmlvWcVYpuAdpgnpe6BxwW7gdGOIpwi
OAKytVQLGsWsf/IbVjWnx3JQsb86XRodF3HGQNrb5Xzdez6dD4GaAVWHnZjqaPlS
REHLS5iRz7Q8ZqtPGqqy/GPUEpT2kppJeqUprzcUByZwXFThkPUjF3pGZEdE753W
Jlxvr8x6hapqY3dsFHbWiN6lI6mEGIjAK/8q+O+tihvk+9ZChw8rDMxj8q2C1IGG
mhF8cIl1E0RVp4EVs+vVVlnMB8I+pMcocmR/8LIzPFnG2PyJxSKxu1ql6FSZ6zfx
ZOjLRtvNdr0mBvAJT3zw6IwGnRSNNrqwqEOvfeDTB/nqaL/6B9/krNpGjcdIOwKB
Atnscto7KI7Xdrp4shnsjJaQYf0F4Vl4HaiDXMS2ighESol+jT3v40GD//rLk/a0
tyIVpF2agxe8ePX6dKhJwaKvaWE4+xXJAseZHJoMV3o1sameXIHDdpjtxnx5DxD7
3x9nHI/w95EGG4/leq6MAcOg1zS/r/D9Bs3YocuejIjUZnbbg63Iu1hWoWz/xyGi
U1GG58DEwDzOh+7Ol8huBJUaSfVuT5pQQw==
-----END CERTIFICATE-----
subject=/C=US/ST=California/O=Exemplar, Inc./OU=IT Department/CN=www.example.com/emailAddress=itteam@example.com
issuer=/C=US/ST=California/L=San Francisco/O=Exemplar, Inc./OU=IT Department/CN=lb_test_root_CA_1/emailAddress=itteam@example.com
---
No client certificate CA names sent
---
SSL handshake has read 1913 bytes and written 460 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: DE7F22EA486EFB11C8FAFAB9D191637875D9410273AD51EF2419A982E4A26FC1
    Session-ID-ctx: 
    Master-Key: 83ACFBB0CD615455FB35019C4FC2036AE0649A2238F0CA2F952D782A06A3C90794F5B4CA5FA00F861F88FFDDC1849C0D
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - 82 c8 de 59 85 86 40 c9-be c8 d9 e6 7f 29 2e 91   ...Y..@......)..
    0010 - a4 53 ea 18 bf 5f ff 3e-cd a4 ac 0b 54 fe 12 ef   .S..._.>....T...
    0020 - fd d9 8b 76 e6 69 81 9b-9b ed 79 69 26 d6 e2 70   ...v.i....yi&..p
    0030 - 4f 8b 7d 15 d3 e3 43 6f-d5 60 f5 0b 76 5a 26 48   O.}...Co.`..vZ&H
    0040 - 22 52 8f b3 a6 10 50 92-9d 8d d4 42 2b 8d b2 d7   "R....P....B+...
    0050 - 83 a7 5b 6b fe 7b a2 d8-9a db 14 0e de bf 54 d4   ..[k.{........T.
    0060 - db f8 4e 71 9d 7b 57 1d-7a 50 24 ae f3 16 76 e5   ..Nq.{W.zP$...v.
    0070 - ef 8b 4d 04 60 05 43 d7-74 99 39 68 bc aa d0 d5   ..M.`.C.t.9h....
    0080 - 51 31 1a 96 b0 35 65 8c-ec 92 5f 1a 48 7f 4f 5c   Q1...5e..._.H.O\
    0090 - 65 be 85 9f 36 13 13 84-4b aa df 92 e4 58 31 59   e...6...K....X1Y

    Start Time: 1362183958
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
GET / HTTP/1.1
host: www.example.com

HTTP/1.1 302 Found
Server: nginx
Date: Sat, 02 Mar 2013 00:26:17 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.3.13-1~dotdeb.0
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Sat, 02 Mar 2013 00:26:20 +0000
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
ETag: "1362183980"
Location: http://www.example.com/
Content-Length: 9

302 Found

sslscan

sslscan www.example.com

SSL Testing Scripts

This checks that the SSL certificate is valid and has no problems.

#!/bin/sh
# FIXME: This does not handle star certs (*.example.com).
# if echo "${CERT_SUBJECT_CN}" | grep -q -v "*"; then
######################################################################
#
# This checks SSL certificates for problems.
#
# SYNOPSIS
#
#     check_ssl_cert HOSTNAME
#
# DESCRIPTION
#
#     This checks SSL certificates for problems.
#
# EXAMPLES
#
#     check_ssl_cert hostname.example.com
#
# EXIT STATUS
#
#     This exits with status 0 on success or non-zero on error.
#
# AUTHOR
#
#     Noah Spurrier noah@noah.org
#
# LICENSE
#
#     This license is OSI and FSF approved as GPL-compatible.
#     This license identical to the ISC License and is registered with and
#     approved by the Open Source Initiative. For more information vist:
#         http://opensource.org/licenses/isc-license.txt
#
#     Copyright (c) 2014, Noah Spurrier
#
#     Permission to use, copy, modify, and/or distribute this software for any
#     purpose with or without fee is hereby granted, provided that the above
#     copyright notice and this permission notice appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
#     WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#     MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
#     ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#     ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#
# VERSION
#
#     Version 1
#
######################################################################

SSL_HOSTNAME=$1

NOW=$(date "+%s")
CERT_INFO=$(openssl s_client -connect ${SSL_HOSTNAME}:443 </dev/null 2>/dev/null | openssl x509 -text -noout)
CERT_EXPIRATION_DATE=$(echo "${CERT_INFO}" | sed -n 's/.*Not After.*: \(.*\)/\1/p')
CERT_EXPIRATION_SECONDS=$(date '+%s' --date "${CERT_EXPIRATION_DATE}")
CERT_EXPIRATION_DAYS=$(( ( $CERT_EXPIRATION_SECONDS - ${NOW} ) / 60 / 60 / 24))
CERT_ISSUER=$(echo "${CERT_INFO}" | sed -n 's/.*Issuer.*: \(.*\)/\1/p')
CERT_ISSUER_CN=$(echo "${CERT_INFO}" | sed -n 's/.*Issuer.*:.*CN=\(.*\)/\1/p')
CERT_SUBJECT=$(echo "${CERT_INFO}" | sed -n 's/.*Subject.*: \(.*\)/\1/p')
CERT_SUBJECT_CN=$(echo "${CERT_INFO}" | sed -n 's/.*Subject.*:.*CN=\(.*\)/\1/p')

if [ "${CERT_SUBJECT_CN}" != "${SSL_HOSTNAME}" ]; then
    # Ignore star certs. They match everything.
    # FIXME I should at least check that the domain names are the same.
    if ! printf '%s' "${CERT_SUBJECT_CN}" | egrep -q '\*'; then
        echo "ERROR: SSL hostname does not match Subject CN in the cert." >&2
        echo "SSL_HOSTNAME: ${SSL_HOSTNAME}" >&2
        echo "CERT_SUBJECT_CN: ${CERT_SUBJECT_CN}" >&2
        exit 1
    fi
fi

if [ ${CERT_EXPIRATION_DAYS} -lt 0 ]; then
        echo "ERROR: Certificate has expired." >&2
        echo "CERT_EXPIRATION_DATE: ${CERT_EXPIRATION_DATE}" >&2
        exit 1
fi
#####################################################################
# END
#########1#########2#########3#########4#########5#########6#########7
#j
#     __________________            _-_
#     \___=NCC-1701= __))  ____.---'---`---.____
#                 \_ \     \----._________.----'
#                   \ \     / /    `-_-'
#               __,--`-`---'-'-.
#              /}___           )(-
#                   `--.____,-'
#
# vim: set ft=sh sr et ts=4 sw=4 : See help 'modeline'

This show the default cipher used to connect to a remote host and it lists all the client ciphers that the remote host supports.

#!/bin/bash
######################################################################
#
# This tests the ciphers used by a remote HTTPS (SSL) server.
#
# SYNOPSIS
#
#     test-ciphers [REMOTE_HOST]
#
# DESCRIPTION
#
#     This shows the default cipher that is used with a remote host.
#     It also lists all the client ciphers that the remote host supports.
#
# LICENSE
#
#     This license is OSI and FSF approved as GPL-compatible.
#     This license identical to the ISC License and is registered with and
#     approved by the Open Source Initiative. For more information vist:
#         http://opensource.org/licenses/isc-license.txt
#
#     Copyright (c) 2013, Noah Spurrier <noah@noah.org>
#
#     Permission to use, copy, modify, and/or distribute this software for any
#     purpose with or without fee is hereby granted, provided that the above
#     copyright notice and this permission notice appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
#     WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#     MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
#     ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#     ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
######################################################################

HOST="${1}:443"

echo "== default cipher used =="
DEFAULT_CIPHER=$(echo -n | openssl s_client -connect ${HOST} 2>/dev/null | sed -n -e "s/^.*Cipher[[:space:]]*:[[:space:]]*\(.*\)*/\1/ p")
echo ${DEFAULT_CIPHER}
echo

echo "== check which client ciphers are supported by the remote server. =="
ciphers=$(openssl ciphers 'ALL:eNULL' | sed -e 's/:/ /g')
for cipher in ${ciphers[@]}; do
        response=$(echo -n | openssl s_client -cipher "$cipher" -connect $HOST 2>&1)
        if [[ "$response" =~ "Cipher is " ]] ; then
                echo "1 ${cipher}"
        else
                if [[ "$response" =~ ":error:" ]] ; then
                        whynot=$(echo -n $response | cut -d':' -f6)
                        echo "0 ${cipher} ${whynot}"
                else
                        echo "0 ${cipher} ERROR: ${response}"
                fi
        fi
done