SMB-Check: When a 50-Line Bash Script Beats Your Security Scanner
Hook
The most effective penetration testing tools aren't always the ones with the most stars on GitHub—sometimes they're the 50-line bash scripts that do exactly one thing without requiring a Python virtual environment, a Docker container, or three hours of reading documentation.
Context
Network administrators and penetration testers face a recurring challenge: quickly discovering which Windows file shares are accessible across dozens or hundreds of hosts. Whether you're conducting an internal security audit, running a red team engagement, or simply trying to understand your organization's SMB exposure before the next ransomware campaign does, you need to enumerate SMB shares at scale.
Traditionally, this meant either manually running smbclient against each host (tedious and error-prone), scripting your own solution (reinventing the wheel), or deploying heavyweight frameworks like Metasploit or CrackMapExec (overkill for simple reconnaissance). The smb-check repository addresses this gap with an unapologetically minimal approach: a bash wrapper around smbclient that reads a list of IPs and outputs what's accessible. No installation. No dependencies beyond standard Samba tools. No framework lock-in. Just a script that assumes you understand SMB enumeration and want to automate the repetitive parts.
Technical Insight
At its core, smb-check is a study in deliberate simplicity. The script's architecture is a straightforward pipeline: read IP addresses from an input file, iterate through each one, invoke smbclient with specified credentials, parse the output, and write results to a log file. What makes it interesting isn't complexity—it's the conscious decisions about what not to include.
The main loop structure reveals the tool's philosophy:
while IFS= read -r ip; do
echo "[*] Testing $ip"
smbclient -L //$ip -U "$DOMAIN/$USERNAME%$PASSWORD" -g 2>&1 | \
grep -E "Disk|IPC" | \
while IFS='|' read -r type name comment; do
echo "$ip|$name|$comment" >> $OUTPUT_FILE
done
done < "$INPUT_FILE"
This snippet demonstrates the script's core pattern: the -g flag puts smbclient into "grepable" mode, which outputs pipe-delimited fields instead of human-readable tables. The output is then filtered for share types (Disk and IPC$), parsed by field separator, and logged in a structured format. It's bash one-liner culture applied to security tooling—maximizing the capabilities of existing command-line tools through composition rather than reimplementation.
The credential handling mechanism is similarly pragmatic. Rather than implementing complex argument parsing or interactive prompts, smb-check expects you to edit variables at the top of the script:
DOMAIN="WORKGROUP"
USERNAME=""
PASSWORD=""
INPUT_FILE="ips.txt"
OUTPUT_FILE="smb_results.txt"
Empty username and password values trigger anonymous authentication, which is exactly what you want when initially mapping an unknown network. For authenticated scans, you modify the script directly—a workflow that sounds primitive but is actually faster than remembering command-line flag syntax when you're in the middle of a time-boxed engagement.
The error handling—or deliberate lack thereof—is where the script's limitations become architectural choices. The author explicitly acknowledges that certain NT_STATUS codes aren't properly handled, resulting in malformed output lines. Rather than trying to enumerate every possible SMB error condition (a sisyphean task given the protocol's complexity), the script embraces imperfection and delegates cleanup to downstream tools:
# Post-processing to clean malformed entries
grep -v "NT_STATUS" smb_results.txt > cleaned_results.txt
This Unix philosophy approach—do one thing, accept that output will need further processing—makes the script maintainable and transparent. You can read the entire implementation in minutes and understand exactly what it's doing, which is valuable when you're running security tools that you need to trust.
The sequential execution model is another deliberate simplification. While parallel execution would dramatically improve scan times for large networks, it would also require significantly more code (job control, rate limiting, output synchronization). For networks under a few hundred hosts, sequential scanning is acceptable, and the lack of concurrency complexity means fewer edge cases and failure modes. You can always wrap the script in GNU Parallel if you need concurrency without modifying the source.
Gotcha
The script's simplicity comes with real limitations that you'll hit immediately on anything beyond small, controlled scans. The most significant issue is the incomplete error handling that the author candidly documents. SMB is a notoriously complex protocol with dozens of possible error responses—authentication failures, access denials, protocol version mismatches, timeout conditions, and various NT_STATUS codes. The script captures and logs some of these, but others slip through, creating malformed output lines that corrupt your results file. You'll need to post-process the output with grep, sed, or awk to filter garbage, which defeats some of the automation value.
The hardcoded configuration approach becomes painful if you're running multiple scans with different parameters. Want to test both anonymous and authenticated access? You're modifying the script, running it, then modifying it again. Need different timeout values for different network segments? More script editing. The lack of command-line arguments means you can't easily integrate this into larger automation frameworks without wrapping it in yet another script. Additionally, the sequential execution model that seemed reasonable for 50 hosts becomes agonizingly slow at 500+ hosts, especially when scanning networks with high latency or many unresponsive IPs. There's no built-in timeout mechanism beyond smbclient's defaults, so dead hosts can hang your scan for extended periods.
Verdict
Use if: You're conducting a quick penetration test or security audit on a small to medium network (under 200 hosts), you value transparency and simplicity over features, you're already comfortable with smbclient and bash scripting, and you need something you can audit and modify in minutes rather than hours. This tool excels in scenarios where you need a disposable, trustworthy script that does exactly what it says without hidden behaviors, complex dependencies, or framework overhead. It's perfect for the consultant who needs to drop onto a client network, enumerate SMB shares during a four-hour assessment window, and move on.
Skip if: You're scanning large networks where sequential execution would be prohibitively slow, you need robust error handling and production-grade reliability, you want extensive output formatting or integration with reporting tools, or you're uncomfortable with post-processing malformed output. For enterprise-scale assessments, ongoing monitoring, or situations where comprehensive enumeration is critical, use CrackMapExec (parallel execution, better error handling, extensive features), enum4linux-ng (structured output, modern Python implementation), or nmap's SMB NSE scripts (integration with broader network scanning). The 80/20 rule applies here: smb-check handles 80% of use cases with 20% of the complexity, but that remaining 20% of edge cases will require different tooling.