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.csvindex), 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.pyis EDB-ID12345 - 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.
| Flag | Does | Flag | Does |
|---|---|---|---|
-t | Title-only search (default also matches the path) | -p | Print the full path for an EDB-ID (copies to clipboard) |
-e | Exact, ordered title match (implies -t) | -m | Mirror: copy an exploit into the current folder |
-s | Strict version match, no fuzzy ranges | -x | Examine an exploit in $PAGER (no copy) |
-c | Case-sensitive search | -j | JSON output for scripting |
--exclude | Drop rows containing a term (chain with ` | `) | -w |
--cve | Match a CVE ID | --id | Show the EDB-ID instead of the path |
--nmap | Search every service in an Nmap XML file | -o | Let long titles overflow their column |
-u | Update the local archive | -v | Verbose: 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.
Print (and clipboard) a file path for an EDB-ID#
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 segment | Exploit class | What it means |
|---|---|---|
/remote/ | Runs against a service over the network | Often the highest-value lead |
/webapps/ | Web application exploit | Common for web boxes |
/local/ | Needs a local shell already | Privilege escalation, post-foothold |
/dos/ | Denial of service only | Rarely a path to access; --exclude it |
/shellcode/ | Raw shellcode, not a full exploit | A 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#
| Problem | Cause | Fix |
|---|---|---|
command not found | exploitdb not installed / stale PATH | Reinstall; open a fresh shell or fix the symlink |
Exploits: No Results for a known query | Empty or unset database | Run searchsploit -u; check the DB path in .searchsploit.rc |
| Zero rows when you expect hits | Too many AND-matched terms | Drop a word, try -t, or search the product alone |
| Update fails or hangs | No network / blocked git or HTTPS | Check connectivity; for git installs git -C /opt/exploitdb pull |
| Too many irrelevant rows | Terms matched the path, not the title | Add -t, then --exclude categories |
| A known-vuln version misses | DB stores the version differently | Search the product alone, or drop -s; verify by hand |
-m writes nothing | Wrong EDB-ID or no write permission | Confirm the ID with -p; copy into a writable folder |
| Colours garble a saved file | ANSI codes piped to disk | Add --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.
--colourdisables colour (the naming is backwards), and piped ANSI codes corrupt saved output, so add it when youteeorgrepresults into files.- Fuzzy version matching is on by default.
searchsploit PRODUCT 2.4.7can surface entries for a whole2.4.xrange; add-sto 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.