#!/usr/bin/env bash ################################################################################## # # Copyright (C) 2015-2018 Craig Miller # # See the file "LICENSE" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # Distributed under GPLv2 License # ################################################################################## # # Script asks for password, then runs SHA1 hash, and checks it against haveibeenpwned # Password never leaves the machine, only first 5 digits of SHA1 hash are sent to haveibeenpwned # # by Craig Miller 20 Dec 2021 # # Assumptions: # # function usage { echo " $0 - check haveibeenpwned password database " echo " for more info see:" echo " https://haveibeenpwned.com/API/v3#SearchingPwnedPasswordsByRange" echo " " echo " e.g. $0 -p <password> " echo " -d debug" echo " " echo " By Craig Miller - Version: $VERSION" exit 1 } VERSION=0.96 # initialize some vars HAVEIBEENPWNED_API="https://api.pwnedpasswords.com/range/" GREP_OPT="colour" DEBUG=0 PASSWORD="" while getopts "?hdp:s" options; do case $options in p ) PASSWORD=$OPTARG numopts=$(( numopts + 2));; d ) DEBUG=1 (( numopts++));; h ) usage;; \? ) usage # show usage with flag and no value exit 1;; * ) usage # show usage with unknown flag exit 1;; esac done # remove the options as cli arguments shift $numopts # check that there are no arguments left to process if [ $# -ne 0 ]; then usage exit 1 fi # detect if sha1 is prsent cmd_detect=$(which sha1sum 2>/dev/null) if [ $? -ne 0 ]; then # Oops, better stop echo "sha1sum NOT FOUND, please install, exiting..." usage exit 1 fi sha1_cmd=$cmd_detect # detect if curl is prsent cmd_detect=$(which curl 2>/dev/null) if [ $? -ne 0 ]; then # Oops, better stop echo "curl NOT FOUND, please install, exiting..." usage exit 1 fi curl_cmd=$cmd_detect # detect if grep support --colour cmd_detect=$(grep --colour test /dev/null 2> /dev/null) if [ $? -gt 1 ]; then echo "Note:grep does not support colour" GREP_OPT="" fi # if password not on command line, then ask for it if [ "$PASSWORD" == "" ]; then echo -n "Enter password: " stty -echo read -r PASSWORD echo stty echo fi # grab password test_pass=$PASSWORD # create sha1 of Password test_sha1=$(echo -n "$test_pass" | $sha1_cmd) # trim tail spaces test_sha1=${test_sha1:0:40} # make upper case test_sha1=${test_sha1^^} if (( DEBUG == 1 )); then echo "SHA1=$test_sha1" fi test_sha1_tail=${test_sha1:5:35} #echo "tail:$test_sha1_tail|" # extract first 5 chars test_sha5=${test_sha1:0:5} if (( DEBUG == 1 )); then echo "SHA5=$test_sha5" fi # submit to API result=$($curl_cmd $HAVEIBEENPWNED_API"$test_sha5" 2> /dev/null) #if (( DEBUG == 1 )); then # echo "API Result=$result" #fi if (( DEBUG == 1 )); then sleep 1 echo "password md5 hash:" echo "$test_sha1_tail" echo " look for similarities:" echo "$(echo "$result" | tr '\r' '\n' | grep "^${test_sha1_tail:0:2}")" echo "------" #exit fi # check our SHA1 to API result check_sha_result=$(echo "$result" | grep "$test_sha1_tail") if [ $? -ne 0 ]; then echo "Password appears safe, unknown to HAVEIBEENPWNED_API" else if [ "GREP_OPT" == "colour" ]; then echo "Password matches HAVEIBEENPWNED_API" | grep --colour ".*" else echo "Password matches HAVEIBEENPWNED_API" fi check_sha_result=$(echo "$result" | tr '\r' '\n' | grep "$test_sha1_tail" ) result_hash=$(echo "$check_sha_result" | cut -d ':' -f 1 ) result_amt=$(echo "$check_sha_result" | cut -d ':' -f 2 ) echo "SHA1 Match: $test_sha5$result_hash, $result_amt times" fi echo "pau"