-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathGet-LAPSPassword.ps1
157 lines (109 loc) · 4.89 KB
/
Get-LAPSPassword.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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<#
.SYNOPSIS
This cmdlet can be used to retrieve the LAPS password using an LDAP query from a domain joined device. This will always return the LAPS username as Administrator
.DESCRIPTION
Retrieve the LAPS password of a computer on a remote domain joined device. The username will always be returned as Administrator
.PARAMETER Server
Define the Active Directory server to perform your query against for the LAPS password
.PARAMETER ComputerName
Define the name of the computer you want to retrieve the LAPS password for
.EXAMPLE
Get-LAPSPassword -Server DC01.osbornepro.com -ComputerName Desktop02
# The example performs an LDAP query against DC01.osbornepro.com for the Desktop02 LAPS password
.EXAMPLE
Get-LAPSPassword -Server DC01.osbornepro.com -ComputerName Desktop02 -Group "OSBORNEPRO\LAPS-Admin"
# The example performs an LDAP query against DC01.osbornepro.com for the Desktop02 LAPS password and verifies you have permissions to grab the password
.INPUTS
None
.OUTPUTS
None
.NOTES
Author: Robert H. Osborne
Alias: tobor
Contact: [email protected]
.LINK
https://github.com/tobor88
https://github.com/osbornepro
https://www.powershellgallery.com/profiles/tobor
https://osbornepro.com
https://writeups.osbornepro.com
https://btpssecpack.osbornepro.com
https://www.powershellgallery.com/profiles/tobor
https://www.hackthebox.eu/profile/52286
https://www.linkedin.com/in/roberthosborne/
https://www.credly.com/users/roberthosborne/badges
#>
Function Get-LAPSPassword {
[CmdletBinding()]
param(
[Parameter(
Position=0,
Mandatory=$True,
ValueFromPipeline=$False,
HelpMessage="Define the domain controller to query for the LAPS password `nEXAMPLE: dc01.osbornepro.com"
)] # End Parameter
[String]$Server,
[Parameter(
Position=1,
Mandatory=$True,
ValueFromPipeline=$False,
HelpMessage="Define the machine hostname to obtain the LAPS password of. (Not FQDN) `nEXAMPLE: desktop01"
)] # End Parameter
[String]$ComputerName,
[Parameter(
Position=2,
Mandatory=$False,
ValueFromPipeline=$False
#HelpMessage="Enter the security group required to read the LAPS passwords in Active Directory `nEXAMPLE: OSBORNEPRO.COM\LAPS-Admins"
)] # End Parameter
[String[]]$Group
) # End param
$Domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain
$DomainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
If ($Null -eq $Server) {
$Server = ($DomainObj.PdcRoleOwner).Name
} # End If
If (Test-NetTcpConnection -ComputerName $Server -Port 389 -ErrorAction Continue) {
Write-Error "[x] Could not reach LDAP port 389 on $Server. Trying to obtain password anyway"
} # End If
# Verifying LAPS group membership
If ($Group) {
$CurrentUserId = [Security.Principal.WindowsIdentity]::GetCurrent()
$GroupMembership = $CurrentUserId.Groups | ForEach-Object {
$_.Translate([Security.Principal.NTAccount])
} # End ForEach-Object
ForEach ($G in $Group) {
If (!($GroupMembership.Value.Contains("$($G)"))) {
Throw "[x] $($CurrentUserId.Name) does not have permissions to access LAPS"
} # End If
} # End ForEach
} # End If
# Use LDAP to search Active Directory for LAPS
$SearchString = "LDAP://" + $Server + ":389/"
$LdapFilter = "(Name=$ComputerName)"
$ObjDomain = New-Object -TypeName System.DirectoryServices.DirectoryEntry
$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
$DistinguishedName = "CN=$ComputerName,*,DC=$($DomainObj.Name.Replace('.',',DC='))"
$SearchString += $DistinguishedName
$Searcher.SearchRoot = $ObjDomain
$Searcher.Filter = $LdapFilter
$Searcher.SearchScope = "Subtree"
$Searcher.FindAll() | ForEach-Object {
$LAPS = $Null
$CompObject = $_.GetDirectoryEntry()
If ($Null -ne $($CompObject.'ms-Mcs-AdmPwd')) {
$LAPS = $($CompObject.'ms-Mcs-AdmPwd'.Replace("{","").Replace("}",""))
} # End If
$Results = New-Object -TypeName PSCustomObject -Property @{
HostName=$($CompObject.Name.Replace("{","").Replace("}",""));
Username="Administrator";
Password=$LAPS;
Domain=$Domain
} # End New-Object Property
} # End ForEach-Object
If ($Null -ne $Results) {
Return $Results
} Else {
Write-Error "[x] No LAPS password found for $ComputerName on $Server"
} # End If Else
} # End Function Get-LocalAdminPassword