Service Executable Hijacking is a misconfiguration flaw, where a service runs an executable which has overly permissive permissions on it (for example: “Full Control” permissions to “Authenticated Users”). If a service runs under the security context of a user with high permissions (such as: NT Authority\SYSTEM), and an attacker with low privileges is able to modify the executable that service is running (such as replacing it with their own) - the service could run that executable with high privileges.
This hunt finds all Windows services which are vulnerable to service executable hijacking. It does so in the following manner:
#services #hijacking
name: Windows.Services.Hijacking
description: |
Service Executable Hijacking is a misconfiguration flaw, where a service runs an executable which has
overly permissive permissions on it (for example: "Full Control" permissions to "Authenticated Users").
If a service runs under the security context of a user with high permissions (such as: NT Authority\SYSTEM),
and an attacker with low privileges is able to modify the executable that service is running (such as
replacing it with their own) - the service could run that executable with high privileges.
This hunt finds all Windows services which are vulnerable to service executable hijacking.
It does so in the following manner:
1. Enumerate all services, and extract the full path of their executables.
2. Run an external Powershell script to enumerate the ACLs of those executables.
3. Display all relevant information regarding found vulnerable services.
#services #hijacking
author: "Yaron King - @Sam0rai"
type: CLIENT
sources:
- precondition:
SELECT OS From info() where OS = 'windows'
query: |
LET services = SELECT *
FROM Artifact.Windows.System.Services()
LET Script <= tempfile(data='''
$glob = $args[0]
$pathsArray = $glob -split ";"
$aclArray = @()
foreach($filePath in $pathsArray) {
foreach($acl in (Get-Acl $filePath).Access) {
$obj = new-object PSObject -Property @{
FilePath = $filePath
IdentityReference = $acl.IdentityReference.Value
FileSystemRights = $acl.FileSystemRights
IsInherited = $acl.IsInherited
InheritanceFlags = $acl.InheritanceFlags
PropagationFlags = $acl.PropagationFlags
}
$aclArray += $obj
}
}
$aclArray | ConvertTo-Json
''', extension=".ps1")
Let servicesPath = Select AbsoluteExePath, count() AS Count
FROM services
GROUP BY AbsoluteExePath
LET ExecutableACLs = SELECT * FROM foreach(
row={
SELECT Stdout FROM execve(argv=["Powershell", "-ExecutionPolicy",
"bypass", "-file", Script, join(array=servicesPath.AbsoluteExePath, sep=";")], length=1000000)
}, query={
SELECT * FROM parse_json_array(data=Stdout)
})
// Dictionary of hard-coded File System Rights index numbers to human-readable strings
LET FileSystemRightsDict = dict(
`2032127` = "Full Control",
`1180063` = "Read, Write",
`1245631` = "Change",
`1180095` = "ReadAndExecute, Write",
`268435456` = "FullControl (Sub Only)")
LET ExecutableACLs_Filtered = SELECT FilePath, IdentityReference, get(item=FileSystemRightsDict, member=str(str=FileSystemRights)) AS Permissions, FileSystemRights, IsInherited, InheritanceFlags, PropagationFlags
FROM ExecutableACLs
WHERE (
IdentityReference != "BUILTIN\\Administrators" and
IdentityReference != "NT AUTHORITY\\SYSTEM" and
IdentityReference != "NT SERVICE\\TrustedInstaller"
)
and (
FileSystemRights = 2032127 or -- NTFS permission "Full Control"
FileSystemRights = 1180063 or -- NTFS permission "Read, Write"
FileSystemRights = 1245631 or -- NTFS permission "Change"
FileSystemRights = 1180095 or -- NTFS permission "ReadAndExecute, Write"
FileSystemRights = 268435456 -- NTFS permission "FullControl (Sub Only)"
)
SELECT * FROM foreach(
row={SELECT * FROM ExecutableACLs_Filtered},
query={
SELECT Name, DisplayName, State, Status, StartMode, PathName, AbsoluteExePath as Command, UserAccount, Permissions, IdentityReference as UserWithPermissions, Created
FROM services
WHERE AbsoluteExePath = FilePath
}
)