forked from NetSPI/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGet-AdDecodedPassword.psm1
More file actions
97 lines (78 loc) · 3.82 KB
/
Get-AdDecodedPassword.psm1
File metadata and controls
97 lines (78 loc) · 3.82 KB
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
<#
Author: Scott Sutherland (@_nullbind), NetSPI
Version: 0.0.1
Description
This script uses the Active Directory Powershell Module to query Active Directory
for users with the UnixUserPassword, UserPassword, unicodePwd, or msSFU30Password properties
populated. It then decodes those password fields and displays them to the user.
This script is based on information shared in the blog below.
Reference: https://www.blackhillsinfosec.com/domain-goodness-learned-love-ad-explorer/
Example 1: Run on domain system as domain user.
Get-AdDecodedPassword -Verbose
Example 2: Run on non-domain system and target a remote domain controller with provided credentials
New-PSDrive -PSProvider ActiveDirectory -Name RemoteADS -Root "" -Server a.b.c.d -credential domain\user
cd RemoteADS:
Get-AdDecodedPassword -Verbose
#>
Function Get-AdDecodedPassword
{
[CmdletBinding()]
Param()
# Import the AD PS module
Import-Module ActiveDirectory
# Get domain users with populated UnixUserPassword properties
Write-Verbose "Getting list of domain accounts and properties..."
$EncodedUserPasswords = Get-AdUser -Filter * -Properties * |
Select-Object samaccountname, description, UnixUserPassword, UserPassword, unicodePwd, msSFU30Name, msSFU30Password
# Decode passwords for each user
Write-Verbose "Decoding passwords for each account..."
$DecodedUserPasswords = $EncodedUserPasswords |
ForEach-Object{
# Grab fields and decode password
$SamAccountName = $_.samaccountname
$Description = $_.description
$UnixUserPasswordEnc = $_.UnixUserPassword | ForEach-Object {$_};
if($UnixUserPasswordEnc -notlike ""){
$UnixUserPassword = [System.Text.Encoding]::ASCII.GetString($UnixUserPasswordEnc)
}else{
$UnixUserPassword = ""
}
$UserPasswordEnc = $_.UserPassword | ForEach-Object {$_};
if($UserPasswordEnc -notlike ""){
$UserPassword = [System.Text.Encoding]::ASCII.GetString($UserPasswordEnc)
}else{
$UserPassword = ""
}
$unicodePwdEnc = $_.unicodePwd | ForEach-Object {$_};
if($unicodePwdEnc -notlike ""){
$unicodePwd = [System.Text.Encoding]::ASCII.GetString($unicodePwdEnc)
}else{
$unicodePwd = ""
}
$msSFU30Name = $_.msSFU30Name
$msSFU30PasswordEnc = $_.msSFU30Password | ForEach-Object {$_};
if ($msSFU30PasswordEnc -notlike ""){
$msSFU30Password = [System.Text.Encoding]::ASCII.GetString($msSFU30PasswordEnc)
}else{
$msSFU30Password = ""
}
# Check if any of the password fields are populated
if(($UnixUserPassword) -or ($UserPassword) -or ($msSFU30Password) -or ($unicodePwd)){
# Create object to be returned
$UnixPasswords = New-Object PSObject
$UnixPasswords | add-member Noteproperty SamAccountName $SamAccountName
$UnixPasswords | add-member Noteproperty Description $Description
$UnixPasswords | add-member Noteproperty UnixUserPassword $UnixUserPassword
$UnixPasswords | add-member Noteproperty UserPassword $UserPassword
$UnixPasswords | add-member Noteproperty unicodePwd $unicodePwd
$UnixPasswords | add-member Noteproperty msSFU30Name $msSFU30Name
$UnixPasswords | add-member Noteproperty msSFU30Password $msSFU30Password
}
# Return object
$UnixPasswords
}
# Display recovered/decoded passwords
$DecodedUserPasswords | Sort-Object SamAccountName -Unique
$FinalCount = $FinalList.Count
write-verbose "Decoded passwords for $FinalCount domain accounts."
}