Windows.Services.Hijacking

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


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
            }
        )