Pular para o conteúdo

Snaffler

Snaffler is a powerful C# tool that discovers and classifies sensitive files across Windows network shares. It hunts for credentials, configuration files, SSH keys, certificates, and other secrets stored on accessible file shares, automating the tedious process of manual share enumeration during red team operations.

The easiest method is downloading precompiled binaries from the official Snaffler GitHub repository:

# Download latest release
Invoke-WebRequest -Uri "https://github.com/SnaffCon/Snaffler/releases/download/v2.1.0/Snaffler.exe" -OutFile "Snaffler.exe"

# Verify execution
.\Snaffler.exe -h

If you need to customize Snaffler or compile it yourself:

# Clone repository
git clone https://github.com/SnaffCon/Snaffler.git
cd Snaffler

# Build with Visual Studio (requires .NET Framework/Core)
msbuild Snaffler.sln /p:Configuration=Release

# Or compile manually with csc.exe
csc.exe /target:exe /out:Snaffler.exe *.cs

Requirements:

  • Windows system (runs on Windows only)
  • .NET Framework 4.6+ or .NET Core 3.1+
  • Network access to target shares
  • Appropriate credentials/domain membership for share enumeration

Launch Snaffler with minimal options to begin discovering sensitive files:

# Basic enumeration with results to stdout
.\Snaffler.exe -s

# Log results to file for later analysis
.\Snaffler.exe -s -o snaffler.log

# Scan with increased verbosity
.\Snaffler.exe -s -o results.log -v verbose

# Scan a specific domain
.\Snaffler.exe -s -d contoso.com -o contoso-findings.log
OptionUsageDescription
-sSnaffler.exe -sOutput results to stdout (console)
-oSnaffler.exe -o file.logWrite results to specified log file
-vSnaffler.exe -v verboseSet verbosity level (quiet, normal, verbose, debug)
-dSnaffler.exe -d contoso.comTarget specific domain name
-cSnaffler.exe -c dc01.contoso.comSpecify domain controller for LDAP queries
-iSnaffler.exe -i C:\ -i D:\Include specific paths (can specify multiple)
-nSnaffler.exe -n "Windows" -n "Temp"Exclude paths matching patterns (can specify multiple)
-jSnaffler.exe -j 20Set maximum thread count (default: 20)
-zSnaffler.exe -z 10485760Skip files larger than specified bytes (10MB example)
-lSnaffler.exe -l 260Skip paths longer than specified characters

Snaffler uses a severity-based classification system to prioritize findings. Results are colored by criticality:

SeverityColorWhat It Catches
BlackBlackExtremely sensitive findings requiring immediate action
RedRedHigh-value secrets and credentials
YellowYellowPotentially sensitive configuration and code files
GreenGreenLow-value informational findings

Black Tier:

  • Plaintext passwords in files
  • Private keys (SSH, PuTTY, OpenVPN, etc.)
  • AWS keys and secrets
  • API credentials and tokens
  • Database connection strings with passwords
  • Active credentials in scripts

Red Tier:

  • Configuration files that may contain secrets
  • Password managers (KeePass .kdbx files, 1Password vaults)
  • Backup files (.bak, .backup, .old)
  • Registry hive files
  • Exchange/Outlook PST files
  • VPN connection files
  • Remote Desktop connection files

Yellow Tier:

  • Source code files (.cs, .java, .py, .js)
  • Build scripts and configuration (gradle, maven, npm)
  • IIS configuration (web.config, applicationHost.config)
  • PowerShell scripts
  • Batch files and shell scripts
  • Configuration management files (ansible, puppet, chef)

Green Tier:

  • Log files
  • Documentation files
  • System information files
  • Other informational content

Snaffler uses a modular rule system to identify sensitive files. Rules can be customized and extended:

Master configuration file controlling which rules are active:

<!-- SnaffRules.xml structure -->
<SnaffRules>
  <ShareRules>
    <ShareRule Scope="Excluded" Path="SYSVOL" />
    <ShareRule Scope="Excluded" Path="NETLOGON" />
  </ShareRules>
  
  <PathRules>
    <PathRule Scope="Excluded" Path="Windows" />
    <PathRule Scope="Excluded" Path="Program Files" />
  </PathRules>
  
  <FileNameRules>
    <FileNameRule Scope="Black" Regex=".*password.*" />
    <FileNameRule Scope="Red" Regex=".*\.kdbx$" />
  </FileNameRules>
  
  <FileContentRules>
    <FileContentRule Scope="Black" Regex="password\s*=|api.?key|secret" />
  </FileContentRules>
</SnaffRules>
Rule TypePurposeExample
ShareRulesInclude/exclude network sharesExclude SYSVOL, NETLOGON, IPC$
PathRulesInclude/exclude directory pathsExclude Windows, System32, Program Files
FileNameRulesMatch file names and extensionsweb.config, *.kdbx, password, *.pem
FileContentRulesSearch file content (regex)password=, api_key:, secret_
FileExtensionRulesTarget specific file types.config, .ps1, .sh, .sql

Create custom SnaffRules.xml for your engagements:

