threat hunting

Detecting DCSync Attack in Active Directory

Detect DCSync attacks where adversaries abuse Active Directory replication privileges to extract password hashes by monitoring for non-domain-controller accounts requesting directory replication via DsGetNCChanges.

active-directorycredential-theftdcsynckerberosmimikatzmitre-t1003-006threat-hunting
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • When hunting for credential theft in Active Directory environments
  • After compromise of accounts with Replicating Directory Changes permissions
  • When investigating suspected use of Mimikatz or Impacket secretsdump
  • During incident response involving lateral movement with domain admin credentials
  • When auditing AD replication permissions as part of security hardening

Prerequisites

  • Windows Security Event Logs with Event ID 4662 (Object Access) enabled
  • Advanced Audit Policy: Audit Directory Service Access enabled
  • Domain Controller event forwarding to SIEM
  • Knowledge of legitimate domain controller hostnames and IPs
  • Directory Service Access auditing with SACL on domain object

Workflow

  1. Identify Legitimate Replication Sources: Document all domain controllers in the environment by hostname, IP, and computer account. Only these should perform directory replication.
  2. Enable Required Auditing: Configure Advanced Audit Policy to capture Event ID 4662 on domain controllers with specific GUID monitoring for replication rights.
  3. Monitor Replication Rights Access: Track access to three critical GUIDs -- DS-Replication-Get-Changes (1131f6aa-9c07-11d1-f79f-00c04fc2dcd2), DS-Replication-Get-Changes-All (1131f6ad-9c07-11d1-f79f-00c04fc2dcd2), and DS-Replication-Get-Changes-In-Filtered-Set (89e95b76-444d-4c62-991a-0facbeda640c).
  4. Detect Non-DC Replication Requests: Alert when any account NOT associated with a domain controller requests replication rights.
  5. Correlate with Network Traffic: DCSync generates replication traffic (MS-DRSR/RPC) from the attacker's machine to the DC. Monitor for DrsGetNCChanges RPC calls from non-DC IP addresses.
  6. Investigate Source Context: Examine the process, user account, and machine originating the replication request.
  7. Check for Credential Abuse: After DCSync detection, audit for subsequent use of extracted hashes (pass-the-hash, golden ticket creation).

Key Concepts

Concept Description
T1003.006 OS Credential Dumping: DCSync
DCSync Mimicking domain controller replication to extract credentials
DsGetNCChanges RPC function used to request AD replication data
DS-Replication-Get-Changes AD permission required (GUID: 1131f6aa-...)
DS-Replication-Get-Changes-All Permission including confidential attributes (GUID: 1131f6ad-...)
MS-DRSR Microsoft Directory Replication Service Remote Protocol
KRBTGT Hash Key target of DCSync enabling Golden Ticket attacks
Event ID 4662 Directory service object access audit event

Tools & Systems

Tool Purpose
Mimikatz (lsadump::dcsync) Primary DCSync attack tool
Impacket secretsdump.py Python-based DCSync implementation
DSInternals PowerShell module for AD replication
BloodHound Map accounts with replication rights
Splunk / Elastic SIEM correlation of 4662 events
Microsoft Defender for Identity Native DCSync detection
CrowdStrike Falcon EDR-based DCSync detection

Detection Queries

Splunk -- DCSync Detection via Event 4662

index=wineventlog EventCode=4662
| where Properties IN ("*1131f6aa-9c07-11d1-f79f-00c04fc2dcd2*",
    "*1131f6ad-9c07-11d1-f79f-00c04fc2dcd2*",
    "*89e95b76-444d-4c62-991a-0facbeda640c*")
| where NOT match(SubjectUserName, ".*\\$$")
| where NOT SubjectUserName IN ("known_svc_account1", "known_svc_account2")
| stats count values(Properties) as ReplicationRights by SubjectUserName SubjectDomainName Computer
| where count > 0
| table SubjectUserName SubjectDomainName Computer count ReplicationRights

KQL -- Microsoft Sentinel DCSync Detection

SecurityEvent
| where EventID == 4662
| where Properties has "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"
    or Properties has "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"
