Exploiting the Windows Task Scheduler Through CVE-2019-1069

June 11, 2019 | Simon Zuckerbraun

Earlier today, Microsoft released a patch to address CVE-2019-1069, an escalation of privilege vulnerability in the Windows Task Scheduler. Bugs of this nature have existed since Windows XP, but this most recent version impacts the latest Windows 10 and Windows Server 2019 versions. Information about the vulnerability was publicly available prior to the patch being released, and now that the patch is out, we can take a closer look at the vulnerability and the likelihood of exploitation.

The Vulnerability

The Task Scheduler service runs at the maximum level of privilege defined by the local machine, namely NT AUTHORITY\SYSTEM. Since it runs with such high-level privileges, Task Scheduler is a natural target for attackers. The service also accepts certain requests via RPC, allowing clients to manage tasks scheduled on the machine. Low-privileged clients can use this interface, but they are restricted to defining tasks that will run with credentials possessed by that client.

Task Scheduler stores tasks as files in two separate locations. The first, C:\Windows\Tasks, is a legacy location. The second location, used for all new tasks, is C:\Windows\System32\Tasks. If an RPC client uses the service to modify a task that is represented in the legacy location of C:\Windows\Tasks, when the service saves the modifications, the task will be migrated to the preferred location of C:\Windows\System32\Tasks.

When saving a task file to the preferred location, the service will set security information on the file granting ownership and full control to the owner of the task. Critically, the Task Scheduler service performs this action using its own highly-privileged SYSTEM token.

The permissions on the two task folders permit all authenticated users to create files within those folders. One consequence of this is that a client can manually place a file in the legacy folder, then make use of the Task Scheduler to have the task migrated to the preferred folder.

This particular combination of behaviors leaves an opening for a hard link attack. The essential steps of the attack are as follows:

  1. Create a new task.

  2. Replace the file in the preferred folder with a hard link to an arbitrary target file.

  3. Manually place a new task with the same name into the legacy folder.

  4. Use the Task Scheduler RPC interface to migrate the task to the preferred folder. The Task Scheduler service will update the security information on the file in the preferred folder, granting ownership and full control to the attacker. Since this file is actually a hard link, this security information will be applied to the target file.

 Through this, an attacker can gain full control of any local file on all versions of Windows 10.

 The Exploit Methodology

In the publicly available exploit code, executable files schtasks.exe and schedsvc.dll copied from Windows XP are pressed into service as the RPC client. Reversing schtasks.exe reveals that the requisite functionality is exposed by the Windows Task Scheduler COM API.

The posted exploit code requires the attacker to possess the cleartext password of the account being used for the attack. This somewhat limits the usability of the exploit in a real-world attack scenario. For example, if malware executes with user-level privileges, it may not know the cleartext password. However, in the documentation for the Task Scheduler COM API, one finds the following information regarding the password parameter (pwszPassword) of the SetAccountInformation method:

Set this parameter to NULL if the local system account is specified. If you set the TASK_FLAG_RUN_ONLY_IF_LOGGED_ON flag, you may also set pwszPassword to NULL for local or domain user accounts. Use the IScheduledWorkItem::SetFlags method to set the flag.

If pwszAccountName specifies the local system account, the caller must be an administrator on the local computer or an application running in the local system account. If not, this method will fail.

 According to this, even a low-privileged client may pass in a NULL value in place of a password, provided that: (a) the specified flag is set, and (b) the caller is not attempting to create a task that runs as the local system account. Testing confirms that this technique is perfectly valid. Therefore, this vulnerability is significantly more serious than has been recognized previously or publicly acknowledged.


This analysis shows how a locally-authenticated attacker can leverage this vulnerability to write malicious code to critical system executables, and thereby escalate privilege to SYSTEM – even without knowing the password of a user. If successfully exploited, the attacker could take complete control of the target system. Microsoft gave this bug an Exploit Index rating of 1, which means they believe attackers will start to use this vulnerability within 30 days. Given the publicity this has generated, and the high level of privilege held by the Task Scheduler service, it does seem safe to anticipate attacks sooner rather than later. Thanks also should go out to my colleagues at Trend Micro Research for their help in the analysis of this vulnerability.

You can find me on Twitter at @HexKitchen, and follow the team for the latest in exploit techniques and security patches.