<FileNameRule Scope="Black" Regex=".*\.pem$" />
<FileNameRule Scope="Black" Regex=".*id_rsa.*" />
<FileNameRule Scope="Red" Regex=".*web\.config$" />
<FileNameRule Scope="Red" Regex=".*appsettings\..*json$" />
<FileContentRule Scope="Black" Regex="password\s*[:=].*" />
<FileContentRule Scope="Black" Regex="api.?key.*=.*" />
<FileContentRule Scope="Red" Regex="connectionstring.*=.*" />

Snaffler outputs structured results showing the classification, file path, and content snippet:

[Black] \\fileserver01\developers\src\config.py - Contains: password = "CompanyPassword123!"
[Red] \\fileserver01\shared\web.config - Contains: <connectionString value="Server=...;Password=..." />
[Yellow] \\fileserver02\archive\build.xml - Found in path containing "jenkins"
[Green] \\fileserver01\public\readme.txt - Informational match

Results are typically piped to other tools for analysis:

# Save to log file for review
.\Snaffler.exe -s -o snaffler-results.txt

# Filter for Black/Red severity findings
Select-String "^\[Black\]|^\[Red\]" snaffler-results.txt | Sort-Object | Unique

# Extract just the file paths
Select-String "\\\\.*" snaffler-results.txt -o | % { $_.Matches.Value } > file-list.txt

# Count findings by severity
@((Get-Content snaffler-results.txt | Select-String "^\[Black\]" | Measure-Object).Count, 
  (Get-Content snaffler-results.txt | Select-String "^\[Red\]" | Measure-Object).Count) | % { "Critical: $_" }

Post-processing findings for actionable intelligence:

# Group findings by severity
$findings = Get-Content snaffler-results.txt
$findings | Select-String "^\[" | Group-Object { $_ -replace "^\[(.+?)\].*", '$1' }

# Extract credentials from web.config matches
$findings | Select-String "web\.config" | Select-String "Password|password"

# Find all SSH keys
$findings | Select-String "id_rsa|ssh-rsa|\.pub"

Target individual shares instead of domain-wide enumeration:

# Enumerate a single share
.\Snaffler.exe -s -d "fileserver01\sharename" -o results.log

# Multiple shares
.\Snaffler.exe -s -i "\\fileserver01\developers" -i "\\fileserver02\archive" -o results.log

# UNC paths
.\Snaffler.exe -s -i "\\internal.corp\data" -i "\\backup.corp\archives" -o results.log

Target Distributed File System namespaces:

# DFS root enumeration
.\Snaffler.exe -s -i "\\contoso.com\shares" -o dfs-results.log

# Enumerate all DFS paths
.\Snaffler.exe -s -d contoso.com -o dfs-full.log

Target file shares on specific computers:

# Single computer
.\Snaffler.exe -s -i "\\fileserver01\c$" -o c-drive-results.log

# Multiple target machines
.\Snaffler.exe -s -i "\\computer1\c$" -i "\\computer2\c$" -i "\\computer3\c$" -o shared-drive-results.log

Enumerate shares across IP ranges (requires additional tools):

# Use ShareFinder to generate targets, pipe to Snaffler
foreach ($ip in 10.0.0.1..10.0.0.254) {
    .\Snaffler.exe -s -i "\\$ip\c$" -o results-$ip.log
}

Skip system shares and uninteresting locations:

# Exclude multiple path patterns
.\Snaffler.exe -s -n "Windows" -n "Program Files" -n "ProgramData" -n "Temp" -o results.log

# Exclude by share name
.\Snaffler.exe -s -d contoso.com -n "SYSVOL" -n "NETLOGON" -n "IPC$" -o results.log

# Combine inclusion and exclusion
.\Snaffler.exe -s -i "\\fileserver01\d$" -n "Windows" -n "Pagefile" -o d-drive.log

Snaffler’s performance can be optimized for different environments and constraints:

Adjust thread count based on system resources and target impact:

# Aggressive enumeration (high threads = faster, higher resource use)
.\Snaffler.exe -s -j 50 -o results.log

# Conservative enumeration (low threads = slower, stealthier)
.\Snaffler.exe -s -j 5 -o results.log

# Default (good balance)
.\Snaffler.exe -s -j 20 -o results.log

Skip large files to speed up enumeration:

# Skip files larger than 10MB
.\Snaffler.exe -s -z 10485760 -o results.log

# Skip files larger than 100MB
.\Snaffler.exe -s -z 104857600 -o results.log

# No size limit (scans everything)
.\Snaffler.exe -s -o results.log

Skip excessively long paths:

# Skip paths longer than 260 characters
.\Snaffler.exe -s -l 260 -o results.log

# No path length limit
.\Snaffler.exe -s -l 0 -o results.log

Adjust timeouts for slow networks:

# Snaffler timeout parameters (if supported in your version)
# Reference documentation for timeout syntax
.\Snaffler.exe -s -o results.log

IIS and ASP.NET applications often store database credentials:

# Web.config hunting
.\Snaffler.exe -s -i "C:\inetpub" -o webconfig-findings.log

# Results typically contain:
# <connectionString value="Server=db.corp;User ID=sa;Password=P@ssw0rd!" />

