1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
function Get-KerberosAESKey
{
<#
.SYNOPSIS
Generate Kerberos AES 128/256 keys from a known username/hostname, password, and kerberos realm. The
results have been verified against the test values in RFC3962, MS-KILE, and my own test lab.
https://tools.ietf.org/html/rfc3962
https://msdn.microsoft.com/library/cc233855.aspx
Author: Kevin Robertson (@kevin_robertson)
License: BSD 3-Clause
.PARAMETER Password
[String] Valid password.
.PARAMETER Salt
[String] Concatenated string containing the realm and username/hostname.
AD username format = uppercase realm + case sensitive username (e.g., TEST.LOCALusername, TEST.LOCALAdministrator)
AD hostname format = uppercase realm + the word host + lowercase hostname without the trailing '$' + . + lowercase
realm (e.g., TEST.LOCALhostwks1.test.local)
.PARAMETER Iteration
[Integer] Default = 4096: Int value representing how many iterations of PBKDF2 will be performed. AD uses the
default of 4096.
.PARAMETER OutputType
[String] Default = AES: (AES,AES128,AES256,AES128ByteArray,AES256ByteArray) AES, AES128, and AES256 will output strings.
AES128Byte and AES256Byte will output byte arrays.
.EXAMPLE
Get-KerberosAESKey -Password password -Salt ATHENA.MIT.EDUraeburn -Iteration 1
Verify results against first RFC3962 sample test vectors in section B.
.EXAMPLE
Get-KerberosAESKey -Salt TEST.LOCALuser
Generate keys for a valid AD user.
.LINK
https://github.com/Kevin-Robertson/Powermad
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][String]$Salt,
[parameter(Mandatory=$false)][System.Security.SecureString]$Password,
[parameter(Mandatory=$false)][ValidateSet("AES","AES128","AES256","AES128ByteArray","AES256ByteArray")][String]$OutputType = "AES",
[parameter(Mandatory=$false)][Int]$Iteration=4096
)
if(!$Password)
{
$password = Read-Host -Prompt "Enter password" -AsSecureString
}
$password_BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password_cleartext = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($password_BSTR)
[Byte[]]$password_bytes = [System.Text.Encoding]::UTF8.GetBytes($password_cleartext)
[Byte[]]$salt_bytes = [System.Text.Encoding]::UTF8.GetBytes($Salt)
$AES256_constant = 0x6B,0x65,0x72,0x62,0x65,0x72,0x6F,0x73,0x7B,0x9B,0x5B,0x2B,0x93,0x13,0x2B,0x93,0x5C,0x9B,0xDC,0xDA,0xD9,0x5C,0x98,0x99,0xC4,0xCA,0xE4,0xDE,0xE6,0xD6,0xCA,0xE4
$AES128_constant = 0x6B,0x65,0x72,0x62,0x65,0x72,0x6F,0x73,0x7B,0x9B,0x5B,0x2B,0x93,0x13,0x2B,0x93
$IV = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
$PBKDF2 = New-Object Security.Cryptography.Rfc2898DeriveBytes($password_bytes,$salt_bytes,$iteration)
$PBKDF2_AES256_key = $PBKDF2.GetBytes(32)
$PBKDF2_AES128_key = $PBKDF2_AES256_key[0..15]
$PBKDF2_AES256_key_string = ([System.BitConverter]::ToString($PBKDF2_AES256_key)) -replace "-",""
$PBKDF2_AES128_key_string = ([System.BitConverter]::ToString($PBKDF2_AES128_key)) -replace "-",""
Write-Verbose "PBKDF2 AES128 Key: $PBKDF2_AES128_key_string"
Write-Verbose "PBKDF2 AES256 Key: $PBKDF2_AES256_key_string"
$AES = New-Object "System.Security.Cryptography.AesManaged"
$AES.Mode = [System.Security.Cryptography.CipherMode]::CBC
$AES.Padding = [System.Security.Cryptography.PaddingMode]::None
$AES.IV = $IV
# AES 256
$AES.KeySize = 256
$AES.Key = $PBKDF2_AES256_key
$AES_encryptor = $AES.CreateEncryptor()
$AES256_key_part_1 = $AES_encryptor.TransformFinalBlock($AES256_constant,0,$AES256_constant.Length)
$AES256_key_part_2 = $AES_encryptor.TransformFinalBlock($AES256_key_part_1,0,$AES256_key_part_1.Length)
$AES256_key = $AES256_key_part_1[0..15] + $AES256_key_part_2[0..15]
$AES256_key_string = ([System.BitConverter]::ToString($AES256_key)) -replace "-",""
# AES 128
$AES.KeySize = 128
$AES.Key = $PBKDF2_AES128_key
$AES_encryptor = $AES.CreateEncryptor()
$AES128_key = $AES_encryptor.TransformFinalBlock($AES128_constant,0,$AES128_constant.Length)
$AES128_key_string = ([System.BitConverter]::ToString($AES128_key)) -replace "-",""
Remove-Variable password_cleartext
switch($OutputType)
{
'AES'
{
Write-Output "AES128 Key: $AES128_key_string"
Write-Output "AES256 Key: $AES256_key_string"
}
'AES128'
{
Write-Output "$AES128_key_string"
}
'AES256'
{
Write-Output "$AES256_key_string"
}
'AES128ByteArray'
{
Write-Output $AES128_key
}
'AES256ByteArray'
{
Write-Output $AES256_key
}
}
}
|