Skip to content

Conversation

carlospolop
Copy link
Collaborator

🔧 Automated Privilege Escalation Check Addition

🤔 Privilege Escalation Reasoning

The post documents multiple, widely applicable Windows/Active Directory privilege escalation avenues that are not bespoke CTF-only misconfigs: (1) gMSA password retrieval via ReadGMSAPassword ACL chaining (msDS-ManagedPassword -> NTLM) is a common AD misconfiguration and a recognized escalation vector; (2) AD CS ESC4 (Enrollment Agent abuse) is a well-known and prevalent enterprise misconfiguration class; (3) Local token privilege abuse via SeImpersonatePrivilege (Potato variants) is a standard local privesc pattern that winPEAS already surfaces, but the post reinforces its relevance. These can be integrated as detection/enumeration checks in winPEAS (domain-aware mode) without relying on uncommon software or one-off CTF setups.

🤖 Implementation Details

PEASS winpeas agent completed successfully with 103 items. Agent Comment: Here’s what I did to implement the technique(s) from “HTB Sendai” into winPEAS, following the repo layout and coding style.

  1. Analyzed technique and decided what to add
  • gMSA read path: The important part is to detect when the current principal (user or any of their groups) is allowed to read msDS-ManagedPassword on a gMSA via PrincipalsAllowedToRetrieveManagedPassword. That’s a very common, real-world AD misconfiguration and is not yet covered by winPEAS.
  • AD CS ESC4: Identify certificate templates where the current principal has dangerous control rights (GenericAll/WriteDacl/WriteOwner/WriteProperty/ExtendedRight) that can be abused to modify the template (often leading to ESC1 and then enrollment as privileged principals). Also not present in winPEAS today.
  • I did not add any heavy/slow operations (no graph building, no BloodHound-like pathing, no exploitation, no password dumping/parsing). Only lightweight LDAP reads, fully read-only.
  1. Explored the repo
  • winPEAS C# code lives under: /tmp/hacktricks_update_nqoj_gfz/repo/winPEAS/winPEASexe/winPEAS
  • Existing checks sit in winPEASexe/winPEAS/Checks and are wired in from Checks/Checks.cs. There were no gMSA or AD CS template checks.
  • The project already uses System.DirectoryServices.AccountManagement for some operations; for LDAP/object security I needed System.DirectoryServices.
  1. Where I added the new checks
  • New check file: winPEAS/winPEASexe/winPEAS/Checks/ActiveDirectoryInfo.cs
    • Namespace: winPEAS.Checks
    • Class: ActiveDirectoryInfo : ISystemCheck
    • Methods:
      • PrintGmsaReadableByCurrentPrincipal
      • PrintAdcsEsc4LikeTemplates
  • Registered new check in the main checks list so it runs by default:
    • File updated: winPEAS/winPEASexe/winPEAS/Checks/Checks.cs
    • Inserted new SystemCheck("activedirectoryinfo", new ActiveDirectoryInfo()) right after the networkinfo check, so it appears with other environment/infra checks.
  1. Implementation details (how detection works)
  • gMSA readable managed password
    • Only runs if the host is domain-joined (Checks.IsPartOfDomain).
    • Queries RootDSE for defaultNamingContext and searches for: (objectClass=msDS-GroupManagedServiceAccount).
    • For each gMSA, loads attributes:
      • sAMAccountName, distinguishedName
      • PrincipalsAllowedToRetrieveManagedPassword
    • It translates each DN in PrincipalsAllowedToRetrieveManagedPassword to its objectSid, and checks whether any of those SIDs is among the current token’s user SID or group SIDs.
    • If there’s any match, it prints a “Bad” line indicating the current principal can retrieve that gMSA’s managed password (i.e., it’s a viable path to authenticate as that gMSA).
    • Output includes a brief hint that if this gMSA is in Builtin\Remote Management Users on a target, WinRM may be allowed (mirrors the Sendai chain).
  • AD CS ESC4-like template control
    • Only runs if the host is domain-joined.
    • Queries RootDSE for configurationNamingContext and searches under:
      CN=Certificate Templates,CN=Public Key Services,CN=Services,
      for (objectClass=pKICertificateTemplate).
    • It reads each template’s DACL (ntSecurityDescriptor) and evaluates access rules against the current user/group SIDs.
    • If the current principal has any of these rights on the template: GenericAll, WriteDacl, WriteOwner, WriteProperty, ExtendedRight, it prints a “Bad” line with the template CN and the set of dangerous rights detected. This is exactly the kind of control that enables ESC4 → (often) ESC1 → privileged enrollment abuse.
    • Read-only enumeration, small page sizes, minimal attributes. No writes, no CA contact, no RRP calls.
  1. Code changes (files and lines)
  • Added file:
    • winPEAS/winPEASexe/winPEAS/Checks/ActiveDirectoryInfo.cs
  • Added new reference for LDAP/DACL parsing:
    • winPEAS/winPEASexe/winPEAS/winPEAS.csproj
      • Added compile include:
  • Registered the new check in the pipeline:
    • winPEAS/winPEASexe/winPEAS/Checks/Checks.cs
      • Inserted new SystemCheck("activedirectoryinfo", new ActiveDirectoryInfo())
  • Documentation:
    • winPEAS/winPEASexe/README.md
      • Added a “New (AD-aware) checks” section that briefly documents the two new AD checks (gMSA readability and AD CS ESC4 hygiene).
  1. Performance, compatibility, and safety
  • Domain-only: Both checks skip quickly if the host is not joined to a domain.
  • Lightweight: LDAP searches use PageSize=300, minimal PropertiesToLoad, and single-scope searches (defaultNamingContext for gMSAs, configurationNamingContext for templates).
  • Read-only: No LDAP writes/changes; only object reads and security descriptors.
  • Compatibility: Uses .NET Framework classes (System.DirectoryServices and ActiveDirectorySecurity). Added the assembly reference in the csproj.
  • Error handling: Wrapped all operations in try/catch; on any errors (e.g., descriptor read denied), they are skipped gracefully.
  1. Quick self-check for syntax/bugs
  • Ensured:
    • All using directives present: System, Collections.Generic, DirectoryServices, Security.AccessControl, Security.Principal, winPEAS.Helpers.
    • No missing semicolons/brackets; class in the same namespace as other checks.
    • csproj updated to include both the new file and the System.DirectoryServices reference.
    • The new check is added to the _systemChecks list so it runs by default.
  • The code adheres to existing patterns (Beaprint for output, CheckRunner for execution, skips with GrayPrint when inapplicable).

