{
	"id": "4df0b118-7575-426a-aa20-9e52790600c7",
	"created_at": "2026-04-06T00:06:32.934021Z",
	"updated_at": "2026-04-10T13:11:40.720289Z",
	"deleted_at": null,
	"sha1_hash": "9eeb57132a311e8feced63835c622741e6916668",
	"title": "Kerberoasting Without Mimikatz",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1435526,
	"plain_text": "Kerberoasting Without Mimikatz\r\nPublished: 2016-11-01 · Archived: 2026-04-05 19:14:37 UTC\r\nJust about two years ago, Tim Medin presented a new attack technique he christened “Kerberoasting“. While we\r\ndidn’t realize the full implications of this at the time of release, this attack technique has been a bit of a game\r\nchanger for us on engagements. More and more attention has been brought to Kerberoasting recently, with\r\n@mubix releasing a three part series on the topic, Sean Metcalf covering it several times, and @leonjza doing a\r\ndetailed writeup as well.\r\nThanks to an awesome PowerView pull request by @machosec, Kerberoasting is easier than ever using pure\r\nPowerShell. I wanted to briefly cover this technique and its background, how we’ve been using it recently, and a\r\nfew awesome new developments.\r\nKerberoasting Background\r\nI first heard about Kerberoasting from Tim at SANS HackFest 2014 during his “Attacking Kerberos: Kicking the\r\nGuard Dog of Hades” talk (he also released a Kerberoasting toolkit here). I’ll briefly paraphrase some technical\r\ndetail of the attack, but I highly recommend you read Tim’s slides and/or Sean’s explanation for more detail.\r\nThere’s also an excellent page of Microsoft documentation titled “Kerberos Technical Supplement for Windows”\r\nwhich finally clarified a few points involved in this process that were fuzzy to me.\r\nHere’s my version of the obligatory “this is how kerberos works” graphic:\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 1 of 6\n\nAs far as how Kerberoasting fits into this process, this is how I understand it (if I am mistaken on some point\r\nplease let me know!): after a user authenticates to the key distribution center (KDC, which in the case of a\r\nWindows domain is the domain controller) they receive a ticket-granting-ticket (TGT) signed with the domain\r\nkrbtgt account that proves they are who they say they are. The TGT is then used to request service tickets (TGS)\r\nfor specific resources/services on the domain. Part of the service ticket is encrypted with the NTLM hash of the\r\ntarget service instance. So how does the KDC determine exactly what key to use when encrypting these service\r\ntickets?\r\nThe Windows implementation of the Kerberos protocol uses service principal names (SPNs) to determine which\r\nservice account hash to use to encrypt the service ticket. There are two “types” of service principal names in\r\nActive Directory: “host-based” SPNs that are linked to a domain computer account and “arbitrary” SPNs that are\r\nusually (but not always) linked to a domain user account.\r\nAs Microsoft explains, “When a new computer account is created in Active Directory, host-based SPNs are\r\nautomatically generated for built-in services…In reality, SPNs are only created for the HOST service and all built-in services use the HOST SPN”. Put another way, “The HOST service represents the host computer. The HOST\r\nSPN is used to access the host computer account whose long term key is used by the Kerberos protocol when it\r\ncreates a service ticket”. Here’s an example of a default computer account in my test domain:\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 2 of 6\n\nYou can see the HOST/WINDOWS1 and HOST/WINDOWS1.testlab.local SPNs for the WINDOWS1$ computer\r\naccount. When a domain user requests access to \\\\WINDOWS1.testlab.local\\C$, the KDC maps this request to the\r\nHOST/WINDOWS1.testlab.local SPN, indicating that the WINDOWS1$ machine account NTLM hash (which is\r\nstored both on WINDOWS1 locally and the NTDS.dit Active Directory database on the DC/KDC) should be used\r\nto encrypt the server part of the service ticket. The signed/encrypted ticket is then presented to\r\nWINDOWS1.testlab.local, which is responsible for determining whether the requesting user should be granted\r\naccess.\r\nFrom the Kerberoasting perspective, we generally don’t care about host-based SPNs, as a computer’s machine\r\naccount password is randomized by default and rotates every 30 days. However, remember that arbitrary SPNs\r\ncan also be registered for domain user accounts as well. One common example is a service account that manages\r\nseveral MSSQL instances; this user account would have a \u003cMSSQLSvc/HOST:PORT\u003e SPN for each MSSQL\r\ninstance it’s registered for stored in the user’s serviceprincipalname attribute (Sean keeps an updated list of SPNs\r\nhere). If we have an arbitrary SPN that is registered for a domain user account, then the NTLM hash of that user’s\r\naccount’s plaintext password is used for the service ticket creation. This is the key to Kerberoasting.\r\nObligatory “So Why Does This Matter?”\r\nBecause of how Kerberos works, any user can request a TGS for any service that has a registered SPN (HOST or\r\narbitrary) in a user or computer account in Active Directory. Remember that just requesting this ticket doesn’t\r\ngrant access to the requesting user, as it’s up to the server/service to ultimately determine whether the user should\r\nbe given access. Tim realized that because of this, and because part of a TGS requested for an SPN instance is\r\nencrypted with the NTLM hash of a service account’s plaintext password, any user can request these TGS\r\ntickets and then crack the service account’s plaintext password offline, without the risk of account lockout!\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 3 of 6\n\nTo reiterate, any domain user account that has a service principal name set can have a TGS for that SPN requested\r\nby any user in the domain, allowing for the offline cracking of the service account plaintext password! This is\r\nobviously dependent on a crackable service account plaintext, but luckily for us service accounts tend to often\r\nhave simple passwords that change very infrequently. ¯\\_(ツ)_/¯\r\nAs an added bonus, Tim mentions on slide 18 of his presentation deck:\r\n¯\\_(ツ)_/¯\r\n“Old School” Kerberoasting\r\nTim’s outlined approach/toolkit used a combination of toolsets to request tickets, extract them from memory\r\n(using Mimikatz), and transform them into a crackable format. In general, the process (up until recently) went as\r\nfollows:\r\nEnumerate the domain accounts with SPNs set- either with Tim’s GetUserSPNS.ps1 script, Sean’s Find-PSServiceAccounts.ps1 script, or PowerView’s “Get-NetUser -SPN“.\r\nRequest TGSs for these specific SPNs with the builtin Windows tool setspn.exe or the .NET\r\nSystem.IdentityModel.Tokens.KerberosRequestorSecurityToken class in PowerShell.\r\nExtract these tickets from memory by invoking the kerberos::list /export Mimikatz command , with the\r\noptional base64 export format set first. The tickets were then downloaded, or the base64-encoded versions\r\npulled down to the attacker’s machine and decoded.\r\nBegin offline password cracking with Tim’s tgsrepcrack.py, or extract a crackable hash format from the\r\nraw ticket with John the Ripper’s  kirbi2john.py.\r\nxan7r branched Tim’s toolset and added an autokerberoast.ps1 script that automated large components of this\r\nprocess. Also, @tifkin_ wrote a Go version of a TGS cracker that functioned a bit faster than the original Python\r\nversion.\r\n“New School” Kerberoasting\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 4 of 6\n\nA few recent(ish) things really simplified our usage of Kerberoasting on engagements. First, Michael Kramer\r\nadded the KRB5TGS format to John the Ripper in September of 2015. Second, @Fist0urs committed the same\r\nalgorithm to Hashcat in Febuary 2016, opening the door for GPU-based cracking of these tickets. This was really\r\na watershed for us, as it greatly expanded the range of service account passwords we could crack. And finally,\r\nMatan Hart (@machosec)’s pull request to PowerView removed the Mimikatz requirement.\r\n@machosec realized that .NET class KerberosRequestorSecurityToken used in previous approaches also had a\r\nGetRequest() method, which returns the raw byte stream of the Kerberos service ticket. With a bit string\r\nmanipulation, Matan was able to easily extract out the encrypted (i.e. the crackable hash component) of the TGS.\r\nWe are now no longer dependent on Mimikatz for ticket extraction!\r\nI recently rolled the necessary functions into a single, self-contained script that contains the necessary components\r\nfrom PowerView (this has also been updated in Empire). We are currently in the process of refactoring large\r\ncomponents of PowerSploit, and the updated functions will be posted here after the changes are published. This\r\ncustom-rolled script includes the Invoke-Kerberoast function, which wraps the logic from Get-NetUser -SPN\r\n(to enumerate user accounts with a non-null servicePrincipalName) and Get-SPNTicket to request associated\r\nTGS tickets and output John and Hashcat crackable strings. For now, here’s what the output of the script looks\r\nlike:\r\nIt also works across domains!\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 5 of 6\n\nBy default, the John format is output, but -OutputFormat Hashcat will output everything Hashcat-ready. Note\r\nthat the -AdminCount flag only Kerberoasts accounts with AdminCount=1, meaning user accounts that are (or\r\nwere) ‘protected’ and, therefore, almost always highly privileged:\r\nAnd here’s how the updated Empire module looks:\r\nNote that for non-Empire weaponizations, as PSObjects are output, you will need to pipe the results to Format-List or ConvertTo-Csv -NoTypeInformation in order to preserve the information you want displayed. You can\r\nthen crack these tickets as @mubix described in his third post.\r\nAgain, the self-contained, PowerShell 2.0-compliant script is on my Gists here. Hopefully this is as much use to\r\nyou as it has been for us over the past few months!\r\nSource: https://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nhttps://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://blog.harmj0y.net/powershell/kerberoasting-without-mimikatz/"
	],
	"report_names": [
		"kerberoasting-without-mimikatz"
	],
	"threat_actors": [
		{
			"id": "8670f370-1865-4264-9a1b-0dfe7617c329",
			"created_at": "2022-10-25T16:07:23.69953Z",
			"updated_at": "2026-04-10T02:00:04.716126Z",
			"deleted_at": null,
			"main_name": "Hades",
			"aliases": [
				"Operation TrickyMouse"
			],
			"source_name": "ETDA:Hades",
			"tools": [
				"Brave Prince",
				"Gold Dragon",
				"GoldDragon",
				"Lovexxx",
				"Olympic Destroyer",
				"Running RAT",
				"RunningRAT",
				"SOURGRAPE",
				"running_rat"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775433992,
	"ts_updated_at": 1775826700,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/9eeb57132a311e8feced63835c622741e6916668.pdf",
		"text": "https://archive.orkl.eu/9eeb57132a311e8feced63835c622741e6916668.txt",
		"img": "https://archive.orkl.eu/9eeb57132a311e8feced63835c622741e6916668.jpg"
	}
}