SearchSploit

SearchSploit searches a local copy of the Exploit-DB archive: feed it a product, a version, or a CVE and it returns the matching public exploit titles and the on-disk path to each proof-of-concept file. Reach for it right after enumeration, the moment Nmap or a banner hands you software and a version and you want to know what public research already exists before you run anything.

Mental model: searchsploit [options] terms. Terms are AND-matched words; everything else is one flag away.

New to Exploit-DB? Core concepts
  • Local database: SearchSploit reads an on-disk copy of Exploit-DB (titles plus a files_exploits.csv index), not the live website
  • AND-matched terms: every word must appear, so more words narrow results, they never widen them, for example searchsploit apache 2.4
  • EDB-ID: each entry has a numeric Exploit-DB ID; it is the stable handle for -x, -m, and -p
  • Title vs path: the left column is the human title, the right column is the file path on disk
  • The filename is the EDB-ID: exploits/linux/local/12345.py is EDB-ID 12345
  • Category in the path: /remote/, /webapps/, /local/, /dos/ tell you the exploit class at a glance
  • Content types: the archive holds exploit code, raw shellcode, and write-up papers
  • Search is not validation: a hit means a public entry exists, nothing about your target’s real exploitability
When to reach for SearchSploit (and when not)

Reach for it to turn a version banner into a shortlist of public exploits to read, check what is publicly known about software you run, map known issues for a discovered product and version, work fully offline once the database is on disk, or triage whether a service is worth deeper manual testing before you invest time.

Reach for something else when you have no product or version yet (enumerate first with nmap -sV), when you need a scanner that actually tests the host (nmap NSE, nuclei, a real vuln scanner), when you want the freshest research the minute it drops (the exploit-db.com site or a web search may be ahead of your local copy), or when you want a maintained, tested exploit path (msfconsole search).

Install, update, verify#

sudo apt install -y exploitdb                    # Debian / Ubuntu / Kali
sudo dnf install -y exploitdb                    # Fedora / RHEL (via EPEL)
brew install exploitdb                           # macOS (Homebrew)
sudo apt install --only-upgrade -y exploitdb     # update the package

searchsploit -u                    # refresh the local archive in place (deb + git installs)
command -v searchsploit             # confirm it is on PATH
searchsploit afd windows local      # self-test: prints the classic populated table

No distro package? Clone the archive and link the script; searchsploit -u (or git -C /opt/exploitdb pull) keeps it current.

sudo git clone https://gitlab.com/exploit-database/exploitdb.git /opt/exploitdb
sudo ln -sf /opt/exploitdb/searchsploit /usr/local/bin/searchsploit

Flags you’ll actually use#

Skim these first; the cheat sheet below is these flags combined.

FlagDoesFlagDoes
-tTitle-only search (default also matches the path)-pPrint the full path for an EDB-ID (copies to clipboard)
-eExact, ordered title match (implies -t)-mMirror: copy an exploit into the current folder
-sStrict version match, no fuzzy ranges-xExamine an exploit in $PAGER (no copy)
-cCase-sensitive search-jJSON output for scripting
--excludeDrop rows containing a term (chain with ``)-w
--cveMatch a CVE ID--idShow the EDB-ID instead of the path
--nmapSearch every service in an Nmap XML file-oLet long titles overflow their column
-uUpdate the local archive-vVerbose: show CVE description lines

Cheat sheet#

Every block starts simple and adds one flag at a time, so you can stop at the line that does the job.

# Update the local archive first (a stale DB means stale results)
searchsploit -u

# Build up a search: stop at the line that is specific enough
searchsploit PRODUCT                        # 1. broad, see what exists
searchsploit PRODUCT VERSION                # 2. + version (terms are AND-matched)
searchsploit -t PRODUCT VERSION             # 3. + title only, drop path-match noise
searchsploit -e "PRODUCT VERSION"           # 4. + exact, in-order title match
searchsploit -s PRODUCT 2.4.7               # 5. + strict, no fuzzy version ranges

# Match a known CVE
searchsploit --cve 2021-3156                # entries tagged with that CVE
searchsploit -v --cve 2021-3156             # + description lines

# Cut the noise
searchsploit PRODUCT --exclude="dos"        # drop a category
searchsploit PRODUCT --exclude="dos|/tmp"   # drop several at once (chain with |)
searchsploit PRODUCT | grep -i remote       # keep only remote entries
searchsploit -c PRODUCT                     # case-sensitive when a term is generic

# Read before you trust
searchsploit -x 12345                       # open the exploit in the pager (no copy)
searchsploit -p 12345                       # print its full local path (copies to clipboard)
searchsploit --id PRODUCT VERSION           # list results as EDB-IDs, not paths

# Pull code into the lab folder to review
searchsploit -m 12345                       # copy the file to the current directory

# Machine-readable and notes
searchsploit -j PRODUCT VERSION | jq .      # JSON, filter with jq
searchsploit -w PRODUCT                     # Exploit-DB URLs instead of paths
searchsploit PRODUCT VERSION | tee notes/ss.txt   # capture while you watch

# Triage straight from a scan
nmap -sV -oX scan.xml TARGET_IP             # produce service-version XML
searchsploit --nmap scan.xml                # search every service Nmap found

Command breakdowns#

Each block below explains one situation, the exact command, and what to expect back.

Turn a version banner into a shortlist#

searchsploit PRODUCT VERSION

Start with the product, then add the version Nmap reported. Terms are AND-matched, so each extra word narrows the table. Skim titles and paths and treat every row as a lead to read, not a confirmed hit.

Narrow a noisy product search to titles#

