Headhunter

Headhunter: Smart Executive Discovery in Massive Active Directory Environments#
The Problem#
You’re on an engagement and need to map out the executive structure of a Fortune 500 company. The Active Directory forest has 250,000+ users spread across multiple domains. You need names, titles, org hierarchy, and contact information for every VP and above.
Why executives? They’re high-value targets: elevated privileges, access to sensitive data and systems, and typically good vectors for social engineering. A well-crafted spearphishing campaign targeting VPs yields better results than burning zero-days on random endpoints. Plus, understanding the org structure helps you identify approval chains, find executive assistants (who often have delegated access), and build effective pretexts.
What many would do is to query AD for every user with “VP” or “Executive” in their title. Unfortunately, you’ve now just triggered 250,000 LDAP queries and your script will finish sometime next Tuesday. 😄 Or you could recursively crawl the org hierarchy from the CEO down using directReports; nothing says “operational efficiency” like processing thousands of irrelevant nodes to find 50 executives.
There must be a better way.
The Insight#
It seems clear when you think about it but it’s still often overlooked during recon: executives cluster together structurally. If you find a VP, their direct reports are likely to include other VPs, Directors, or Senior VPs. But once you hit a Manager or Lead without an executive title, everyone below them is almost certainly non-executive.
This means we can use the org chart structure itself as a filter. Start at the top, crawl down following directReports, but stop descending branches when executive titles disappear. It’s like a depth-first search with intelligent pruning.
Instead of processing hundreds of thousands of users, you only process the executive spine of the organization—typically 500-1,500 people. That’s a 99%+ reduction in work.
How Headhunter Works#
Headhunter implements title-filtered organizational tree traversal. Here’s the algorithm:
- Start with a known executive (typically the CEO’s AD alias)
- Query their user object from Active Directory, including
TitleandDirectReportsattributes - Check if their title matches executive criteria (VP, EVP, CEO, President, Chief, Director, etc.)
- If yes: Add them to results and examine their direct reports
- If no: Still examine direct reports if parent was executive (catches edge cases where executives report through non-exec roles), but stop if this level also has no execs
- Recurse through direct reports, repeating the process
The key optimization: when we hit a non-executive whose direct reports are also non-executives, we stop crawling that entire downstream branch.
CEO ✓
├── President ✓
│ ├── EVP Marketing ✓
│ │ ├── VP Digital ✓
│ │ │ └── Manager Smith ✗ → Check reports, none are execs → STOP
│ │ └── VP Brand ✓
│ └── Marketing Director ✓
└── Executive Assistant ✗ → Check reports, none are execs → STOP
Note: The algorithm checks one level past non-executives to catch unusual reporting structures where executives might report through non-executive roles.
Implementation Details#
The core of the tool is the recursive crawling function with title filtering:
function Get-ADDirectReportsFiltered {
param(
[string]$Identity,
[int]$CurrentDepth = 0,
[string]$HierarchyPath = ""
)
# Skip if already processed (prevent circular references)
$identityKey = $Identity.ToLower()
if ($processedUsers.ContainsKey($identityKey)) {
return
}
# Get user with Title and DirectReports
$user = Find-UserInDomains -Identity $Identity
$processedUsers[$identityKey] = $true
# Check if title contains executive terms
$hasExecutiveTitle = Test-ExecutiveTitle -Title $user.Title
# Add to results if executive
if ($hasExecutiveTitle) {
$executiveEntry = [PSCustomObject]@{
Name = $user.Name
Title = $user.Title
ExecutiveLevel = Get-ExecutiveLevel -Title $user.Title
Department = $user.Department
EmailAddress = $user.EmailAddress
DirectReportsCount = $user.DirectReports.Count
HierarchyPath = $currentPath
# ... more fields
}
$script:executiveResults += $executiveEntry
}
# Process direct reports
foreach ($reportDN in $user.DirectReports) {
$directReport = Get-ADUser -Identity $reportDN -Properties Title
$reportHasExecutiveTitle = Test-ExecutiveTitle -Title $directReport.Title
# Continue if direct report is exec OR current user is exec (one-level lookahead)
if ($reportHasExecutiveTitle -or $hasExecutiveTitle) {
Get-ADDirectReportsFiltered -Identity $directReport.SamAccountName `
-CurrentDepth ($CurrentDepth + 1) `
-HierarchyPath $currentPath
}
}
}
Safety Features#
Large-scale AD queries blow up in predictable ways: infinite loops from circular references, memory exhaustion from processing entire business units, and timeouts on unreachable domains. Headhunter includes multiple safety mechanisms:
- Circular reference prevention: Tracks processed users to avoid infinite loops if org charts have cycles (they shouldn’t, but enterprises are weird)
- Depth limiting: Maximum depth of 10 levels by default—if you’re more than 10 layers deep from the CEO, something’s wrong
- Result capping: Stops at 1,000 executives by default to prevent runaway searches
- Multi-domain support: Automatically discovers all domains in the forest and searches across them
- Error handling: Continues if individual users can’t be resolved or domains are unreachable
Executive Classification#
Headhunter automatically categorizes executives by level based on title keywords:
- CEO: Chief Executive Officer
- President: President/VP of divisions
- EVP: Executive Vice President
- CVP: Corporate Vice President
- SVP: Senior Vice President
- VP: Vice President
- Vice: Vice-level roles without “President” (Vice Chair, Vice Dean, etc.)
- Director: Director-level (configurable whether to include)
This classification makes it easy to filter results or analyze the executive distribution, and of course you can create your own if you like.
Expected Performance#
In a typical environment with ~250,000 users, you might expect:
- Traditional title search: 10-15 minutes, processes all users
- Blind org chart crawl: 15-25 minutes, processes all users
- Headhunter: 2-5 minutes, processes ~500-1,000 relevant users
The efficiency gain comes from intelligent branch pruning—the script never touches the 99% of the organization that isn’t executive-level. Instead of querying every user, Headhunter only processes the executive spine of the organization.
Important caveat: Your actual results may vary significantly based on your AD permissions, network latency to domain controllers, the size/structure of the target directory, and how executives are distributed in the org chart. Organizations with flatter hierarchies may see different performance characteristics than deeply nested ones.
Usage#
Basic invocation:
.\headhunter.ps1 -CEOAlias "j.smith"
With options:
.\headhunter.ps1 -CEOAlias "ceo.account" `
-ExecutiveTitles @("VP","EVP","CVP","President","CEO","Chief") `
-ShowProgress `
-MaxDepth 8 `
-OutputFile "Q4_Executives.csv"
The output is a CSV with comprehensive data including 15+ fields: names, titles, executive levels, departments, contact info (email, phone), hierarchy paths, direct report counts, organizational depth, manager names, last logon dates, and more. Perfect for building target lists or understanding organizational structure.
The tool also automatically discovers all domains in your AD forest, so multi-domain environments are handled seamlessly.
Operational Considerations#
Permissions: Requires standard AD read access. Most domain users have this by default, but your mileage may vary depending on environment hardening.
Detection: This generates LDAP queries, which could be logged. If you’re trying to be stealthy, throttle your queries or run during business hours when AD traffic is high. The script is efficient enough that it doesn’t stick out like a full AD dump would.
Ethics: Use this responsibly. Organizational data is sensitive, and executive contact information can be used for social engineering. This tool is for authorized security assessments and administrative purposes only.
Why This Matters#
Mapping organizational structure is a critical part of reconnaissance—whether you’re an internal security team assessing risk, a penetration tester building a target list, or an admin trying to understand your own org chart.
Traditional approaches are either slow (process everyone) or incomplete (keyword searches miss people with non-standard titles). Headhunter leverages the inherent structure of organizations to be both fast and comprehensive.
The broader lesson: use structure as a filter. Data often has implicit hierarchies or relationships that can be exploited for efficiency. In this case, the org chart itself tells us where executives cluster and where they don’t, letting us focus our queries where they matter.
Get the Code#
Headhunter is on GitHub: github.com/axiom0x0/Headhunter
Requirements:
- PowerShell 5.1+ (or PowerShell Core)
- Active Directory module
- Domain user credentials
Contributions welcome. If you find bugs or have feature ideas, open an issue or PR.