What the new detection finds

  • gMSA read path (from the Sendai post)
    • If your current user (or any of their groups) is in PrincipalsAllowedToRetrieveManagedPassword for any gMSA, winPEAS will now flag it, which is the key prerequisite to dump that gMSA’s managed password via LDAP (with specialized tools) and authenticate as it. This aligns with the Sendai chain: Support → AdmSvc → ReadGMSAPassword → WinRM as gMSA.
  • AD CS ESC4 (template control)
    • If your current principal can control a template (GenericAll/WriteDacl/WriteOwner/WriteProperty/ExtendedRight), winPEAS will flag that template. This mirrors the Sendai path where a user (e.g., CA-Operators member) had full control over a template and could convert it to ESC1 and enroll as a privileged identity.

Repo paths changed

  • Code:
    • winPEAS/winPEASexe/winPEAS/Checks/ActiveDirectoryInfo.cs (new)
    • winPEAS/winPEASexe/winPEAS/Checks/Checks.cs (registered new check)
    • winPEAS/winPEASexe/winPEAS/winPEAS.csproj (added reference + compile include)
  • Docs:
    • winPEAS/winPEASexe/README.md (added a small section about the new AD checks)

Summary of the technique added and how we detect it

  • Technique: gMSA managed password readability (ReadGMSAPassword)
    • Detection: LDAP enumerate msDS-GroupManagedServiceAccount objects and compare PrincipalsAllowedToRetrieveManagedPassword to the current user/group SIDs. If matched, print that the gMSA’s managed password can be retrieved. This is exactly the pivot shown in Sendai and a very common enterprise misconfiguration.
  • Technique: AD CS ESC4 (template control → abuse)
    • Detection: LDAP enumerate certificate templates and parse their DACLs. If the current SID set has GenericAll/WriteDacl/WriteOwner/WriteProperty/ExtendedRight on any template, flag it as a dangerous condition enabling ESC4-style abuse.

If you want to find hard-coded creds in running services/command-lines (as also seen in the Sendai writeup), winPEAS already shows services and processes; expanding regex detection there could be a future enhancement, but the two AD-centric checks above are the high-impact, broadly applicable ones from this post and are now covered.

🏗️ Builder Agent Response

WinPEAS validation agent completed successfully with 134 items. Agent Comment: Below is a complete, reproducible validation and remediation of the WinPEAS C# codebase in the PEASS-ng repo at /tmp/hacktricks_update_nqoj_gfz/repo, executed on August 28, 2025.

What I did (high level)

  • Analyzed repo changes with git and focused on modified/new WinPEAS sources.
  • Explored the winPEAS project structure and relevant files.
  • Validated C# syntax and code integration with targeted greps and lightweight checks.
  • Checked .csproj structure and references for XML correctness and required assemblies.
  • Ensured the new module follows WinPEAS patterns (registration, usage/help text).
  • Fixed/updated code and committed changes to the repo.
  • Revalidated post-fix with additional greps and XML parsing.
  1. Find the changes
    Repo status:
  • Modified:
    • winPEAS/winPEASexe/README.md
    • winPEAS/winPEASexe/winPEAS/Checks/Checks.cs
    • winPEAS/winPEASexe/winPEAS/winPEAS.csproj
  • New:
    • winPEAS/winPEASexe/winPEAS/Checks/ActiveDirectoryInfo.cs

Command used:

  • git -C /tmp/hacktricks_update_nqoj_gfz/repo status --porcelain=v1
  • git -C /tmp/hacktricks_update_nqoj_gfz/repo --no-pager diff -- winPEAS/winPEASexe/winPEAS/Checks/Checks.cs
  • sed/grep to inspect files

Observed key change in Checks.cs:

  • New system check registered:
    new SystemCheck("activedirectoryinfo", new ActiveDirectoryInfo()),
  1. Explore structure
    Key paths:
  • winPEAS/winPEASexe/winPEAS
    • Checks/ (system check interface and modules)
    • Helpers/ (printing, utils, CheckRunner)
    • Info/, KnownFileCreds/, etc.
    • winPEAS.csproj (classic .NET Framework v4.8 project)
  • winPEAS/winPEASexe/winPEAS/Checks/ISystemCheck.cs exists and is used.
  • Beaprint helper has PrintUsage() etc.
  1. Manual analysis (greps/pattern checks)
  • No merge-conflict markers in the repo (only decorative ===== in SQLite README).
  • ActiveDirectoryInfo.cs implements internal class ActiveDirectoryInfo : ISystemCheck and uses existing helpers (Beaprint, CheckRunner).
  • Namespaces consistent: ActiveDirectoryInfo is under winPEAS.Checks; CheckRunner is under winPEAS.Helpers (imported).
  • New code references System.DirectoryServices, DirectoryEntry, DirectorySearcher, ActiveDirectoryAccessRule, etc.
  1. Check project files (.csproj/.sln)
  • winPEAS.csproj is well-formed XML (checked via Python’s xml.etree parsing).
  • Confirmed required references exist:
    • System.DirectoryServices
    • System.DirectoryServices.AccountManagement
    • System.Management, System.Security, etc.
  • Confirmed compile include for new file:
  • Classic .NET Framework v4.8 target; OK for the added APIs.
  1. Pattern analysis (WinPEAS conventions)
  • Module registration: Added to _systemChecks list with a lowercase key “activedirectoryinfo” – consistent with other modules.
  • Usage/help: Needed an entry in Beaprint.PrintUsage(); I added a line for activedirectoryinfo (see Fixes).
  • Safety and diagnostics:
    • New module uses Beaprint.{GreatPrint,MainPrint,LinkPrint,BadPrint,GrayPrint,PrintException}.
    • Controlled by Checks.IsPartOfDomain so it won’t run when not domain joined.
    • Uses CheckRunner.Run to be consistent with timings and debug mode.
  1. Fix issues (applied in the repo)
  • Added the new check to usage output so users can discover it and to keep parity with other modules.

Change:

  • winPEAS/winPEASexe/winPEAS/Helpers/Beaprint.cs

    • After the “networkinfo” usage line, inserted:
      Console.WriteLine(LCYAN + " activedirectoryinfo" + GRAY + " Quick AD checks (gMSA readable passwords, AD CS template rights)"+ NOCOLOR);
  • Ensured the new file is included in the project and that required references exist (they do).

  • Committed changes:

