A tool to find Windows registry files in a blob of data: Needle
- Useful scenarios
- How does the tool work?
- Can you do it manually?
- HTB Bastion Spoilers
I found an open NFS share during an Internal with a backup of a Domain Controller in it, but the file was too big to download. I wrote this tool to grab SAM, SYSTEM, and SECURITY registry hives from the mounted share to compromise the live DC. I’ve found multiple instances of similar situations as recently as a couple weeks ago. Additionally, I have heard secondhand it came in handy recently. Maybe you’ll find it’s handy? Find it here.
I actually wrote this tool some time ago but never got around to making a blog post about it. Here it is in action on a tar file.
This tool is the most useful if you find a file that looks like it’s backup of a Windows machine in formats like .tar, .vhd, or even a .vmdk file. The large file or blob of data is the haystack and the registry files are the needles in the haystack, hence the tool’s name of Needle.
Needle is also useful for incomplete forensics images or downloads but you still need to pull credentials out of the partial image.
There are also edge cases where
guestmount(1) fails or tar fails to extract.
Is the file is too large to exfil but you can mount it locally using
mount.cifs? Needle has you covered.
Could Needle fix up on-disk registry hives are marked as dirty and still get credentials even though secretsdump fails? Yes it can.
How does the tool work?
First off, let’s focus on our goals: extract some form of credentials to demonstrate impact and potentially escalate privileges. Impacket’s secretsdump.py needs either SAM and SYSTEM or SECURITY and SYSTEM to find potentially useful credentials. SAM+SYSTEM combo would be the local password database for Windows and SECURITY+SYSTEM would return LSA secrets. If impacket is available, Needle will import it and automatically secretsdump the dumped registry files for you.
The SAM file sounds like a good start.
As you hopefully can see, a really good (and long) pattern to match off of would be
I have been told the longer the pattern, the faster the searching so this very long pattern should work out great and we need to keep pattern length in mind for the other registry files.
Moving onto the SYSTEM registry hive since we need the
bootkey out of it to decrypt the data stored in SAM.
SYSTEM part of the file doesn’t seem too longer so after checking a couple SYSTEM registry files from different Windows systems in my homelab, I settle on adding some null bytes to increase the pattern length. After all, no one wants to sit watching a terminal waiting for results longer than required. So we can make our pattern
to maximize length and effectiveness. At this point we could try searching for just SAM and SYSTEM to get the local password hashes but it would also be really nice to try for the machine account hash or potential plaintext credentials stored in LSA secrets.
Now focusing on SECURITY, let’s find a pattern.
It looks like we can get another long one. I’m not sure why the first part truncated but every sample I found has the same start point so I’ll roll with it. The pattern is
Cleaning dirty registry files
Take a look at the SYSTEM registry file shown above. There’s an extra
DIRT and a large chunk of null bytes. Since most tools parsing the registry file, use offsets this is obviously break it. After debating for several nights what the best way to go about fixing up the dirty registry hives could be, I decided on just stripping out the extra data. I’m going to be honest, it’s been long enough I don’t remember why removing extra zeros was sufficient. However, if you come across a registry file that is marked as dirty, it will have those extra chunks of null bytes so Needle will try to remedy this (if the
--clean flag is specified) by removing the extra chunks. Needle will then try to secretsdump as usual and output the results.
Can you do it manually?
Sure! That’s exactly how I started but quickly realized lots of false positives and wanted an automated way to try all possible offsets into a file. You’ll have to repeat for every instance of every pattern which can (and did) get tedious.
grep --byte-offset -Pa $PATTERN /mnt/large.file.tar dd if=/mnt/large.file.tar of=test_SAM.bin skip=$OFFSET count=17000000 iflag=skip_bytes,count=bytes secretsdump.py LOCAL -sam test_SAM.bin -system test_SYSTEM.bin
HTB Bastion Spoilers
In order to test this out using some sample (not client data) I used HTB’s Bastion. If you’re working through this retired machine, you should not read any further and come back when you’re ready for spoilers.
Bastion had an open SMB share with a backup of a Windows machine in the form of a VHD file. The notes in the same directory say to not download the image file as it’d kill bandwidth for other users.
guestmount is likely the intended path but it occasionally fails to mount an image.