Tag: tip

Tip: Enumerating supported SSL ciphers

In a world where Nmap’s NSE scripts, like ssl-enum-ciphers exist, why would anyone want to go to the hassle of enumerating supported SSL ciphers by hand ?  Well, there are a few reasons, some of which are practical while others are more academic.

When Nmap is not installed

Especially if you’re a pen-tester, there may be times when you’ve established a beachhead on a target network but there is no Nmap installed.  Can you try forwarding an Nmap scan from your local system ? sure… but what if that’s not possible ?

When Nmap is old

You’ve found a great bastion host to serve as your pen-test beachhead.  Nmap is actually installed, but the version of Nmap is so old it doesn’t support NSE scripts.

When Nmap is prohibited

Some organizations may have application whitelisting agents running that prevent the execution of unauthorized applications.  Nmap isn’t an application that often makes it onto application whitelists.

When you want to understand it

The best way to learn how painful long-division is is to do long-division.  Sure, it’s a bit painful, but you get a better understanding of how division works, and it sure helps you appreciate your calculator.

Using only Bash and OpenSSL you can achieve the same results:

#!/usr/bin/bash

if [ ! -z $1 ]; then
  SERVER=$1
else
 echo Usage: ./scan-ciphers.sh HOSTNAME:PORT
 exit
fi
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

 

Tip: Harvesting SSL/TLS Certificate Info

From time to time it may be useful to harvest a large number of SSL/TLS certificates for the information encoded therein.  Some situations where this may be useful include;

  • Attributing public cloud IP addresses to a specific service or company.
  • Searching for self-signed certificates.
  • Searching for expired certificates.
  • Searching for certificates using weak signing algorithms.
  • etc.

While this information can be obtained manually, the real value of this technique pays off when you are dealing with hundreds or thousands of IP addresses.

To start off, create a list of IP addresses (ip.list) which are hosting an SSL/TLS-enabled service.  In the example below, we are looking at a list of SSL/TLS enabled web servers running on TCP/443.

$ cat ip.list
216.58.217.78
54.239.17.7
54.239.17.6
54.239.25.192
54.239.25.200
54.239.25.208
54.239.26.128

$ for i in `cat ip.list`; do echo -n "$i, "; echo "GET /" | \ 
openssl s_client -connect $i:443 2>&1 | \
awk '/BEGIN CERTIFICATE/{flag=1}/END CERTIFICATE/{print;flag=0}flag' | \
openssl x509 -noout -text | \
grep "Subject:" | \
sed -e "s/^.*CN=\(.*\)/\1/"; done
216.58.217.78, *.google.com
54.239.17.7, www.amazon.com
54.239.17.6, www.amazon.com
54.239.25.192, www.amazon.com
54.239.25.200, www.amazon.com
54.239.25.208, www.amazon.com
54.239.26.128, www.amazon.com

While there are certainly more elegant ways to obtain this information, this is a quick and dirty method of harvesting the CN’s recorded in an SSL/TLS certificate.  With some simple modifications to this technique it can harvest other parts of the certificates like SAN’s, expiration dates, algorithms, etc.