| where SubjectUserName !endswith "$"
| where SubjectUserName !in ("AzureADConnect", "MSOL_*")
| project TimeGenerated, SubjectUserName, SubjectDomainName, Computer, Properties
| sort by TimeGenerated desc

Sigma Rule -- DCSync Activity

title: DCSync Activity Detected - Non-DC Replication Request
status: stable
logsource:
    product: windows
    service: security
detection:
    selection:
        EventID: 4662
        Properties|contains:
            - '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2'
            - '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'
    filter_dc:
        SubjectUserName|endswith: '$'
    condition: selection and not filter_dc
level: critical
tags:
    - attack.credential_access
    - attack.t1003.006

Common Scenarios

  1. Mimikatz DCSync: Attacker with Domain Admin privileges runs lsadump::dcsync /user:krbtgt to extract KRBTGT hash for Golden Ticket creation.
  2. Impacket secretsdump: Remote DCSync via secretsdump.py domain/user:password@dc-ip extracting all domain hashes.
  3. Delegated Replication Rights: Attacker grants themselves Replicating Directory Changes rights via ACL modification before performing DCSync.
  4. Azure AD Connect Abuse: Compromising the Azure AD Connect service account which has legitimate replication rights.
  5. DSInternals PowerShell: Using Get-ADReplAccount cmdlet to replicate specific account credentials.

Output Format

Hunt ID: TH-DCSYNC-[DATE]-[SEQ]
Alert Severity: Critical
Source Account: [Account requesting replication]
Source Machine: [Hostname/IP of requestor]
Target DC: [Domain controller receiving request]
Replication Rights: [GUIDs accessed]
Timestamp: [Event time]
Legitimate DC: [Yes/No]
Known Service Account: [Yes/No]
Risk Assessment: [Critical - non-DC replication detected]
Source materials

References and resources

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

References 3

api-reference.md2.0 KB

API Reference: Detecting DCSync Attack in Active Directory

DCSync Replication GUIDs

GUID Right
1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 DS-Replication-Get-Changes
1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 DS-Replication-Get-Changes-All
89e95b76-444d-4c62-991a-0facbeda640c DS-Replication-Get-Changes-In-Filtered-Set

Windows Event ID 4662 Fields

<EventID>4662</EventID>
<Data Name="SubjectUserName">attacker</Data>
<Data Name="SubjectDomainName">CORP</Data>
<Data Name="Properties">{1131f6ad-9c07-11d1-f79f-00c04fc2dcd2}</Data>
<Data Name="ObjectName">DC=corp,DC=local</Data>

python-evtx Usage

import Evtx.Evtx as evtx
with evtx.Evtx("Security.evtx") as log:
    for record in log.records():
        xml = record.xml()
        # Filter for EventID 4662 with replication GUIDs

Splunk SPL Detection Query

index=wineventlog EventCode=4662
| where Properties IN ("*1131f6aa*", "*1131f6ad*", "*89e95b76*")
| where NOT match(SubjectUserName, ".*\\$$")
| stats count values(Properties) by SubjectUserName Computer

KQL (Microsoft Sentinel)

SecurityEvent
| where EventID == 4662
| where Properties has "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"
| where SubjectUserName !endswith "$"
| project TimeGenerated, SubjectUserName, Computer, Properties

PowerShell - Audit Replication Permissions

$domain = (Get-ADDomain).DistinguishedName
$acl = Get-Acl "AD:\$domain"
$acl.Access | Where-Object {
    $_.ObjectType -in @(
        '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2',
        '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'
    )
} | Select IdentityReference, ObjectType

Attack Tools Reference

Tool Command
Mimikatz lsadump::dcsync /user:krbtgt /domain:corp.local
Impacket secretsdump.py corp/admin:pass@dc-ip
DSInternals Get-ADReplAccount -SamAccountName krbtgt

CLI Usage

python agent.py --security-log Security.evtx --dc-accounts known_dcs.txt
python agent.py --generate-sigma
python agent.py --check-perms
standards.md2.3 KB

Standards and References - DCSync Attack Detection

MITRE ATT&CK Credential Access (TA0006)

