mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-21 08:59:40 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
#!/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.nmb import NetBIOSTimeout
|
||||
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()
|
||||
Reference in New Issue
Block a user