Skip to content

Commit

Permalink
Set "fuzzy" as default behaviour (to revert, need to use new "--stric…
Browse files Browse the repository at this point in the history
…t" option)
  • Loading branch information
g0tmi1k committed Apr 27, 2020
1 parent 9d47cfa commit 4dd344c
Showing 1 changed file with 120 additions and 15 deletions.
135 changes: 120 additions & 15 deletions searchsploit
Original file line number Diff line number Diff line change
@@ -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,33 +616,33 @@ 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} \
| 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 -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;;

0 comments on commit 4dd344c

Please sign in to comment.