Commands/Get-MachineCredential.ps1
Function Get-MachineCredential { <# .SYNOPSIS Retrieves the machine password from LSA and makes a PSCredential .DESCRIPTION Makes a pscredential object based on the computername and the LSA machine password .EXAMPLE PS> $credential = Get-MachineCredential $ADObject = New-Object -ComObject ADSystemInfo $DistintishedPath = $ADObject.gettype().InvokeMember("ComputerName","GetProperty",$null,$ADObject,$null) $CompDN = "LDAP://$DistintishedPath" $ComputerObject = New-Object System.DirectoryServices.DirectoryEntry($CompDN,$Credential.UserName,$Credential.GetNetworkCredential().Password) $ComputerObject |Select * .LINK http://www.JPScripter.com #> #Check for admin if(-not (Test-LocalAdmin)) { Throw "Run the Command as an Administrator" } #Setting LSA Permissions Set-ProcessPrivilage -ProcessPrivilege SeDebugPrivilege $LSAProcess = (Get-Process -Name lsass) $LSAToken = Get-ProcessToken -ID $LSAProcess.ID $DupToken = Get-DuplicateToken -Token $LSAToken Set-Impersonation -Token $DupToken #Dupliate LSA Key $MachineKey = '$MACHINE.ACC' $Key = 'LSA1' If (-not (Test-Path -Path HKLM:\SECURITY\Policy\Secrets\$MachineKey)){ Throw 'Machine account Password doesnt exist. Please join to a domain.' } Remove-Item HKLM:\SECURITY\Policy\Secrets\$Key -force -recurse -ErrorAction Ignore $Null = New-Item HKLM:\SECURITY\Policy\Secrets\LSA1 -ItemType Directory $values = 'CurrVal','OldVal','OupdTime','CupdTime','SecDesc' Foreach ($Property in $Values) { $copyFrom = "HKLM:\SECURITY\Policy\Secrets\$MachineKey\" + $Property $copyTo = "HKLM:\SECURITY\Policy\Secrets\$Key\" + $Property $Null = New-Item $copyTo -ItemType Directory $item = Get-ItemProperty $copyFrom $Null = Set-ItemProperty -Path $copyTo -Name '(default)' -Value $item.'(default)' } #region Make LSA Objects $objectAttributes = New-Object Pinvoke.LSA_OBJECT_ATTRIBUTES $objectAttributes.Length = 0 $objectAttributes.RootDirectory = [IntPtr]::Zero $objectAttributes.Attributes = 0 $objectAttributes.SecurityDescriptor = [IntPtr]::Zero $objectAttributes.SecurityQualityOfService = [IntPtr]::Zero $localsystem = New-Object Pinvoke.LSA_UNICODE_STRING $localsystem.Buffer = [IntPtr]::Zero $localsystem.Length = 0 $localsystem.MaximumLength = 0 $secretName = New-Object Pinvoke.LSA_UNICODE_STRING $secretName.Buffer = [System.Runtime.InteropServices.Marshal]::StringToHGlobalUni($Key) $secretName.Length = [Uint16]($key.Length * [System.Text.UnicodeEncoding]::CharSize) $secretName.MaximumLength = [Uint16](($key.Length + 1) * [System.Text.UnicodeEncoding]::CharSize) $lsaPolicyHandle = [IntPtr]::Zero $access = [Pinvoke.LSA_AccessPolicy]::POLICY_GET_PRIVATE_INFORMATION #endregion Make LSA Objects #region Open LSA Policy and get Password private Data $lsaOpenPolicyHandle = [Pinvoke.advapi32]::LSAOpenPolicy([ref]$localSystem, [ref]$objectAttributes, $access, [ref]$lsaPolicyHandle) if ( $lsaPolicyHandle -eq 0){ throw "Could not open LSA data" } $privateData = [IntPtr]::Zero $ntsResult = [Pinvoke.advapi32]::LsaRetrievePrivateData($lsaPolicyHandle, [ref]$secretName, [ref]$privateData) $lsaClose = [Pinvoke.advapi32]::LsaClose($lsaPolicyHandle) Remove-Item HKLM:\SECURITY\Policy\Secrets\$Key -force -recurse -ErrorAction Ignore if ( $privateData -eq [System.IntPtr]::Zero){ throw "Could not open Private LSA data" } #endregion #region Retrive and convert password $Length = [System.Runtime.InteropServices.marshal]::ReadInt16($privateData,0) $offset = 16 $Max = [System.Runtime.InteropServices.marshal]::ReadInt16($privateData,1) $stringBuilder = New-Object System.Text.StringBuilder -ArgumentList $Length For ($i = $offset; $I -le $Length*2+$offset ; $I+=[System.Text.UnicodeEncoding]::CharSize){ $b1 = [System.Runtime.InteropServices.marshal]::ReadByte($privateData,$i) $b2 = [System.Runtime.InteropServices.marshal]::ReadByte($privateData,$i+1) $currentChar = [System.BitConverter]::ToChar(($b1,$b2),0) if($currentChar -eq [char]::MinValue) { break; } [void]$stringBuilder.Append($currentChar) #Write-Verbose -message "$i = $currentChar - $b1 - $b2" } $Credential = [pscredential]::new("$env:USERDOMAIN\$env:COMPUTERNAME$", (ConvertTo-SecureString -String $stringBuilder.ToString() -AsPlainText -Force)) $Credential #endregion #Revert Token Back Set-Impersonation } |