I'm creating a bash script that loops through a collection of IP-addresses and scans them with the Nmap ssl-enum-ciphers script. Everything works just fine except for one feature.
I need to find a way how I can link the scanned port with the TLS versions & ciphers found.
The Nmap data looks like this ->
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.2
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A
| TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - F
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
| TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 4096) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| Anonymous key exchange, score capped at F
| Key exchange (dh 1024) of lower strength than certificate key
| Key exchange (secp256r1) of lower strength than certificate key
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A
| TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_128_CBC_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_128_GCM_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_GCM_SHA384 (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - F
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
| TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 4096) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| Anonymous key exchange, score capped at F
| Key exchange (dh 1024) of lower strength than certificate key
| Key exchange (secp256r1) of lower strength than certificate key
|_ least strength: F
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
80/tcp open http nginx
443/tcp open ssl/http nginx
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| compressors:
| NULL
| cipher preference: server
|_ least strength: A
I need to format this data in something like this ->
21/tcp open ftp vsftpd 3.0.2
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A
| TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - F
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
| TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 4096) - A
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A
| TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_128_CBC_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_128_GCM_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_CBC_SHA256 (dh 1024) - F
| TLS_DH_anon_WITH_AES_256_GCM_SHA384 (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - F
| TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - F
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
| TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 4096) - A
443/tcp open ssl/http nginx
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
I've managed to create a awk script that collects all the open ports with status and versions running ->
#!/usr/bin/awk -f
/open/ {
port = $1
state = $2
service = $3
}
/ssl-enum-ciphers/ {
print port, state, service
}
outputs ->
21/tcp open ftp
443/tcp open ssl/http
As you can see the only things that are missing are the found TLS versions + ciphers. Can someone give me a push in the right direction?
Thanks in advance,
Sleek
Using a reduced dataset:
$ cat nmap.dat
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.2
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| Anonymous key exchange, score capped at F
| Key exchange (dh 1024) of lower strength than certificate key
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| Anonymous key exchange, score capped at F
| Key exchange (dh 1024) of lower strength than certificate key
|_ least strength: F
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
80/tcp open http nginx
443/tcp open ssl/http nginx
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| compressors:
| NULL
| cipher preference: server
|_ least strength: A
General approach is to use a flag (printme
) to determine when to print a line; comparisons will determine when to turn on (1
) or off (0
) the flag.
One awk
idea:
awk '
/open/ { port = $1
state = $2
service = $3
}
/ssl-enum-ciphers/ { print port, state, service
printme=1
}
/compressors:/ { printme=0 }
/cipher preference:/ { printme=0 }
/warnings:/ { printme=0 }
/TLS.*:/ { printme=1 }
printme
' nmap.dat
NOTES:
ssl-enum-ciphers
) of interest are of the form TLS*:
; otherwise OP can add more patterns for enabling the print flag (printme=1
)/compressors:/
should be sufficient to clear the print flag (printme=0
); I'm not familiar with all possible nmap
output formats so I've gone ahead and added the /cipher preference:/
and /warnings:/
tests, too; these last two tests can be removed if OP determines /compressors:/
is sufficient for clearing the print flagThis generates:
21/tcp open ftp
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
443/tcp open ssl/http
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A