Technique Name Relevance
T1003.006 OS Credential Dumping: DCSync Primary technique
T1003.001 LSASS Memory Often combined with DCSync for complete credential theft
T1003.003 NTDS Alternative to DCSync using ntdsutil or volume shadow copy
T1078.002 Valid Accounts: Domain Accounts Using dumped credentials
T1558.001 Steal or Forge Kerberos Tickets: Golden Ticket Primary goal of KRBTGT hash extraction
T1222.001 File and Directory Permissions Modification Granting replication rights

Critical Replication GUIDs

GUID Permission Name Risk
1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 DS-Replication-Get-Changes Required for DCSync
1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 DS-Replication-Get-Changes-All Includes confidential attributes (passwords)
89e95b76-444d-4c62-991a-0facbeda640c DS-Replication-Get-Changes-In-Filtered-Set Partial replication rights

Windows Event IDs for DCSync Detection

Event ID Source Description
4662 Security Directory Service Object Access (primary detection)
4624 Security Successful logon (correlate source of replication)
4672 Security Special privileges assigned (admin logon)
4738 Security User account changed (permission grants)
5136 Security Directory Service Object modified (ACL changes)

Known Threat Actors Using DCSync

Actor Context
APT29 (Cozy Bear) Used DCSync in SolarWinds campaign
FIN6 DCSync for credential harvesting in retail/hospitality
Wizard Spider TrickBot/Conti ransomware using DCSync pre-encryption
APT28 (Fancy Bear) DCSync in government network intrusions
LAPSUS$ DCSync after AD compromise for data theft

Legitimate Replication Sources

Source Reason How to Distinguish
Domain Controllers Normal AD replication Computer account ends with $
Azure AD Connect Hybrid identity sync MSOL_ service account
Backup Software AD backup operations Documented service accounts
Migration Tools Cross-forest migrations Temporary, documented operations
workflows.md3.0 KB

Detailed Hunting Workflow - DCSync Attack Detection

Phase 1: Enumerate Legitimate Replication Accounts

Step 1.1 - List All Domain Controllers

Get-ADDomainController -Filter * | Select-Object Name, IPv4Address, OperatingSystem

Step 1.2 - Find Accounts with Replication Rights

# Find all accounts with Replicating Directory Changes
Import-Module ActiveDirectory
$rootDSE = Get-ADRootDSE
$domainDN = $rootDSE.defaultNamingContext
$acl = Get-Acl "AD:\$domainDN"
$acl.Access | Where-Object {
    $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -or
    $_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"
} | Select-Object IdentityReference, ActiveDirectoryRights, ObjectType

Step 1.3 - BloodHound Query for DCSync Rights

MATCH p=(n)-[:GetChanges|GetChangesAll]->(d:Domain)
WHERE NOT n:Domain
RETURN n.name, labels(n)

Phase 2: Deploy Detection

Step 2.1 - Enable Required Audit Policy

auditpol /set /subcategory:"Directory Service Access" /success:enable /failure:enable

Step 2.2 - Configure SACL on Domain Object

Apply SACL to the domain root object monitoring for:

  • Control Access rights
  • Access to Replication GUIDs
  • By Everyone or Authenticated Users

Phase 3: Active Monitoring

Step 3.1 - Splunk Real-Time Detection

index=wineventlog source="WinEventLog:Security" EventCode=4662
| rex field=Properties "(?<guid>\{[0-9a-f-]+\})"
| where guid IN ("{1131f6aa-9c07-11d1-f79f-00c04fc2dcd2}",
    "{1131f6ad-9c07-11d1-f79f-00c04fc2dcd2}",
    "{89e95b76-444d-4c62-991a-0facbeda640c}")
| lookup dc_accounts SubjectUserName OUTPUT is_dc
| where is_dc!="true"
| eval alert_severity="CRITICAL"
| table _time SubjectUserName SubjectDomainName Computer guid alert_severity

Step 3.2 - Network-Level Detection

index=zeek sourcetype=dce_rpc
| where operation="DRSGetNCChanges"
| lookup domain_controllers src_ip OUTPUT is_dc
| where is_dc!="true"
| table _time src_ip dst_ip operation

Phase 4: Investigation

Step 4.1 - Determine Source Machine

Correlate Event 4662 with Event 4624 to identify the source workstation:

index=wineventlog EventCode=4624 LogonType=3
| where TargetUserName=[suspected_account]
| table _time TargetUserName IpAddress WorkstationName LogonType

Step 4.2 - Check for Subsequent Credential Abuse

index=wineventlog EventCode=4769
| where ServiceName="krbtgt"
| where TicketEncryptionType="0x17"
| table _time TargetUserName ServiceName IpAddress TicketEncryptionType

Phase 5: Response

Step 5.1 - Immediate Containment

  1. Disable compromised account immediately
  2. Rotate KRBTGT password (twice, 12 hours apart)
  3. Reset all service account passwords
  4. Block source IP at network level
  5. Isolate source machine for forensics

Step 5.2 - Remediation

  1. Remove unauthorized replication rights
  2. Review all accounts with DCSync-capable permissions
  3. Implement tiered administration model
  4. Enable Microsoft Defender for Identity DCSync alerts
  5. Deploy Protected Users security group for admin accounts

Scripts 2

agent.py6.1 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""DCSync attack detection agent for Active Directory environments.

Parses Windows Security Event ID 4662 logs to detect non-domain-controller
accounts requesting directory replication (DCSync technique T1003.006).
"""

import argparse
import json
import re
from datetime import datetime

try:
    import Evtx.Evtx as evtx
except ImportError:
    evtx = None

REPLICATION_GUIDS = {
    "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2": "DS-Replication-Get-Changes",
    "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2": "DS-Replication-Get-Changes-All",
    "89e95b76-444d-4c62-991a-0facbeda640c": "DS-Replication-Get-Changes-In-Filtered-Set",
}

KNOWN_REPLICATION_ACCOUNTS = set()


def load_dc_accounts(filepath):
    if not filepath:
        return set()
    accounts = set()
    with open(filepath, "r") as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#"):
                accounts.add(line.upper())
    return accounts


def parse_4662_events(filepath, dc_accounts):
    if evtx is None:
        return {"error": "python-evtx not installed: pip install python-evtx"}
    findings = []
    total_4662 = 0

    with evtx.Evtx(filepath) as log:
        for record in log.records():
            xml = record.xml()
            if "<EventID>4662</EventID>" not in xml:
                continue
            total_4662 += 1

            props = re.search(r'<Data Name="Properties">([^<]+)', xml)
            if not props:
                continue
            prop_text = props.group(1).lower()

            matched_rights = []
            for guid, name in REPLICATION_GUIDS.items():
                if guid in prop_text:
                    matched_rights.append(name)
            if not matched_rights:
                continue

            subject = re.search(r'<Data Name="SubjectUserName">([^<]+)', xml)
            domain = re.search(r'<Data Name="SubjectDomainName">([^<]+)', xml)
            logon_id = re.search(r'<Data Name="SubjectLogonId">([^<]+)', xml)
            object_name = re.search(r'<Data Name="ObjectName">([^<]+)', xml)
            time_created = re.search(r'SystemTime="([^"]+)"', xml)
            computer = re.search(r'<Computer>([^<]+)', xml)

            subject_name = subject.group(1) if subject else ""
            domain_name = domain.group(1) if domain else ""
            full_account = f"{domain_name}\\{subject_name}".upper()

            if subject_name.endswith("$"):
                if subject_name.upper().rstrip("$") in dc_accounts or \
                   full_account.rstrip("$") in dc_accounts:
                    continue

            if subject_name.upper() in dc_accounts or full_account in dc_accounts:
                continue

            is_machine = subject_name.endswith("$")
            severity = "HIGH" if is_machine else "CRITICAL"

            findings.append({
                "event_id": 4662,
                "timestamp": time_created.group(1) if time_created else "",
                "subject_user": subject_name,
                "subject_domain": domain_name,
                "logon_id": logon_id.group(1) if logon_id else "",
                "computer": computer.group(1) if computer else "",
                "object_name": object_name.group(1) if object_name else "",
                "replication_rights": matched_rights,
                "is_machine_account": is_machine,
                "severity": severity,
                "mitre": "T1003.006",
                "description": "Non-DC account requesting directory replication",
            })

    return {"total_4662_events": total_4662, "dcsync_detections": findings}


def check_replication_permissions_powershell():
    query = """
