Red Team Defense
Harden Against Red Team
Important · read first
This page is not a complete hardening checklist. It contains targeted hints derived from the intelligence we received about the red team's planned attack chain · Mimikatz / Rubeus, BackupPriv, Pass-the-Hash, Golden Ticket, Metasploit RC chains, and Ansible-based deployments. Treat it as an extension of, not a replacement for, the general hardening work in the Blue Team Guide.
Known Attack Chain
The red team plan shows this post-exploitation path. Each step below is a place to detect or harden.
Steal Token
Rubeus / Mimikatz
Backup Account
Backup Account
→
BackupPriv
ntds.dit / AD Backup
VSS Shadow Copy
VSS Shadow Copy
→
Hash Dump
Domain Admin NTLM
krbtgt Hash
krbtgt Hash
→
PTH / Golden Ticket
Lateral Movement
Domain Takeover
Domain Takeover
→
Domain Admin
Game over
Note Per red team note: "Not so common anymore · lights up SIEM like Xmas tree" · these techniques are loud and well-detectable when the SIEM is correctly configured.
Mimikatz / Rubeus · Credential Theft
Red Team Technique Mimikatz reads LSASS memory to extract cleartext passwords and NTLM hashes. Rubeus manipulates Kerberos tickets directly in memory. Both can be used to steal a backup account token.
Hardening
- Enable Credential Guard (Hyper-V isolates LSASS)
- Add all admin accounts to the Protected Users security group
- Enable LSA Protection (RunAsPPL)
- Disable WDigest authentication (prevents cleartext in RAM)
- Remove debug rights (SeDebugPrivilege) from user groups
- Configure LSASS as Protected Process Light (PPL)
- Manage local administrator accounts with LAPS
Disable WDigest · Registry
PowerShell (DC / GPO)
# Disable WDigest (prevents cleartext credentials in RAM) Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` -Name "UseLogonCredential" -Value 0 -Type DWORD # Enable LSA Protection (PPL) Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" ` -Name "RunAsPPL" -Value 1 -Type DWORD
Credential Guard via GPO
GPO Path
Computer Configuration → Administrative Templates
→ System → Device Guard
→ Turn On Virtualization Based Security
→ Credential Guard: Enabled with UEFI lock Detect (SPL)
SPL · LSASS access / Mimikatz signature
# Sysmon Event 10: ProcessAccess on lsass.exe index=wineventlog sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational EventCode=10 TargetImage="*lsass.exe" GrantedAccess IN ("0x1010", "0x1410", "0x147a", "0x1fffff") | table _time, ComputerName, SourceImage, TargetImage, GrantedAccess, User
Detect (SPL)
SPL · Rubeus / known tool names
index=wineventlog EventCode=4688 (New_Process_Name="*rubeus*" OR New_Process_Name="*mimikatz*" OR Process_Command_Line="*sekurlsa*" OR Process_Command_Line="*lsadump*" OR Process_Command_Line="*kerberos::ptt*" OR Process_Command_Line="*asktgt*") | table _time, ComputerName, User, New_Process_Name, Process_Command_Line
BackupPriv · ntds.dit / AD Backup Abuse
Red Team Technique With SeBackupPrivilege, an attacker can copy ntds.dit (the AD database with all hashes) via Volume Shadow Copy (VSS) or directly · without DA rights. A backup service account is enough.
Hardening
- Grant SeBackupPrivilege only to strictly necessary accounts · use the tier model
- Add backup service accounts to the Protected Users group
- Restrict and log VSS access on DCs
- Audit ntds.dit access via SACL (enable file-system auditing)
- Make backup accounts non-interactive (deny logon locally / via RDP)
- Manage backup accounts with long, rotating passwords (LAPS or vault)
Set SACL on ntds.dit (audit access)
PowerShell · on Domain Controller
# Set audit rule on ntds.dit $acl = Get-Acl -Audit "C:\Windows\NTDS\ntds.dit" $rule = New-Object System.Security.AccessControl.FileSystemAuditRule( "Everyone", "ReadData", "None", "None", "Success,Failure") $acl.AddAuditRule($rule) Set-Acl -Path "C:\Windows\NTDS\ntds.dit" -AclObject $acl
Detect (SPL)
SPL · VSS / shadow copy creation on DC
index=wineventlog EventCode=4688 (New_Process_Name="*vssadmin*" OR New_Process_Name="*diskshadow*" OR New_Process_Name="*wbadmin*") (Process_Command_Line="*create shadow*" OR Process_Command_Line="*ntds*" OR Process_Command_Line="*backup*") | table _time, ComputerName, User, New_Process_Name, Process_Command_Line
Detect (SPL)
SPL · ntds.dit file access (Event 4663)
index=wineventlog EventCode=4663 Object_Name="*ntds.dit*" | table _time, ComputerName, Account_Name, Object_Name, Access_Mask, Process_Name
Pass-the-Hash (PTH)
Red Team Technique With a stolen NTLM hash, an attacker can authenticate without the cleartext password · e.g. via PSExec, WMI or SMB on other hosts. The goal is lateral movement to the DC.
Hardening
- Disable NTLM where possible · force Kerberos
- Add all admin accounts to Protected Users group (blocks NTLM auth, no credential caching)
- Ensure KB2871997 (Windows 8.1 / 2012R2+): blocks PTH with the RID-500 account
- Rename local admin accounts and manage with LAPS
- Enforce SMB signing on all hosts (blocks relay attacks)
- Network segmentation: workstations must not communicate directly via SMB
- Enable Restricted Admin Mode for RDP
Enforce SMB signing · GPO
GPO Path
Computer Configuration → Windows Settings → Security Settings
→ Local Policies → Security Options
→ Microsoft network server: Digitally sign communications (always) = Enabled
→ Microsoft network client: Digitally sign communications (always) = Enabled Restrict NTLM · GPO
GPO Path
Computer Configuration → Windows Settings → Security Settings
→ Local Policies → Security Options
→ Network security: Restrict NTLM: NTLM authentication in this domain
→ Deny all (or first: Audit all, then restrict step by step) Detect (SPL)
SPL · PTH indicator (Logon Type 3 with NTLM)
index=wineventlog EventCode=4624 Logon_Type=3 Authentication_Package="NTLM" Account_Name!="ANONYMOUS LOGON" | stats count by Account_Name, src_ip, ComputerName, Workstation_Name | sort -count
Golden Ticket · krbtgt
Red Team Technique Whoever has the krbtgt hash can forge arbitrary Kerberos tickets for any user or service · valid for up to 10 years. Often still usable even after password resets if krbtgt is not reset twice.
Hardening
- Reset the krbtgt password twice (at least 10h apart for replication)
- Schedule periodic krbtgt resets (e.g. every 180 days)
- Reduce Kerberos ticket lifetime to the minimum (GPO: max 10h user, 7-day renewal)
- Strictly limit DC access to Tier-0 admins
- Enable Sysmon on DCs for Kerberos events
- Enable Microsoft ATA / Defender for Identity (detects Golden Tickets natively)
Reset krbtgt twice
PowerShell · Domain Controller
# First reset Set-ADAccountPassword -Identity "krbtgt" -Reset ` -NewPassword (ConvertTo-SecureString -AsPlainText "<very long PW>" -Force) # Wait until AD has replicated (at least 10 hours), then second reset: Set-ADAccountPassword -Identity "krbtgt" -Reset ` -NewPassword (ConvertTo-SecureString -AsPlainText "<another very long PW>" -Force) # Alternative: use Microsoft's KRBTGT reset script # https://github.com/microsoft/New-KrbtgtKeys.ps1
Detect (SPL)
SPL · Golden Ticket indicators (Event 4769 + anomalies)
# Kerberos service ticket with unusual encryption (RC4 instead of AES) index=wineventlog EventCode=4769 Ticket_Encryption_Type="0x17" Service_Name!="krbtgt" Account_Name!="*$" | stats count by Account_Name, Service_Name, Client_Address | sort -count
Detect (SPL)
SPL · ticket with unusually long lifetime
# TGT requests with suspicious fields (Event 4768) index=wineventlog EventCode=4768 Ticket_Options="0x40810010" Ticket_Encryption_Type="0x17" | table _time, Account_Name, Client_Address, Ticket_Encryption_Type, Failure_Code
Kerberoasting
Red Team Technique Any domain user can request service tickets (TGS) for SPNs. These tickets are encrypted with the service account's password hash and can be cracked offline.
Hardening
- Service accounts with long, random passwords (25+ chars) · makes cracking impractical
- Use Managed Service Accounts (gMSA) instead of regular accounts · passwords rotate automatically
- Enforce AES encryption for SPN accounts (disable RC4)
- Audit SPNs regularly · remove unneeded ones
Audit SPNs in AD
PowerShell
# List all accounts with SPNs Get-ADUser -Filter {ServicePrincipalName -ne "$null"} ` -Properties ServicePrincipalName, PasswordLastSet, Enabled | Select-Object Name, Enabled, PasswordLastSet, ServicePrincipalName | Sort-Object PasswordLastSet
Detect (SPL)
SPL · Kerberoasting: many TGS requests from one user
index=wineventlog EventCode=4769 Ticket_Encryption_Type="0x17" Service_Name!="krbtgt" Account_Name!="*$" | bucket _time span=5m | stats dc(Service_Name) as unique_services, count by _time, Account_Name, Client_Address | where unique_services > 5 | sort -unique_services
↔ Lateral Movement · PSExec / WMI / SMB
Red Team Technique After credential theft, the red team uses PSExec, WMI remote execution or SMB admin shares (C$, ADMIN$) to move to other hosts · typically toward the DC.
Hardening
- Windows Firewall: block SMB (445) between workstations · allow DC access only
- Disable admin shares (C$, ADMIN$) on workstations via GPO
- Restrict WMI remote access via firewall (port 135 + dynamic ports)
- AppLocker / WDAC: block PSExec and other LOLBAS tools
- Remove local admin rights on workstations (standard user)
- Use Privileged Access Workstations (PAWs) for admin tasks
Detect (SPL)
SPL · PSExec indicators (service + named pipe)
index=wineventlog (EventCode=7045 ServiceName="PSEXESVC") OR (EventCode=4688 New_Process_Name="*PSEXESVC*") OR (EventCode=5145 RelativeTargetName="PSEXESVC") | table _time, ComputerName, EventCode, Account_Name, _raw
Detect (SPL)
SPL · WMI Remote Execution (Event 4688 / Sysmon)
index=wineventlog EventCode=4688 Creator_Process_Name="*WmiPrvSE.exe" New_Process_Name!="*WmiPrvSE.exe" | stats count by ComputerName, New_Process_Name, Process_Command_Line | sort -count
Detect (SPL)
SPL · admin share access (C$ / ADMIN$)
index=wineventlog EventCode=5140 Share_Name IN ("\\*\C$", "\\*\ADMIN$", "\\*\IPC$") | stats count by Account_Name, src_ip, ComputerName, Share_Name | sort -count
Metasploit / RC Killchains
Red Team Technique The red team uses MSF resource scripts (RC killchains) to automate exploit chains · grouped into Delfino, Stambecco and Bigi. They run as sequences of MSF commands and can combine many techniques very quickly.
Hardening & Detection
- Meterpreter signatures in IDS/IPS (Suricata / Snort): ET EXPLOIT and ET TROJAN rulesets
- Cover stageless payloads with AV / EDR (AMSI for PowerShell)
- Strictly whitelist outbound connections from DC (no internet from DC)
- Egress-filter MSF default ports (4444, 5555, 8080)
- Monitor process injection events via Sysmon Event 8 (CreateRemoteThread)
Detect (SPL)
SPL · Sysmon Event 8: Remote Thread Injection
index=wineventlog sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational EventCode=8 TargetImage!="*svchost.exe" | stats count by SourceImage, TargetImage, ComputerName, User | sort -count
Detect (SPL)
SPL · outbound connections on MSF ports
index=network (dest_port=4444 OR dest_port=5555 OR dest_port=8443 OR dest_port=9001 OR dest_port=1234) | stats count by src_ip, dest_ip, dest_port | sort -count
Ansible / Git Deployment Hardening
Red Team Technique The red team uses
ansible.builtin.git to manage their attack repos (.msf4, attack.rb). Ansible with Git access on infrastructure hosts is a highly privileged path · a compromised Ansible controller means access to all managed hosts.
Hardening
- Strictly isolate the Ansible controller · own VLAN, no direct internet
- Ansible Vault for all secrets · never cleartext in playbooks or repos
- Git repos only via SSH with deploy keys · no HTTPS with stored credentials
- Deploy keys read-only · separate key per repo
- Ansible user on target hosts: no sudo without password · NOPASSWD only for specific tasks
- Never commit inventory files with credentials to the repo (.gitignore)
- Git branch protection: main/master only via PR, no direct push
- Enforce Git commit signing (GPG) · prevents forged commits
- Forward Ansible logs to the central SIEM
- Rotate SSH keys for the Ansible user regularly
Ansible Vault · encrypt secrets
bash
# Encrypt a secret file ansible-vault encrypt secrets.yml # Encrypt a single variable ansible-vault encrypt_string 'my_password' --name 'db_password' # Run a playbook with vault ansible-playbook site.yml --ask-vault-pass # or with a vault password file (never commit it!): ansible-playbook site.yml --vault-password-file ~/.vault_pass
Git · .gitignore for Ansible
.gitignore
# Ansible Secrets *.vault vault_pass* .vault_pass* secrets.yml inventory/production inventory/staging group_vars/all/vault.yml # SSH Keys *.pem *.key id_rsa* id_ed25519* # Temporary files *.retry .ansible/
Sudoers · restrict the Ansible user
/etc/sudoers.d/ansible
# Allow ONLY specific commands without a password · never blanket NOPASSWD:ALL ansible ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get install * ansible ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx # Everything else requires a password or is forbidden
Detect (SPL)
SPL · monitor Ansible user sudo activity
index=main sourcetype=linux_secure "sudo" user="ansible" | rex field=_raw "COMMAND=(?<cmd>.+)" | stats count by host, cmd | sort -count
Detect (SPL)
SPL · git clone / pull from unknown repos
index=main sourcetype=linux_secure OR sourcetype=syslog ("git clone" OR "git pull" OR "git fetch") | rex field=_raw "git (?:clone|pull|fetch)\s+(?<repo_url>\S+)" | stats count by host, user, repo_url | sort -_time
AD General Hardening · Quick Wins
Tier model
Tier 0 = DC / AD
Tier 1 = servers
Tier 2 = workstations
Admins must never log on at a lower tier.
Protected Users
All privileged accounts in the Protected Users group: no NTLM, no DES/RC4, no credential caching, no Kerberos delegation.
LAPS
Local Administrator Password Solution: each host has a random, rotating local admin password · prevents PTH lateral movement via shared local admin.
Sysmon on all hosts
SwiftOnSecurity Sysmon config as a baseline. Provides Process Create (1), Network Connect (3), Remote Thread (8), Process Access (10), DNS Query (22).
Install Sysmon (all Windows hosts)
PowerShell (Admin)
# Sysmon64 + SwiftOnSecurity config Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Sysmon.zip" -OutFile Sysmon.zip Expand-Archive Sysmon.zip # Download config Invoke-WebRequest -Uri "https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml" ` -OutFile sysmonconfig.xml # Install .\Sysmon64.exe -accepteula -i sysmonconfig.xml
Tip Priority for the CTF: (1) Sysmon on the DC, (2) krbtgt 2x reset, (3) Protected Users for all admins, (4) SMB signing · this covers most of the described kill chain.