Defense: Windows task scheduling as an attack vector

Windows[German]Attackers use Windows task scheduling as a technique and create tasks (scheduled tasks) there to infiltrate a victim's machine. The Qualys research team has investigated a number of ways attackers can hide such scheduled tasks. This paper describes three new techniques for hiding and deleting scheduled tasks in a Microsoft Windows environment. This is not theoretical work "in a vacuum," as the technique has been used by suspected Chinese attacker (APT) Hafnium.


Advertising

Attackers abuse the task scheduling (task scheduler) in Microsoft Windows environments to enable the initial or repeated execution of malicious code at system startup or at a scheduled time. The MITRE ATT&CK framework even cites this as one of the most popular techniques used by attackers, as the ability to schedule programs or scripts is a common service in various operating systems. 

Hafnium uses this technique

Recently, Microsoft security researchers published an article describing how hackers from the state-sponsored Chinese group Hafnium hide scheduled tasks by deleting the Security Descriptor (SD) value in the Windows registry path: :

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\TASK_NAME

After Microsoft publicly disclosed this attack technique, the Qualys research team wondered if there were other ways to hide scheduled tasks and decided to investigate further.

Hide scheduled task

This blog post explains the results. The most important finding of the analysis is that the index value in the Windows registry path

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\TASK_NAME

may be misused to hide or delete a scheduled task. Below, we briefly describe the technique that Hafnium and other actors use to hide a scheduled task. We then detail new techniques that can be used to hide a scheduled task in Microsoft environments.


Advertising

How attackers hide scheduled tasks

According to the Microsoft post, when each scheduled task is created, the following two registry subkeys are generated, one in the Tree path and the other in the Tasks path.

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\TASK_NAME 
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID} 

The first subkey TASK_NAME generated in the tree path corresponds to the name of the scheduled task. The values generated in it (i.e. Id, Index and SD) contain metadata for task registration in the system. 

The second subkey {GUID} generated in the Tasks path corresponds to the Id value in the Tree subkey. The values created in it (i.e. actions, path, triggers, etc.) contain the basic parameters required to execute the task.

In Hafnium's case, the attackers created a scheduled task called WinUpdate to restore broken connections to their Command & Control infrastructure. As a result, subkeys were created in the Tree path and the Tasks path. The attackers then gained SYSTEM privileges (through token theft) and deleted the SD value in the Tree subkey.

Removing the SD value caused the task to "disappear" from the task scheduler and from the output of the schtasks /query command, which meant that the scheduled task could no longer be found using any of the traditional identification methods.

The investigation by Qualsys security researchers now revealed that changing or deleting the index value in the tree subkey also causes scheduled tasks to be hidden. The security researchers will explain their findings below, but first a brief description of the investigation conditions.

The Qualys research team's investigation setup

The security researchers conducted their investigations on Windows 10 Pro (v10.0.19043), Windows 10 Enterprise (v10.0.19044) and Windows 2016 Server. On each machine, they first performed the following two steps

  • Configuring object monitoring in the advanced monitoring settings of the local security policy to display entries for creation (4698), deletion (4699) and update (4702) of scheduled tasks in the Windows security event log.
  • Creation of a scheduled task named ImpTask that runs after user logon.

schtasks /create /tn ImpTask /tr cmd.exe /sc onlogon /rl highest

As soon as the schtasks /create command is executed, the following three subkeys are created for the newly created ImpTask task (see Fig. 1).

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ImpTask 
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID} 
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Logon\{GUID}

The index value in the ImpTask subkey is set to 0x2 (see Fig. 1) because the {GUID} subkey for this task is created in the login path (because the task is scheduled to run after user login).

 
Fig. 1. Three registration keys to the scheduled task ImpTask. .

New methods of hiding a scheduled task

The security researchers found that when a scheduled task is created, another subkey is generated in addition to the Tree and Tasks subkeys. This third subkey is generated depending on when the scheduled task is to be executed:

  • At startup, specified by the /sc onstart parameter in schtasks /create.
  • During user logon, specified by the /sc onlogon parameter in schtasks /create
  • At a time other than startup or logon (for example, /sc daily /st 09:00).

The third subkey is created under one of the following paths:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Boot\{GUID} 
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Logon\{GUID} 
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Plain\{GUID}

The name of the third subkey {GUID} matches the Id value in the Tree subkey. In addition, we observed that the index value in the Tree subkey is also associated with this third subkey for the scheduled task. As the security researchers noted, the index value is set to either 0x1 or 0x2 or 0x3. Specifically: :

  • All tasks registered in the path HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\ Boot have an index value of 0x1.
  • All tasks registered in the path HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Logon have an index value of 0x2.
  • All tasks registered in the path HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\(Plain or Maintenance) have an index value of 0x3.

The Qualys research team wrote a Python script and ran it on several Windows machines to confirm this behavior. Since each scheduled task is part of either Boot or Logon or Plain or Maintenance, there appear to be only three possible values for Index: 0x1, 0x2 or 0x3.

