This article is based mostly on the work of Grzegorz Tworek (@0gtweet)
I recently saw this tweet from Grzegorz Tworek (@0gtweet – who if you aren’t following you really should be!) come across my timeline

I had seen previous tweets referencing the AppLocker hash/signature cache and having a CPD day I thought I would take a closer look at see what did work and what didn’t. Probably fair to say if it didn’t work – that would be on me, rather than the source material
Having a look at the https://github.com/gtworek/PSBits/tree/master/CopyEAs repository there isn’t a huge amount of material to go off (for someone new to it like me – once you get your head around it, then it actually is everything you need to know).

Righty then. Let’s dig down and see what we can find. Let’s start with NTFS EA – Wikipedia helpfully tells us Extended Attributes (EA) are file system features that enable users to associate computer files with metadata not interpreted by the filesystem, whereas regular attributes have a purpose strictly defined by the filesystem (such as permissions or records of creation and modification times). General documentation on EAs is actually quite sparse – the best resource I found giving an overview is the ever dependable SpecterOps : https://posts.specterops.io/host-based-threat-modeling-indicator-design-a9dbbb53d5ea
Like Alternative Data Streams (ADS) but with a data limit of ~65k on NTFS (varies according to file system but that limit is from the Linux implementation of EAs)

So how does AppLocker use these EAs and how do we abuse them to bypass it?
In my test environment I set up an AppLocker rule to allow a file with a certain hash

It is worth noting that this is a specific AppLocker hash, not a file hash

Querying the EAs of the file using fsutil shows that the AppLocker Hash is stored in $KERNEL.PURGE.APPID.HASHINFO
From what I can gather from the tools that Grzegorz released, we can write EAs but we can’t overwrite the $ prefixed entries. That is why his CopyEAs toolkit creates entries prefixed with a # and direct disk access is required to rename them.

So let’s PoC this up and see what we can do. I created a 20Mb VHD and mounted it as a test user. I placed a file, imaginatively called Malware.exe on the mounted drive.
Prior to execution, no attributes were visible

Running it was prohibited via AppLocker

After running it we could see that some EAs had been populated

Our hash did not match the AppLocker rule according to the EA value on KERNEL.PURGE.APPID.HASHINFO

Which can be confirmed from the command line

Now we have a couple of options at this point – we can add a #KERNEL.PURGE.APPID.HASHINFO
with a ‘good’ hash value using the SetApplockerCache.exe that is part of the CopyEAS tool suite as below :

Or we can just search and replace for the original hash value with the ‘good’ value. Unmounting the VHD and popping it into a hex editor we can search for the values we are looking for.

Replace those hash values with the ‘good’ value and after remounting the VHD and re-querying the values shows that the AppLocker hash cache now contains the ‘good’ values.

So what happens if we run it?


We get our CS_Is_Dead_Sliver_Is_The_New_Hotness callback 🙂
This also worked for me on a USB stick, or any NTFS aware filesystem.
Big shout out to Grzegorz Tworek for https://github.com/gtworek/PSBits – you can literally lose days of your life digging a little deeper into the stuff he uncovers!
Hope you found this useful. There is mention of getting it to work with Microsoft signed AppLocker rules using the CopyEAs tool but I couldn’t get that working, not sure if that has been patched since the tool release. If you get it working, please let me know!