PrivHound: turning local privilege escalation findings into a BloodHound graph
A BloodHound OpenGraph collector that models Windows local privilege escalation as interconnected attack paths.
At a glance
- What is it?
- PrivHound is a BloodHound OpenGraph collector that models Windows local privilege escalation as connected attack paths rather than a list of isolated misconfigurations. It runs 29 checks covering 30 techniques, and the readme is unusually careful about which of its findings are verified and which are only candidates.
- Who is it for?
- PrivHound suits a Windows defender who already uses BloodHound and wants local privilege escalation findings joined to the Active Directory graph, and it does not suit a team looking for a one command report of local misconfigurations, because the output is a graph for BloodHound rather than a readable list.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 15 days ago.
- What is it written in?
- Mainly PowerShell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The complaint is about lists, not about coverage
The readme states the problem in a way that explains the project's design better than any feature list would.
For a long time, BloodHound has proven that attackers think in graphs, transforming Active Directory misconfigurations from static checklists into explorable attack paths. Yet when it comes to local privilege escalation, the industry is still stuck in 2015: run a tool, read a wall of text, manually connect the dots or have an LLM do it for you.
The named alternatives are WinPEAS, PowerUp and Seatbelt, and the readme credits them as excellent at finding individual misconfigurations. The criticism is not accuracy. It is that they cannot answer chained questions, and the readme gives three examples of the kind of question it means.
Does this writable Program Files directory actually lead to SYSTEM because a service runs a binary from it. Does this PowerShell history file contain credentials that are valid for a local admin. Can I read another user's profile, find their stored credentials, log in as them, and exploit a service they have write access to.
The reasoning behind the criticism is precise: these tools report findings in isolation, but in reality privilege escalation is a multi-step chain where one finding feeds into another. A writable directory means nothing if no service runs from it, and a credential in a history file means nothing if it does not belong to a privileged user. The real question is never what misconfigurations exist, it is what can I actually reach from here.
The closing line of the section is the design brief: if Active Directory attacks can be thought of as a graph, why not local privilege escalation.
What a chain looks like in the graph
The example the readme gives is worth reading slowly, because it shows exactly what the graph buys you.
Your current user can read the profile of another user on the machine. That profile contains cleartext credentials stored on their desktop for a third user. That third user has write permission to a service binary running as Administrator. No existing tool connects these dots, and PrivHound does automatically.
The graph form of that chain uses named edges for the relationships.
CurrentUser ─PHCanAccessProfile─→ OtherUser's Profile
─PHProfileContains─→ .git-credentials ─PHContainsCreds─→ ...
─PHCanLoginAs─→ UserX ─PHCanWriteBinary─→ VulnService ─PHRunsAs─→ SYSTEMEvery arrow is a specific, checkable fact rather than a generic link. PHCanAccessProfile is a permission relationship between two local users. PHProfileContains is a containment relationship between a directory and a file. PHContainsCreds says the file holds credentials. PHCanLoginAs connects those credentials to a local account. PHCanWriteBinary connects that account to a service binary. PHRunsAs connects the service to SYSTEM.
The readme says the result is that multi-hop escalation chains become visible, queryable with Cypher, and overlayable on top of existing Active Directory attack paths. The last of those three is the one that changes the tool's role. A chain that ends at a local account with a write permission to a service binary is much more interesting when that account also appears in the Active Directory graph, because it tells you which domain credentials the local escalation is worth.
That is also the reason to use OpenGraph rather than a bespoke format. OpenGraph is BloodHound's extension mechanism for adding node and edge types, and a collector built on it means the local findings live in the same database and the same query language as the domain findings.
Twenty nine checks, and a careful column of qualifiers
The check table is the substance of the tool, and one column in it deserves attention.
The coverage runs from weak service permissions and writable service binaries through unquoted service paths, DLL hijacking via PATH, AlwaysInstallElevated, token privileges such as SeImpersonate and SeDebug, scheduled tasks, autorun executables and writable registry service keys. The credential side covers stored credentials in Credential Manager and AutoLogon, Group Policy Preferences cached passwords, unattended install files, PowerShell history and transcripts, and sensitive files including SAM backups, kdbx files, rdg files and git-credentials. There are also UAC policy observations, writable Program Files directories, cross-user profiles, credential login paths, cross-user privilege escalation, JIT admin tools such as MakeMeAdmin, CyberArk EPM and Admin By Request, and the print spooler, WSUS over HTTP, SCCM and MECM credential sources, COM override candidates, named pipe connectivity, cached credential sources, WMI event subscriptions, WebClient relay surface, service recovery commands and shadow copy sensitive files.
Each row carries a MITRE ATT&CK technique identifier, which is what makes the output usable by people who already work in that vocabulary.
Now the column that matters. A number of rows carry an explicit qualifier in their technique description. UAC policy observations say that bypass exploitability is unverified. The print spooler entry says the running service and explicitly weakened Point and Print policy, with patch and exploitability unverified. The WSUS HTTP row says the MITM prerequisites and impact require verification. The SCCM row says credential extraction is unverified. COM override candidates say privileged activation is unverified. Named pipe connectivity says server identity and impersonation are unverified. WebClient relay surface says relay and exploitability are unverified.
This is unusual and it is the most valuable thing in the readme. A tool that models attack paths will otherwise imply more certainty than it has, because the graph makes a hypothesis look like a fact. PrivHound distinguishes what it observed from what it inferred, and it does so per check rather than in a blanket disclaimer.
The readme says 29 checks cover the 30 techniques listed, and the table does have 30 rows, which suggests at least one check covers more than one technique.
The chains are templates, and the qualifiers travel with them
The multi-hop section lists the chain patterns the tool is built to find, and it is a list of attack narratives rather than of check names.
The credential pipeline runs User, PSHistory, PHContainsCreds, PHCanLoginAs, LocalUser, Admin. A writable directory leading to a service runs User, WritableProgramDir, PHHostsBinaryFor, Service, SYSTEM. The cross-user profile chain is User, Profile, SensitiveFile, PHCanLoginAs, LocalUser, Admin. The cross-user escalation chain adds the credentials step: User, (creds), PHCanLoginAs, UserX, PHCanWriteBinary, Service, SYSTEM.
The SeBackup sub-chain is the one that shows the tool modelling token privileges rather than just files: User, SeBackup, PHCanReadProtected, SAM, PHCanExtractHashes, Admin.
And then the chains with their caveats attached, which is the point. The stored cmdkey entries chain is User, PHHasStoredCreds, StoredCred, with runas reuse unverified. The SCCM NAA source chain is User, PHCanReadNAA, PHSCCMCredential, with credential extraction unverified. The WebClient relay surface chain is User, WebClientRelay, PHEscalatesTo, SYSTEM, with relay prerequisites requiring verification. The COM override candidate chain is User, PHCanOverrideCOM, COM candidate, with privileged activation unverified. The named pipe candidate chain is User, PHCanConnectPipe, Pipe, with impersonation unverified.
The shadow copy chain, User, ShadowCopy, SAM, PHCanExtractHashes, is where the readme text runs out in the visible excerpt, and that is a fair sign of how long these chains get.
Reading the two tables together gives you the design. The check table tells you what the collector observes and how confident it is. The chain table tells you what the observed facts combine into. A chain is a hypothesis about how the facts connect, and the tool is explicit about the ones where the connection is only a candidate.
The other chains carry no caveat because the connection there is mechanical rather than inferred. A WMI subscription chain runs User, WMISubscription, PHRunsAs, SYSTEM, because if you can write the consumer binary then the subscription runs as the privileged principal. A service recovery chain runs User, PHCanWriteRecoveryBin, Service, SYSTEM, and the same is true of the write binary chains.
Running it against a BloodHound instance
The repository layout is small, and the .env.example file shows the whole configuration surface.
# BloodHound base URL
BH_URL=http://localhost:8080
# Use a BloodHound API key/ID pair for integrations:
BH_KEY=replace-with-api-key
BH_ID=replace-with-api-key-id
# Alternatively, a JWT can be used for short-lived/manual uploads:
# BH_TOKEN=replace-with-your-bloodhound-jwtThree variables and two authentication routes. The API key and ID pair is the option for integrations, and the JWT is the alternative for short-lived or manual uploads. The base URL points at a BloodHound instance, and the default of localhost:8080 is the standard local port.
The repository root holds PrivHound.ps1 as the collector entry point, a bh/ directory, a lab/ directory and assets/. The primary language is PowerShell, which is the obvious choice for a Windows privilege escalation collector, since the checks read the registry, the service configuration, the credential stores and the file system of the machine being assessed.
The .env.example file is present in the repository, which suggests the .env file itself is not, so you would copy the example, fill in the base URL and whichever credential applies, and run the script. The readme as visible does not give the command line, so the invocation is whatever the script's own help or parameter block documents.
One point worth raising for anyone deploying this is what the collection touches. The checks cover stored credentials, PowerShell history, sensitive files, SAM and SYSTEM hives in shadow copies, WMI subscriptions and the registry. Running a collector like this against a machine means reading credential data that lives on it, and a defender should decide where that output goes before running it rather than after.
Where PrivHound is the wrong tool
There are four cases where this is the wrong choice, and they are all about the shape of the output rather than the quality of the checks.
The first is a team that wants a report. The output is a BloodHound graph. If what you need is a list of misconfigurations for a ticket, or a spreadsheet for a review, then the graph is an extra step, and the tools the readme names as alternatives will give you that more directly. PrivHound is for a team that already has a BloodHound instance and wants the local findings to live in it.
The second is a team that does not run BloodHound. Adopting this means adopting a graph database, a query language and a collection infrastructure, and the readme's framing of overlayable on top of existing Active Directory attack paths only means something if those paths exist.
The third is a machine whose local configuration is not the attack surface. A workstation joined to a domain, with the local administrator account irrelevant because everything of value is in Active Directory, gains very little from modelling its service permissions as a graph. The tool is aimed at the local escalation case, and that case has to be real for it to pay.
The fourth is a compliance exercise that needs demonstrated exploitability. The readme is explicit that a good number of its chains are unverified, that the print spooler and WSUS entries have unverified patch and prerequisite status, and that credential extraction, privileged activation, relay prerequisites and impersonation are not confirmed. If a finding has to survive a challenge, an unverified chain is a lead, not a result.
On the alternative, the difference in approach against the tools the readme names is the unit of output. WinPEAS, PowerUp and Seatbelt enumerate configurations of a single machine and report what is wrong with them. PrivHound enumerates the same kinds of facts and then joins them into a claim about what an attacker could do from a starting point. The first is a checklist you read; the second is a set of paths you can query. A team that runs periodic configuration audits will recognise the first model immediately, and the second is the better fit only once the audit starts asking what an attacker would actually do with the findings.
On maintenance and licensing, the facts are thin. The last push was on 2026-10-08, the repository has no GitHub releases, and the licence field is listed as unknown and no licence file appears in the repository listing. For a tool that reads credential data off Windows machines and uploads it to a graph database, resolve the licensing question before you deploy it internally.
Editorial conclusion
PrivHound suits a Windows defender who already uses BloodHound and wants local privilege escalation findings joined to the Active Directory graph, and it does not suit a team looking for a one command report of local misconfigurations, because the output is a graph for BloodHound rather than a readable list. Before you rely on its chains, read the qualifiers attached to them, since the readme marks credential extraction, relay prerequisites and privileged activation as unverified, and note that the licence field on the repository is listed as unknown.
Frequently asked questions
What is PrivHound?
It is a BloodHound OpenGraph collector that models Windows local privilege escalation as interconnected attack paths rather than isolated findings. It runs 29 checks covering 30 techniques, from weak service permissions to COM hijacking and WebClient relay.
Which local privilege escalation techniques does PrivHound check?
The table covers weak service permissions, writable service binaries, unquoted service paths, DLL hijacking via PATH, AlwaysInstallElevated, token privileges, scheduled tasks, autorun executables, stored and cached credentials, PowerShell history, cross-user profiles, WMI event subscriptions, shadow copy hives and more, each with a MITRE ATT&CK identifier.
How does PrivHound connect to BloodHound?
The .env.example file defines a base URL along with an API key and ID pair for integrations, or alternatively a JWT for short-lived or manual uploads. The default base URL in the example is a local BloodHound instance on port 8080.
Are PrivHound's attack chains confirmed exploits?
No, and the readme marks the difference per check. Credential extraction, privileged activation of COM candidates, named pipe impersonation and WebClient relay prerequisites are all described as unverified or requiring verification, while chains based on writable binaries are mechanical.
What licence is PrivHound released under?
The licence field on the repository is listed as unknown and no licence file appears in the repository listing, so resolve the licensing terms before deploying it internally.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dazzyddos-privhound)Was this useful?