One day I took my red SANS poster out (link) and figured it might be a good idea to acquire one or the other artifact using an EDR – in our case Tanium. I was particularly interested in getting RDP MRUs out of the registry. That’s when the struggle began.
So what are RDP MRUs. Sorry, not gonna explain what RDP stands for, but MRU usually stands for Most Recently Used. Did you ever ask yourself how windows or more correctly mstsc.exe – the RDP client distributed with Windows stores the information it propagates it’s address drop-down menu with? We’ll no surprise here – it’s a registry key. As the servers people connect to are usually something you don’t necessarily want to share with every other user on a system (particularly not on a jumphost) those specifically keys are stored in the user-specific portion of the registry – HKCU or HKEY_CURRENT_USER.
As soon as a user logs in, Windows propagates the HKCU branch with the contents of the individuals NTUser.dat hive file. So on a terminal server with many parallel sessions, HKCU is different for every user. So far so good – isn’t it. Well yes, it is for the user, but not so much for the incident responder. This whole process makes every HKCU based artifact a very dynamic concept. Let’s invest some time to figure out how to leverage that quite dynamic concept.
So from the start. The RDP MRUs are stored at HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default using the values MRU0 MRU<x> depending on how many historical RDP servers are stored.
As depicted above it’s quite easy to access this data from in an establishes interactive session (sounds sophisticated, just means logged on to explorer gui). But what if you want to access the MRUs from an agent on that system, and maybe the MRUs of all users? Well then it’s a different story. The typical agent based endpoint solutions run with SYSTEM privileges. SYSTEM is the highest privileged user on Windows systems – it’s not the typical kind of user though.
If you access the registry, namely the HKCU branch in a SYSTEM context, it seems not to be there (e.g. using the Tanium Get Registry Value Sensor). The same sensor works just fine for HKLM entries (HKEY_LOCAL_MACHINE). Crap. So what do I do now? Well actually it’s not surprising that I don’t get a lot of results using that sensor. HKCU is a very private affair, and how would Windows know which specific HKCU or in other words NTUser.dat I’m interested in.
So back to the drawing board. What I need the agent to do is something like the following steps:
- Figure out how many and which NTUser.dat files exist on the system
- Load them into a temporary key under HKLM
- Address the desired HKCU key within the temporary key
- Rinse and Repeat
As the solution I wanted that to work on is Tanium. I’m kind of limited to VB-Script, Powershell or WMI – newer versions will support python as well. I’m not so much into either of those languages (besides python, but most of our customers just haven’t that rolled out yet). So I figure that google was still my friend and could give me all the answers I was looking for. And frankly, it did, but it did so very reluctantly – or I was just tired and couldn’t find a good search term.
I ended up on a GitHub repo where someone needed to write some values in all NTUser.dat hives on a machine. That sounded like a good basis to start my sensor. Essentially it follows exactly the steps I drew up above. So the only thing I needed to do was changing the write operations to read operations and integrate everything into a Tanium sensor. If you want to implement that into whatever solution you use, the base code is here (https://github.com/micksmix/RegUpdateAllUsers/blob/master/RegUpdateAllHkcuHkcr)
This principle works for all keys under HKCU thus giving you a whole lot of useful, sometimes even stackable results. Stay tuned for the next post where I’ll explain what you can do with RDP MRUs when an attacker goes native in an APT3 style (aka doesn’t use malware to pivot)