diff --git a/cipherscan b/cipherscan index 24be563..c5b9714 100755 --- a/cipherscan +++ b/cipherscan @@ -195,6 +195,8 @@ declare -A sigalgs_fallback # array with preferred sigalgs for aRSA and aECDSA ciphers declare -a sigalgs_preferred_rsa declare -a sigalgs_preferred_ecdsa +renegotiation="" +compression="" # because running external commands like sleep incurs a fork penalty, we # first check if it is necessary @@ -210,12 +212,15 @@ usage() { [-v|--verbose] [-o|--openssl file] [openssl s_client args] usage: $0 -h|--help -$0 attempts to connect to a target site using all the ciphersuites it knows. -Julien Vehent [:ulfr] - https://github.com/jvehent/cipherscan +$0 attempts to connect to a target site using all the ciphersuites known +to OpenSSL it is using. + +Julien Vehent [:ulfr] and others (see README.md) +https://github.com/jvehent/cipherscan Port defaults to 443 -example: $ $0 www.google.com:443 +example: $ $0 www.google.com Use one of the options below: @@ -239,9 +244,20 @@ Use one of the options below: -v | --verbose Increase verbosity. The rest of the arguments will be interpreted as openssl s_client argument. -This enables checking smtp/imap/pop3/ftp/xmpp via -starttls -EXAMPLES: $0 -starttls xmpp jabber.ccc.de:5222 +Some useful OpenSSL options: +-starttls [smtp|imap|pop3|ftp|xmpp] Enable support and testing of the protocols + that require turning TLS after initial protocol specific + hello +-servername name Request SNI support for connections +-verify_hostname name Request host name verification in connection + (req. OpenSSL 1.0.2) +-verify_ip ip Request host name verification for an IP address, usually + not specified in certificates (req. OpenSSL 1.0.2) + +EXAMPLES: +$0 -starttls xmpp jabber.ccc.de:5222 +$0 -servername youtube.com youtube.com:443 " } @@ -359,6 +375,8 @@ parse_openssl_output() { current_pubkey=0 current_trusted="False" current_sigalg="None" + current_renegotiation="False" + current_compression="" certs_found=0 current_raw_certificates=() @@ -388,6 +406,19 @@ parse_openssl_output() { continue fi + # renegotiation support + if [[ $line =~ Secure\ Renegotiation\ IS\ supported ]]; then + current_renegotiation="secure" + fi + if [[ $line =~ Secure\ Renegotiation\ IS\ NOT\ supported ]]; then + current_renegotiation="insecure" + fi + + # compression settings + if [[ $line =~ Compression:\ (.*) ]]; then + current_compression="${BASH_REMATCH[1]}" + fi + # extract the signing algorithm used in TLSv1.2 ephemeral kex if [[ $line =~ Peer\ signing\ digest ]]; then local match=($line) @@ -840,6 +871,26 @@ display_results_in_terminal() { fi echo -e "Curves ordering: $curvesordering - fallback: $fallback_supported" fi + if [[ $renegotiation ]]; then + if [[ $renegotiation == "secure" ]]; then + echo -e "Server ${c_green}supports${c_reset} secure renegotiation" + else + echo -e "Server ${c_red}DOESN'T${c_reset} support secure renegotiation" + fi + else + echo "Renegotiation test error" + fi + if [[ $compression ]]; then + if [[ $compression != "NONE" ]]; then + color="${c_red}" + else + color="${c_green}" + fi + echo -e "Server supported compression methods:" \ + "${color}$compression${c_reset}" + else + echo -e "Supported compression methods ${c_red}test error${c_reset}" + fi if [[ $TEST_KEX_SIGALG == "True" ]]; then echo @@ -948,6 +999,18 @@ display_results_in_json() { echo -n ",\"curves_fallback\":\"$fallback_supported\"" fi + if [[ $renegotiation ]]; then + echo -n ",\"renegotiation\":\"$renegotiation\"" + else + echo -n ",\"renegotiation\":\"False\"" + fi + + if [[ $compression ]]; then + echo -n ",\"compression\":\"$compression\"" + else + echo -n ",\"compression\":\"False\"" + fi + if [[ $TEST_KEX_SIGALG == "True" ]]; then echo -n ',"sigalgs":{' echo -n "\"ordering\":\"${sigalgs_ordering}\"," @@ -1260,6 +1323,16 @@ test_tls_tolerance() { tls_tolerance[$version]="False" else tls_tolerance[$version]="True $current_protocol $current_cipher $current_trusted" + + # collect renegotiation info + if [[ $current_renegotiation != "False" ]]; then + renegotiation="$current_renegotiation" + fi + + # collect compression info + if [[ $version == "big-TLSv1.2" || -z $compression ]]; then + compression="$current_compression" + fi fi done diff --git a/top1m/parse_results.py b/top1m/parse_results.py index bcdebbe..6350bb4 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -138,6 +138,8 @@ fallback_ids[' '] = i pfssigalgfallback = defaultdict(int) pfssigalgs = defaultdict(int) pfssigalgsordering = defaultdict(int) +compression = defaultdict(int) +renegotiation = defaultdict(int) dsarsastack = 0 total = 0 for r,d,flist in os.walk(path): @@ -161,6 +163,8 @@ for r,d,flist in os.walk(path): temppfssigalgordering = {} temppfssigalgfallback = {} temppfssigalgs = {} + tempcompression = {} + temprenegotiation = {} ciphertypes = 0 AESGCM = False AESCBC = False @@ -324,6 +328,13 @@ for r,d,flist in os.walk(path): except KeyError: pass + """ get some extra data about server """ + if 'renegotiation' in results: + temprenegotiation[results['renegotiation']] = 1 + + if 'compression' in results: + tempcompression[results['compression']] = 1 + """ loop over list of ciphers """ for entry in results['ciphersuite']: @@ -538,6 +549,12 @@ for r,d,flist in os.walk(path): for s in tempsigstats: sigalg[s] += 1 + for s in temprenegotiation: + renegotiation[s] += 1 + + for s in tempcompression: + compression[s] += 1 + if len(tempticketstats) == 1: for s in tempticketstats: tickethint[s + " only"] += 1 @@ -785,6 +802,18 @@ for stat in sorted(pfssigalgfallback): percent = round(pfssigalgfallback[stat] / total * 100, 4) sys.stdout.write(stat.ljust(30) + " " + str(pfssigalgfallback[stat]).ljust(10) + str(percent).ljust(9) + "\n") +print("\nRenegotiation Count Percent ") +print("-------------------------+---------+--------") +for stat in natural_sort(renegotiation): + percent = round(renegotiation[stat] / total * 100, 4) + sys.stdout.write(stat.ljust(25) + " " + str(renegotiation[stat]).ljust(10) + str(percent).ljust(9) + "\n") + +print("\nCompression Count Percent ") +print("-------------------------+---------+--------") +for stat in natural_sort(compression): + percent = round(compression[stat] / total * 100, 4) + sys.stdout.write(stat.ljust(25) + " " + str(compression[stat]).ljust(10) + str(percent).ljust(9) + "\n") + print("\nTLS session ticket hint Count Percent ") print("-------------------------+---------+--------") for stat in natural_sort(tickethint):