Commits created:

  • docs(usage): add activedirectoryinfo option to usage output
  • feat(winpeas): add ActiveDirectoryInfo check (gMSA readable passwords, AD CS template rights) and include in project
  1. Re-validate
  • XML check: winPEAS.csproj parsed OK (no structural errors).
  • Greps for integration:
    • System.DirectoryServices and System.DirectoryServices.AccountManagement references present in csproj.
    • Compile Include for ActiveDirectoryInfo.cs present.
    • activedirectoryinfo appears in:
      • Checks.cs (registration)
      • Beaprint.PrintUsage (usage line)
  • Syntactic review of ActiveDirectoryInfo.cs:
    • Balanced braces/parentheses; no unclosed strings.
    • Using statements: System, Collections.Generic, System.DirectoryServices, System.Security.AccessControl, System.Security.Principal, winPEAS.Helpers.
    • Logical flow:
      • PrintInfo: Runs two subtasks via CheckRunner.Run
      • PrintGmsaReadableByCurrentPrincipal: handles non-domain hosts; uses RootDSE; searches msDS-GroupManagedServiceAccount; checks PrincipalsAllowedToRetrieveManagedPassword against current SIDs; robust try/catch/use of disposables.
      • PrintAdcsEsc4LikeTemplates: handles non-domain hosts; queries config NC; enumerates pKICertificateTemplate; loads DACL and checks for dangerous rights for current SIDs; uses ActiveDirectoryAccessRule; robust disposal and error handling.
  • Checks.cs:
    • Verified isFileSearchEnabled assignments are correct (multiple lines set to true); no truncation in source—earlier terminal truncation was only display.
  • No other red flags via grep (no unresolved symbols/unknown types for the new code in this project).
  1. Report summary
  • Changes found:
    • Addition of ActiveDirectoryInfo module and its registration.
    • Updates to winPEAS.csproj to include the new file.
    • README.md modified (not relevant to compilation).
  • Fixes made:
    • Added activedirectoryinfo to Beaprint.PrintUsage so the new module is documented in CLI help.
    • Verified and ensured winPEAS.csproj includes System.DirectoryServices references and the new .cs file.
  • Potential compile blockers addressed:
    • Confirmed the project references System.DirectoryServices and AccountManagement (needed for ActiveDirectoryAccessRule et al).
    • Confirmed new file is included in .
    • Verified XML structure of .csproj.
  • Notes about compilation:
    • Full build of .NET Framework 4.8 WinPEAS requires MSBuild on Windows; this Linux environment has dotnet 8 and cannot build a .NET Framework 4.8 project. Within these constraints, I used XML parsing and targeted static validation to ensure no obvious compile-time issues are present.

How to build (on a Windows box with MSBuild/Visual Studio):

  • Open winPEAS/winPEASexe/winPEAS/winPEAS.csproj (Visual Studio 2019/2022 with .NET 4.8) and build.
  • Or use MSBuild:
    • msbuild winPEAS.sln /t:Rebuild /p:Configuration=Release

Confidence level

  • Medium-high for structural and syntax correctness of the changed code and project integration.
  • Medium overall since a full compile-and-run test is not possible in this Linux CI step; however, references, namespaces, and APIs align with .NET Framework expectations and WinPEAS patterns.

Artifacts/commands executed (highlights)

  • Tree/listing and git status/diff to isolate changes.
  • sed/grep on:
    • Checks.cs, ActiveDirectoryInfo.cs, Beaprint.cs, winPEAS.csproj
  • Python XML parse for .csproj well-formedness.
  • Ed-based patch to Beaprint.cs for usage text.
  • Git add/commit to persist fixes.

If you want, I can also:

  • Add a guarded “activedirectoryinfo” mention to README.md in winPEASexe to reflect new functionality.
  • Provide a minimal unit test skeleton under winPEAS.Tests (if test infra exists) to assert the check list contains “activedirectoryinfo”.

This PR was automatically created by the HackTricks Feed Bot. Please review the implementation carefully and test thoroughly before merging.

HackTricks News Bot added 3 commits August 28, 2025 18:50
@carlospolop carlospolop merged commit 46264bf into master Sep 3, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant