The Windows Incident Response Blog is dedicated to the myriad information surrounding and inherent to the topics of IR and digital analysis of Windows systems. This blog provides information in support of my books; "Windows Forensic Analysis" (1st thru 4th editions), "Windows Registry Forensics", as well as the book I co-authored with Cory Altheide, "Digital Forensics with Open Source Tools".
Sunday, March 12, 2023
On Using Tools
Saturday, December 31, 2022
Persistence and LOLBins
Grzegorz/@0gtweet tweeted something recently that I thought was fascinating, suggesting that a Registry modification might be considered an LOLBin. What he shared was pretty interesting, so I tried it out.
First, the Registry modification:
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\Utilities\query" /v LOLBin /t REG_MULTI_SZ /d 0\01\0LOLBin\0calc.exe
Then the command to launch calc.exe:
query LOLBin
Now, I've tried this on a Windows 10 system and it works great, even though Terminal Services isn't actually running on this system. Running just the "query" command on both Windows 10 and Windows 11 systems (neither with Terminal Services running) results in the same output on both:
C:\Users\harlan>query
Invalid parameter(s)
QUERY { PROCESS | SESSION | TERMSERVER | USER }
Running the "query" command with different parameters (i.e., "process", "user", etc.) proxies that command to the appropriate entry based on the value in the Registry, as illustrated in figure 1.
![]() |
| Fig 1: query key values |
As such, running "query user" runs quser.exe, and you see the same output as if you simply ran "quser".
Note that the Utilities key has two other subkeys, in addition to "query"; "change" and "reset", as illustrated in fig. 2.
![]() |
| Fig. 2: Utilities subkeys |
So, I thought, what if I change the key path from "query", and make the same modification (via the 'reg add' command above) to the "change" subkey...would that have the same effect? Well, I tried it with an elevated command prompt, for both the "change" and "reset" subkeys, and got "Access is denied." both times. Okay, so we can only use this...at an Admin level, anyway...with the "query" subkey.
So what?
Part of what makes this particular persistence so insidious (IMHO) is how it can be launched. When we use the Run keys (or a Scheduled Task, or a Windows service) for persistence, an analyst may not have any trouble seeing the launch mechanism for the program/malware. In fact, even outside of Registry analysis, some SOC consoles will allow the analyst to see notable events, and even provide enough process lineage to allow the analyst to deduce that a notable event occurred.
To Grzegorz's point, this is an interesting LOLBin, because query.exe exists on the system by default. IMHO, this is important because when I started learning computers over 40 yrs ago (yes, circa 1982), all we had was the command line; as such, understanding which commands were available on the system, as well as things like STDOUT, STDERR, file redirection, etc., were all just part of what we learned. Now, 40 yrs later, we have entire generations of analysts (SOC, DFIR, etc.) who "grew up" without ever touching a command line. So, when I saw Grzegorz's tweet, the first thing I did was go the command prompt and type "query", and saw the response listed above. Easy peasy...but how many analysts do that? What's going to happen if a SOC analyst sees telemetry for "query user"? Or, what happens if a DFIR analyst sees a Prefetch file for query.exe? What assumptions will they make, and how will those assumptions drive the rest of their analysis and response?
What is a way to use this? Well, let's say you gain access to a system...and this is just hypothetical...and run a script that enables RDP (if it's not already running), enables StickyKeys, writes a Trojan to an alternate data stream (thanks to Dr. Hadi for some awesome research!!) and then creates a value beneath the "query" key for the Trojan. That way, if your activity on other systems gets discovered, you have a way back into the infrastructure that doesn't require authentication. Connect to the system via the Remote Desktop Client, access StickyKeys so that you get a System-level command prompt, and you type "query LOLBin". Boom, you're back in!
As you might expect, I did write a RegRipper plugin for this persistence mechanism, the output of which makes it pretty straightforward to see any changes that may have been made. For example, "normal" look like the following:
utilities v.20221231
(System) Get TS Utilities subkey values
Category: persistence - T1546
ControlSet001\Control\Terminal Server\Utilities\change
LastWrite time: 2018-04-12 09:20:04Z
logon 0 1 LOGON chglogon.exe
port 0 1 PORT chgport.exe
user 0 1 USER chgusr.exe
winsta 1 WINSTA chglogon.exe
ControlSet001\Control\Terminal Server\Utilities\query
LastWrite time: 2018-04-12 09:20:04Z
appserver 0 2 TERMSERVER qappsrv.exe
process 0 1 PROCESS qprocess.exe
session 0 1 SESSION qwinsta.exe
user 0 1 USER quser.exe
winsta 1 WINSTA qwinsta.exe
ControlSet001\Control\Terminal Server\Utilities\reset
LastWrite time: 2018-04-12 09:20:04Z
session 0 1 SESSION rwinsta.exe
winsta 1 WINSTA rwinsta.exe
Analysis Tip: The "query" subkey beneath "\Terminal Server\Utilities" can be used for persistence. Look for unusual value names.
Ref: https://twitter.com/0gtweet/status/1607690354068754433
Monday, November 14, 2022
RegRipper Value Proposition
When an analyst finds something new, either through research, review of open reporting, or through their investigative process, they can write a plugin to address the finding, and include references, statements/comments, etc.
Writing a plugin means that the capabilities developed by one analyst are now available to all analysts, without every analyst having to experience the same investigation. Keep in mind, as well, that not all analysts will approach investigations the same way, so one analyst may find something of value that another analyst might miss, simply because their perspectives and backgrounds are different.
A plugin can be written and documented (comments, etc.) such that it provides more than just the basic information about the finding; as such, the "corporate knowledge" (references, context, etc.) is retained and available to analysts, even when the plugin author is unavailable. The plugin can be modified and maintained across versions of Windows, if needed.
Monday, October 31, 2022
Testing Registry Modification Scenarios
After reading some of the various open reports regarding how malware or threat actors were "using" the Registry, manipulating it to meet their needs, I wanted to take a look and see what the effects or impacts of these actions might "look like" from a dead-box, DFIR perspective, looking solely at the Registry. I wanted to start with an approach similar to what I've experienced during my time in IR, particularly the early days, before EDR, before things like Sysmon or enabling Process Tracking in the Security Event Log. I thought that would be appropriate, given what appears to be the shear number of organizations with limited visibility into their infrastructures. For those orgs that have deployed Sysmon, the current version (v14.1) has three event IDs (12, 13, and 14) that pertain to the Registry.
The first scenario I looked at was from this Avast write-up on Raspberry Robins's Roshtyak component; in the section titled "Indirect registry writes", the article describes the persistence mechanism of renaming the RunOnce key, adding a value, then re-renaming the key back to "RunOnce", apparently in an effort to avoid rules/filters that look specifically for values being added to the RunOnce key. As most analysts are likely aware, the purpose of the RunOnce key is exactly that...to launch executables once. When the RunOnce key is enumerated, the value is read, deleted, and the executable it pointed to is launched. In the past, I've read about malware executables that are launched from the RunOnce key, and the malware itself, once executed, will re-write a value to that key, essentially allowing the RunOnce key and the malware together to act as if the malware were launched from the Run key.
I wanted to perform this testing from a purely dead-box perspective. Using EDR tools, or relying on the Windows Event Logs. Depending upon your configuration, you could perhaps look to the Sysmon Event Log, or if the system had been rebooted, you could also look to the Microsoft-Windows-Shell-Core%4Operational.evtx Event Log and Events Ripper to percolate unusual executables.
For reference, information on the Registry file format specification can be found here.
Methodology
The first thing I did was use "reg save" to create a backup of the Software hive. I then renamed the RunOnce key, and added a value (i.e., "Calc"), and renamed the key back to "RunOnce", all via RegEdit. I then closed RegEdit and used "reg save" to create a second copy of the Software hive. I then opened RegEdit, deleted the value, and saved a third copy of the Software hive.
During this process, I did not reboot the system; rather, I 'simulated' a reboot of the system by simply deleting the added value from the RunOnce key. Had the system been rebooted, there would likely be an interesting event record (or two) in the Microsoft-Windows-Shell-Core%4Operational.evtx Event Log.
Finally, I created a specific RegRipper plugin to extract explicit information about the key from the hive file.
First Copy - Software
So, again, the first thing I wanted to do was create a baseline; in this case, based on the structure for the key node itself.
![]() |
| Fig 1: Software hive, first copy output |
Using the API available from the Perl Parse::Win32Registry module, I wrote a RegRipper plugin to assist me in this testing. I wanted to get the offset of the key node; that is, the location within the hive file for the node itself. I also wanted to get both the parsed and raw information for the key node. This way, I could not only see the parsed data from within the structure of the key node itself, but I could also see the raw, binary structure, as well.
Second Copy - Software2
After renaming the RunOnce key, adding a value, and re-renaming the key back to "RunOnce", I saved a second copy of the Software hive, and ran the runonce_test.pl plugin to retrieve the information illustrated in figure 2.
![]() |
| Fig 2: Plugin output, second copy, Software hive |
We can see between figures 1 and 2 that there are no changes to the offset, the location of the key within the hive file itself. In fact, the only changes we do see are the LastWrite time (which is to be expected), and the number of values, which is now set to 1.
Third Copy - Software3
The third copy of the Software hive is where I had deleted the value that had been added. Again, this was intended to simulate rebooting the system, and did not account for the malware adding a reference to itself back to the RunOnce key once it was launched.
Figure 3 illustrates the output of the plugin run against the third copy of the Software hive.
![]() |
| Fig 3: Plugin output, third copy, Software hive |
Again, the offset/location of the key node itself hasn't changed, which is to be expected. Deleting the value changes the number of values to "0", and adjusts the key LastWrite time (which is to be expected).
I then ran the del.pl plugin (to get deleted keys and values from unallocated space within the hive file) against the third copy of the Software hive, opened the output in Notepad++, searched for "calc", and found the output shown in figure 4 below. I could have used regslack, from Jolanta Thomassen (go here to see Jolanta's thesis from 2008), but simply chose the RegRipper plugin because I was already using RegRipper.
![]() |
| Fig 4: Del.pl output from third copy, Software hive |
Unfortunately, value nodes contain neither time stamps, nor a reference back to the original key node (parent key offset) to which they were a member, as described in sections 4.1.1 and 4.1.2 of the Registry file format specification for key nodes; value node structures are described in sections 4.4.1 and 4.4.2.
Conclusion
As we can see from this testing, there's not much that we can see just from the Registry hive file that would lead us to believe that anything unusual had happened. While we might have an opportunity to see something of this activity via the transaction logs, that would depend a great deal upon how long after the activity that the incident was discovered, the amount of usage on the system, etc. It appears that the way this specific activity would be discerned would be through a combination of malware RE, EDR, Windows Event Log records, etc.
Next, I'll take a look at at least one of the scenarios presented in this Microsoft blog post.
Addendum, 1 Nov: Maxim Suhanov reached to me about running "yarp-print --deleted" to get a different view of deleted data within the hive, and I found some anomalous results that I simply cannot explain. As a result, I'm going to completely re-run the tests, fully documenting each step, and providing the results again.
Friday, July 01, 2022
Distros and RegRipper, pt deux
Now and again I pop my head up and take a look around to see where RegRipper has been, and is being, used. My last blog post on this topic had quite a few listings, but sometimes changing the search terms reveals something new, or someone else has decided to use RegRipper since the last time I looked.
References to RegRipper go way back, almost as far as RegRipper itself (circa 2008):
SANS blog (2009)
SANS blog (2010)
SANS Infosec Handler's Diary blog (2012)
Kali Tools (RR v2.5)
SANS Blog, Mass Triage, pt 4 (2019)

You can see the Registry parsing in action and how it's incorporated into the platform at the Paraben YouTube Channel:
AppCompatCache parsing
Reviewing Data from AmCache
Reviewing the videos, there's something very familiar about the output illustrated on-screen. ;-)
Other Resources (that incorporate RegRipper)
YouTube video by Ric Messier
CAINE forensics video
PacktPub Subscription
LIFARS Whitepaper on Shellbags
Windows Registry Forensics, 1/e (PDF)
Paradigm Solutions blog
Jason Shaver's NPS thesis (2015)
I found recently that James, the author of the module, had updated it in Sept, 2020. That's great, but there are a few other tweaks I'd made to the code, one that allowed me to check to see if hives are 'dirty'.
Sunday, September 19, 2021
Distros and RegRipper
Over the years, every now and then I've taken a look around to try to see where RegRipper is used. I noticed early on that it's included in several security-oriented Linux distros. So, I took the opportunity to compile some of the links I'd found, and I then extended those a bit with some Googling. I will admit, I was a little surprised to see how, over time, how far RegRipper has gone, from a "here, look at this" perspective.
Not all of the below links are current, some are several years old. As such, they are not the latest and greatest; however, they may still apply and they may still be useful/valuable.
RegRipper on Linux (Distros)
Kali, Kali GitLab
SANS SIFT
CAINE
Installing RegRipper on Linux
Install RRv2.8 on Ubuntu
CentOS RegRipper package
Arch Linux
RegRipper Docker Image
Install RegRipper via Chocolatey
Forensic Suites
Something I've always been curious about is why the value of RegRipper being incorporated into and maintained through a forensic analysis suite isn't more of "a thing", but that fact doesn't prevent RegRipper and tools like it from being extremely valuable in a wide range of analyses.
RegRipper is accessible via Autopsy
OSForensics Tutorial
Launching RegRipper via OpenText/EnCase
When I worked for Nuix, I worked with Dan Berry's developers to build extensions for Yara and RegRipper (Nuix RegRipper Github) giving users of the Workstation product access to these open source tools in order to extend their capabilities. While both extensions really do a great deal to leverage the open source tool for use by the investigator, I was especially happy to see how the RegRipper extension turned out. The extension would automatically locate hive files, regardless of the Windows version (including the AmCache.hve file), automatically run the appropriate plugins against the hive, and then automatically incorporate the RegRipper output into the case file. In this way, the results were automatically incorporated into any searches the investigator would run across the case. During testing, we added images of Windows XP, Windows 2008 and Windows 7 systems to a case file, and the extension ran flawlessly.
It seems that RegRipper (as well as other tools) have been incorporated into KAPE, particularly into the Registry and timelining modules. This means that whether you're using KAPE freely, or you're using the enterprise license, you're likely using RegRipper and other tools I've written, to some extend.
I look back on this section, and I really have to wonder why, given how I've extended RegRipper since last year, why there is no desire to incorporate RegRipper into (and maintain it through) a commercial forensic analysis suite. Seriously.
Presentations/Courses
I've covered RegRipper as a topic in this blog, as well as in my books. I've also given presentations discussing the use of RegRipper, as have others. Here are just a few links:
OSDFCon 2020 - Effectively Using RegRipper (video)
PluralSight Course
RegRipper in Academia
Okay, I don't have a lot of links here, but that's because there were just so many. I typed "site:edu RegRipper" into a Google search and got a LOT of hits back; rather than listing the links, I'm just going to give you the search I ran and let you do with it what you will. Interestingly, the first link in the returned search results was from my alma mater, the Naval Postgraduate School; specifically, Jason Shaver's thesis from 2015.
Sunday, October 11, 2020
#OSDFCON
The agenda for the 11th annual Open Source Digital Forensics Conference has been posted. I've attended OSDFCON before (several times), it's one of the conferences where I've enjoyed presenting over the years. Maybe someone reading this remembers the "mall-wear" incident from a number of years ago.
So, on 18 Nov, I'll be speaking on Effectively Using RRv3. This past spring, I shared some information about about this new version of RegRipper (here, and here), as well as highlighting specific plugins. What I'd like to do is, in the same vein as the conference agenda, crowd-source some of the content for my 30 min presentation.
What would you like to see, hear, or learn about during my 30-ish minute presentation regarding RegRipper 3.0?
Wednesday, February 24, 2016
Links: Plugin Updates and Other Things
Mari has done some fascinating research into MS Office Trust Records and posted her findings here. Based on her sharing her findings and sample data, I was able to update the trustrecords.pl plugin. Further, Mari's description of what she had done was so clear and concise that I was able to replicate what she did and generate some of my own sample data.
The last update to the trustrecords.pl plugin was from 16 July 2012; since then, no one's used it or apparently had any issues with it or questions about what it does. For this update, I added a check for the VBAWarnings value, and added parsing of the last 4 bytes of the TrustRecords value data, printing "Enable Content button clicked" if the data is is in accordance with Mari's findings. I also changed how the plugin determines which version of Office is installed. I also made sure to update the trustrecords_tln.pl plugin accordingly, as well.
So, from the sample data that Mari provided, the output of the trustrecords.pl plugin looks like this:
**Word**
----------
Security key LastWrite: Wed Feb 24 15:58:02 2016 Z
VBAWarnings = Enable all macros
Wed Feb 24 15:08:55 2016 Z : %USERPROFILE%/Downloads/test-document-domingo.doc
**Enable Content button clicked.
...and the output of the trustrecords_tln.pl plugin looks like this:
1456326535|REG|||TrustRecords - %USERPROFILE%/Downloads/test-document-domingo.doc [Enable Content button clicked]
Addendum, 25 Feb
![]() |
| Default Macro Settings (MSWord 2010) |
What this seems to indicate is that if the VBAWarnings value exists in the Registry, even if the Macro Settings appear as seen in the image above (the data for the value would be "2"), that someone specifically changed the value. So, if the VBAWarnings value doesn't exist in the Registry, it appears (based on limited testing) that the default behavior is to disable macros with a notification. If the setting is changed, the VBAWarnings value is created. If the VBAWarnings value is set to "2", then it may be that the Macro Settings were set to something else, and then changed back.
For example, take a look at the plugin output I shared earlier in this post. You'll notice that the LastWrite time of the Security key is 50 min later than the TrustRecords time stamp for the document. In this case, this is due to the fact that Mari produced the sample data (hive) for the document, and then later modified the Macro Settings because I'd reached back to her and said that the hive didn't contain a VBAWarnings value.
Something else to think about...has anyone actually used the reading_locations.pl plugin? If you read Jason's blog post on the topic, it seems like it could be pretty interesting in the right instance or case. For example, if an employee was thought to have modified a document and claimed that they hadn't, this data might show otherwise.
**end addendum**
Also, I ran across a report of malware using a persistence mechanism I hadn't seen before, so I updated termserv.pl to address the "new" key.
Process Creation Monitoring
My recent look into and description of PECapture got me thinking about process creation monitoring again.
Speaking of process creation monitoring, Dell SecureWorks recently made information publicly available regarding the AdWind RAT. If you read through the post, you'll see that the RAT infection process spawns a number of external commands, rather than using APIs to do the work. As such, if you're recording process creation events on your endpoints, filters can be created to watch for these commands in order to detect this (and other) activity.
Malicious LNK
Wait, what? Since when did those two words go together? Well, as of the morning of 24 Feb, the ISC handlers have made it "a thing" with this blog post. Pretty fascinating, and thanks to the handlers for walking through how they pulled things out of the LNK file; it looks as if their primary tool was a hex editor.
A couple of things...
First, process creation monitoring of what this "looks like" when executing would be very interesting to see. If there's one thing that I've found interesting of late is how DFIR folks can nod their heads knowingly at something like that, but when it comes to actual detection, that's another matter entirely. Yes, the blog post lists the command line used but the question is, how would you detect this if you had process creation monitoring in place?
Second, in this case, the handlers report that "the ACE file contains a .lnk file"; so, the ACE file doesn't contain code that creates the .lnk file, but instead contains the actual .lnk file itself. Great...so, let's grab Eric Zimmerman's LECmd tool, or my own code, and see what the NetBIOS name is of the system on which the LNK file was created. Or, just go here to get that (I see the machine name listed, but not the volume serial number...). But I'd like to parse it myself, just to see what the shell items "look like" in the LNK file.
As a side note, it's always kind of fascinating to me how some within the "community" will have data in front of them, and for whatever reason, just keep it. Just as an example (and I'm not disparaging the work the handlers did, but commenting on an observation...), the handlers have the LNK file, but they're not sharing the vol SN, NetBIOS name, or shell items included in the LNK file, just the command line and the embedded payload. I'm sure that this is a case of "this is what we feel is important, and the other stuff isn't...", but what happens when others find something similar? How do we start correlating, mapping and linking similar incidents if some data that might reveal something useful about the author is deemed unnecessary by some?
Like I said, not disparaging the work that the handlers did, just thinking out loud a bit.
8Kb One-Liner
There was a fascinating post over at Decalage recently regarding a single command line that was 8Kb long. They did a really good walk-through for determining what a macro was up to, even after the author took some pretty significant steps to make getting to a human-readable format tough.
I think it would be fascinating to get a copy of this sample and run it on a system with SysMon running, to see what the process tree looks like for something like this. That way, anyone using process creation monitoring could write a filter rule or watchlist to monitor for this in their environment.
From the Trenches
The "From the Trenches" stuff I've been posting doesn't seem to have generated much interest, so I'm going to discontinue those posts and move on to other things.
Wednesday, February 03, 2016
Updated samparse.pl plugin
This is a great example of what I've said time and again since I released RegRipper; if you need a plugin and don't feel that you can create or update one yourself, all you need to do is provide a concise description of what you're looking for, and some sample data. It's that easy, and I've always been able to turn a new or updated plugin around pretty quickly.
Now, I know some folks are hesitant to share data/hive files with me, for fear of exposure. I know people are afraid to share information for fear it will end up in my blog, and I have actually had someone tell me recently that they were hesitant to share something with me because they thought I would take the information and write a new book around it. Folks, if you take a close look at the blog and books, I don't expose data in either one. I've received hive files from two members of law enforcement, one of whom shared hive files from a Windows phone. That's right...law enforcement. And I haven't exposed, nor have I shared any of that data. Just sayin'...
Interestingly enough, randomaccess also asked in his email if I'd "updated the samparse plugin for the latest book", which was kind of an interesting question. The short answer is "no", I don't generally update plugins only when I'm releasing a new book. If you've followed this blog, you're aware that plugins get created or updated all the time, without a new book being released. The more extensive response is that I simply haven't seen a SAM hive myself that contains the information in question, nor has anyone provided a hive that I could used to update and test the plugin, until now.
And yes, the second edition of Windows Registry Forensics is due to hit the shelves in April, 2016.
Saturday, January 23, 2016
Analysis
I have to wonder...is this even possible? Will analysts talk about what they do? For me, I'm more than happy to. But will this spark a conversation?
I thought I'd try a different tact this time around. In a recent blog post, I mentioned that two Prefetch parsers had recently been released. While it is interesting to see these tools being made available, I have to ask...how are analysts using these tools? How are analysts using these tools to conduct analysis, and achieve the results that they're sharing with their clients?
Don't get me wrong...I think having tools is a wonderful idea. We all have our favorite tools that we tend to gravitate toward or reach for under different circumstances. Whether it's commercial or free/open source tools, it doesn't really matter. Whether you're using a dongle or a Linux distro...it doesn't matter. What does matter is, how are you using it, and how are you interpreting the data?
Someone told me recently, "...I know you have an issue with EnCase...", and to be honest, that's simply not the case. I don't have an issue with EnCase at all, nor with FTK. I do have an issue with how those tools are used by analysts, and the issue extends to any other tool that is run auto-magically and expected to spit out true results with little to no analysis.
What do the tools really do for us? Well, basically, most tools parse data of some sort, and display it. It's then up to us, as analysts, to analyze that data...interpret it, either within the context of that and other data, or by providing additional context, by incorporating either additional data from the same source, or data from external sources.
RegRipper is a great example. The idea behind RegRipper (as well as the other tools I've written) is to parse and display data for analysis...that's it. RegRipper started as a bunch of scripts I had sitting around...every time I'd work on a system and have to dig through the Registry to find something, I'd write a script to do the actual work for me. In some cases, a script was simply to follow a key path (or several key paths) that I didn't want to have to memorize. In other cases, I'd write a script to handle ROT-13 decoding or binary parsing; I figured, rather than having to do all of that again, I'd write a script to automate it.
For a while, that's all RegRipper did...parse and display data. If you had key words you wanted to "pivot" on, you could do so with just about any text editor, but that's still a lot of data. So then I started adding "alerts"; I'd have the script (or tool) do some basic searching to look for things that were known to be "bad", in particular, file paths in specific locations. For example, an .exe file in the root of the user profile, or in the root of the Recycle Bin, is a very bad thing, so I wanted those to pop out and be put right in front of the analyst. I found...and still find...this to be an incredibly useful functionality, but to date,
Here's an example of what I'm talking about with respect to analysis...I ran across this forensics challenge walk-through recently, and just for sh*ts and grins, I downloaded the Registry hive (NTUSER.DAT, Software, System) files. I ran the appcompatcache.pl RegRipper plugin against the system hive, and found the following "interesting" entries within the AppCompatCache value:
C:\dllhot.exe Tue Apr 3 18:08:50 2012 Z Executed
C:\Windows\TEMP\a.exe Tue Apr 3 23:54:46 2012 Z Executed
c:\windows\system32\dllhost\svchost.exe Tue Apr 3 22:40:25 2012 Z Executed
C:\windows\system32\hydrakatz.exe Wed Apr 4 01:00:45 2012 Z Executed
C:\Windows\system32\icacls.exe Tue Jul 14 01:14:21 2009 Z Executed
Now, the question is, for each of those entries, what do they mean? Do they mean that the .exe file was "executed" on the date and time listed?
No, that's not what the entries mean at all. Check out Mandiant's white paper on the subject. You can verify what they're saying in the whitepaper by creating a timeline from the shim cache data and file system metadata (just the $MFT will suffice); if the files that had been executed were not deleted from the system, you'll see that the time stamp included in the shim cache data is, in fact, the last modification time from the file system (specifically, the $STANDARD_INFORMATION attribute) metadata.
I use this as an example, simply because it's something that I see a great deal of; in fact, I recently experienced a "tale of two analysts", where I reviewed work that had previously been conducted, by two separate analysts. The first analyst did not parse the Shim Cache data, and the second parsed it, but assumed that what the data meant was that the .exe files of interested had been executed at the time displayed alongside the entry.
Again, this is just an example, and not meant to focus the spotlight on anyone. I've talked with a number of analysts, and in just about every conversation, they've either known someone who's made the same mistake misinterpreting the Shim Cache data, or they've admitted to misinterpreting it themselves. I get it; no one's perfect, and we all make mistakes. I chose this one as an example, because it's perhaps one of the most misinterpreted data sources. A lot of analysts who have attended (or conducted) expensive training courses have made this mistake.
Pointing out mistakes isn't the point I'm trying to make...it's that we, as a community, need to engage in a community-wide conversation about analysis. What resources do we have available now, and what do we need? We can't all attend training courses, and when we do, what happens most often is that we learn something cool, and then don't see it again for 6 months or a year, and we forget the nuances of that particular analysis. Dedicated resources are great, but they (forums, emails, documents) need to be searched. What about just-in-time resources, like asking a question? Would that help?
Tuesday, January 19, 2016
More Registry Fun
Recently, Jamie shared this Symantec article with me; figure 1 in the article illustrates an interesting aspect of the malware when it comes to persistence...it apparently prepends a null character to the beginning of the value name. Interesting, some seem to think that this makes tools like RegEdit "brokken".
So, I wrote a RegRipper plugin called "null.pl" that runs through a hive file looking for key and value names that being with a null character. Jamie also shared a couple of sample hives, so I got to test the plugin out. The following image illustrates the plugin output when run against one of the hives:
![]() |
| Figure 1 |
All in all, the turn-around time was pretty quick. I started this morning, and had the plugin written, tested, and uploaded to Github before lunch.
Later in the day, Eric Zimmerman followed up by testing the hive that Jamie graciously shared with me against the Registry Explorer. I should also note that MiTeC WRR has no issues with the value names; it displays them as follows:
![]() |
| Figure 2 |
Addendum, 20 Jan: On a whim, I ran the fileless.pl plugin against the hive, and it detected the two values with the "fileless" data seen in figure 2.
Monday, April 15, 2013
Plugin: Winlogon
The Winlogon plugin is a valuable resource when it comes to determining autostart information for the system. For example, the UserInit and Shell values point to the shell that is launched when a user logs in. From here:
The Winlogon key controls actions that occur when you log on to a computer running Windows 7. Most of these actions are under the control of the operating system, but you can also add custom actions here. The “HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit” and “HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell” subkeys can automatically launch programs.
MS KB 555648 addresses an issue where either the Shell or Userinit values have been modified.
The Winlogon plugin extracts values and data from beneath the HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon key, as well as it's accompanying Wow6432Node cousin on 64-bit Windows systems, and it also collects information from several subkeys, as well.
This Microsoft page provides additional information about some of the values that appear beneath this key. Another way that a value beneath this key can be used to subvert the system is to add the TaskMan value, and point to malicious software.
Notify
This subkey maintains a running list of functionality made available to Windows systems via notification packages. In short, a "package" (DLL) can receive notifications from Windows when certain events occur. When these events occur, Windows will look for the package and launch the handler for that specific event. For example, you can have specific functions run automatically when a user logs on, locks the console, when a smartcard is plugged into the system, etc.
As with other functionality on Windows system, this also provides a great mechanism for malware (see this Cutwail example) persistence.
Special Accounts
One of the subkeys that can exist beneath the Winlogon key is the "SpecialAccounts\UserList" subkey. The values beneath this key, and each value's accompanying data, determines whether or not the specific account appears on the Welcome screen. Very often, this information is used to for legitimate purposes, so that the screen isn't cluttered with accounts that are not used for logging into the system at the console. However, this functionality can be, and has been, used for malicious purposes. I've seen this in the wild, most often when an intruder has accessed an infrastructure via RDP, and creates accounts on systems that they can use to log in; hiding the user account from the Welcome screen prevents legitimate users from seeing anything suspicious when the system is rebooted. In one instance, I saw this being used, but the "SpecialAccounts" key had been misspelled, so the functionality was not enabled.
The Winlogon plugin encapsulates data from several plugins, which led me to retire those other plugins. For example, I added the checks from the taskman.pl, notify.pl, and specaccts.pl plugins to the winlogon.pl plugin, and retired those other plugins. All of this will appear in the history file associated with the next roll-out of the plugin archive. The output of the winlogon.pl plugin also includes analysis notes, so that the analyst has information right there in the report with respect to what they should look for, and what might be suspicious.
Resources
Winlogon\Nofity entries
MS KB 102972: Explains many of the Winlogon values
Thursday, April 11, 2013
Plugin: specaccts.pl
Beneath the Winlogon key (specifically, HKLM\Software\Microsoft\Windows\CurrentVersion\Winlogon), there may be a subkey path of "SpecialAccounts\UserList". The values listed beneath the UserList key would be user account names, and if the data associated with a value is "0", then that account will not appear on the Welcome screen (any value greater than 0 allows the account to appear on the Welcome logon screen).
I've seen this used twice in the wild...once, it worked, and the second time, the bad guy had misspelled "SpecialAccounts", and as such, the functionality that they were trying to achieve wasn't realized. Sometimes, a little attention to detail can go a long way.
There is malware that uses these Registry keys to keep new user accounts hidden from view on a live system, such as TrojanSpy:Win32/Ursnif , Trojan:Win32/Starter, and EyeStye. As such, this plugin can provide indicators of a malware infection, an intrusion, or of malicious user intent on the system. However, keep in mind, that this functionality can also be used for legitimate purposes, such as hiding an Administrator or HelpDesk account from view on the Welcome screen.
As of this writing, Corey Harrell and I are finishing updates to a number of plugins, and looking at merging plugins where appropriate. As the information that we're looking for with the specaccts.pl plugin is beneath the Winlogon key, I've rolled the functionality into the winlogon.pl plugin, and retired the specaccts.pl plugin.
So, the functionality isn't going away...rather, it's going to be incorporated into an existing plugin.
Monday, April 08, 2013
Plugin: *_tln
Many folks using the RegRipper tools may not be aware that you can use rip.exe to determine information about the plugins that you have currently have available. For example, the following command will allow you to see all the plugins that you have, listed in a tabular format:
rip -l
This next command will allow you to see all of the plugins you have, listed in CSV format:
rip -l -c
This command will let you see all of the plugins that end in "*_tln", in CSV format:
rip -l -c | find "_tln"
Now that we have a list of the plugins that provide TLN output, we can easily include the output of the plugin in our timeline events file by using the following command:
rip -r path
An example of how this can be useful is in adding the UserAssist data for a specific user to the timeline events file...you can do that using the following command:
rip -r path
Very easy, very straightforward, and the use of these plugins can provide us with a good deal of granularity in our timeline.
Something that's very important to understand about the TLN plugins is that, in most cases, they will not display the same information as their accompanying plugin without "_tln" in the name. In many cases, the information maintained in the keys and values extracted via the plugins is stored in a "most recently used" or "MRU" format, and as such, the LastWrite time of the key is associated with the most recent entry. An example of this is the shellbags_tln.pl plugin...running this one side-by-side with the shellbags.pl plugin won't provide you with the same information, nor the same number of lines in the output. However, this is by design...shellbag data is one of those "MRU" sources within the Registry. One exception to this is the output of the userassist_tln.pl plugin; the time stamp data extracted by this plugin is stored in the binary content of the value data.
Typing the command to list the *_tln plugins will illustrate that most of the plugins appear to be oriented toward the NTUSER.DAT and Software hives. The shellbags_tln.pl plugin was written to run against the USRCLASS.DAT hive, and lists its output based on the key LastWrite time or "MRU Time"; it does not list information in TLN format based on the created, last accessed or last modified times extracted from the shell items. The samparse_tln.pl plugin will list information in TLN format based on various time stamps associated with each user account. Also, with this plugin, you don't need to add the "-u" switch, as the user information is embedded within the hive file itself.
Saturday, April 06, 2013
Plugin: Findexes
This plugin can be run against any hive file. What it does is traverse through all of the keys (so for larger hives, it can take a little bit of time to complete), looking for values with binary data. When it finds binary data, it checks to see if that data includes "MZ". Note that it does not look in a specific location, nor at offset 0...it uses a grep() statement to see if the data includes "MZ" at all.
When the plugin completes, you get a couple of pieces of information. One is the count of values with binary data, along with the count of binary data with "MZ". If there were any values found to contain "MZ", the key path, key LastWrite time, and value name are listed.
One System hive I ran the code against found 22660 binary values but none that contained "MZ". A Software hive I ran the code against found 23190 binary values, one of which contained "MZ", and I got the key path and other data for that value.
Key: Microsoft\SystemCertificates\Disallowed\Certificates\471C949A8143DB5AD5CDF1C972864A2504FA23C9 LastWrite time: Mon Mar 28 21:26:31 2011
Value: Blob Length: 1751 bytes
Number of values w/ binary data types: 23190
Number of values w/ MZ in binary data: 1
It's pretty trivial to validate the information, in general, found by this plugin. One way to do is to simply navigate to the key(s) in a viewer, and then look at the data. Another is to add code to the plugin to dump the data out in a hex editor style view.
Now this plugin doesn't indicate that what it finds is a persistence mechanism; rather, it's used for data storage, so you might consider running it across any and all hives, including USRCLASS.DAT. The process in which I tend to use this plugin is that I'll start by creating a timeline and if I see some unusual activity in the Registry during the time window during which the system seemed to be infected (i.e., Registry and file system data, *.idx metadata, etc.). Given that the LastWrite time is only indicative of a change occurring to a Registry key, I might opt to run the plugin against hives from VSCs, rather than those within the system32\config folder, instead.
Overall, this plugin can be very useful. The plugin can be added to profiles for every hive, or can be used for pivot point analysis when examining a timeline.
Friday, April 05, 2013
Plugin: EMDMgmt
The first plugin that I thought I'd take a look at is emdmgmt.pl. "EMD" apparently stands for "external memory device", which was the working name of ReadyBoost while it was being developed. When you connect a device to a Vista+ system, the ReadyBoost service checks the device to determine its characteristics and stores this information beneath the following key:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Emdmgmt
This key gets populated with subkeys that refer not just to thumb drives connected to the system, but also external drives, sometimes referred to as "drive enclosures" (which, of course, has to have a drive in it). It appears that ReadyBoost performs some sort of "check" of the device in order to determine it's capabilities and see if it's suitable for use.
This plugin is useful for two primary reasons. First, it's a great way to verify that certain types of devices (thumb drives, external drives) had been connected to the system at one point. This can be validated against other sources of information (System hive, etc.).
The other useful aspect of information stored in this key applies specifically to thumb drives. In particular, the subkey that applies to a thumb drive contains the device class identifier, the device serial number, the volume serial number, and possibly the volume name (if the mounted volume has a name). For example,
Disk&Ven_Best_Buy&Prod_Geek_Squad_U3&Rev_6.15
LastWrite: Sun Jul 17 12:13:25 2011 Z
SN: 0C90195032E36889&0
Vol Name: TEST
VSN: 6403-CD1C
This is clearly a Best Buy Geek Squad U3 thumb drive that I connected to my system. That I really like about this is the volume serial number that's listed in the output. This is translated from the information maintained at the very end of the key name. I've used this information to correlate to VSNs stored in Windows shortcut/LNK streams (shortcuts in the user's Recent folder, Jump Lists), allowing me to tie the various artifacts together in order to demonstrate not only that a particular user accessed the thumb drive, but to also demonstrate what the file system on that device looked like at the time that the user accessed it. I can then further augment this information with the output of the comdlg32.pl and shellbags.pl plugins.
Thursday, April 04, 2013
RegRipper Consolidation
Going forward, everything related to RegRipper will be available via (either at, or linked from) this one site. Updates to the tools will be available here, documentation will be available in the Wiki, and the latest plugin archives will be available from this site, as well.
The reason for doing this is that there just seems to be too much confusion associated with the tool. I've received emails saying that there are just too many sites that offer RegRipper, and that it's too confusing to figure out which one is the right one. So, let's just make it simple...this is the right one.
You'll notice that there's material in the Wiki, as well. We'll be using this to document and provide information in one single, static location. There is some information there now, but if there's something of interest that you can't find, let me know. I'll be happy to add or update information on the Wiki so that it's more useful.
I greatly appreciate all of the work that folks like Francesco, Brett, and Corey have put into the tool over the years. I also greatly appreciate the work of folks who have written plugins, as well as folks like Adam and "Cheeky4n6Monkey" who've written tools in an effort to make RegRipper easier to use. This consolidation does not take away from the great work that they've all done...it's simply a desire to bring everything together in one place.
So, what's different with this iteration of RegRipper? Not a lot, really. Again, it's more of a consolidation than anything else. Corey and I have put a lot of effort into "cleaning" up the plugin archive. We have updated a number of the plugins, consolidating some functionality, and adding other functionality (support for Wow6432Node where appropriate, etc.); in fact, there are so many of those little changes that we're going to forego the History page, but we'll pick it back up as we start documenting changes again going forward. So really...the biggest change is just the consolidation of everything in a single location.
Again, going forward, I'd like to have everything related to RegRipper at one site. Also, if you have any plugin requests, or just want to provide sample data for testing, please feel free to send it to me.
Finally, one more great big thanks to all of those who have supported RegRipper, by blogging about it, requesting or providing plugins, including it in an archive or distro, etc.
Wednesday, October 31, 2012
Shellbag Analysis, Revisited...Some Testing
In her post, Jamie states that the term "Shellbags" is commonly used within the community to indicate artifacts of user window preferences specific to Windows Explorer. MS KB 813711 indicates that the artifacts are created when a user repositions or resizes an Explorer windows.
ShellItem Metadata
As Jamie illustrates in her blog post, many of the structures that make up the SHELLITEMS (within the Shellbags) contain embedded time stamps, in DOSDate format. However, there's still some question as to what those values mean (even though the available documentation refers to them as MAC times for the resource in question) and how an analyst may make use of them during an examination.
Having some time available recently due to inclement weather, I thought I would conduct a couple of very simple tests in to begin to address these questions.
Testing Methodology
On a Windows 7 system, I performed a number of consecutive, atomic actions and recorded the system time (visible via the system clock) for when each action was performed. The following table lists the actions I took, and the time (in local time format) at which each action occurred.
| Action | Time |
|---|---|
| Create a dir: mkdir d:\shellbag | 12:54pm |
| Create a file in the dir: echo "..." > d:\shellbag\test.txt | 1:03pm |
| Create another dir: mkdir d:\shellbag\test | 1:08pm |
| Create a file in the new dir: echo "..." > d:\shellbag\test\test.txt | 1:16pm |
| Delete a file: del d:\shellbag\test.txt | 1:24pm |
| Open D:\shellbag\test via Explorer, reposition/resize the window | 1:29pm |
| Close the Explorer window opened in the previous step | 1:38pm |
The purpose of having some time pass between actions is so that they can be clearly differentiated in a timeline.
Once these steps were completed, I restarted the system, and once it came back up, I extracted the USRCLASS.DAT hive from the relevant user account into the D:\shellbag directory for analysis (at 1:42pm). I purposely chose this directory in order to determine how actions external to the shellbags artifacts affect the overall data seen.
Results
The following table lists the output from the shellbags.pl RegRipper plugin for the directories in question (all times are in UTC format):
| Directory | MRU Time | Modified | Accessed | Created |
|---|---|---|---|---|
| Desktop\My Computer\D:\shellbag | 2012-10-29 17:29:25 | 2012-10-29 17:24:26 | 2012-10-29 17:24:26 | 2012-10-29 16:55:00 |
| Desktop\My Computer\D:\shellbag\test | 2012-10-29 17:29:29 | 2012-10-29 17:16:20 | 2012-10-29 17:16:20 | 2012-10-29 17:08:18 |
Let's walk through these results. First, I should remind you that that MRU Time is populated from Registry key LastWrite times (FILETIME format, granularity of 100 ns) while the MAC times are embedded within the various shell items (used to reconstruct the paths) in DOSDate time format (granularity of 2 seconds).
First, we can see that the Created dates for both folders correspond approximately to when the folders were actually created. We can also see that the same thing is true for the Modified dates. Going back to the live system and typing "dir /tw d:\shell*" shows me that the last modification time for the directory is 1:42pm (local time), which corresponds to changes made to that directory after the USRCLASS.DAT hive file was extracted.
Next, we see that MRU Time values correspond approximately to when the D:\shellbag\test folder was opened and then resized/repositioned via the Explorer shell, and not to when the Explorer window was actually closed.
Based on this limited test, it would appear that the DOSDate time stamps embedded in the shell items for the folders correspond to the MAC times of that folder, within the file system, at the time that the shell items were created. In order to test this, I deleted the d:\shellbag\test\test.txt file at 2:14pm, local time, and then extracted a copy of the USRCLASS.DAT and parsed it the same way I had before...and saw no changes in the Modified times listed in the previous table.
In order to test this just a bit further, I opened Windows Explorer, navigated to the D:\shellbag folder, and repositioned/resized the window at 2:21pm (local time), waited 2 minutes, and closed the window. I extracted and parsed the USRCLASS.DAT hive again, and this time, the MRU Time for the D:\shellbag folder had changed to 18:21:48 (UTC format). Interestingly, that was the only time that had changed...the Modified time for the D:\shellbag\test folder remained the same, even though I had deleted the test.txt file from that directory at 2:14pm local time ("dir /tw d:\shellbag\te*" shows me that the last written time for that folder is, indeed, 2:14pm).
Summary
Further testing is clearly required; however, it would appear that based on this initial test, we can draw the following conclusions with respect to the shellbag artifacts on Windows 7:
1. The embedded DOSDate time stamps appear to correspond to the MAC times of the resource/folder at the time that the shell item was created. If the particular resource/folder was no longer present within the active file system, an analyst could use the Created date for that resource in a timeline.
2. Further testing needs to be performed in order to determine the relative value of the Modified date, particularly given that events external to the Windows Explorer shell (i.e., creating/deleting files and subfolders after the shell items have been created) may have limited effect on the embedded dates.
3. The MRU Time appears to correspond to when the folder was resized or repositioned. Analysts should keep in mind that (a) there are a number of ways to access a folder that do not require the user to reposition or resize the window, and (b) the MRU Time is a Registry key LastWrite time that only applies to one folder within the key...the Most Recently Used folder, or the one listed first in the MRUListEx value.
I hope that folks find this information useful. I also hope that others out there will look at this information, validate it through their own testing, and even use it as a starting point for their own research.
Tuesday, May 08, 2012
Approximating Program Execution via VSC Analysis with RegRipper
Now, one of the things we may run across during our analysis, if we create a timeline, is that we may have a Registry key that was modified in some way during a particular time window of interest. There are a number of Registry keys for which all we have available is a LastWrite time (which is analogous to a files last modification time) but we do not know what that modification entailed.
For example, some keys maintain a "most recently used" (MRU) list, and we know that whatever the most recent activity was (user accessed/viewed a file, etc.), we can be pretty sure that, in most cases, the activity we see is associated with the key's LastWrite time. However, we may see other keys that simply contain values and subkeys, with LastWrite times that occur during our window of interest. Examples of these keys include the Run key (in both the Software and NTUSER.DAT hives), the MUICache key, etc. We don't know, simply by looking at the contents of the key, what change may have occurred; was a value or subkey added or deleted?
So, given that we have an image of a Windows 7 (or Vista) system, which may have a number of VSCs available, how can we attempt to determine what that change may have been?
Well, the first thing you want to do is mount the image as a volume on your Windows 7 analysis system in a manner that allows you to access the VSCs within the image; perhaps the easiest way to do so is via the VHD method. Once you have the image mounted (let's call it V:\), you'll want to determine which VSCs are available using the vssadmin command:
You'll see a bunch of stuff go by, and you'll want to look for lines that look like this:
Shadow Copy Volume: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy8
A really easy way to cut through all of that stuff is to use the following command line:
Okay, so now you should have a list of VSCs from the image; for the sake of this example, let's say that you have VSCs numbered 23 through 30. How can we use this information to compare the values in, say, the Run key from the Software hive? We know that the 'soft_run.pl' plugin lets us output the contents of this key, but how can we easily retrieve information from the previous versions of the Software hive within the VSCs?
Let's create a batch file to automate this for us. A simple 'for' loop in a batch file looks like this:
If you put the above command in a batch file ('test.bat') and then run the batch file, you'll see the numbers 23 through 30 echo'd to the console. We can use variables in our batch file by substituting the first and last numbers with '%1' and '%2', respectively:
Okay, that's easy enough. Now, all we need to do is get RegRipper to parse this information for us. We can do that using the latest version (2.5) of RegRipper, and specifically rip.exe.
We would save this command into a batch file (name it "vsc_run.bat") in the same directory where we have rip.exe, and then run it using the following command line:
That's it. That's all it takes. And the cool thing is that we can save this batch file and use it again and again, or modify it in some way for future use. One way to modify it would be to output everything to a file, rather than just allowing everything to fly by at the console. To do that, simply add " >> output.txt" to the end of the command within the batch file. You can also add comments to the batch file, via normal batch file scripting techniques.
This is just another example of how we can use already-available tools and techniques to build better and more efficient analysis methodologies. Why sit around staring at your monitor when there are easy and efficient ways to extract the data that you need for analysis?
Here's another use for this technique; at the request of a member of LE, I recently modified the currently available 'ares.pl' plugin (for parsing Registry keys for the Ares P2P application) to parse out just specific information, which includes decoding the search terms typed in by the user. If a Windows 7 (or Vista) system was being examined, you could use this technique to see the change of of several of the values, including the user typing in search terms, over time. The key that maintains the search terms does not include an MRU value, so you can use this technique to easily parse out exactly what you're looking for, and rather than seeing "between these two dates, the user typed in 30 search terms", you could see the progression of the terms typed in over time, across the available VSCs.
Following that same technique, I've seen instances where administrators have "taken remediation actions" and "cleaned up" prior to systems being reported as compromised and acquired. Using the contents of the MUICache key (located in the USRCLASS.DAT hive on a Win7 system), I found that this little bundle of joy had been run on the system, but "cleaned up". Using this technique, I could narrow down when the application had been run, and then go into my timeline to see what else was going on around that time.
Note that this technique can be used to approximate the time of program execution on systems where application Prefetch files are not available, either because they were deleted, or because the system is a server (Win2003, Win2008) and doesn't have application prefetching enabled by default.
With that kind of pin-point, surgical accuracy, this kind of sounds like Sniper Forensics to me!











