From 9d47cfa837b08bbad71613c2f500f43b86a4fcbe Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 27 Apr 2020 19:55:34 +0100 Subject: [PATCH 1/5] Bash improvements --- searchsploit | 240 +++++++++++++++++++++++++++------------------------ 1 file changed, 129 insertions(+), 111 deletions(-) diff --git a/searchsploit b/searchsploit index 5fb8ae049..6c0a1da48 100755 --- a/searchsploit +++ b/searchsploit @@ -54,9 +54,8 @@ fi LANG=C -## Usage info -function usage() -{ +## Usage info ~ https://www.tldp.org/LDP/abs/html/standard-options.html +function usage() { echo " Usage: ${progname} [options] term1 [term2] ... [termN]" echo "" echo "==========" @@ -73,46 +72,58 @@ function usage() echo "=========" echo " Options " echo "=========" - echo " -c, --case [Term] Perform a case-sensitive search (Default is inSEnsITiVe)." - echo " -e, --exact [Term] Perform an EXACT match on exploit title (Default is AND) [Implies \"-t\"]." - echo " -h, --help Show this help screen." - echo " -j, --json [Term] Show result in JSON format." - echo " -m, --mirror [EDB-ID] Mirror (aka copies) an exploit to the current working directory." - echo " -o, --overflow [Term] Exploit titles are allowed to overflow their columns." - echo " -p, --path [EDB-ID] Show the full path to an exploit (and also copies the path to the clipboard if possible)." - echo " -t, --title [Term] Search JUST the exploit title (Default is title AND the file's path)." - echo " -u, --update Check for and install any exploitdb package updates (deb or git)." - echo " -w, --www [Term] Show URLs to Exploit-DB.com rather than the local path." - echo " -x, --examine [EDB-ID] Examine (aka opens) the exploit using \$PAGER." - echo " --colour Disable colour highlighting in search results." - echo " --id Display the EDB-ID value rather than local path." - echo " --nmap [file.xml] Checks all results in Nmap's XML output with service version (e.g.: nmap -sV -oX file.xml)." - echo " Use \"-v\" (verbose) to try even more combinations" - echo " --exclude=\"term\" Remove values from results. By using \"|\" to separate, you can chain multiple values." - echo " e.g. --exclude=\"term1|term2|term3\"." + echo "## Search Terms" + echo " -c, --case [Term] Perform a case-sensitive search (Default is inSEnsITiVe)" + echo " -e, --exact [Term] Perform an EXACT & order match on exploit title (Default is an AND match on each term) [Implies \"-t\"]" + echo " e.g. \"WordPress 4.1\" would not be detect \"WordPress Core 4.1\")" + echo " -t, --title [Term] Search JUST the exploit title (Default is title AND the file's path)" + echo " --exclude=\"term\" Remove values from results. By using \"|\" to separate, you can chain multiple values" + echo " e.g. --exclude=\"term1|term2|term3\"" + echo "" + echo "## Output" + echo " -j, --json [Term] Show result in JSON format" + echo " -o, --overflow [Term] Exploit titles are allowed to overflow their columns" + echo " -p, --path [EDB-ID] Show the full path to an exploit (and also copies the path to the clipboard if possible)" + echo " -v, --verbose Display more information in output" + echo " -w, --www [Term] Show URLs to Exploit-DB.com rather than the local path" + echo " --id Display the EDB-ID value rather than local path" + echo " --colour Disable colour highlighting in search results" + echo "" + echo "## Non-Searching" + echo " -m, --mirror [EDB-ID] Mirror (aka copies) an exploit to the current working directory" + echo " -x, --examine [EDB-ID] Examine (aka opens) the exploit using \$PAGER" + echo "" + echo "## Non-Searching" + echo " -h, --help Show this help screen" + echo " -u, --update Check for and install any exploitdb package updates (brew, deb & git)" + echo "" + echo "## Automation" + echo " --nmap [file.xml] Checks all results in Nmap's XML output with service version" + echo " e.g.: nmap [host] -sV -oX file.xml" echo "" echo "=======" echo " Notes " echo "=======" - echo " * You can use any number of search terms." echo " * Search terms are not case-sensitive (by default), and ordering is irrelevant." - echo " * Use '-c' if you wish to reduce results by case-sensitive searching." - echo " * And/Or '-e' if you wish to filter results by using an exact match." - echo " * Use '-t' to exclude the file's path to filter the search results." - echo " * Remove false positives (especially when searching using numbers - i.e. versions)." - echo " * When updating or displaying help, search terms will be ignored." + echo " * You can use any number of search terms" + echo " * Use '-c' if you wish to reduce results by case-sensitive searching" + echo " * And/Or '-e' if you wish to filter results by using an exact match" + echo " * Use '-t' to exclude the file's path to filter the search results" + echo " * Remove false positives (especially when searching using numbers - i.e. versions)" + echo " * When using '--nmap', adding '-v' (verbose), it will search for even more combinations" + echo " * When updating or displaying help, search terms will be ignored" echo "" exit 2 } ## Update database check -function update() -{ +function update() { arraylength="${#files_array[@]}" for (( i=0; i<${arraylength}; i++ )); do ## Check to see if we already have the value - [[ "${tmp_package[*]}" =~ "${package_array[${i}]}" ]] && continue + [[ "${tmp_package[*]}" =~ "${package_array[${i}]}" ]] \ + && continue ## Else save all the information tmp_git+=("${git_array[${i}]}") @@ -151,39 +162,36 @@ function update() ## Update database (via .deb/apt) -function updatedeb() -{ +function updatedeb() { package_in="${1}" echo -e "[i] Updating via apt package management (Expect weekly-ish updates): ${package_in}\n" sudo apt update \ - || echo -e "\n[-] Issue with apt update (Please check network connectivity & apt SourcesList values)." 1>&2 + || echo -e "\n[-] Issue with apt update (Please check network connectivity & apt SourcesList values)" 1>&2 sudo apt -y install "${package_in}" \ - || echo -e "\n[-] Issue with apt upgrade." 1>&2 + || echo -e "\n[-] Issue with apt upgrade" 1>&2 - echo -e "\n[*] apt update finished." + echo -e "\n[*] apt update finished" } ## Update database (via homebrew) -function updatedbrew() -{ +function updatedbrew() { package_in="${1}" echo -e "[i] Updating via brew package management.\n" brew update \ - || echo -e "\n[-] Issue with brew update (Please check network connectivity)." 1>&2 + || echo -e "\n[-] Issue with brew update (Please check network connectivity)" 1>&2 brew upgrade "${package_in}" - echo -e "\n[*] Brew update finished." + echo -e "\n[*] Brew update finished" } ## Update database (via Git) -function updategit() -{ +function updategit() { package_in="${1}" path_in="${2}" git_in="${3}" @@ -232,14 +240,13 @@ function updategit() || sudo git pull -v upstream master fi - echo -e "\n[*] Git update finished." + echo -e "\n[*] Git update finished" echo "[i] Path: ${path_in}/" } ## Printing dotted lines in the correct manner -function drawline() -{ +function drawline() { printf "%0.s-" $( eval echo {1..$(( COL1 + 1 ))} ) echo -n " " printf "%0.s-" $( eval echo {1..$(( COL2 - 1 ))} ) @@ -248,8 +255,7 @@ function drawline() ## Used in searchsploitout/nmap's XML -function validterm() -{ +function validterm() { ## Check to see if its any phrases which would give a TON of incorrect results if [ "$( echo ${1} | tr '[:upper:]' '[:lower:]' )" == "microsoft" ] \ || [ "$( echo ${1} | tr '[:upper:]' '[:lower:]' )" == "microsoft windows" ] \ @@ -263,9 +269,9 @@ function validterm() || [ "$( echo ${1} | tr '[:upper:]' '[:lower:]' )" == "oracle" ] \ || [ "$( echo ${1} | tr '[:upper:]' '[:lower:]' )" == "ssh" ] \ || [ "$( echo ${1} | tr '[:upper:]' '[:lower:]' )" == "unknown" ]; then - echo -e "[-] Skipping term: ${1} (Term is too general. Please re-search manually: $0 ${arg} ${1})\n" 1>&2 - ## Issues, return with something - return 1 + echo -e "[-] Skipping term: ${1} (Term is too general. Please re-search manually: $0 ${arg} ${1})\n" 1>&2 + ## Issues, return with something + return 1 fi ## No issues, return without anything @@ -274,19 +280,24 @@ function validterm() ## Used in searchsploitout/nmap's XML -function searchsploitout() -{ +function searchsploitout() { ## Make sure there is a value - [ "${software}" = "" ] && return + [ "${software}" = "" ] \ + && return #echo "" 1>&2 arg="-t" ## Title search by default! - [[ "${JSON}" == "1" ]] && arg="${arg} --json" - [[ "${OVERFLOW}" == "1" ]] && arg="${arg} --overflow" - [[ "${WEBLINK}" == "1" ]] && arg="${arg} --www" - [[ "${COLOUR}" != "1" ]] && arg="${arg} --colour" - [[ "${EDBID}" == "1" ]] && arg="${arg} --id" + [[ "${COLOUR}" != "1" ]] \ + && arg="${arg} --colour" + [[ "${EDBID}" == "1" ]] \ + && arg="${arg} --id" + [[ "${JSON}" == "1" ]] \ + && arg="${arg} --json" + [[ "${OVERFLOW}" == "1" ]] \ + && arg="${arg} --overflow" + [[ "${WEBLINK}" == "1" ]] \ + && arg="${arg} --www" ## Try and remove terms that could confuse searches #software=$( echo "${software}" | sed 's_/_ _g' ) @@ -344,8 +355,7 @@ function searchsploitout() ## Read XML file -function nmapxml() -{ +function nmapxml() { ## Feedback to the end user echo -e "[i] Reading: '${FILE}'\n" 1>&2 @@ -390,8 +400,7 @@ function nmapxml() ## Build search terms -function buildterms() -{ +function buildterms() { tag_in="${1}" ## If we are to use colour ("--colour"), add the values to search for between "or" @@ -407,7 +416,8 @@ function buildterms() ## Search just the title, NOT the path ("-t"/"-e") else ## If there is already a value, prepend text to get ready - [[ "${AWK_SEARCH}" ]] && AWK_SEARCH="${AWK_SEARCH}/ && ${CASE_TAG_FGREP}(\$3) ~ /" + [[ "${AWK_SEARCH}" ]] \ + && AWK_SEARCH="${AWK_SEARCH}/ && ${CASE_TAG_FGREP}(\$3) ~ /" ## Escape any slashes tag_in="$( echo ${tag_in} | sed 's_/_\\/_g' )" @@ -423,8 +433,7 @@ function buildterms() ## Read in the values from files_*.csv -function findresults() -{ +function findresults() { file_in="${1}" path_in="${2}" name_in="${3}" @@ -438,17 +447,17 @@ function findresults() fi - ## JSON require full options if [[ "${JSON}" -eq 1 ]]; then - ## Read in (id, title, path, date, author, type, platform) separated between commas + ## JSON require full options ("--json") + ## Read (id, path, title, date, author, type, platform) separated between commas SEARCH="awk -F '[,]' '{print \$1\",\"\$2\",\"\$3\",\"\$4\",\"\$5\",\"\$6\",\"\$7}' \"${path_in}/${file_in}\"" else - ## Read in (id, title, path) separated between commas (as these are the only visible fields) + ## Read (id, path, title) separated between commas (as these are the only visible fields) SEARCH="awk -F '[,]' '{print \$1\",\"\$2\",\"\$3}' \"${path_in}/${file_in}\"" fi - ## EXACT search command ("-e")? + ## EXACT search command ("-e") if [[ "${EXACT}" -eq 1 ]]; then buildterms "${TAGS}" ## or AND search command? @@ -461,7 +470,8 @@ function findresults() ## If we are NOT to use the path name ("-t"/"-e") - [[ "${FILEPATH}" -eq 0 ]] && SEARCH="${SEARCH} | awk -F '[,]' '${CASE_TAG_FGREP}(\$3) ~ /${AWK_SEARCH}/ {print}'" + [[ "${FILEPATH}" -eq 0 ]] \ + && SEARCH="${SEARCH} | awk -F '[,]' '${CASE_TAG_FGREP}(\$3) ~ /${AWK_SEARCH}/ {print}'" ## If we are to use colour ("--colour"), add the value here @@ -471,16 +481,16 @@ function findresults() ## Dynamically set column widths to the current screen size - [[ "${WEBLINK}" -eq 1 ]] && COL2=45 || COL2=$(( ${#path_in} + 21 )) + [[ "${WEBLINK}" -eq 1 ]] \ + && COL2=45 \ + || COL2=$(( ${#path_in} + 21 )) COL1=$(( $( tput cols ) - COL2 - 1 )) ## Search, format, and print results (--overflow) - if [[ "${OVERFLOW}" -eq 1 ]]; then - FORMAT_COL1=${COL1} - else - FORMAT_COL1=${COL1}'.'${COL1} - fi + [[ "${OVERFLOW}" -eq 1 ]] \ + && FORMAT_COL1=${COL1} \ + || FORMAT_COL1=${COL1}'.'${COL1} ## Maximum length COL2 can be FORMAT_COL2=$(( ${COL2} - 2 )) @@ -490,10 +500,16 @@ function findresults() ## Remove any terms not wanted from the search - [[ "${EXCLUDE}" ]] && SEARCH="${SEARCH} | grep -vEi '${EXCLUDE}'" + [[ "${EXCLUDE}" ]] \ + && SEARCH="${SEARCH} | grep -vEi '${EXCLUDE}'" ## Magic search Fu + + ## If there are no results, no point going on + [[ -z "$OUTPUT" ]] \ + && return + ## Print JSON format (full options) ("--json")? if [[ "${JSON}" -eq 1 ]]; then ## Web link format ("--json --www")? @@ -510,38 +526,37 @@ function findresults() | awk -F ',' '{ printf "\\n\\t\\t'{'\"Title\":\"%s\",\"EDB-ID\":\"%s\",\"Date\":\"%s\",\"Author\":\"%s\",\"Type\":\"%s\",\"Platform\":\"%s\",\"Path\":\"'${path_in}/'%s\"},", $3, $1, $4, $5, $6, $7, $2 }' )" fi OUTPUT="$( echo -e ${OUTPUT} \ - | sort \ + | sort -f \ | sed '$ s/,$//' )" ## Web link format ("--www")? elif [[ "${WEBLINK}" -eq 1 ]]; then OUTPUT="$( eval ${SEARCH} \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %s\n", $3, "https://www.exploit-db.com/'${url}'/"$1 }' \ - | sort )" + | sort -f )" ## Just the EDB-ID ("--id")? elif [[ "${EDBID}" -eq 1 ]]; then OUTPUT="$( eval ${SEARCH} \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %s\n", $3, $1 }' \ - | sort )" + | sort -f )" ## Default view else OUTPUT="$( eval ${SEARCH} \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %.'${FORMAT_COL2}'s\n", $3, $2 }' \ - | sort )" + | sort -f )" fi ## Display colour highlights ("--colour")? - if [[ "${COLOUR_TAG}" ]] && [[ "${JSON}" -eq 0 ]]; then - [[ "${OUTPUT}" ]] && OUTPUT=$( echo -e "${OUTPUT}" | eval ${COLOUR_TAG} ) + if [[ "${COLOUR_TAG}" ]] && [[ "${JSON}" -eq 0 ]] && [[ "${OUTPUT}" ]]; then + OUTPUT=$( echo -e "${OUTPUT}" | eval ${COLOUR_TAG} ) fi } -function printresults() -{ +function printresults() { title_in="${1}" path_in="${2}" - json_title="$(echo ${title_in} | tr /a-z/ /A-Z/)" + json_title="$( echo ${title_in} | tr /a-z/ /A-Z/ )" ## Print header if in JSON ("--json") @@ -567,7 +582,8 @@ function printresults() ## Show content - [[ "${OUTPUT}" ]] && echo "${OUTPUT}" + [[ "${OUTPUT}" ]] \ + && echo "${OUTPUT}" ## Print footer if in JSON ("--json") @@ -590,11 +606,11 @@ if [[ -f "${HOME}/.searchsploit_rc" ]]; then elif [[ -f "/etc/searchsploit_rc" ]]; then rc_file="/etc/searchsploit_rc" ## Method #1 - File itself -elif [[ -f "$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)/.searchsploit_rc" ]]; then - rc_file="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)/.searchsploit_rc" +elif [[ -f "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.searchsploit_rc" ]]; then + rc_file="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.searchsploit_rc" ## Method #2 - Symbolic link -elif [[ -f "$(dirname "$(readlink "$0")")/.searchsploit_rc" ]]; then - rc_file="$(dirname "$(readlink "$0")")/.searchsploit_rc" +elif [[ -f "$( dirname "$( readlink "$0")" )/.searchsploit_rc" ]]; then + rc_file="$( dirname "$( readlink "$0")" )/.searchsploit_rc" ## Manually specified? elif [[ ! -f "${rc_file}" ]]; then echo "[!] Could not find: rc_file ~ ${rc_file}" @@ -620,6 +636,8 @@ ARGS="-" for param in "$@"; do if [[ "${param}" == "--case" ]]; then SCASE=1 + elif [[ "${param}" == "--colour" ]] || [[ "${param}" == "--color" ]]; then + COLOUR="" elif [[ "${param}" == "--exact" ]]; then EXACT=1 elif [[ "${param}" == "--examine" ]] || [[ "${param}" == "--open" ]] || [[ "${param}" == "--view" ]]; then @@ -627,11 +645,15 @@ for param in "$@"; do EXAMINE=1 elif [[ "${param}" == "--help" ]]; then usage >&2 + elif [[ "${param}" == "--id" ]]; then + EDBID=1 elif [[ "${param}" == "--json" ]]; then JSON=1 elif [[ "${param}" == "--mirror" ]] || [[ "${param}" == "--copy" ]] || [[ "${param}" == "--dup" ]] || [[ "${param}" == "--duplicate" ]]; then GETPATH=1 MIRROR=1 + elif [[ "${param}" == "--nmap" ]]; then + XML=1 elif [[ "${param}" == "--overflow" ]]; then OVERFLOW=1 elif [[ "${param}" == "--path" ]]; then @@ -641,18 +663,12 @@ for param in "$@"; do FILEPATH=0 elif [[ "${param}" == "--update" ]]; then update - elif [[ "${param}" == "--www" ]]; then - WEBLINK=1 - elif [[ "${param}" == "--colour" ]] || [[ "${param}" == "--color" ]]; then - COLOUR="" - elif [[ "${param}" == "--id" ]]; then - EDBID=1 - elif [[ "${param}" == "--nmap" ]]; then - XML=1 - elif [[ "${param}" =~ "--exclude=" ]]; then - EXCLUDE="$( echo "${param}" | cut -d '=' -f 2- )" elif [[ "${param}" == "--verbose" ]]; then VERBOSE=1 + elif [[ "${param}" == "--www" ]]; then + WEBLINK=1 + elif [[ "${param}" =~ "--exclude=" ]]; then + EXCLUDE="$( echo "${param}" | cut -d '=' -f 2- )" else if [[ "${param:0:1}" == "-" ]]; then ARGS=${ARGS}${param:1} @@ -699,17 +715,17 @@ for (( i=0; i<${arraylength}; i++ )); do if [[ -f "${files}" ]]; then continue ## Method #1 - File itself - elif [[ -f "$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)/${files_array[${i}]}" ]]; then - echo "[i] Found (#1): $(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)/${files_array[${i}]}" 1>&2 + elif [[ -f "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/${files_array[${i}]}" ]]; then + echo "[i] Found (#1): $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/${files_array[${i}]}" 1>&2 echo "[i] To remove this message, please edit \"${rc_file}\" for \"${files_array[${i}]}\" (package_array: ${package_array[${i}]})" 1>&2 echo 1>&2 - path_array[${i}]="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" + path_array[${i}]="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ## Method #2 - Symbolic link - elif [[ -f "$(dirname "$(readlink "$0")")/${files_array[${i}]}" ]]; then - echo "[i] Found (#2): $(dirname "$(readlink "$0")")/${files_array[${i}]}" 1>&2 + elif [[ -f "$( dirname "$( readlink "$0" )" )/${files_array[${i}]}" ]]; then + echo "[i] Found (#2): $( dirname "$( readlink "$0" )" )/${files_array[${i}]}" 1>&2 echo "[i] To remove this message, please edit \"${rc_file}\" for \"${files_array[${i}]}\" (package_array: ${package_array[${i}]})" 1>&2 echo 1>&2 - path_array[${i}]="$(dirname "$(readlink "$0")")" + path_array[${i}]="$( dirname "$( readlink "$0" )" )" else #echo "[!] Could not find: ${files}" 1>&2 #echo "[i] To remove this message, please remove \"${files_array[${i}]}\" (package_array: ${package_array[${i}]}) from \"${rc_file}\"" 1>&2 @@ -739,7 +755,7 @@ if [[ "${XML}" -eq 1 ]]; then if ! hash xmllint 2>/dev/null; then echo -e "\n[!] Please install xmllint" 1>&2 - echo -e "[i] Kali Linux -> apt -y install libxml2-utils" 1>&2 + echo -e "[i] Kali Linux: sudo apt -y install libxml2-utils" 1>&2 exit 1 fi @@ -814,11 +830,11 @@ if [[ "${GETPATH}" -eq 1 ]]; then ## Linux (Will require $DISPLAY) if hash xclip 2>/dev/null; then echo -ne "${location}" | xclip -selection clipboard 2>/dev/null - echo "Copied EDB-ID #${edbdb}'s path to the clipboard." + echo "Copied EDB-ID #${edbdb}'s path to the clipboard" ## OSX elif hash pbcopy 2>/dev/null; then echo -ne "${location}" | pbcopy - echo "Copied EDB-ID #${edbdb}'s path to the clipboard." + echo "Copied EDB-ID #${edbdb}'s path to the clipboard" fi fi @@ -880,7 +896,8 @@ TAGS="$( echo ${TAGS} | sed -e 's/^[[:space:]]//' )" ## Print header if in JSON ("--json") -[[ "${JSON}" -eq 1 ]] && printf "{\n\t\"SEARCH\": \"${TAGS}\"" +[[ "${JSON}" -eq 1 ]] \ + && printf "{\n\t\"SEARCH\": \"${TAGS}\"" ## Check for files_*.csv @@ -893,7 +910,7 @@ for (( i=0; i<${arraylength}; i++ )); do printresults "${name_array[${i}]}" "${path_array[${i}]}" ## Summary if NOT JSON ("--json") elif [[ "${JSON}" -eq 0 ]]; then - echo "${name_array[${i}]}s: No Result" + echo "${name_array[${i}]}s: No Results" fi ## Reset COLOUR_TAG="" @@ -901,7 +918,8 @@ done ## Print footer if in JSON ("--json") -[[ "${JSON}" -eq 1 ]] && printf "\n}\n" +[[ "${JSON}" -eq 1 ]] \ + && printf "\n}\n" ## Done From 4dd344c2a8d025e5263403a16830d8060ddaf6c6 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 27 Apr 2020 19:56:53 +0100 Subject: [PATCH 2/5] Set "fuzzy" as default behaviour (to revert, need to use new "--strict" option) --- searchsploit | 135 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 15 deletions(-) diff --git a/searchsploit b/searchsploit index 6c0a1da48..71229a762 100755 --- a/searchsploit +++ b/searchsploit @@ -1,6 +1,6 @@ #!/bin/bash # Name: SearchSploit - Exploit-DB's CLI search tool -# Version: 4.0.5 (2019-03-27) +# Version: 4.1.0 (2020-04-27) # Written by: Offensive Security, Unix-Ninja, and g0tmi1k # Homepage: https://github.com/offensive-security/exploitdb # Manual: https://www.exploit-db.com/searchsploit @@ -24,6 +24,7 @@ EDBID=0 EXACT=0 EXAMINE=0 FILEPATH=1 +FUZZY=1 GETPATH=0 JSON=0 MIRROR=0 @@ -39,6 +40,7 @@ EXCLUDE="" CASE_TAG_GREP="-i" CASE_TAG_FGREP="tolower" AWK_SEARCH="" +FUZZY_SEARCH="" COLOUR_OFF_GREP= COLOUR_ON_GREP= @@ -64,7 +66,7 @@ function usage() { echo " ${progname} afd windows local" echo " ${progname} -t oracle windows" echo " ${progname} -p 39446" - echo " ${progname} linux kernel 3.2 --exclude=\"(PoC)|/dos/\"" + echo " ${progname} linux kernel 3.2 -s --exclude=\"(PoC)|/dos/\"" echo " ${progname} linux reverse password" echo "" echo " For more examples, see the manual: https://www.exploit-db.com/searchsploit" @@ -76,6 +78,8 @@ function usage() { echo " -c, --case [Term] Perform a case-sensitive search (Default is inSEnsITiVe)" echo " -e, --exact [Term] Perform an EXACT & order match on exploit title (Default is an AND match on each term) [Implies \"-t\"]" echo " e.g. \"WordPress 4.1\" would not be detect \"WordPress Core 4.1\")" + echo " -s, --strict Perform a strict search, so input values must exist, disabling fuzzy search for version range" + echo " e.g. \"1.1\" would not be detected in \"1.0 < 1.3\")" echo " -t, --title [Term] Search JUST the exploit title (Default is title AND the file's path)" echo " --exclude=\"term\" Remove values from results. By using \"|\" to separate, you can chain multiple values" echo " e.g. --exclude=\"term1|term2|term3\"" @@ -104,10 +108,11 @@ function usage() { echo "=======" echo " Notes " echo "=======" - echo " * Search terms are not case-sensitive (by default), and ordering is irrelevant." echo " * You can use any number of search terms" + echo " * By default, search terms are not case-sensitive, ordering is irrelevant, and will search between version ranges" echo " * Use '-c' if you wish to reduce results by case-sensitive searching" echo " * And/Or '-e' if you wish to filter results by using an exact match" + echo " * And/Or '-s' if you wish to look for an exact version match" echo " * Use '-t' to exclude the file's path to filter the search results" echo " * Remove false positives (especially when searching using numbers - i.e. versions)" echo " * When using '--nmap', adding '-v' (verbose), it will search for even more combinations" @@ -296,6 +301,8 @@ function searchsploitout() { && arg="${arg} --json" [[ "${OVERFLOW}" == "1" ]] \ && arg="${arg} --overflow" + [[ "${FUZZY}" != "1" ]] \ + && arg="${arg} --strict" [[ "${WEBLINK}" == "1" ]] \ && arg="${arg} --www" @@ -413,6 +420,28 @@ function buildterms() { if [[ "${FILEPATH}" -eq 1 ]]; then ## Search command for each term (with case sensitive flag, "-c") SEARCH="${SEARCH} | grep ${COLOUR_OFF_GREP} -F ${CASE_TAG_GREP} \"${tag_in}\"" + + ## 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 + 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 @@ -447,10 +476,12 @@ function findresults() { fi - if [[ "${JSON}" -eq 1 ]]; then ## JSON require full options ("--json") + if [[ "${JSON}" -eq 1 ]] || [[ "${FUZZY}" -eq 1 ]]; then ## Read (id, path, title, date, author, type, platform) separated between commas SEARCH="awk -F '[,]' '{print \$1\",\"\$2\",\"\$3\",\"\$4\",\"\$5\",\"\$6\",\"\$7}' \"${path_in}/${file_in}\"" + ## Read (id, title) separated between commas & search for less than (and grater than values) too + FUZZY_SEARCH="awk -F '[,]' '{print \$1\",\"\$3}' \"${path_in}/${file_in}\" | grep ${COLOUR_OFF_GREP} \"<\|>\"" else ## Read (id, path, title) separated between commas (as these are the only visible fields) SEARCH="awk -F '[,]' '{print \$1\",\"\$2\",\"\$3}' \"${path_in}/${file_in}\"" @@ -495,16 +526,87 @@ function findresults() { ## Maximum length COL2 can be FORMAT_COL2=$(( ${COL2} - 2 )) - ## Strip un-wanted values - SEARCH="${SEARCH} | sed 's/\"//g'" - ## Remove any terms not wanted from the search [[ "${EXCLUDE}" ]] \ && SEARCH="${SEARCH} | grep -vEi '${EXCLUDE}'" - ## Magic search Fu + ## 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 ) + + ## 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 + done < <( + eval "${FUZZY_SEARCH}" + ) + fi + fi + + + ## Magic search Fu + strip double quotes + OUTPUT="$( + ( \ + eval ${SEARCH}; \ + awk "/^(${ID}),/ {print}" "${path_in}/${file_in}" \ + ) \ + | sed 's/\"//g' + )" ## If there are no results, no point going on [[ -z "$OUTPUT" ]] \ @@ -514,15 +616,15 @@ function findresults() { if [[ "${JSON}" -eq 1 ]]; then ## Web link format ("--json --www")? if [[ "${WEBLINK}" -eq 1 ]]; then - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "\\n\\t\\t'{'\"Title\":\"%s\",\"URL\":\"https://www.exploit-db.com/'${url}'/%s\"},", $3, $1 }' )" ## Just the EDB-ID ("--json --id")? elif [[ "${EDBID}" -eq 1 ]]; then - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "\\n\\t\\t'{'\"Title\":\"%s\",\"EDB-ID\":\"%s\",\"Path\":\"'${path_in}/'%s\"},", $3, $1, $2 }' )" ## Default JSON ("--json")? else - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "\\n\\t\\t'{'\"Title\":\"%s\",\"EDB-ID\":\"%s\",\"Date\":\"%s\",\"Author\":\"%s\",\"Type\":\"%s\",\"Platform\":\"%s\",\"Path\":\"'${path_in}/'%s\"},", $3, $1, $4, $5, $6, $7, $2 }' )" fi OUTPUT="$( echo -e ${OUTPUT} \ @@ -530,17 +632,17 @@ function findresults() { | sed '$ s/,$//' )" ## Web link format ("--www")? elif [[ "${WEBLINK}" -eq 1 ]]; then - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %s\n", $3, "https://www.exploit-db.com/'${url}'/"$1 }' \ | sort -f )" ## Just the EDB-ID ("--id")? elif [[ "${EDBID}" -eq 1 ]]; then - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %s\n", $3, $1 }' \ | sort -f )" ## Default view else - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %.'${FORMAT_COL2}'s\n", $3, $2 }' \ | sort -f )" fi @@ -659,6 +761,8 @@ for param in "$@"; do elif [[ "${param}" == "--path" ]]; then GETPATH=1 CLIPBOARD=1 + elif [[ "${param}" == "--strict" ]]; then + FUZZY=0 elif [[ "${param}" == "--title" ]]; then FILEPATH=0 elif [[ "${param}" == "--update" ]]; then @@ -681,7 +785,7 @@ done ## Parse short arguments -while getopts "cehjmnoptuvwx" arg "${ARGS}"; do +while getopts "cehjmnopstuvwx" arg "${ARGS}"; do if [[ "${arg}" = "?" ]]; then usage >&2; fi @@ -694,6 +798,7 @@ while getopts "cehjmnoptuvwx" arg "${ARGS}"; do n) XML=1;; o) OVERFLOW=1;; p) GETPATH=1; CLIPBOARD=1;; + s) FUZZY=0;; t) FILEPATH=0;; u) update;; v) VERBOSE=1;; From 830465d5a92b46b8f5baaf52dc01c46183ca8dc2 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 27 Apr 2020 20:25:00 +0100 Subject: [PATCH 3/5] Update README for v4.1 --- README.md | 71 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index e20bd09ee..dd31f6c27 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ For more information, please see the **[SearchSploit manual](https://www.exploit ## Usage/Example ``` -root@kali:~# searchsploit -h +kali@kali:~$ searchsploit -h Usage: searchsploit [options] term1 [term2] ... [termN] ========== @@ -39,7 +39,7 @@ root@kali:~# searchsploit -h searchsploit afd windows local searchsploit -t oracle windows searchsploit -p 39446 - searchsploit linux kernel 3.2 --exclude="(PoC)|/dos/" + searchsploit linux kernel 3.2 -s --exclude="(PoC)|/dos/" searchsploit linux reverse password For more examples, see the manual: https://www.exploit-db.com/searchsploit @@ -47,34 +47,49 @@ root@kali:~# searchsploit -h ========= Options ========= - -c, --case [Term] Perform a case-sensitive search (Default is inSEnsITiVe). - -e, --exact [Term] Perform an EXACT match on exploit title (Default is AND) [Implies "-t"]. - -h, --help Show this help screen. - -j, --json [Term] Show result in JSON format. - -m, --mirror [EDB-ID] Mirror (aka copies) an exploit to the current working directory. - -o, --overflow [Term] Exploit titles are allowed to overflow their columns. - -p, --path [EDB-ID] Show the full path to an exploit (and also copies the path to the clipboard if possible). - -t, --title [Term] Search JUST the exploit title (Default is title AND the file's path). - -u, --update Check for and install any exploitdb package updates (deb or git). - -w, --www [Term] Show URLs to Exploit-DB.com rather than the local path. - -x, --examine [EDB-ID] Examine (aka opens) the exploit using $PAGER. - --colour Disable colour highlighting in search results. - --id Display the EDB-ID value rather than local path. - --nmap [file.xml] Checks all results in Nmap's XML output with service version (e.g.: nmap -sV -oX file.xml). - Use "-v" (verbose) to try even more combinations - --exclude="term" Remove values from results. By using "|" to separate, you can chain multiple values. - e.g. --exclude="term1|term2|term3". +## Search Terms + -c, --case [Term] Perform a case-sensitive search (Default is inSEnsITiVe) + -e, --exact [Term] Perform an EXACT & order match on exploit title (Default is an AND match on each term) [Implies "-t"] + e.g. "WordPress 4.1" would not be detect "WordPress Core 4.1") + -s, --strict Perform a strict search, so input values must exist, disabling fuzzy search for version range + e.g. "1.1" would not be detected in "1.0 < 1.3") + -t, --title [Term] Search JUST the exploit title (Default is title AND the file's path) + --exclude="term" Remove values from results. By using "|" to separate, you can chain multiple values + e.g. --exclude="term1|term2|term3" + +## Output + -j, --json [Term] Show result in JSON format + -o, --overflow [Term] Exploit titles are allowed to overflow their columns + -p, --path [EDB-ID] Show the full path to an exploit (and also copies the path to the clipboard if possible) + -v, --verbose Display more information in output + -w, --www [Term] Show URLs to Exploit-DB.com rather than the local path + --id Display the EDB-ID value rather than local path + --colour Disable colour highlighting in search results + +## Non-Searching + -m, --mirror [EDB-ID] Mirror (aka copies) an exploit to the current working directory + -x, --examine [EDB-ID] Examine (aka opens) the exploit using $PAGER + +## Non-Searching + -h, --help Show this help screen + -u, --update Check for and install any exploitdb package updates (brew, deb & git) + +## Automation + --nmap [file.xml] Checks all results in Nmap's XML output with service version + e.g.: nmap [host] -sV -oX file.xml ======= Notes ======= - * You can use any number of search terms. - * Search terms are not case-sensitive (by default), and ordering is irrelevant. - * Use '-c' if you wish to reduce results by case-sensitive searching. - * And/Or '-e' if you wish to filter results by using an exact match. - * Use '-t' to exclude the file's path to filter the search results. - * Remove false positives (especially when searching using numbers - i.e. versions). - * When updating or displaying help, search terms will be ignored. + * You can use any number of search terms + * By default, search terms are not case-sensitive, ordering is irrelevant, and will search between version ranges + * Use '-c' if you wish to reduce results by case-sensitive searching + * And/Or '-e' if you wish to filter results by using an exact match + * And/Or '-s' if you wish to look for an exact version match + * Use '-t' to exclude the file's path to filter the search results + * Remove false positives (especially when searching using numbers - i.e. versions) + * When using '--nmap', adding '-v' (verbose), it will search for even more combinations + * When updating or displaying help, search terms will be ignored root@kali:~# root@kali:~# searchsploit afd windows local @@ -117,13 +132,13 @@ You can find a **more in-depth guide in the [SearchSploit manual](https://www.ex Exploit-DB/SearchSploit is already packaged inside of Kali-Linux. A method of installation is: ``` -root@kali:~# apt -y install exploitdb +kali@kali:~$ sudo apt -y install exploitdb ``` _NOTE: Optional is to install the additional packages:_ ``` -root@kali:~# apt -y install exploitdb-bin-sploits exploitdb-papers +kali@kali:~$ sudo apt -y install exploitdb-bin-sploits exploitdb-papers ``` **Git** From a2a942ae0aeeecab44806097c2a1019a1844df9e Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 30 Apr 2020 17:10:35 +0100 Subject: [PATCH 4/5] Improved bash, more help, less bugs, and cleaner output --- searchsploit | 219 +++++++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 94 deletions(-) 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 + + #-----------------------------------------------------------------------------# From 2cffa6f07cb0c65a9686ff1f494a84c413f52172 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 30 Apr 2020 17:13:29 +0100 Subject: [PATCH 5/5] README update for new output --- README.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index dd31f6c27..080afc502 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,10 @@ kali@kali:~$ searchsploit -h searchsploit afd windows local searchsploit -t oracle windows searchsploit -p 39446 - searchsploit linux kernel 3.2 -s --exclude="(PoC)|/dos/" + searchsploit linux kernel 3.2 --exclude="(PoC)|/dos/" + searchsploit -s Apache Struts 2.0.0 searchsploit linux reverse password + searchsploit -j 55555 | json_pp For more examples, see the manual: https://www.exploit-db.com/searchsploit @@ -91,31 +93,30 @@ kali@kali:~$ searchsploit -h * When using '--nmap', adding '-v' (verbose), it will search for even more combinations * When updating or displaying help, search terms will be ignored -root@kali:~# -root@kali:~# searchsploit afd windows local +kali@kali:~$ +kali@kali:~$ searchsploit afd windows local ---------------------------------------------------------------------------------------- ----------------------------------- Exploit Title | Path - | (/usr/share/exploitdb/) ---------------------------------------------------------------------------------------- ----------------------------------- -Microsoft Windows (x86) - 'afd.sys' Local Privilege Escalation (MS11-046) | exploits/windows_x86/local/40564.c -Microsoft Windows - 'AfdJoinLeaf' Local Privilege Escalation (MS11-080) (Metasploit) | exploits/windows/local/21844.rb -Microsoft Windows - 'afd.sys' Local Kernel (PoC) (MS11-046) | exploits/windows/dos/18755.c -Microsoft Windows 7 (x64) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | exploits/windows_x86-64/local/39525.py -Microsoft Windows 7 (x86) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | exploits/windows_x86/local/39446.py -Microsoft Windows XP - 'afd.sys' Local Kernel Denial of Service | exploits/windows/dos/17133.c -Microsoft Windows XP/2003 - 'afd.sys' Local Privilege Escalation (K-plugin) (MS08-066) | exploits/windows/local/6757.txt -Microsoft Windows XP/2003 - 'afd.sys' Local Privilege Escalation (MS11-080) | exploits/windows/local/18176.py +Microsoft Windows (x86) - 'afd.sys' Local Privilege Escalation (MS11-046) | windows_x86/local/40564.c +Microsoft Windows - 'afd.sys' Local Kernel (PoC) (MS11-046) | windows/dos/18755.c +Microsoft Windows - 'AfdJoinLeaf' Local Privilege Escalation (MS11-080) (Metasploit) | windows/local/21844.rb +Microsoft Windows 7 (x64) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | windows_x86-64/local/39525.py +Microsoft Windows 7 (x86) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | windows_x86/local/39446.py +Microsoft Windows XP - 'afd.sys' Local Kernel Denial of Service | windows/dos/17133.c +Microsoft Windows XP/2003 - 'afd.sys' Local Privilege Escalation (K-plugin) (MS08-066) | windows/local/6757.txt +Microsoft Windows XP/2003 - 'afd.sys' Local Privilege Escalation (MS11-080) | windows/local/18176.py ---------------------------------------------------------------------------------------- ----------------------------------- Shellcodes: No Result -root@kali:~# -root@kali:~# searchsploit -p 39446 +kali@kali:~$ +kali@kali:~$ searchsploit -p 39446 Exploit: Microsoft Windows 7 (x86) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) URL: https://www.exploit-db.com/exploits/39446 Path: /usr/share/exploitdb/exploits/windows_x86/local/39446.py File Type: Python script, ASCII text executable, with CRLF line terminators Copied EDB-ID #39446's path to the clipboard. -root@kali:~# +kali@kali:~$ ``` - - -