-
Notifications
You must be signed in to change notification settings - Fork 603
Add taskhound module for Windows scheduled task enumeration #933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- New SMB module to enumerate Windows scheduled tasks - Identifies tasks running with privileged accounts - Detects tasks with stored credentials vs token-based logon - Legacy BloodHound integration for high-value user identification - Supports CSV and JSON BloodHound exports - Includes comprehensive filtering options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new SMB module called "taskhound" that enumerates Windows scheduled tasks to identify privileged tasks with stored credentials. The module analyzes tasks running under high-value user accounts and distinguishes between tasks that store credentials versus those using token-based authentication.
- Implements comprehensive scheduled task enumeration over SMB protocol
- Integrates with BloodHound data to identify high-value user tasks
- Provides filtering options to exclude default Microsoft tasks and system accounts
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/e2e_commands.txt | Adds taskhound module to end-to-end test suite |
| nxc/modules/taskhound.py | New module implementing scheduled task enumeration with BloodHound integration |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
|
Man that's really hot ahah! Love it!! |
|
Thanks for the PR, looks cool! |
|
Hey there @NeffIsBack :). |
Absolutely! Feel free to add anything you think is useful. |
… works on my machine :P) Some things still need improvement. Like the Auto-Detection for BHCE/Legacy BloodHound is currently dependent on the existence of specific attributes like isTierZero for BHCE. But it works for now. Features Added: - Dual BloodHound format support + Auto-Detect (Legacy + BHCE) - Rudimentary Tier 0 detection with AdminSDHolder and isTierZero flags for BHCE, SID Mapping for Legacy - Password age analysis for DPAPI dump viability - Output options (plain,csv,json) - Backup Functionality to save raw XMLs - Language-independent group membership analysis (Because I was really dumb earlier. Languages change, SIDs are eternal)
|
Soooooo, finally done :D. Lot's of changes. I hope nothing breaks (It works on my machine :P) Some things still need improvement. Like the Auto-Detection for BHCE/Legacy BloodHound is currently dependent on the existence of specific attributes like isTierZero for BHCE. But it works for now. Features Added:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 15 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
Co-authored-by: Copilot <[email protected]> Signed-off-by: r0BIT <[email protected]>
|
Hey thanks for the update. A few things that should be changed:
|
|
Hey, As for the connector: Great idea! I'll get to work on that :). But would it be possible to keep both? I actually run into scenarios quite often where the box I'm executing netexec from has no easy way of communicating directly with a bloodhound db. I think we could get the best of both worlds there. What do you think? |
No worries, but would be nice for the future. I might squash merge now to not have 20+ the same commit in the history.
Perhaps, but i think this is the wrong place for it. Currently we have the live connector to the database and if we would decide to integrate an offline version of this, the code should not sit in one specific module. I think we should use existing infrastructure for now and if we decide to add an offline parser this should happen in a separate PR and somewhere accessible for the entire application. |
Hey there! Just a quick update. The Connector for TaskHound itself is now finished an in testing. If you want to give it a spin, just checkout the specific branch. Once that one has been battle-tested and merged to main on the primary repo I'll get to work on the netexec specific integration. Would that work for you? :) |
|
I think so yes. Currently there just shouldn't be a separate bh parsing logic in the PR. Querying/identifying/parsing the tasks should be the first step for the module. Any BH stuff could be added later on. |
|
Understood. Let me strip the logic for now so the PR can go into testing and I'll open an enhancement once the OpenGraph Integration has been battle-tested. |
|
I am currently reworking the entire module with a "barebone" approach. For convenience and the maximum value (without needing a bloodhound connector) I would like to leave a rudimentary LDAP lookup in place that does the following:
Would that be ok? |
|
Sounds good. We should probably use the existing |
- Simplified barebone module focusing on task enumeration and LDAP-based privilege checking - changed ldap.py protocol with check_if_admin(username) and resolve_sid(sid) functions - Now Supports --local-auth with separate LDAP credentials via LDAP_USER/LDAP_PASS/LDAP_DOMAIN options - Automatic task XML backup to ~/.nxc/logs/taskhound_backup/ for later offline analysis - TIER-0 task detection based on privileged group membership (Domain Admins, Enterprise Admins, etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 14 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Implemented fixes from Copilot's automated code review: Security Fixes: - Fixed LDAP injection in resolve_sid() - added SID regex validation - Fixed LDAP injection in check_if_admin() - escape username in filter - Created escape_ldap_filter() function implementing RFC 4515 escaping - Fixed path traversal vulnerability - validate backup paths with abspath - Documented XXE vulnerability limitation (trusted source mitigation) Bug Fixes: - Fixed system account detection - now checks 'nt authority\' not 'nt ' - Added domain FQDN validation - requires proper format like 'example.local' - Improved exception handling - specific types before broad Exception - Added module __init__() - prevents AttributeError on early calls Code Quality: - Fixed typo in ldap.py - 'domaine' → 'domain' - Moved import re to module level for better performance - Cleaned up all linting issues (whitespace, quotes, docstrings) Per Neffs comment, implemented LDAP connection logic directly instead of fragile importlib dynamic imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@NeffIsBack Done :). |
Complete overlooked Copilot review item - implement hash-based LDAP authentication. Changes: - Detect nthash/lmhash from SMB connection object - Use ldap_conn.login() with hash parameters when password empty - Enables LDAP privilege detection with -H flag Fixes issue where module couldn't determine task privileges when using NetExec's -H flag for hash-based authentication.
Description
This PR aims at introducing a new module "taskhound" to enumerate and categorize Scheduled Tasks on remote systems.
Key Features:
Identifies tasks running with privileged accounts
Detects tasks with stored credentials vs token-based logon
Includes comprehensive filtering options (exclude default tasks under \Windows\ and Default Local SIDs like S-1-5-18, etc. unless enabled via option
Dual BloodHound format support + Auto-Detect (Legacy + BHCE)
Rudimentary Tier 0 detection with AdminSDHolder and isTierZero flags for BHCE, SID Mapping for Legacy
Password age analysis for DPAPI dump viability
Output options (plain,csv,json)
Backup Functionality to save raw XMLs
Language-independent group membership analysis (Because I was really dumb earlier. Languages change, SIDs are eternal)
See https://github.com/1r0BIT/TaskHound for original Repo (And some more features)
Type of change
Setup guide for the review
Setup only requires a (domain joined) windows machine with a few Scheduled Tasks to test features.
1x Task from a High Value User with Stored Creds
1x Task from a non High Value User with Stored Creds
1x Any Scheduled Task without Stored Creds
You can generate a suitable export for the json/csv parsing using the following cyphers:
BHCE (JSON only):
Legacy (JSON only because of all_props):
Then just export as csv or json and feed it to taskhound.
Screenshots (if appropriate):
Checklist:
poetry run python -m ruff check . --preview, use--fixto automatically fix what it can)tests/e2e_commands.txtfile if necessary (new modules or features are required to be added to the e2e tests)