diff --git a/README.md b/README.md index e20bd09ee..080afc502 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] ========== @@ -40,67 +40,83 @@ root@kali:~# searchsploit -h searchsploit -t oracle windows searchsploit -p 39446 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 ========= 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 +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:~$ ``` - - - @@ -117,13 +133,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** diff --git a/searchsploit b/searchsploit index 75edc5ac2..eec8a0c83 100755 --- a/searchsploit +++ b/searchsploit @@ -1,6 +1,6 @@ #!/bin/bash # Name: SearchSploit - Exploit-DB's CLI search tool -# Version: 4.0.7 (2020-04-09) +# 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 @@ -24,6 +24,7 @@ EDBID=0 EXACT=0 EXAMINE=0 FILEPATH=1 +FUZZY=1 GETPATH=0 JSON=0 MIRROR=0 @@ -39,8 +40,11 @@ EXCLUDE="" 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 @@ -49,14 +53,20 @@ 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 -## 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 "==========" @@ -66,40 +76,57 @@ function usage() echo " ${progname} -t oracle windows" echo " ${progname} -p 39446" 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 "" echo "=========" echo " Options " echo "=========" + echo "## Search Terms" 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 " -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 " -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 "" + 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 " * 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" echo " * When updating or displaying help, search terms will be ignored" echo "" exit 2 @@ -107,8 +134,7 @@ function usage() ## 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 @@ -152,8 +178,7 @@ 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" @@ -168,8 +193,7 @@ function updatedeb() ## Update database (via homebrew) -function updatedbrew() -{ +function updatedbrew() { package_in="${1}" echo -e "[i] Updating via brew package management\n" @@ -183,8 +207,7 @@ function updatedbrew() ## Update database (via Git) -function updategit() -{ +function updategit() { package_in="${1}" path_in="${2}" git_in="${3}" @@ -239,8 +262,7 @@ function updategit() ## 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 ))} ) @@ -249,8 +271,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" ] \ @@ -264,9 +285,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} (Too generic. You'll need to force a search: $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 @@ -275,8 +296,7 @@ function validterm() ## Used in searchsploitout/nmap's XML -function searchsploitout() -{ +function searchsploitout() { ## Make sure there is a value [ "${software}" = "" ] \ && return @@ -284,11 +304,18 @@ function searchsploitout() #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" + [[ "${FUZZY}" != "1" ]] \ + && arg="${arg} --strict" + [[ "${WEBLINK}" == "1" ]] \ + && arg="${arg} --www" ## Try and remove terms that could confuse searches #software=$( echo "${software}" | sed 's_/_ _g' ) @@ -350,8 +377,7 @@ function searchsploitout() ## Read XML file -function nmapxml() -{ +function nmapxml() { ## Feedback to the end user echo -e "[i] Reading: '${FILE}'\n" 1>&2 @@ -397,8 +423,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" @@ -412,6 +437,13 @@ 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 ${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 @@ -421,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 @@ -432,8 +464,7 @@ function buildterms() ## Read in the values from files_*.csv -function findresults() -{ +function findresults() { file_in="${1}" path_in="${2}" name_in="${3}" @@ -447,17 +478,19 @@ 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") + 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 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? @@ -483,78 +516,140 @@ 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 )) ## 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 )) - ## Strip un-wanted values from titles - #SEARCH="${SEARCH} | sed 's/\"//g" - SEARCH="${SEARCH} | sed 's/,\"/,/; s/\"$//;'" - ## Remove any terms not wanted from the search [[ "${EXCLUDE}" ]] \ && SEARCH="${SEARCH} | grep -vEi '${EXCLUDE}'" - ## Magic search Fu + ## 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 + + 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 ${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 + + + ## 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" ]] \ + && return + ## Print JSON format (full options) ("--json")? 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} \ - | sort \ + | sort -f \ | 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 )" + | 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 )" + | sort -f )" ## Default view else - OUTPUT="$( eval ${SEARCH} \ + OUTPUT="$( echo "${OUTPUT}" \ + | sed 's_,exploits/_,_; s_,shellcodes/_,_; s_,papers/_,_' \ | awk -F ',' '{ printf "%-'${FORMAT_COL1}'s | %.'${FORMAT_COL2}'s\n", $3, $2 }' \ - | sort )" - #| sed 's_,exploits/_,_; s_,shellcodes/_,_; s_,papers/_,_' \ + | 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/ )" @@ -575,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 @@ -637,6 +733,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 @@ -644,32 +742,32 @@ 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 GETPATH=1 CLIPBOARD=1 + elif [[ "${param}" == "--strict" ]]; then + FUZZY=0 elif [[ "${param}" == "--title" ]]; then 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} @@ -682,7 +780,7 @@ done ## Parse short arguments -while getopts "cehjmnoptuvwx" arg "${ARGS}"; do +while getopts "cehjmnopstuvwx" arg "${ARGS}"; do if [[ "${arg}" = "?" ]]; then usage >&2; fi @@ -695,6 +793,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;; @@ -756,7 +855,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 @@ -774,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' )" @@ -831,7 +930,7 @@ 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 @@ -876,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 + + #-----------------------------------------------------------------------------#