When we transmit sensitive data through the network, we want to feel secure doing it. For that, we use HTTPS traffic, which is HTTP protocol secured via an SSL/TLS. It checks confidentiality and authentication, this last one is done through digital certificates. Let's explore how to test vulnerabilities surrounding HTTP protocol transmission. What are we going to use?
Openssl
As explained in the official site, openssl is a software library for applications that secure communications over computer networks against eavesdropping or need to identify the party at the other end. It's usually included in linux systems, but -in debian based systems- can be installed using sudo apt install openssl
.
nmap
nmap is a security scanner used to discover hosts and services on a computer network. In debian you can install it using sudo apt install nmap
. This is a widely used tool for security, so if you don't have it and you are into cybersec, it's a must-install.
Okay let's do this. What are we going to look for when testing SSL/TLS security? First of all we are going to check if there are weak ciphers or protocols. As explained in OWASP wiki about this topic, anonymous Diffie-Hellmann is a good example of authentication vulnerability, or SSLv2 protocol. With nmap we can scan a host using, for example nmap [target]
; a ping only scan usign nmap -sn [target]
; TCP SYN ping using nmap -PS [target]
. We are foing to use -sV
wich is the standard service scan.
nmap -sV www.example.com
We can use other custom options such as -PN
, --top-ports
and others. Anyway, with this last command we are able to identify the SSL service. Now we can check the certificate information, weak ciphers and SSLv2 each port. We are checking 443,465,993,995 in the example, but this should be customized in each case.
nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995 www.example.com
Finally, openssl is used for testing manually SSL/TLS trying to initiate a renegotiation by client connecting to server with openssl.
openssl s_client -connect www.example.com:443
I created a simple gist for automating all of this using default configuration and customized host. It saves the output in three different files for analysis. Here's the code:
#!/bin/bash
BLUE='\033[0;36m'
RED='\033[0;31m'
NC='\033[0m' # No Color
#based in OWASP wiki
if [[ -z "$1" || -z "$2" ]]; then
echo "./tls.sh host directory"
else
mkdir $2
cd $2
echo -e "${BLUE}Checking for Client-initiated Renegotiation and Secure Renegotiation via openssl...${NC}"
openssl s_client -connect $1:443 > negotiations
if grep -q 'Secure Renegotiation IS NOT supported' "negotiations"; then
echo -e "${RED}Secure Renegotiation IS NOT supported.${NC}"
else
echo -e "${BLUE}Certificate validity ensured.${NC}"
fi
echo -e "${BLUE}Checking for Certificate information, Weak Ciphers and SSLv2 via nmap...${NC}"
nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995 $1 > ciphernmap
if grep -q SSLv2 "ciphernmap"; then
echo -e "${RED}Weak protocol found (SSLv2).${NC}"
else
echo -e "${BLUE}No weak protocol found.${NC}"
fi
echo -e "${BLUE}SSL service recognition via nmap...${NC}"
nmap -sV --reason -PN -n --top-ports 100 $1 > nmapsslservice
echo -e "${BLUE}Done.${NC}"
echo -e "${RED}Don't forget to manually check the files created in case of doubt. Check OWASP wiki for more information.${NC}"
fi
For more information please heck the amazing wiki of OWASP.
Top comments (1)
Hi Paula, great post! I hadn't seen nmap used for this task before.
I think there's one potential problem to consider:
After you grep the
negotiations
file contents you captured withopenssl
to make sure the correct renegotiation string is there your script concludes "Certificate validity ensured."Depending on what you meant here it might not be true and its mostly the fault of
openssl s_client
having really bad defaults :'(Your script uses
openssl s_client -connect $1:443
but this command will return successfully even if the presented certificate chain is invalid. It will also return successfully if the subject common name (CN) and subject alternate names (SAN) in the certificate don't match$1
. One great way to get a sense for this is to try usings_client
with various subdomains of badssl.com/ and seeing what the output looks like for different failure conditions.To have your script give a better sense of whether the certificate is valid I recommend adding
-CApath
or-CAfile
arguments pointing to your system CA trust store and a-verify_hostname $1
argument to forces_client
to check the certificate hostname matches expected. It may also be beneficial to check the "Verify return code" output froms_client
.Hope that helps!