diff --git a/searchsploit b/searchsploit index f762d4fd8..eec8a0c83 100755 --- a/searchsploit +++ b/searchsploit @@ -1,6 +1,6 @@ #!/bin/bash # Name: SearchSploit - Exploit-DB's CLI search tool -# Version: 4.1.0 (2020-04-27) +# Version: 4.1.0 (2020-04-30) # Written by: Offensive Security, Unix-Ninja, and g0tmi1k # Homepage: https://github.com/offensive-security/exploitdb # Manual: https://www.exploit-db.com/searchsploit @@ -41,8 +41,10 @@ CASE_TAG_GREP="-i" CASE_TAG_FGREP="tolower" AWK_SEARCH="" FUZZY_SEARCH="" +VERSION= COLOUR_OFF_GREP= COLOUR_ON_GREP= +REGEX_GREP= ## Check if our grep supports --color @@ -51,6 +53,13 @@ if grep --help 2>&1 | grep "[-]-color" >/dev/null 2>&1 ; then COLOUR_ON_GREP="--color=always" fi +## Check if our grep supports ---perl-regexp +if grep --help 2>&1 | grep "[-]-perl-regexp" >/dev/null 2>&1 ; then + REGEX_GREP="-P" +else + REGEX_GREP="-E" +fi + ## Set LANG variable to avoid illegal byte sequence errors LANG=C @@ -66,8 +75,10 @@ function usage() { echo " ${progname} afd windows local" echo " ${progname} -t oracle windows" echo " ${progname} -p 39446" - echo " ${progname} linux kernel 3.2 -s --exclude=\"(PoC)|/dos/\"" + echo " ${progname} linux kernel 3.2 --exclude=\"(PoC)|/dos/\"" + echo " ${progname} -s Apache Struts 2.0.0" echo " ${progname} linux reverse password" + echo " ${progname} -j 55555 | json_pp" echo "" echo " For more examples, see the manual: https://www.exploit-db.com/searchsploit" echo "" @@ -430,24 +441,9 @@ function buildterms() { ## Some regex to try and detect version ## Basic: major.minor[.build][.revision] // major.minor[.maintenance][.build] -- example: 1.2.3.4) ## Plus alphanumeric (e.g. alpha, beta): 1a, 2.2b, 3.3-c, 4.4-rc4, 5.5-r - if echo "${tag_in}" | grep -Eq "^(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\w*))$"; then - ## 1.2.3-4abc - VERSION=$( echo "${tag_in}" | grep -Eo "^(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\w*))$" ) - [[ -n "${VERSION}" ]] && [[ "${VERBOSE}" -eq 1 ]] \ - && echo "[i] Version ID: ${VERSION}" - - ## 1.2.3-4 - CLEANVERSION=$( echo "${tag_in}" | grep -Eo "^(\d*\.?)(\d*\.?)(\d*\.?)((\.|\-)?(\d+))" ) - if [[ -n "${CLEANVERSION}" ]] && [[ "${CLEANVERSION}" != "${VERSION}" ]]; then - VERSION="${CLEANVERSION}" - - [[ "${VERBOSE}" -eq 1 ]] \ - && echo "[i] Clean ID: ${VERSION}" - fi - else + if ! echo "${tag_in}" | grep ${REGEX_GREP} -q "^(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\w*))$"; then FUZZY_SEARCH="${FUZZY_SEARCH} | grep ${COLOUR_OFF_GREP} -F ${CASE_TAG_GREP} \"${tag_in}\"" fi - ## Search just the title, NOT the path ("-t"/"-e") else ## If there is already a value, prepend text to get ready @@ -457,7 +453,7 @@ function buildterms() { ## Escape any slashes tag_in="$( echo ${tag_in} | sed 's_/_\\/_g' )" - ## Case sensitive ("-c")? + ## Case sensitive ("-c") if [[ "${SCASE}" -eq 1 ]]; then AWK_SEARCH="${AWK_SEARCH}${tag_in}" else @@ -520,7 +516,8 @@ function findresults() { ## Dynamically set column widths to the current screen size [[ "${WEBLINK}" -eq 1 ]] \ && COL2=45 \ - || COL2=$(( ${#path_in} + 21 )) + || COL2=$(( 34 )) ## Max length + 2 ~ $ find . ! -path '*/.*' -type f | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2- | tail -n 1 + #|| COL2=$(( ${#path_in} + 21 )) COL1=$(( $( tput cols ) - COL2 - 1 )) @@ -538,70 +535,60 @@ function findresults() { && SEARCH="${SEARCH} | grep -vEi '${EXCLUDE}'" - ## Did we manage to detect the version? - if [[ "${FUZZY}" -eq 1 ]] && [[ -z "${VERSION}" ]] && [[ "${VERBOSE}" -eq 1 ]]; then - echo "[i] Unable to detect version in terms: ${TAGS}" 1>&2 - echo "[i] Disabling '${progname} -f'" 1>&2 - elif [[ "${FUZZY}" -eq 1 ]]; then - ## Check to see if sort is supported - echo | sort -V 2>/dev/null >/dev/null - if [ $? -ne "0" ]; then - echo "[-] 'sort' doesn't support '-V'" 1>&2 - echo "[-] Disabling '${progname} -f'" 1>&2 - else - ## SubShells - http://mywiki.wooledge.org/BashFAQ/024 - while IFS= read -r TITLE; do - while IFS= read -r RANGE; do - ## Read in input and trim - MIN=$( echo "${RANGE}" | awk -F '<' '{print $1}' | xargs ) - MAX=$( echo "${RANGE}" | awk -F '<' '{print $2}' | xargs ) + ## Are we doing a fuzzy search & did we manage to detect the version + if [[ "${FUZZY}" -eq 1 ]] && [[ -n "${VERSION}" ]]; then + ## SubShells - http://mywiki.wooledge.org/BashFAQ/024 + while IFS= read -r TITLE; do + while IFS= read -r RANGE; do + ## Read in input and trim + MIN=$( echo "${RANGE}" | awk -F '<' '{print $1}' | xargs ) + MAX=$( echo "${RANGE}" | awk -F '<' '{print $2}' | xargs ) - ## As its optional to put it, set a value if blank - [ -z "${MIN}" ] \ - && MIN=0 + ## As its optional to put it, set a value if blank + [ -z "${MIN}" ] \ + && MIN=0 - RESULT="$( printf '%s\n' "${MIN}" "${VERSION}" "${MAX}" | sort -V )" - ## Sub if sort -v isn't working? if (( $( echo "${MIN} <= ${VERSION}" | bc -l ) )) && (( $( echo "${MAX} >= ${VERSION}" | bc -l ) )) ; then - ## ...else there is dpkg (if Debian) - if [[ "$( echo "${RESULT}" | head -n 1 )" == "${MIN}" ]] \ - && [[ "$( echo "${RESULT}" | tail -n 1 )" == "${MAX}" ]]; then - [ -n "${ID}" ] \ - && ID="${ID}|" - ID="${ID}$( echo $TITLE | awk -F ',' '{print $1}' )" - ## Found one, no point going on - break - fi - done < <( - echo "${TITLE}" \ - | grep -Eo "((\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\d|x)*)(\s*))?((<|>)=?)(\s*)(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\d|x)*)" \ - | sed 's_=__; s_>_<_' - ) - ## Do the same search (just without the version) & loop around all the exploit titles (as thats where the versions are) - ## Two main "parts" - ## (a.b.c.d )(<= e.f.g.h) - ## This can be broken down more: - ## Group 1 == a & e == major = [0-9] - ## Group 2 == b & f == minor = .[0-9] (optional) - ## Group 3 == c & g == build/maintenance = .[0-9] (optional) - ## Group 4a == d & h == revision/build = . OR - (optional) - ## Group 4b == = x OR [0-9] (optional) - ## So it really is more like ~ (a)(.b)(.c)(.d)( )(<=)( )(e)(.f)(.g)(.h) - ## NOTE: ..."x" is used as a wild card in titles - ## Quick regex recap - ## Digit == \d - ## Space == \s - ## Group == ( ) - ## OR == | - ## 1 or more == + - ## 0 or more == * - ## 0 or 1 == ? - ## Should support: - ## Exploit < 1 / <= 1.2 / < 1.2.3.4 / < 1.2.3.x - ## Exploit 1.0 < 1.2.3.4 + RESULT="$( printf '%s\n' "${MIN}" "${VERSION}" "${MAX}" | sort -V )" + ## Sub if sort -v isn't working? if (( $( echo "${MIN} <= ${VERSION}" | bc -l ) )) && (( $( echo "${MAX} >= ${VERSION}" | bc -l ) )) ; then + ## ...else there is dpkg (if Debian) + if [[ "$( echo "${RESULT}" | head -n 1 )" == "${MIN}" ]] \ + && [[ "$( echo "${RESULT}" | tail -n 1 )" == "${MAX}" ]]; then + [ -n "${ID}" ] \ + && ID="${ID}|" + ID="${ID}$( echo $TITLE | awk -F ',' '{print $1}' )" + ## Found one, no point going on + break + fi done < <( - eval "${FUZZY_SEARCH}" - ) - fi + echo "${TITLE}" \ + | grep ${REGEX_GREP} -o "((\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\d|x)*)(\s*))?((<|>)=?)(\s*)(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\d|x)*)" \ + | sed 's_=__; s_>_<_' + ) + ## Do the same search (just without the version) & loop around all the exploit titles (as thats where the versions are) + ## Two main "parts" + ## (a.b.c.d )(<= e.f.g.h) + ## This can be broken down more: + ## Group 1 == a & e == major = [0-9] + ## Group 2 == b & f == minor = .[0-9] (optional) + ## Group 3 == c & g == build/maintenance = .[0-9] (optional) + ## Group 4a == d & h == revision/build = . OR - (optional) + ## Group 4b == = x OR [0-9] (optional) + ## So it really is more like ~ (a)(.b)(.c)(.d)( )(<=)( )(e)(.f)(.g)(.h) + ## NOTE: ..."x" is used as a wild card in titles + ## Quick regex recap + ## Digit == \d + ## Space == \s + ## Group == ( ) + ## OR == | + ## 1 or more == + + ## 0 or more == * + ## 0 or 1 == ? + ## Should support: + ## Exploit < 1 / <= 1.2 / < 1.2.3.4 / < 1.2.3.x + ## Exploit 1.0 < 1.2.3.4 + done < <( + eval "${FUZZY_SEARCH}" + ) fi @@ -649,9 +636,9 @@ function findresults() { ## Default view else OUTPUT="$( echo "${OUTPUT}" \ + | sed 's_,exploits/_,_; s_,shellcodes/_,_; s_,papers/_,_' \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %.'${FORMAT_COL2}'s\n", $3, $2 }' \ | sort -f )" - #| sed 's_,exploits/_,_; s_,shellcodes/_,_; s_,papers/_,_' \ fi @@ -683,8 +670,9 @@ function printresults() { else echo "| Path" #echo " > Results (0)" - printf "%-${COL1}s " - echo "| (${path_in}/)" + # + #printf "%-${COL1}s " + #echo "| (${path_in}/)" fi drawline fi @@ -885,7 +873,7 @@ fi ## Print the full path. If pbcopy/xclip is available then copy to the clipboard if [[ "${GETPATH}" -eq 1 ]]; then - for exploit in $( echo ${TAGS} ); do + for exploit in ${TAGS}; do ## Get EDB-ID from input edbdb="$( echo ${exploit} | rev | cut -d '/' -f1 | rev | cut -d'-' -f1 | cut -d'.' -f1 | tr -dc '0-9' )" @@ -987,23 +975,66 @@ fi ## Are we are doing an exact match ("-e")? If so, do NOT check folder path (Implies "-t"). -if [[ "${EXACT}" -eq 1 ]]; then - FILEPATH=0 -fi +[[ "${EXACT}" -eq 1 ]] \ + && FILEPATH=0 -## Case sensitive? -if [[ "${SCASE}" -eq 1 ]]; then - ## Remove the default flags - CASE_TAG_GREP="" - CASE_TAG_FGREP="" -fi +## Case sensitive ("-c"), remove the default flags +[[ "${SCASE}" -eq 1 ]] \ + && CASE_TAG_GREP="" \ + && CASE_TAG_FGREP="" ## Remove leading space TAGS="$( echo ${TAGS} | sed -e 's/^[[:space:]]//' )" +## Check to see if the version of "sort" is supported +echo | sort -V 2>/dev/null >/dev/null +if [ $? -ne "0" ]; then + echo "[-] 'sort' doesn't support '-V'" 1>&2 + echo "[i] Enabling '${progname} --strict'" 1>&2 + FUZZY=0 +fi + + +## Some regex to try and detect version +## Basic: major.minor[.build][.revision] // major.minor[.maintenance][.build] -- example: 1.2.3.4) +## Plus alphanumeric (e.g. alpha, beta): 1a, 2.2b, 3.3-c, 4.4-rc4, 5.5-r +for tag_in in ${TAGS}; do + if echo "${tag_in}" | grep ${REGEX_GREP} -q "^(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\w*))$"; then + ## 1.2.3-4abc + VERSION=$( echo "${tag_in}" | grep ${REGEX_GREP} -o "^(\d+)(\.?\d*)(\.?\d*)((\.|\-)?(\w*))$" ) + [[ -n "${VERSION}" ]] && [[ "${VERBOSE}" -eq 1 ]] \ + && echo "[i] Version ID: ${VERSION}" + + ## 1.2.3-4 + CLEANVERSION=$( echo "${tag_in}" | grep ${REGEX_GREP} -o "^(\d*\.?)(\d*\.?)(\d*\.?)((\.|\-)?(\d+))" ) + if [[ -n "${CLEANVERSION}" ]] && [[ "${CLEANVERSION}" != "${VERSION}" ]]; then + VERSION="${CLEANVERSION}" + + [[ "${VERBOSE}" -eq 1 ]] \ + && echo "[i] Clean ID: ${VERSION}" + fi + fi +done + + +## Did not get a version? If so, no point doing a fuzzy search +if [[ "${FUZZY}" -eq 1 ]] && [[ -z "${VERSION}" ]] && [[ "${VERBOSE}" -eq 1 ]]; then + echo "[i] Unable to detect version in terms: ${TAGS}" 1>&2 + echo "[i] Enabling '${progname} --strict'" 1>&2 + FUZZY=0 +fi + + +## Was it just an number entered in the terms? +if echo "${TAGS}" | grep ${REGEX_GREP} -q "^(\d+)$"; then + ## Disable fuzzy + FUZZY=0 +fi + + #-----------------------------------------------------------------------------#