Introduction
This post is about an interesting forensic challenge that I solved during the StarHackademINT 2023 CTF. We were given a Quarantine
folder coming from Windows Defender, and we had to find back the original filename on the internet.
The structure of the given folder looks like this:
Quarantine
├── Entries
│ └── {80059732-0000-0000-6667-EF3396D235E7}
├── ResourceData
│ └── 9F
│ └── 9F598F562DDCFB69FA21A077BAD87F01A3F6258E
└── Resources
└── 9F
└── 9F598F562DDCFB69FA21A077BAD87F01A3F6258E
If we look on the internet, we can find some blog post that gives a lot of useful information on how to get the original files back. We can find the Quarantine
directory structure:
- The
Entries
folder contains information about the quarantined files, such as the reason of the quarantine, the original full path, timestamp, etc. The files are encrypted in a particular way that we will see later. - The
ResourceData
folder contains the encrypted original binary. - The
Resources
folder won’t be used here, but it contains information such as a GUID and a hash used to link theEntries
and theResourceData
folder.
We can also find the hardcoded RC4 key used to encrypt the files (it is common for AV vendors to have a single RC4/XOR hardcoded key) used for the quarantine process. So we can use this small python script in order to decrypt the files:
from Crypto.Cipher import ARC4
import sys
with open(sys.argv[1], "rb") as encrypted_file:
print(f"Reading {sys.argv[1]}")
data = encrypted_file.read()
key = b"\x1E\x87\x78\x1B\x8D\xBA\xA8\x44\xCE\x69\x70\x2C\x0C\x78\xB7\x86\xA3\xF6\x23\xB7\x38\xF5\xED\xF9\xAF\x83\x53\x0F\xB3\xFC\x54\xFA\xA2\x1E\xB9\xCF\x13\x31\xFD\x0F\x0D\xA9\x54\xF6\x87\xCB\x9E\x18\x27\x96\x97\x90\x0E\x53\xFB\x31\x7C\x9C\xBC\xE4\x8E\x23\xD0\x53\x71\xEC\xC1\x59\x51\xB8\xF3\x64\x9D\x7C\xA3\x3E\xD6\x8D\xC9\x04\x7E\x82\xC9\xBA\xAD\x97\x99\xD0\xD4\x58\xCB\x84\x7C\xA9\xFF\xBE\x3C\x8A\x77\x52\x33\x55\x7D\xDE\x13\xA8\xB1\x40\x87\xCC\x1B\xC8\xF1\x0F\x6E\xCD\xD0\x83\xA9\x59\xCF\xF8\x4A\x9D\x1D\x50\x75\x5E\x3E\x19\x18\x18\xAF\x23\xE2\x29\x35\x58\x76\x6D\x2C\x07\xE2\x57\x12\xB2\xCA\x0B\x53\x5E\xD8\xF6\xC5\x6C\xE7\x3D\x24\xBD\xD0\x29\x17\x71\x86\x1A\x54\xB4\xC2\x85\xA9\xA3\xDB\x7A\xCA\x6D\x22\x4A\xEA\xCD\x62\x1D\xB9\xF2\xA2\x2E\xD1\xE9\xE1\x1D\x75\xBE\xD7\xDC\x0E\xCB\x0A\x8E\x68\xA2\xFF\x12\x63\x40\x8D\xC8\x08\xDF\xFD\x16\x4B\x11\x67\x74\xCD\x0B\x9B\x8D\x05\x41\x1E\xD6\x26\x2E\x42\x9B\xA4\x95\x67\x6B\x83\x98\xDB\x2F\x35\xD3\xC1\xB9\xCE\xD5\x26\x36\xF2\x76\x5E\x1A\x95\xCB\x7C\xA4\xC3\xDD\xAB\xDD\xBF\xF3\x82\x53"
cipher = ARC4.new(key)
decrypted = cipher.decrypt(data)
with open(sys.argv[1]+".decrypted", "wb") as dec:
print(f"Writing decrypted file to {sys.argv[1]}.decrypted")
dec.write(decrypted)
Many scripts are avaibles on the internet, but they were not working properly for me.
Entries folder
The first thing that I wanted to do was to decrypt the file in the Entries
folder. The main issue is that the file is separated in 3 chunks, encrypted separately using the RC4 key.
If we take a look at this document, we can see that the first chunk has a fixed size:
So we can just truncate the first chunk (I used HxD in order to display the data efficiently, but you can do it with python), and decrypt it using our script. We get the following data:
We have our magic bytes, 0x18
null bytes, 2 sizes (4 bytes each), and then 0x0C
bytes:
We got the two chunks size (big endian, then we have 0x55
and 0x101
), so let’s truncate ([0x3C:0x3C+0x55] and [0x3C+0x56:END]), and decrypt them:
Well, this is interesting but Star{virus.exe}
is not the flag… So we will have to decrypt the original malware file.
ResourceData folder
Luckily for us, the malware file is encrypted in one chunk. Some metadata are added at the beginning, and then we have our malware file:
rc4encrypted:
seq:
**- id: fixed
contents: [0x03, 0, 0, 0, 0x02, 0, 0, 0]
size: 8**
- id: length
type: u4
- id: padding
size: 0x08
- id: binarysd
size: length
- id: unknown1
size: 0x08
**- id: len_malfile
type: u8**
- id: unknown2
size: 0x04
- id: mal_file
size: len_malfile
If we decrypt it, we can see the PE magic bytes (in green) as well as the This program cannot be run in DOS mode. Everything before is our metadatas. If we look at the metadata structure, we can see that the malfile size is 8 bytes long (in red). So we have a malfile size of 1A00
(6656) bytes:
At first, I truncated from the MZ bytes to the end and sent it to Virustotal. The file was flagged as malicious by ~50 AV vendors, but I couldn’t find any original name for the file.
So I ended up truncating 6656 bytes from the MZ bytes. If we take a look at the end of the file, there seems to have appended data (after the highlighted part). Thoses data looks like a Mark of the web, but I don’t really know why it is here:
If we submit our new file to VT, it is still widely detected as malicious:
In the details section, we can see the name with which this files has been submitted or seen in the wild:
So the flag is Star{hrtc_false_positive.exe}
!
Sources
https://static.ernw.de/whitepaper/ERNW-Whitepaper-71_AV_Quarantine_signed.pdf
https://reversingfun.com/posts/how-to-extract-quarantine-files-from-windows-defender/