PowerShell, batch, and shell scripts frequently contain plaintext passwords:

# Script enumeration
.\Snaffler.exe -s -n "Windows" -n "Program Files" -o script-findings.log

# Look for:
# -Password "Cr3d3ntial123"
# -ApiKey "sk_live_1234567890"
# password="db_password_here"

KeePass, 1Password, and similar databases are high-value targets:

# Locate password databases
.\Snaffler.exe -s -o password-mgr-findings.log

# Common files:
# *.kdbx (KeePass)
# *.agilekeychain (1Password)
# *.opvault (1Password)

Private keys for SSH, VPN, and code signing:

# SSH key enumeration
.\Snaffler.exe -s -o ssh-findings.log

# Common matches:
# id_rsa, id_dsa, id_ecdsa
# authorized_keys
# *.pem (private key format)
# *.ppk (PuTTY private key)

Application and system configurations often contain sensitive data:

# Configuration file discovery
.\Snaffler.exe -s -o config-findings.log

# Target files:
# web.config, app.config
# appsettings.json, appsettings.Production.json
# config.php, settings.py
# .env, .env.production

CI/CD pipelines and build automation frequently contain credentials:

# Build script enumeration
.\Snaffler.exe -s -i "\\fileserver\builds" -o build-findings.log

# Common files:
# build.xml, build.gradle, pom.xml
# Jenkinsfile, .gitlab-ci.yml
# github-workflows, azure-pipelines.yml

Map discovered shares to BloodHound’s Active Directory:

# Export Snaffler findings for BloodHound correlation
.\Snaffler.exe -s -o snaffler.log

# Use pathnames to identify computers and shares:
# \\computer01\share → Correlate with computer object
# Identify share permissions and access patterns

Combine Snaffler discoveries with CME for credential testing:

# Run Snaffler to find files
.\Snaffler.exe -s -d contoso.com -o findings.log

# Extract credentials and test with CME
# cme smb 10.0.0.0/24 -u domain\user -p password --spider_plus C$

Compare Snaffler results with manual share enumeration:

# Net view for share discovery
net view \\fileserver01 /all

# Manual spider (slower alternative)
dir "\\fileserver01\sharename" /s /b > manual-share-listing.txt

Encountered when lacking permissions on shares:

# Solution: Run as domain user with broader permissions
runas /user:CONTOSO\Domain_Admin cmd.exe
.\Snaffler.exe -s -d contoso.com -o results.log

# Or: Authenticate before running
net use * /delete /y
net use \\fileserver01\ipc$ /user:CONTOSO\username password
.\Snaffler.exe -s -o results.log

Occurs with very large shares or high thread counts:

# Solution: Reduce thread count
.\Snaffler.exe -s -j 5 -o results.log

# Or: Exclude large directories
.\Snaffler.exe -s -j 10 -n "Archive" -n "Backup" -o results.log

# Or: Limit file size
.\Snaffler.exe -s -z 52428800 -o results.log

Network latency or large share sizes:

# Increase threads for faster enumeration
.\Snaffler.exe -s -j 50 -z 10485760 -o results.log

# Or target specific paths
.\Snaffler.exe -s -i "\\fileserver01\developers" -j 40 -o results.log

# Run multiple instances against different shares
.\Snaffler.exe -s -i "\\fileserver01\c$" -o server1.log &
.\Snaffler.exe -s -i "\\fileserver02\c$" -o server2.log &

Check rule configuration and path inclusion:

# Run with verbose output
.\Snaffler.exe -s -v verbose -o verbose-results.log

# Verify shares are accessible
net view \\fileserver01 /all
dir "\\fileserver01\sharename"

# Check rule configuration
# Verify SnaffRules.xml is in correct location and valid XML
  1. Obtain Authorization First - Always have written permission before running Snaffler on production systems.

  2. Run During Maintenance Windows - Schedule enumeration during low-traffic periods to minimize impact.

  3. Start with Rule Validation - Test custom rules on a small set before domain-wide scans.

  4. Monitor Resource Usage - Start with conservative thread counts, increase if needed.

  5. Preserve Results - Log all findings to file for documentation and legal compliance.

  6. Prioritize High-Severity Findings - Focus on Black and Red tier discoveries first.

  7. Clean Up Shares After Engagement - Recommend removing discovered sensitive files and implementing proper secrets management.

  8. Document Share Locations - Create recommendations for share hardening and access control review.

  9. Cross-Reference Findings - Correlate discovered credentials with user accounts via Active Directory.

  10. Test Credentials Responsibly - Only test found credentials in controlled lab environments.

ToolPurposeIntegration
ShareFinderEnumerate network shares across domainsFeed share list to Snaffler targets
CrackMapExecTest credentials and execute commandsSpider shares with spider_plus module
ManSpiderHunt for sensitive files in sharesAlternative to Snaffler with different rules
SeatBeltLocal enumeration of sensitive filesComplement for local share access
BloodHoundMap Active Directory and share permissionsCorrelate Snaffler findings with AD structures
SharpHoundIngestor for BloodHoundCollect share access details
Get-AclEnumerate share permissionsDetermine access to discovered shares