A collection of cybersecurity content.

Scheduled Tasks: Collecting Evidence

Intro

Scheduled tasks are a valuable feature in Windows that enables users to schedule specific actions on their systems at desired times. This feature allows users to start designated programs at login, reboot their computers on a set schedule, and execute custom commands or scripts. However, this feature can also be exploited by adversaries to establish persistence on a compromised system, enabling them to maintain unauthorized access through the same features.

Adversarial Use

Adversaries can abuse scheduled tasks to accomplish their objectives remaining concealed on your system and launching attacks. They may configure a scheduled task to activate their malware whenever they feel like it which is almost always to evade detection. Scheduled tasks can also enable them to perform operations like executing malicious commands, exfiltrating sensitive data, or engaging in whatever malicious activities are necessary.

Let’s make a scheduled task that simply adds notepad.exe to a Run registry key which is commonly used for persistence.

Set a Scheduled Task

We can now see that notepad.exe has been added to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run registry key causing any program listed here to run automatically when we log in.

Scheduled Task Added Run Registry Key

When it comes to compromised systems, adversaries may use a range of techniques, including scheduled tasks, to achieve their objectives. However, it is unlikely that they will resort to benign commands such as the ones we have been discussing using notepad.exe. Instead, they are more likely to use more sophisticated and malicious techniques that are designed to evade detection and enable them to achieve their goals more effectively.

Detection

As part of their incident response strategy, security teams should proactively monitor for any newly created or altered scheduled tasks as this could indicate potentially malicious activity.

The following script will output scheduled task information necessary for incident response teams to make a decision by outputting parsed fields to C:\temp\ScheduledTasks.csv. The last few columns provide pre-made commands to take action on any malicious scheduled tasks found, allowing for quicker remediation to stop, disable, delete, or re-enable the task in question.

However, always quarantine the machine in question if a compromise is confirmed.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

$results = Get-ScheduledTask | ForEach-Object {
    $ActionFields = $_.Actions | ForEach-Object {
        @{
            Id            = $_.Id
            Arguments     = $_.Arguments
            Execute       = $_.Execute
            WorkDirectory = $_.WorkingDirectory
            PSComputerName = $_.PSComputerName
        }
    }

    $ExpandedTriggers = ($_.Triggers | ForEach-Object {
        "Enabled: $($_.Enabled)`n" +
        "StartBoundary: $($_.StartBoundary)`n" +
        "EndBoundary: $($_.EndBoundary)`n" +
        "ExecutionTimeLimit: $($_.ExecutionTimeLimit)`n" +
        "Id: $($_.Id)`n" +
        "StateChange: $($_.StateChange)`n" +
        "Repetition: $($_.Repetition)"
    }) -join "`n`n"

    $DisableTask = "Disable-ScheduledTask -TaskName '$($_.TaskName)' -TaskPath '$($_.TaskPath)'"
    $StopTask = "Stop-ScheduledTask -TaskName '$($_.TaskName)' -TaskPath '$($_.TaskPath)'"
    $EnableTask = "Enable-ScheduledTask -TaskName '$($_.TaskName)' -TaskPath '$($_.TaskPath)'"
    $DeleteTask = "Unregister-ScheduledTask -TaskName '$($_.TaskName)' -TaskPath '$($_.TaskPath)' -Confirm:`$false"
    $StartTask = "Start-ScheduledTask -TaskName '$($_.TaskName)' -TaskPath '$($_.TaskPath)'"

    foreach ($action in $ActionFields) {
        [PSCustomObject]@{
            State         = $_.State
            Author        = $_.Author
            RunAs         = $_.Principal.UserId
            LastUpdated   = $_.Date
            TaskName      = $_.TaskName
            TaskPath      = $_.TaskPath
            Execute       = $action.Execute
            Arguments     = $action.Arguments
            Id            = $action.Id
            Description   = $_.Description
            Triggers      = $ExpandedTriggers.Trim()
            WorkDirectory = $action.WorkDirectory
            PSComputerName = $action.PSComputerName
            StopTask = $StopTask
            DeleteTask = $DeleteTask
            DisableTask = $DisableTask
            EnableTask = $EnableTask
            StartTask = $StartTask
        }
    }
}

$results | Sort-Object LastUpdated -Descending | Export-Csv -Path "C:\temp\ScheduledTasks.csv" -NoTypeInformation
Conclusion

It’s important to stay alert to potential threats on your systems, including suspicious scheduled tasks. By quickly identifying and investigating any new or modified tasks, you can detect and mitigate potential attacks before they can cause significant damage.

Automated tools like SOAR platforms, SIEM, and EDR telemetry can help streamline this process and make it easier to monitor for potential threats. Use this script to assist with your data collection processes during an incident.