Import-Module ActiveDirectory
$domain = (Get-ADDomain).DistinguishedName
$acl = Get-Acl "AD:\\$domain"
$repl_rights = @(
    '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2',
    '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'
)
$acl.Access | Where-Object {
    $_.ObjectType -in $repl_rights -and
    $_.AccessControlType -eq 'Allow'
} | Select-Object IdentityReference, ObjectType, AccessControlType |
  ConvertTo-Json
"""
    return {"powershell_query": query.strip(),
            "note": "Run on a domain controller with RSAT tools"}


def generate_sigma_rule():
    return {
        "title": "DCSync Activity - Non-DC Replication Request",
        "status": "stable",
        "logsource": {"product": "windows", "service": "security"},
        "detection": {
            "selection": {
                "EventID": 4662,
                "Properties|contains": [
                    "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2",
                    "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2",
                ]
            },
            "filter_dc": {"SubjectUserName|endswith": "$"},
            "condition": "selection and not filter_dc"
        },
        "level": "critical",
        "tags": ["attack.credential_access", "attack.t1003.006"],
    }


def main():
    parser = argparse.ArgumentParser(description="DCSync Attack Detector")
    parser.add_argument("--security-log", help="Windows Security EVTX file")
    parser.add_argument("--dc-accounts", help="File with known DC account names (one per line)")
    parser.add_argument("--generate-sigma", action="store_true", help="Output Sigma detection rule")
    parser.add_argument("--check-perms", action="store_true",
                        help="Show PowerShell query for replication permissions")
    args = parser.parse_args()

    results = {"timestamp": datetime.utcnow().isoformat() + "Z"}

    dc_accounts = load_dc_accounts(args.dc_accounts)
    dc_accounts.update(KNOWN_REPLICATION_ACCOUNTS)

    if args.security_log:
        parsed = parse_4662_events(args.security_log, dc_accounts)
        if isinstance(parsed, dict) and "error" in parsed:
            results["error"] = parsed["error"]
        else:
            results.update(parsed)
            results["total_detections"] = len(parsed.get("dcsync_detections", []))

    if args.generate_sigma:
        results["sigma_rule"] = generate_sigma_rule()

    if args.check_perms:
        results["permission_check"] = check_replication_permissions_powershell()

    print(json.dumps(results, indent=2))


if __name__ == "__main__":
    main()
process.py5.8 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
DCSync Attack Detection Script
Analyzes Windows Security Event 4662 logs to identify non-domain-controller
accounts requesting Active Directory replication rights.
"""

import json
import csv
import argparse
import datetime
import re
from pathlib import Path

REPLICATION_GUIDS = {
    "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2": "DS-Replication-Get-Changes",
    "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2": "DS-Replication-Get-Changes-All",
    "89e95b76-444d-4c62-991a-0facbeda640c": "DS-Replication-Get-Changes-In-Filtered-Set",
}

