Skip to content

Feature/rubeus kerberoast adversary#588

Open
JedLi-2014 wants to merge 3 commits intomitre:masterfrom
JedLi-2014:feature/rubeus-kerberoast-adversary
Open

Feature/rubeus kerberoast adversary#588
JedLi-2014 wants to merge 3 commits intomitre:masterfrom
JedLi-2014:feature/rubeus-kerberoast-adversary

Conversation

@JedLi-2014
Copy link
Copy Markdown

Description

Adds support for the T1558.003 Kerberoasting technique through Rubeus:
New Stockpile ability YAML under data/abilities/credential-access/2797bb09-3b49-4295-b5da-26333bf0b61d.yml
New adversary profile YAML under data/adversaries/1ef21846-a4d4-49df-a140-66f9ab27a05f.yml
New Fact Source YAML under data/fact_sources/6cf9a926-177d-480d-927d-9b44ee72f95a.yml
New parser module app/parsers/rubeus_kerberoast.py
Puts everything together so that in Caldera UI you can pick “Kerberoast Rubeus” as an adversary and have the operation automatically seed the DC FQDN/IP, run Rubeus, parse the output into domain.user.crackable_tgs

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Seeded Fact Source with placeholder CHANGEME values, then updated to THECOMPANY.ORG / 192.168.100.10. for testing purposes
Launched a Sandcat agent on the Windows VM, ran an Operation using the “Kerberoast Rubeus” adversary.

Verified that:
Parser captured domain.user.name → domain.user.crackable_tgs facts

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works

@deacon-mp deacon-mp requested a review from Copilot October 6, 2025 22:44
Copy link
Copy Markdown

Copilot AI left a 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 support for the T1558.003 Kerberoasting technique through Rubeus, implementing a complete adversary profile that can automatically execute Kerberoasting attacks and parse TGS hashes for cracking.

Key changes:

  • Adds new adversary profile "Kerberoast Rubeus" with ability to execute Rubeus kerberoasting
  • Implements parser to extract domain usernames and TGS hashes from Rubeus output
  • Creates fact source for seeding domain controller FQDN and IP information

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
data/sources/6cf9a926-177d-480d-927d-9b44ee72f95a.yml Fact source for seeding DC FQDN/IP with placeholder values
data/adversaries/1ef21846-a4d4-49df-a140-66f9ab27a05f.yml Adversary profile configuration for Kerberoast Rubeus technique
data/abilities/credential-access/2797bb09-3b49-4295-b5da-26333bf0b61d.yml Ability definition for executing Rubeus kerberoasting command
app/parsers/rubeus_kerberoast.py Parser implementation to extract usernames and TGS hashes from Rubeus output

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +10 to +11
def parse(self, blob):
"""Parse the output from `.\Rubeus.exe kerberoast /simple`
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring references /simple flag but the actual command in the ability uses /domain and /dc flags without /simple. The docstring should match the actual command being parsed.

Copilot uses AI. Check for mistakes.
Comment on lines +63 to +68
i += 1

# Validate extraction
if username and tgs_hash and tgs_hash.startswith('$krb5tgs$'):
relationships.extend(self.create_relationships(username, tgs_hash))

Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parser only creates relationships for the last username/tgs_hash pair found due to variable overwriting. For multiple Kerberoastable users, previous username/tgs_hash pairs will be lost. The relationship creation should occur immediately after each complete username/hash pair is extracted.

Suggested change
i += 1
# Validate extraction
if username and tgs_hash and tgs_hash.startswith('$krb5tgs$'):
relationships.extend(self.create_relationships(username, tgs_hash))
# After extracting both username and tgs_hash, create relationships if valid
if username and tgs_hash and tgs_hash.startswith('$krb5tgs$'):
relationships.extend(self.create_relationships(username, tgs_hash))
username = None
tgs_hash = None
i += 1

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +9
value: CHANGEME
- trait: remote.host.ip
value: CHANGEME
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeholder values 'CHANGEME' should be more descriptive to guide users on what values are expected, such as 'domain.example.com' and '192.168.1.10' respectively.

Suggested change
value: CHANGEME
- trait: remote.host.ip
value: CHANGEME
value: domain.example.com
- trait: remote.host.ip
value: 192.168.1.10

Copilot uses AI. Check for mistakes.
@deacon-mp
Copy link
Copy Markdown
Contributor

Can you address the comments above and resubmit for review

@github-actions
Copy link
Copy Markdown

This pull request is stale because it has had no activity for 60 days. Remove the stale label or comment or this will be closed in 60 days

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.

3 participants