searchsploit -t PRODUCT

By default SearchSploit matches your terms against both the title and the file path, which drags in unrelated entries. -t restricts the match to the title, usually a much cleaner table.

Match an exact product and version#

searchsploit -e "PRODUCT 2.4.7"

-e requires an exact, in-order title match and implies -t. Use it when a loose search buries the one entry you want. Note that a non-consecutive phrase misses if the words are not adjacent in the title.

Pin a strict version so ranges do not fuzz in#

searchsploit -s PRODUCT 2.4.7

Without -s, SearchSploit fuzzy-matches versions, so 2.4.7 can surface an entry written for a 2.4.x range. -s forces your exact input to appear. If it then returns nothing, re-check by hand rather than assuming the target is safe.

Search by CVE, and read the description#

searchsploit --cve 2021-3156
searchsploit -v --cve 2021-3156

--cve matches entries tagged with that CVE in the local archive. Add -v to print the description lines so you can confirm the entry is the right bug before chasing it.

Drop denial-of-service and other noise#

searchsploit PRODUCT --exclude="dos"
searchsploit PRODUCT --exclude="dos|json|/tmp"

--exclude removes any row containing the term; chain several with |. DoS entries and stub PoCs are the usual noise you want gone when hunting for something that yields access.

Read an exploit without copying it#

searchsploit -x 12345

-x opens the file for that EDB-ID in $PAGER so you can read it in place. Always read before you trust: the “exploit” is source you must vet line by line.

Copy an exploit into your lab folder#

searchsploit -m 12345

-m mirrors (copies) the file for that EDB-ID into the current directory, keeping its name. Run it inside a per-engagement folder, then read the whole thing before you execute anything.

searchsploit -p 12345

-p prints the full path to the file on disk and, where a clipboard tool is present, copies it. Handy for feeding the path straight into an editor or a cat.

Show Exploit-DB URLs instead of local paths#

searchsploit -w PRODUCT

-w swaps the path column for the exploit-db.com URL, so you can open the entry in a browser for the full write-up, comments, and any newer context.

Output JSON for scripts and notes#

searchsploit -j PRODUCT VERSION | jq '.RESULTS_EXPLOIT[].Path'

-j prints structured JSON. Pipe it into jq to pull just the paths, EDB-IDs, or titles into a script or a clean note instead of scraping the table.

Triage straight from an Nmap scan#

nmap -sV -oX scan.xml TARGET_IP
searchsploit --nmap scan.xml

--nmap reads the service and version data from Nmap’s XML and runs a search for each. It is a fast first pass; expect broad, noisy results and treat every hit as a lead to verify.

Save every search to a timestamped note#

searchsploit PRODUCT VERSION 2>&1 | tee "notes/ss-$(date +%Y%m%d-%H%M).txt"

tee writes the table to a dated file while you still see it. Keep one note per EDB-ID with its CVE and whether the version actually matched, so your evidence trail stays clean.

Reading the output#

Path segmentExploit classWhat it means
/remote/Runs against a service over the networkOften the highest-value lead
/webapps/Web application exploitCommon for web boxes
/local/Needs a local shell alreadyPrivilege escalation, post-foothold
/dos/Denial of service onlyRarely a path to access; --exclude it
/shellcode/Raw shellcode, not a full exploitA building block, not a drop-in

The left column is the human title; the right column is the on-disk path, whose filename (minus extension) is the EDB-ID you pass to -x, -m, and -p. A hit is a public entry, never proof your target is vulnerable: version, config, and patch level still decide.

Troubleshooting#

ProblemCauseFix
command not foundexploitdb not installed / stale PATHReinstall; open a fresh shell or fix the symlink
Exploits: No Results for a known queryEmpty or unset databaseRun searchsploit -u; check the DB path in .searchsploit.rc
Zero rows when you expect hitsToo many AND-matched termsDrop a word, try -t, or search the product alone
Update fails or hangsNo network / blocked git or HTTPSCheck connectivity; for git installs git -C /opt/exploitdb pull
Too many irrelevant rowsTerms matched the path, not the titleAdd -t, then --exclude categories
A known-vuln version missesDB stores the version differentlySearch the product alone, or drop -s; verify by hand
-m writes nothingWrong EDB-ID or no write permissionConfirm the ID with -p; copy into a writable folder
Colours garble a saved fileANSI codes piped to diskAdd --colour to disable highlighting

Gotchas#

  • Terms are AND-matched, not OR. Every word must appear, so a long query narrows to nothing. When an expected hit vanishes, drop a term rather than concluding the entry does not exist.
  • A match is a lead, never a verdict. The archive does not know your target’s real version, config, or patch level; a title hit proves only that public code exists.
  • --colour disables colour (the naming is backwards), and piped ANSI codes corrupt saved output, so add it when you tee or grep results into files.
  • Fuzzy version matching is on by default. searchsploit PRODUCT 2.4.7 can surface entries for a whole 2.4.x range; add -s to force your exact string, then re-check by hand if it returns nothing.
  • The search touches nothing; running the code is the loud part. Reading the database sends no packets. Every consequence (logs, IDS, EDR) begins only when you execute a mirrored exploit, so vet it in full and stay in scope.

Pairs with#

nmap -sV supplies the product and version every search depends on, and --nmap reads its XML directly. jq slices the -j JSON into clean notes, while grep and awk filter the table down to remote or webapps rows. For a maintained, tested path against a confirmed in-scope finding, an msfconsole search beats running raw files. When your local copy lags, the exploit-db.com site (via -w) carries the freshest entries and the full context around each one.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop