Friday, July 20, 2018

Forensics Quickie: Identifying an Unknown GUID with Shellbags Explorer, Detailing Shell Item Extension Block 0xbeef0026, & Creative Cloud GUID Behavior

FORENSICS QUICKIES! These posts will consist of small tidbits of useful information that can be explained very succinctly.

I ran into an unknown GUID while using Shellbags Explorer (SBE) recently. Here's what I did to confirm what it was -- with some testing and new findings along the way. All of this was done on Windows 10. Thanks to Eric Zimmerman and Joachim Metz for quick response times and details.

An unmapped GUID in SBE.

You have an unknown GUID. You have an idea of what it is, but want to confirm.

The Solution
I had an inkling that this GUID was related to Adobe Creative Cloud. Usually, you'll be able to see some folders under the unknown GUID within SBE that are specific enough to pinpoint the application responsible -- doubly so if you're analyzing your own machine and can recognize the folders. With Creative Cloud in mind, let's confirm.

First, boot up a testing virtual machine and install the Adobe Creative Cloud Desktop application. The free Microsoft VMs for IE/Edge testing are useful for this.

Installing and updating the Adobe Creative Cloud desktop application.

Upon installation of the application and sign-in, we can see that a new library called "Creative Cloud Files" shows up in the Windows Explorer sidebar (the default location of the folder is in the root of the user's profile).

Observing new "Creative Cloud Files" library added to Explorer sidebar.

Before interacting with this folder, let's do a sanity check baseline on what our UsrClass.dat looks like in SBE. At this point, we shouldn't see any shellbags entries for this location.

Recursive view of shellbags entries within SBE. No "Creative Cloud Files" entries. 

As expected, there are no entries for the "Creative Cloud Files" location. But before we move on any further, let's grab the timestamps (standard information) for the directory. This will be important later.

FTK Imager Lite showing MACE times for the "Creative Cloud Files" folder.

Now that we've noted those timestamps, let's interact with the folder.

Interacting with the "Creative Cloud Files" folder via Windows Explorer.

There should now be a shellbags entry for this folder in the user's UsrClass.dat. Pull that, along with its .LOG files (if necessary), and open it up with SBE.

Observing the shellbags entry for the "Creative Cloud Files" folder with SBE.

Looks like we got what we came for...but we're not done just yet.

After running this same test on another Windows 10 machine, I noticed something strange: the last section of the GUID wasn't the same.


Typically, these GUIDs will stay consistent from system to system, since most of the ones you'll come across during shellbags analysis are built-in Known Folder GUIDs. But it turns out that software vendors can extend this set of known folders by registering their own [6] [7].

While the final section of the GUID seems to be different on each machine, the first sections (0e270daa-1be6-48f2-ac49) seem to have remained consistent since at least 2015 (Google it).

With that out of the way, let's dig deeper into the actual makeup of the unmapped GUID entry, out of curiosity. I happened to notice that the unmapped GUID entry looked very similar to the existing "Dropbox" entry on another test machine (for which the GUID was mapped). As I compared the two, I noticed that there were three Windows FILETIME timestamps in both of them. I couldn't find any explanation for these, so I referenced Eric Zimmerman's "Plumbing the Depths: ShellBags" presentation and Joachim Metz's Windows Shell Item format specification.

Using SBE's data interpreter to identify three FILETIME timestamps.

Eric's and Joachim's documentation were invaluable for walking through the hex. They serve as perfect foundations for digging into the file formats. Still, I wasn't able to determine why I was seeing three timestamps instead of the two that were showing in the "Details" tab. And I wasn't seeing a 0xbeef0026 extension block in the specification or any reference to it when the class type indicator for the entry is 0x1f (a root folder shell item).

With this information in hand, it was time to start piecing it all together.

If we take a look at the above animation, as well as the timestamps of the "Creative Cloud Files" folder that we pulled with FTK Imager earlier, you'll notice that the FILETIME timestamps in the shellbags entry match up exactly with the SI MACE times of the "Creative Cloud Files" folder at the time we interacted with it.

By creating a color coded template of this entry, we can come close to attributing every byte of the entry to something including the timestamps:

Hex of unmapped "Creative Cloud Files" shellbags entry
0000 0000:  3a 00 1f 42 aa 0d 27 0e  
0000 0008:  e6 1b f2 48 ac 49 61 17 
0000 0010:  16 7f 79 94 26 00 01 00 
0000 0018:  26 00 ef be 11 00 00 00 
0000 0020:  5e bf 26 f7 bf 1f d4 01
0000 0028:  3e 9b 02 f8 bf 1f d4 01 
0000 0030:  39 10 8c fb bf 1f d4 01 
0000 0038:  14 00 00 00

Offset 0x00: Shell Item Size (42d)
Offset 0x02: Class Type Indicator (0x1F - Root Folder Shell Item)
Offset 0x03: Sort Index (Libraries)
Offset 0x04: GUID (0e270daa-1be6-48f2-ac49-6117167f7994)
Offset 0x14: Extension Block Size (38d)
Offset 0x16: Extension Version (?)
Offset 0x18: Extension Block Signature (0xbeef0026)
Offset 0x1C: ????
Offset 0x20: Windows FILETIME 1 (Creation)
Offset 0x28: Windows FILETIME 2 (Last Modified)
Offset 0x30: Windows FILETIME 3 (Last Accessed)
Offset 0x38: ????  

The bottom line is that, by performing behavioral analysis and walking through the file format at the hex level, we were not only able to find what the unknown GUID maps back to, but we were also able to (a) identify a set of SI MACE FILETIMEs for an undocumented extension block (0xbeef0026) and (b) determine that software-vendor-generated/registered GUIDs may not be consistent all the time (at least the last section, in this example).

The larger question is: are the inconsistent GUIDs we see specific to Creative Cloud or are there more instances of this inconsistency? Every "Creative Cloud Files" GUID I have seen -- from three different machines tested -- show a different end-section of the GUID. Dropbox seems to have consistent GUIDs across machines. Could Creative Cloud be generating the end-section of the "Creative Cloud Files" GUID based on something inconsistent like username?

And just like that, we have another hypothesis that we can test. Using the same VM from before, I created a new user and gave it the same name as a user on one of my other test machines. After signing in using the Creative Cloud desktop application, the new "Creative Cloud Files" folder was created for my new user account. Following the same steps as above, the shellbags entry was created for it, and it was observed that the GUIDs (including the last section) for the "Creative Cloud Files" location on two different machines, using the same username, were the same!

If you were to create a user named "IEUser" on your machine, and run through this whole process, you'll find that the GUID for "Creative Cloud Files" will be 0e270daa-1be6-48f2-ac49-6117167f7994. Likewise, for the "4n6k" user, you'll find the GUID to be 0e270daa-1be6-48f2-ac49-fc258b405d45. Also, this is case insensitive, so user "4N6K" will result in the same GUID.

With that said, it may be necessary to match the "Creative Cloud Files" location (and any other application GUIDs that exhibit the same behavior) to the first few sections of the GUID (0e270daa-1be6-48f2-ac49-) instead of the whole thing.



Sunday, January 14, 2018

Forensics Quickie: Methodology for Identifying Linux ext4 Timestamp Values in debugfs `stat` Command

FORENSICS QUICKIES! These posts will consist of small tidbits of useful information that can be explained very succinctly.

I saw this tweet from @JPoForenso recently.

Archived tweet here.

I didn't know what this was either, so I began testing. And as always, remember that it's one thing to know that an artifact exists; it's another to know how to find, understand, and make use of it. This is more of a methodology post related to problem solving, but having the logic behind the approach is typically pretty useful.

So, from start to finish, let's delve into how you'd go about answering the question Jonathon posted.

You want to determine what a specific part of the debugfs `stat` command refers to (but this process can be applied to any other Linux command!).

The Solution
My first thought on how to approach this question was to see if we could get lucky by looking at readily available source code. Since verifying program behavior from source code has proven to work several times in the past, it doesn't hurt to look in this instance. So, knowing that the Linux kernel is open source, I first Googled something fairly simple, just to see what I'd get:

Googling "debugfs stat source code"

The first result is what seems to be the stat.c source file, related to the standard `stat` Linux command. It's not exactly what I want, but it's close enough for now. As we open the link, we can see a bunch of Linux kernel versions on the left sidebar. I didn't know what kernel version I was running on my Ubuntu virtual machine, so I ran a `uname -or` via command line to find out.

Running `uname -or` to get the operating system and Linux kernel version

Looks like I'm running kernel version 4.10.0-42-generic. Since I'm going to be running my tests on this Ubuntu VM (I already had a clean snapshot), I'd like to make sure I'm reading the stat.c source code for the closest kernel version I can get. And since we have the luxury of picking the version of the source code using this first Google search result, I'm going to go ahead and select version 4.10 from the left sidebar on the page (direct link here).

Looking at the source code, I can already see that it has a lot of the same strings that we see in Jonathon's screenshots (and just by using the `stat` command in the past) -- namely, I can see references to atime (access time), mtime (modify time), and ctime (change time).

stat.c source code showing references to relevant timestamp variable names

As I Ctrl+F for "ctime" within this source file, I noticed something at line 389: the added "nsec."

stat.c source code showing references to "sec" and "nsec". Possibly referring to nanoseconds

As I looked back at Jonathon's screenshots showing the output of both the debugfs's `stat` command and the standard `stat` command, I noticed that the standard command was showing the timestamps with nanosecond granularity. The theory at this point was that the characters after the hex bytes and the colon were probably the encoded nanoseconds value. To confirm this, I ran some tests.

I needed to further ensure that my setup was the same as Jonathon's; I needed to make sure my Ubuntu VM was using an ext4 file system. First, I ran `sudo fdisk -l` to list the disks and partitions present on my VM.

`fdisk -l` output showing /dev/sda1 as the boot partition and that it is of type 0x83.

We see that /dev/sda1 is our boot partition, that it is the largest partition, and that it is of type 0x83. Brian Carrier's "File System Forensic Analysis" book tells us in Table 5.3 (Chapter 5 > DOS Partitions) that a partition ID of 0x83 is, in fact, a Linux partition. But as this web page suggests:

"Various filesystem types like xiafs, ext2, ext3, reiserfs, etc. all use ID 83. Some systems mistakenly assume that 83 must mean ext2."

Therefore, this is not enough information and we will need to learn something new. With some quick Googling, we can see that the `df -T` command will get us the information that we need to confirm we're running an ext4 file system.

`df -T` output showing that /dev/sda1 is running an ext4 file system

Now that we know our setup more or less matches the original, let's run a quick and dirty test to get a feel for what Jonathon was doing. First, I'm going to do a quick `ls -la` in my home directory to see what existing file I can use to run a standard `stat` against. I found a file called ".xsession-errors". We'll use that. I then run the standard `stat`.

Standard `stat` command output of a file showing nanosecond granularity

Running a standard `stat` (stat /home/b/.xsession-errors) gives us the following that we will jot down for later:

Access: 2018-01-14 17:59:51.272474556 -0800
Modify: 2018-01-14 17:59:52.632462056 -0800
Change: 2018-01-14 17:59:52.632462056 -0800

Now, let's run the debugfs `stat` command on the same file and see what we get.

Before running the debugfs `stat` command

Note that, to use the debugfs `stat` command, you need to first specify the file system you want to use with the -w option. Since we already ran an `fdisk -l` before, we already know that we need to specify /dev/sda1. So we run `sudo debugfs -w /dev/sda1`, we will then get a debugfs prompt where we will run our `stat` command: `stat /home/b/.xsession-errors`. Also note that you can run the `stat` command against an inode or the full path of a file (as I did here) within the specified file system.

Output of the debugfs `stat` command, showing encoded timestamps

Let's go ahead and jot down the relevant lines of this output:

ctime: 0x5a5c0b18:96ca6ba0 -- Sun Jan 14 17:59:52 2018
atime: 0x5a5c0b17:40f686f0 -- Sun Jan 14 17:59:51 2018
mtime: 0x5a5c0b18:96ca6ba0 -- Sun Jan 14 17:59:52 2018
crtime: 0x5a5c0b17:40f686f0 -- Sun Jan 14 17:59:51 2018

(An off-topic tidbit here is that we see a "crtime," which is the "born/creation time" of the file being queried; ext file systems prior to ext4 did not support this).

Jonathon already identified the first section of hex bytes (before the colon) to be the Unix epoch representation of each timestamp. Let's confirm using TimeLord.

Using TimeLord to decode the first section of a debugfs `stat` command timestamp

As we can see, Jonathon is correct; the first section of the debugfs `stat` timestamp is the Unix time timestamp (remember, my Ubuntu VM is set to Pacific time (-8), so you must apply the offset to get it to match).

But what about the second portion? That's the real question! Knowing what we know already, we have some really good reasons to believe that the second portion of the debugfs timestamp is the nanoseconds value: we saw references to possible nanoseconds in the source code, we confirmed nanosecond granularity in the standard `stat` command, and the modify and changed times are the same using both `stat` commands.

But how do we confirm this? Well...let's try Googling it.

Googling "ext4 debugfs nanoseconds"

With our testing, we were able to search more effectively for what we needed. And this time, it really paid off -- there's already an answer for us! In fact, the answer goes one step further and even links us to one of Hal Pomeranz's "Understanding EXT4" articles that walks us through the ext4 timestamp format in-depth. I would highly recommend reading the full series, but to answer our initial question, we do not need to look further than the "Fractional Seconds" portion of Hal's post.
"The hex value of the create time "extra" is 0x148AF06C, or 344649836. But the low-order two bits are not used for counting nanoseconds. We need to throw those bits away and shift everything right by two bits- this is equivalent to dividing by 4. So our actual nanosecond value is 344649836 / 4 = 86162459."
Hal explains that the second part of the debugfs `stat` timestamps (after the colon) need to be divided by 4 after being converted to decimal. So let's try that with our example. The values for each stat command are replicated below (we'll only use the access and modify times since there are only 2 unique timestamps among the four total timestamps for the .xsession-errors file).

Standard `stat` command
Access: 2018-01-14 17:59:51.272474556 -0800
Modify: 2018-01-14 17:59:52.632462056 -0800

debugfs `stat` command
atime: 0x5a5c0b17:40f686f0 -- Sun Jan 14 17:59:51 2018
mtime: 0x5a5c0b18:96ca6ba0 -- Sun Jan 14 17:59:52 2018

0x40f686f0 (hex) --> 1089898224 (decimal) / 4 = 272474556
0x96ca6ba0 (hex) --> 2529848224 (decimal) / 4 = 632462056

We convert hex to decimal, then divide by 4, and we get the nanoseconds value!

With that, we've answered the question and learned a thing or two. Again, this was more of an exercise in problem solving and verification, but knowing how to go about solving a problem is something that you can apply to any question you may have.