GUID_PATTERN = re.compile(r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", re.IGNORECASE)


def load_dc_list(dc_file: str) -> set:
    """Load known domain controller accounts from file."""
    dcs = set()
    if dc_file:
        path = Path(dc_file)
        if path.exists():
            with open(path, "r", encoding="utf-8") as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith("#"):
                        dcs.add(line.lower())
    return dcs


def parse_events(input_path: str) -> list[dict]:
    """Parse Windows event log exports (JSON, CSV, EVTX-exported CSV)."""
    path = Path(input_path)
    events = []
    if path.suffix == ".json":
        with open(path, "r", encoding="utf-8") as f:
            data = json.load(f)
            events = data if isinstance(data, list) else data.get("events", [])
    elif path.suffix == ".csv":
        with open(path, "r", encoding="utf-8-sig") as f:
            events = [dict(row) for row in csv.DictReader(f)]
    return events


def detect_dcsync(events: list[dict], known_dcs: set) -> list[dict]:
    """Detect DCSync activity from Event 4662 logs."""
    findings = []
    for event in events:
        event_id = str(event.get("EventID", event.get("EventCode", event.get("event_id", ""))))
        if event_id != "4662":
            continue

        properties = event.get("Properties", event.get("properties", ""))
        if not properties:
            continue

        found_guids = GUID_PATTERN.findall(properties.lower())
        replication_guids = [g for g in found_guids if g in REPLICATION_GUIDS]
        if not replication_guids:
            continue

        subject_user = event.get("SubjectUserName", event.get("subject_user_name", ""))
        subject_domain = event.get("SubjectDomainName", event.get("subject_domain_name", ""))
        computer = event.get("Computer", event.get("computer", ""))
        timestamp = event.get("TimeCreated", event.get("_time", event.get("timestamp", "")))

        # Check if this is a legitimate domain controller
        is_dc = False
        subject_lower = subject_user.lower()
        if subject_lower.endswith("$"):
            if subject_lower in known_dcs or subject_lower.rstrip("$") in known_dcs:
                is_dc = True

        if is_dc:
            continue

        replication_rights = [REPLICATION_GUIDS[g] for g in replication_guids]
        has_get_changes_all = "DS-Replication-Get-Changes-All" in replication_rights

        severity = "CRITICAL" if has_get_changes_all else "HIGH"

        findings.append({
            "timestamp": timestamp,
            "subject_user": subject_user,
            "subject_domain": subject_domain,
            "computer": computer,
            "replication_guids": replication_guids,
            "replication_rights": replication_rights,
            "has_get_changes_all": has_get_changes_all,
            "is_machine_account": subject_user.endswith("$"),
            "severity": severity,
            "description": f"Non-DC account '{subject_user}' requested replication rights: {', '.join(replication_rights)}",
        })

    return sorted(findings, key=lambda x: x.get("timestamp", ""), reverse=True)


def run_hunt(input_path: str, dc_file: str, output_dir: str) -> None:
    """Execute DCSync detection hunt."""
    print(f"[*] DCSync Detection Hunt - {datetime.datetime.now().isoformat()}")

    known_dcs = load_dc_list(dc_file)
    print(f"[*] Known domain controllers: {len(known_dcs)}")

    events = parse_events(input_path)
    print(f"[*] Loaded {len(events)} events")

    findings = detect_dcsync(events, known_dcs)
    print(f"[!] DCSync detections: {len(findings)}")

    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    with open(output_path / "dcsync_findings.json", "w", encoding="utf-8") as f:
        json.dump({
            "hunt_id": f"TH-DCSYNC-{datetime.date.today().isoformat()}",
            "total_events": len(events),
            "findings_count": len(findings),
            "findings": findings,
        }, f, indent=2)

    with open(output_path / "dcsync_report.md", "w", encoding="utf-8") as f:
        f.write("# DCSync Attack Detection Report\n\n")
        f.write(f"**Date**: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"**Events Analyzed**: {len(events)}\n")
        f.write(f"**Findings**: {len(findings)}\n\n")
        for finding in findings:
            f.write(f"## [{finding['severity']}] {finding['subject_user']}\n")
            f.write(f"- **Time**: {finding['timestamp']}\n")
            f.write(f"- **Computer**: {finding['computer']}\n")
            f.write(f"- **Rights**: {', '.join(finding['replication_rights'])}\n")
            f.write(f"- **Description**: {finding['description']}\n\n")

    print(f"[+] Results written to {output_dir}")


def main():
    parser = argparse.ArgumentParser(description="DCSync Attack Detection")
    parser.add_argument("--input", "-i", required=True, help="Path to Windows event logs")
    parser.add_argument("--dc-list", "-d", default="", help="File with known DC accounts")
    parser.add_argument("--output", "-o", default="./dcsync_hunt_output", help="Output directory")
    args = parser.parse_args()
    run_hunt(args.input, args.dc_list, args.output)


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.6 KB
Keep exploring