From 28555b03f0f6c5438c83d1cd3f6cbb8361c778e3 Mon Sep 17 00:00:00 2001 From: Richard Soderberg Date: Sat, 5 Sep 2015 01:01:19 -0700 Subject: [PATCH 1/3] Refuse to proceed if the final argument starts with a hyphen. This detects and prevents a specific category of user error, where an incomplete cipherscan command line ending in an OpenSSL -option results in cipherscan attempting to scan the target '-option:443'. --- cipherscan | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cipherscan b/cipherscan index 21d52c6..361f4fa 100755 --- a/cipherscan +++ b/cipherscan @@ -1359,6 +1359,14 @@ if [[ "$HOST" = "$PORT" ]]; then PORT=443 fi +# Refuse to proceed if the hostname starts with a hyphen, since hostnames can't +# begin with a hyphen and this likely means we accidentally parsed an option as +# a hostname. +if [[ $HOST =~ ^- ]]; then + echo "The final argument '$TEMPTARGET' begins with a hyphen '-', which is not a valid HOST[:PORT]." 1>&2 + exit 1 +fi + debug "host: $HOST" debug "Port: $PORT" From d81ee1c801bd70bdb6c6e515a45a6bb589a0a4a5 Mon Sep 17 00:00:00 2001 From: Richard Soderberg Date: Sat, 5 Sep 2015 01:06:09 -0700 Subject: [PATCH 2/3] Refuse to proceed if no HOST[:PORT] is provided after the options. Prior to this patch, if the user fails to provide a host:port after specifying cipherscan options, the script runs sed on an empty variable (failing with a syntax error) and then asttempts to cipherscan the target ':443'. This adds a simple test to ensure that a target was actually provided. --- cipherscan | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cipherscan b/cipherscan index 361f4fa..1553ed1 100755 --- a/cipherscan +++ b/cipherscan @@ -1350,6 +1350,11 @@ done # echo parameters left: $@ +if (( $# < 1 )); then + echo "The final argument must be a valid HOST[:PORT], but none was provided." 1>&2 + exit 1 +fi + TEMPTARGET=$(sed -e 's/^.* //'<<<"${@}") HOST=$(sed -e 's/:.*//'<<<"${TEMPTARGET}") PORT=$(sed -e 's/.*://'<<<"${TEMPTARGET}") From 097bd0c43bbf16f101f0ee4201cc6fb223f81328 Mon Sep 17 00:00:00 2001 From: Richard Soderberg Date: Sat, 5 Sep 2015 01:36:50 -0700 Subject: [PATCH 3/3] Rewrite HOST[:PORT] extraction routine (less sed, more validation). The HOST[:PORT] extraction routine was written using several calls to sed and a bunch of regex post-processing of the bash $@ array. This replaces that with bash-native array commands, copying $@ into a $PARAMS array, removing the last element into $TARGET, and then passing the remainder to openssl s_client. This adds validation of the TARGET to ensure that it matches what we expect for a HOST[:PORT]; if a ':' is present, it must be preceded by a hostname and followed by a port number, otherwise :443 is appended. The check to ensure that HOST is not an -option is merged into this as well, since we already test for : at the beginning of the HOST (indicating that only a port was provided). Additionally, this now defends against an empty string "" being passed as the final option, which could occur if a script calling cipherscan goes awry and starts passing empty values as the target. top1m may see a slight speed improvement from this commit, as 4 calls to sed are replaced with native bash functions. Fixes one "SC2086: Double quote to prevent globbing and word splitting.": In cipherscan line 1402: SCLIENTARGS=$(sed -e s,${TEMPTARGET},,<<<"${@}") ^-- SC2086: Double quote to prevent globbing and word splitting. --- cipherscan | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/cipherscan b/cipherscan index 1553ed1..0b9c836 100755 --- a/cipherscan +++ b/cipherscan @@ -1355,27 +1355,21 @@ if (( $# < 1 )); then exit 1 fi -TEMPTARGET=$(sed -e 's/^.* //'<<<"${@}") -HOST=$(sed -e 's/:.*//'<<<"${TEMPTARGET}") -PORT=$(sed -e 's/.*://'<<<"${TEMPTARGET}") - -# Default to https if no port given -if [[ "$HOST" = "$PORT" ]]; then - PORT=443 -fi +PARAMS=("$@") +TARGET=${PARAMS[-1]} +unset PARAMS[-1] # Refuse to proceed if the hostname starts with a hyphen, since hostnames can't # begin with a hyphen and this likely means we accidentally parsed an option as # a hostname. -if [[ $HOST =~ ^- ]]; then - echo "The final argument '$TEMPTARGET' begins with a hyphen '-', which is not a valid HOST[:PORT]." 1>&2 +if [[ -z $TARGET || $TARGET =~ ^[-:] || $TARGET =~ :.*[^0-9] ]]; then + echo "The final argument '$TARGET' is not a valid HOST[:PORT]." 1>&2 exit 1 fi +if ! [[ $TARGET =~ : ]]; then + TARGET="${TARGET}:443" +fi -debug "host: $HOST" -debug "Port: $PORT" - -TARGET=$HOST:$PORT debug "target: $TARGET" # test our openssl is usable @@ -1399,7 +1393,7 @@ if [[ $VERBOSE != 0 ]] ; then $OPENSSLBIN ciphers ALL 2>/dev/null fi -SCLIENTARGS=$(sed -e s,${TEMPTARGET},,<<<"${@}") +SCLIENTARGS="${PARAMS[*]}" debug "sclientargs: $SCLIENTARGS"