I came across an interesting article by scriptjunkie (which you should really read) about running code on a machine at any time using service-for-user. By changing one line in the export XML of a scheduled task you effectively get a scheduled task that can run whether or not a user is logged in, whether or not the system reboots, whether or not you have the user’s password, run as a limited user, and doesn’t require bypassing UAC! This isn’t an interactive logon but can still be very useful in certain situations.
This works with any user with logon as batch job. While scriptjunkies blog post only showed altering a basic task scheduled to run every hour, it is possible to create more complex triggers based off a variety of things to make a more flexible trigger for your payload. Some of the triggers can even be used to replicate functionality for non-privileged accounts that are usually restricted. Some can even be used to trigger a scheduled task remotely from only your IP address.
Not all of these are available to a non-privileged user or without hitting UAC issues (such as At startup or At log on) but you can still use a time based schedule, on lock/unlock, or event attempt to replicate the functionality of a restricted one with On an event. With these you do have a lot of flexibility to meet whatever your goal is, one of mine earlier on was to emulate the At log on.
While playing with the On an event trigger I noticed there are a number of useful events that occur within the System and Application logs when a user logs in and when a system starts. I need to spend more time to working with some of the kinks with boot events because they appear before the scheduler is up. However while looking around the events caused by a user logging in I noticed the following event.
This event triggers each time a user logs into a licensed copy of Windows and the event is in the Application event log which is generally available to non-privileged users. You can quickly create a trigger for this event via the task scheduler or command line if you know the syntax.
And then when you export it to XML you will get the following as a trigger.
With this trigger and the exported XML modified to set the logon type to Service-for-user (<LogonType>S4U</LogonType> within the principles section of the XML) you now have a scheduled task that will trigger whenever the user logs in.
After getting the logon to work I wanted to find an event that could be remotely triggered by any system on the same network. While playing around and sending different traffic at my test I noticed a few common trends that could be used for to meet my goal. When sending malformed data/authentication to certain services, of particular note SMB and terminal services (RDP), an event was created. One of the ones I found most useful is shown below.
At the end of the data in the Binary tags is the error code 80090330 (SEC_E_DECRYPT_FAILURE) meaning Windows thinks there was corruption as the data was sent and couldn’t decrypt the traffic. Two things jumped out for me when I saw this event, the fact that it was in the System log which generally isn’t restricted and the IP address of my scanning box is present. The first means a trigger can be created that works with most unprivileged users and doesn’t have to bother with UAC issues. The second, my IP address, can then be used within the trigger to make sure only requests coming from my scanning machine can be the one to trigger the scheduled task! Causing a machine to create this event is also trivial, all you need to do is an nmap -sV -p 3389 <IP Address>.
To trigger on the data withing an event you will need a XPath query to look for the event ID and IP address. The XPath I used was *[System[EventID=56]] and *[EventData[Data='192.168.2.18']] to single out this particular event. As seen in the screenshot above containing the event XML has the <System> tag which contains the event ID. The *[System[ section means to search anywhere in the event (denoted by the *) for the <System> tags. Any arguments feed to this will look only within the <System> tags and could be any of the sub-tags and you could also add in multiples to focus the definition even more such as giving the provider name as *[System[Provider[Name='TermDD'] and EventID=56]]. Then I just added an ‘and’ clause and combined another section looking for where Data=’192.168.2.18′ within the EventData sections.
It is easy to test the XPath queries within the event viewer. The event filter will allow you to manually change the XML to include XPaths so you can determine what you want to use. Below is what my XPath looked like when I was getting ready to make my scheduled task.
Now you can either do all of these by modifying the XML export of a scheduled task or use my new handy dandy Metasploit module @zeknox and I wrote. It supports a few premade triggers but will accept event ID/Log along with an optional XPath if you desire.
And once that is done all you need to do to trigger the scheduled task is run the nmap version scan on terminal services and you get a new shell! Be careful because this event does not trigger repeatedly after nmap scans, it will only trigger on the first scan. If you muck up the first attempt you will have to wait an hour or so till you can do it again. It will also generate event ID 36888, an Schannel event every time you scan terminal services but it doesn’t contain the IP address within the alert.
If you don’t have terminal services open on the box you can always look for something else to use. I am going to be playing with an event ID 40968 from LsaSrv in the System log due to an invalid authentication attempt which couldn’t be decoded. The easiest way to trigger this is to scan for MS-04-007 with something like Nessus but that might be something you want to avoid in case something like an IDS causes an alert for it.
From the view of the victim all you see is a new scheduled task that has a “Custom event filter” with no other indications of anything malicious. If you don’t specify the task name the module will assign a randomly generated name for both the payload and task however, which might raise an eyebrow or two if someone views it.
I tried to make the module as flexible as possible to allow the user to specify whatever event they would like to trigger on. If anyone else finds any others of use please let me know! I’d love to play with some different ones. The module has a few pre-set triggers for things like user logon (using the windows license validation event from above) or on user locking, and time based schedule. It will display and save to the notes database commands to quickly delete the task and payload as well.
The best place to grab the code is over on the following github [1, 2]. The s4u_persistence file needs to go into Metasploit directory under ’data/exploits/’. It is an outline of an exported XML used in the module. The module is currently submitted as a pull request to Metasploit.
EDIT: The module has now been merged into Metasploit, grab it at your nearest msfupdate!