During the research, the security researchers did not find any online documentation describing the purpose of the index value in the context of the scheduled task. However, the researchers managed to manipulate the index value to achieve the following results: mit der geplanten Aufgabe beschreibt. Jedoch gelang es den Forscher, den Indexwert zu manipulieren, um die folgenden Ergebnisse zu erzielen:

  • Hide a specific scheduled task: The researchers found that the task is hidden from the task scheduler and the output of the schtasks /query command when the index value in the tree subkey is set to 0x0. Nevertheless, the task continues to execute at the scheduled time, even if the system is restarted. This results in behavior that is exactly the same as what the hafnium attackers achieved by deleting the SD value. In addition, the researchers found that the task was deleted when they tried to change it after its index value was set to 0x0 with the schtasks /change command. However, no event with ID 4699 for deleting a scheduled task appears in the Windows security event log.
  • Hide all scheduled tasks: Further, we found that clearing the index value causes the task scheduler and schtasks /query to print the error message "An internal error has occurred," effectively hiding all scheduled tasks. However, the existing tasks will continue to run, and new tasks may also be created. 

If the index is set to a different value (0x4, 0xffff, etc.), the scheduled task will not be hidden, and the task will continue to execute as scheduled. Now let's take a closer look at the two results of manipulating the index value.

Hiding a scheduled task

In this first scenario, the security researchers create another scheduled task called ModifyIndexTask, which is executed once with SYSTEM privileges-after ImpTask is created-and set its index value to 0x0. The command is as follows:

schtasks /create /tn ModifyIndexTask /tr "reg.exe add  \"HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ImpTask\" /v Index /d 0x0 /t REG_DWORD /f" /ru "NT AUTHORITY\SYSTEM" /rl highest /sc once /st <time later than creation time of ImpTask>

 
Fig. 2. The index value of ImpTask is changed to 0x0.

As soon as the ModifyIndexTask task is executed, it sets the index value of ImpTask to 0 (Fig. 2). As a result, ImpTask disappears from both the task scheduler (Fig. 3) and the output of the schtasks /query command (Fig. 4).

However, ImpTask continues to run, even after a system reboot (Fig. 5). Although ImpTask does not appear in the output of schtasks /query, Fig. 5 shows that it is possible to retrieve the task's status with the schtasks /query command by specifying the task's name with the /tn parameter.


Fig. 3. ImpTask disappears from the task scheduler as soon as the index value is changed to 0x0.

 

Fig. 4. ImpTask disappears from the output of schtasks /query as soon as the index value is changed to 0x0. 


Figure 5. ImpTask continues to run even after the index value is set to 0x0.

The Qualys research team was able to reproduce this issue on every Windows 10 machine experimented with – testing was done on a total of five machines.

Another interesting observation was the following: When we try to change the program name in ImpTask (with index value 0x0) with the schtasks /change /tr command, the task is deleted, as shown in Fig. 6. This is done without showing event ID 4699 (A scheduled task was deleted) or event ID 4702 (A scheduled task was updated) in the Windows security event log. In contrast, event ID 4699 is displayed when the researcher use the schtasks /delete command to delete ImpTask.


Figure 6: When ImpTask is deleted with schtasks /change /tr, it leaves no trace in the Windows security log.

Hide all scheduled tasks

In this second scenario, security researchers create another scheduled task that runs with SYSTEM privileges and deletes the index value in the ImpTask subkey. The command to do this is:

schtasks /create /tn ModifyIndexTask /tr "reg.exe delete \"HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ImpTask\" /v Index /f" /ru "NT AUTHORITY\SYSTEM" /rl highest /sc once /st <time later than creation time of ImpTask>

As soon as the index value in the ImpTask subkey is deleted (Fig. 7), all scheduled tasks disappear from the task scheduler (Fig. 8) and the output of the schtasks /query command (Fig. 9). Instead, we get the error message "An internal error has occurred". Also, specifying the task name ImpTask with the /tn parameter does not work.


Fig. 7. index value deleted from ImpTask subkey.


Fig. 8. after deleting the index value, all scheduled tasks disappear from the task scheduler and an error message is displayed. 
Fig. 9. Specifying the name of the task with the schtasks /query /tn command does not work either. 

Although the scheduled tasks are not displayed, they are executed at the scheduled time. Even after rebooting the system, the scheduled tasks cannot be displayed. If ImpTask is changed with the schtasks /change command, the index value is generated again, and then the schtasks /query command is then executed successfully (Fig. 10).


Fig. 10. Changing ImpTask with the schtasks /change command causes the index value to be generated again, after which the schtasks /query command is executed successfully.

After deleting the index value, the researchers attempted to delete ImpTask with schtasks /delete. Interestingly, this command failed and an error message was issued. When we subsequently tried to change ImpTask with the schtasks /change command, the index value in the ImpTask subkey was restored. All tasks now reappeared in the task scheduler, and running schtasks /query was also successful. Note that the index value is restored only if schtasks /delete is executed before schtasks /change. If we ran schtasks /change without running schtasks /delete first, the index value was not restored, and we still received an error message when running schtasks /query.

Summary

An investigation by the Qualys research team found that in addition to the SD value, the index value in the Tree subkey of a scheduled task also plays an important role and both can be abused by attackers. In this blog, we described three new techniques to hide and delete scheduled tasks:

  • Hide a scheduled task from the task scheduler and the output of the schtasks /query command by setting its index value to 0x0.
  • Delete a scheduled task by first setting its index value to 0x0 and then using the schtasks /change /tr command, which effectively deletes the task without leaving a trace in the Windows security event log.
  • Hide all scheduled tasks from the task scheduler and the output of the schtasks /query command by deleting the index value of any scheduled task.

Any of these new techniques can be used to hide a scheduled task in Microsoft environments. Therefore, it is important to monitor changes to the index and SD values of scheduled tasks. Such changes could indicate that an attacker is attempting to execute malicious code-either at system startup or at a scheduled time-to gain persistence.


Cookies helps to fund this blog: Cookie settings
Advertising


This entry was posted in Security, Windows and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *