Mark Russinovich has presented a screenshot of the autoruns utility during his Malware Hunting with the Sysinternals Tools session at Teched 2012.
He also reported a slowdown issue while he was at Teched 2012 in Europe in the following blog post.
We can actually see more about these scheduled tasks as he posted the following image:
These special scheduled tasks remind me the question that Jonathan Walz (@jonwalz)
asked on twitter:
Does anyone have a good method for detecting a logon or unlock of a computer (besides the security log (way too chatty)) with WMI?
Well, you may wonder what’s the link between the scheduled tasks from Microsoft on Mark’s laptop and Jonathan’s question ?
I’ve actually been using these kind of scheduled tasks to track user logon activity as the scheduler has now new triggers: Logon,SessionUnlock,RemoteDisconnect,ConsoleConnect,RemoteConnect,SessionLock,RemoteConnect and ConsoleDisconnect
I have been using the following code in quick and dirty mode to create all these local tasks:
Function Get-Template
{
param($trigger)
$template = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2011-01-27T17:29:29.0199265</Date>
<Author>SYSTEM</Author>
</RegistrationInfo>
$trigger
<Principals>
<Principal id="Author">
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>$env:systemroot\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-ExecutionPolicy RemoteSigned -File "$env:systemroot\scripts\Get-userinfo.ps1"</Arguments>
</Exec>
</Actions>
</Task>
"@
return $template
} # end of function
Function Get-SessionTrigger
{
param($trigger)
$sessiontrigger = @"
<Triggers>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>$trigger</StateChange>
</SessionStateChangeTrigger>
</Triggers>
"@
return $sessiontrigger
}
# Handle the logon trigger
$logontrigger = @"
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
</LogonTrigger>
</Triggers>
"@
# Create the Logon task
$xml = Get-Template -trigger $logontrigger
$xml | Out-File -FilePath ($env:temp +"\tmp.xml") -Encoding Unicode -Force
Invoke-Expression -Command ("schtasks.exe /create /RU SYSTEM /TN Logon /F /XML " + ($env:temp +"\tmp.xml"))
# Define an array of each connection state
$arraytriggersstate = @(
"SessionUnlock",
"RemoteDisconnect",
"ConsoleConnect",
"RemoteConnect",
"SessionLock",
"RemoteConnect",
"ConsoleDisconnect"
)
# Loop into the array and create the task
for ($i = 0 ; $i -lt $arraytriggersstate.count ; $i++)
{
Write-Host -ForegroundColor Green -Object ($arraytriggersstate[$i])
$xml = Get-Template -trigger (Get-SessionTrigger -trigger $arraytriggersstate[$i])
$xml | Out-File -FilePath ($env:temp +"\tmp.xml") -Encoding Unicode -Force
Invoke-Expression -Command ("schtasks.exe /create /RU SYSTEM /F /TN " + $arraytriggersstate[$i] + " /XML " + ($env:temp +"\tmp.xml"))
}
The tasks names are important as I’ve been extracting the last tasks names from the new Microsoft-Windows-TaskScheduler/Operational log to know what the user did and writing it to a CSV file that can be read afterward by custom helpdesk tools.
Here is the XML query passed to the Get-WinEvent cmdlet I’ve been using in my Get-userinfo.ps1 script:
# Wait a little bit until event 129 occurs
Start-Sleep -Seconds 10
$query =@"
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[Provider[@Name='Microsoft-Windows-TaskScheduler'] and (Level=4 or Level=0) and ( Task = 129 ) and TimeCreated[timediff(@SystemTime) <=200000 ]]]</Select>
</Query>
</QueryList>
"@
To know who logged on, I’m using the technique I’ve previously described in the following post Get Logged on users.
As far as I remember, there’s another way to play with logon triggers. It was published as a powershell tip in April on powershell.com and using the Register-ObjectEvent cmdlet and the [Microsoft.Win32.SystemEvents] .net objects.