Skip to main content

Search SMB shares for interesting files

Project description

SmbCrawler

SmbCrawler is no-nonsense tool that takes credentials and a list of hosts and 'crawls' (or 'spiders') through those shares. Features:

  • takes host names, IP addresses, IP ranges, or an nmap xml file as input
  • checks permissions (check for 'write' permissions is opt-in, because it requires creating an empty directory on the share)
  • crawling depth is customizable
  • outputs results in machine-readable formats or as an interactive HTML report
  • pass-the-hash support
  • auto-download interesting files
  • report potential secrets
  • threaded
  • pausable
  • interactively skip single shares and hosts

Installation

If you require instructions on how to install a Python package, I recommend you make sure you have pipx installed and run pipx install smbcrawler.

SmbCrawler can automatically convert some binary files like PDF, XLSX, DOCX, ZIP, etc. to plain text using MarkItDown. Because this package is pulling a lot of dependencies, it is marked as an extra. However, it is highly recommended to get the best results. If you want to automatically convert binaries, install SmbCrawler like this:

pipx install 'smbcrawler[binary-conversion]'

Adding shell completion is highly recommended. As a Python app using the click library, you can add tab completion to bash, zsh and fish using the usual mechanism.

Example

Run it like this (10 threads, maximum depth 5):

$ smbcrawler crawl -i hosts.txt -u pen.tester -p iluvb0b -d contoso.local -t 10 -D 5

Major changes in version 1.0

SmbCrawler has undergone a major overhaul. The most significant changes are:

  • We cleaned up the CLI and introduced a "profile" mechanism to steer the behavior of the crawler
  • The output is now a sqlite database instead of scattered JSON files
  • Permissions are now reported more granularly

The old CLI arguments regarding "interesting files", "boring shares" and so on was clunky and confusing. Instead we now use "profiles; see below for details.

Also, I realized I basically reinvented relational databases, except did so very poorly, so why not use sqlite directly? The sqlite approach enables us to produce a nice interactive HTML report with good performance. You can still export results in various formats if you need to use the data in some tool pipeline.

The old way SmbCrawler reported permissions sometimes wasn't very useful. For example, it's not uncommon that you have read permissions in the root directory of the share, but all sub directories are protected, e.g. for user profiles. SmbCrawler will now report how deep it was able to read the directory tree of a share and whether it maxed out or could have gone deeper if you had supplied a higher value for the maximum depth argument.

If you prefer the old version, it's still available on PyPI and installable with pipx install smbcrawler==0.2.0, for example.

Usage

During run time, you can use the following keys:

  • p: pause the crawler and skip single hosts or shares
  • <space>: print the current progress
  • s: print a more detailed status update

For more information, run smbcrawler -h.

Notes

Even in medium sized networks, SmbCrawler will find tons of data. The challenge is to reduce false positives.

Notes on permissions

It's important to realize that permissions can apply on the service level and on the file system level. The remote SMB service may allow you to authenticate and your user account may have read permissions in principle, but it could lack these permissions on the file system.

SmbCrawler will report if you have permissions to:

  • authenticate against a target as guest and list shares
  • authenticate against a target with the user creds
  • access a share as guest
  • access a share with the user creds
  • create a directory in the share's root directory
  • the deepest directory level of a share that could be accessed (limited by the --depth argument)

Because it is non-trivial to check permissions of SMB shares without attempting the action in question, SmbCrawler will attempt to create a directory on each share. Its name is smbcrawler_DELETEME_<8 random characters> and will be deleted immediately, but be aware anyway.

[!WARNING] Sometimes you have the permission to create directories, but not to delete them, so you will leave an empty directory there.

Profiles

To decide what to do with certain shares, files or directories, SmbCrawler has a feature called "profiles". Take a look at the default profile.

Profiles are loaded from files with extensions *.yml or *.yaml from these locations:

  • The built-in default profile
  • $XDG_DATA_HOME/smbcrawler/ (~/.local/share/smbcrawler by default)
  • The current working directory
  • The extra directory defined by --extra-profile-directory
  • The extra files defined by --extra-profile-file

Profiles from each location override previous definitions.

The regex value defines whether a profile matches, and the last matching profile will be used. All regular expressions are case-insensitive, mirroring the most common behavior in the Windows world.

Since it can be confusing how profiles from different sources work together, make sure to make use of the --dry-run parameter. It shows you the effective configuration and does nothing more.

Let's look at each section, which is always a list of dictionaries. Each of the keys of the dictionary is an arbitrary label and each of the values is again a dictionary with different properties.

Files

  • comment: A helpful string describing this profile
  • regex: A regular expression that defines which files this profile applies to. The last regex that matches is the one that counts.
  • regex_flags: An array of flags which will be passed to the regex match function
  • high_value (default: false): If a file is "high value", its presence will be reported, but it will not necessarily be downloaded (think virtual hard drives - important, but too large to download automatically)
  • download (default: true): If true, the first 200KiBi will be downloaded (or the entire file if high_value=true) and parsed for secrets

Shares and directories

  • comment, regex, regex_flags: Same as above
  • high_value: its presence will be reported and crawl depth changed to infinity
  • crawl_depth: Crawl this share or directory up to a different depth than what is defined by the --depth argument

Secrets

  • comment, regex_flags: Same as above
  • regex: A regular expression matching the secret. The secret itself can be a named group with the name secret.

Typical workflow

It makes sense to first run SmbCrawler with crawling depth 0 to get an idea of what you're dealing with. In this first run, you can enable the write check with -w:

$ smbcrawler -C permissions_check.crwl crawl -D0 -t10 -w \
    -i <INPUT FILE> -u <USER> -d <DOMAIN> -p <PASSWORD>

Afterwards, you can identify interesting and boring shares for your next run or several runs. Some shares like SYSVOL and NETLOGON appear many times, so you should set the crawl depth to zero on your next run and pick one host to scan these duplicate shares in a third run. Here is an example:

$ smbcrawler -C dc_only.crwl crawl -D -1 <DC IP> \
    -u <USER> -d <DOMAIN> -p <PASSWORD>
$ smbcrawler -C full.crwl crawl -D5 -t10 -i <NEW INPUT FILE> \
    -u <USER> -d <DOMAIN> -p <PASSWORD> \
    --extra-profile-file skip_sysvol.yml

Here, skip_sysvol.yml would be:

shares:
  sysvol:
    comment: "Skip sysvol and netlogon share"
    regex: 'SYSVOL|NETLOGON'
    crawl_depth: 0

Feel free to include other shares here which you may think are not worth crawling.

Output

The raw data is contained in an SQLite database and a directory (output.crwl and output.crwl.d by default). The directory contains two more directories: one with the downloaded files unique-ified by the hash content and a directory mirroring all shares with symlinks pointing to the content files. The latter is good for grepping through all downloaded files.

The data can be transformed to various formats. You can also simply access the database with sqlitebrowser, for example. Some useful views have been pre-defined. Or you can output JSON and use jq to mangle the data.

If you want to display all shares that you were able to read beyond the root directory in a LaTeX table, for instance, use this query:

SELECT target_id || " & " || name || " & " || remark || " \\"
FROM share
WHERE read_level > 0
ORDER BY target_id, name

There is also an experimental HTML output feature. It may not be entirely useful yet for large amounts of data.

Help out

If you notice a lot of false positives or false negatives in the reported secrets, please help out and let me know. Community input is important when trying to improve automatic detection. Best case scenario: provide a pull request with changes to the default profile file.

Credits

Adrian Vollmer, SySS GmbH

License

MIT License; see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smbcrawler-1.1.1.tar.gz (650.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smbcrawler-1.1.1-py3-none-any.whl (659.2 kB view details)

Uploaded Python 3

File details

Details for the file smbcrawler-1.1.1.tar.gz.

File metadata

  • Download URL: smbcrawler-1.1.1.tar.gz
  • Upload date:
  • Size: 650.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.0

File hashes

Hashes for smbcrawler-1.1.1.tar.gz
Algorithm Hash digest
SHA256 cb5aa6e2cedc082c79adaf7b79a6c115cac6ded3594d0e1bef9567261d36bf89
MD5 a55c47e410e1deb49c4484e80d020b12
BLAKE2b-256 cc8071136ce7a4362467c1e711e39337c0bcfbd002eb225958f3c473e584a589

See more details on using hashes here.

File details

Details for the file smbcrawler-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: smbcrawler-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 659.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.0

File hashes

Hashes for smbcrawler-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 34dfb153de7b4deb9c2672e93c5fbb56ad2c680fd60cb93a23e39604e768bf9b
MD5 2fed547d5ad7ca494230e69e622ff302
BLAKE2b-256 4e9512cfea43978f2c85b5fb5057417cb6a203c2c5d87ed79917a8102f5db4e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page