Symlink attacks without code execution

Background

Let’s take a look at the following piece of code:

if (is_infected_file(path)) {
  remove_file(path);
}

This is a oversimplified routine from a typical antivirus scanner — it takes a file path, checks data of that file using malware signatures, and removes the file if it’s “infected”.

However, if the remove_file() routine follows symlinks (i.e., it deletes a symlink target, not a symlink itself), security problems arise…

A malicious program can create a file, fill it with bytes that are detected by a specific antivirus engine (e.g., write the EICAR string), trigger the antivirus scan somehow (e.g., by trying to read that file, thus triggering on-access scans), and then quickly replace that file with a symlink to another file.

This leads to a well-known race condition: the is_infected_file() routine deals with one file, but, occasionally, the remove_file() routine deals with another file! The path is the same, but in these two routines it points to different files: one is a regular file that is detected as “infected”, another one is a symlink pointing somewhere.

If the attacker is lucky enough, the remove_file() routine deletes the symlink target (which is attacker-chosen).

This leads to many possible issues, including denial-of-service (when an important system file is deleted), privilege escalation (when a configuration file with security-related settings is deleted, forcing some software to use “less secure” defaults), or even information disclosure (when software creating a backup is forced to copy sensitive files to a world-readable location).

In general, symlink attacks allow low-privileged programs to do some unintended actions against files they can’t access directly.

More examples can be found in this Wikipedia article and in this research paper.

There is one limitation: symlink attacks require code execution. In particular, attackers must create a file, trigger a vulnerable application, and then quickly replace that file with a symlink.

Challenge

What if no code execution is needed to mount such an attack?

Continue reading “Symlink attacks without code execution”

Multiple vulnerabilities in AMI file system drivers

Background

The same malformed file system structures can cause problems in independently developed file system parsers…

For example, missing boundary checks when parsing the NTFS update sequence array resulted in two vulnerabilities disclosed before: one in the ntfsck tool (from the ntfs-3g package) – CVE-2021-46790, one in the 7-Zip archiver – CVE-2023-52168.

Now, there is a third item in that row: CVE-2022-29974.

This is a pool-based buffer overflow in the AMI NTFS driver, it has the same root cause as two other vulnerabilities mentioned above. And, interestingly, it took more than 2 years for the fix to reach downstream firmware updates…

This post is about 5 vulnerabilities discovered in EFI file system drivers from AMI.

Continue reading “Multiple vulnerabilities in AMI file system drivers”

Vulnerabilities in 7-Zip and ntfs3

As I demonstrated before, the same malformed file system structures can cause overflows/over-reads in independently developed software.

Here is a recent example: a buffer overflow vulnerability found in 7-Zip — CVE-2023-52168. This vulnerability is similar to one previously discovered by me in the ntfsck tool (from the NTFS-3G driver) — CVE-2021-46790.

And even more: a buffer over-read vulnerability in 7-Zip — CVE-2023-52169. It shares the same mechanics as a kernel memory disclosure vulnerability in the Linux ntfs3 driver — CVE-2023-45896.

Continue reading “Vulnerabilities in 7-Zip and ntfs3”

CVE-2023-4692, CVE-2023-4693: vulnerabilities in the GRUB boot manager

The GRUB boot manager is more an operating system than a boot loader. For example, it has more than 20 file system types supported!

This is a really wide attack surface… And, currently, GRUB is the default choice in the Secure Boot implementation using Microsoft-signed shims (but things are moving forward).

Some time ago, I discovered two vulnerabilities (or three vulnerabilities, if we count a security issue which is almost unexploitable) in the NTFS driver of the GRUB boot manager. And here are some technical details…

Continue reading “CVE-2023-4692, CVE-2023-4693: vulnerabilities in the GRUB boot manager”

Playing with case-insensitive file names

Although NTFS has been designed with case-sensitivity in mind, it’s used mostly in the case-insensitive environment. One can natively store, within the same directory, two or more files with their names differing only in case, but Windows-based tools won’t deal with them correctly. To provide true case-sensitivity, Microsoft implemented an additional layer, per-directory case-sensitivity, as described here, here, and here.

But there are several issues with usual, case-insensitive, operations…

Continue reading “Playing with case-insensitive file names”

Shadow copies become less visible

<offtopic>You may find this article interesting: Measured Boot and Malware Signatures: exploring two vulnerabilities found in the Windows loader (archived copy). It’s about two registry-related vulnerabilities found in the Windows loader.</offtopic>

Many examiners use tools like Arsenal Image Mounter to access shadow copies on disk images. I don’t recommend this method, because you won’t see offline shadow copies, but many of us still rely on it.

And it seems there will be more caveats…

Continue reading “Shadow copies become less visible”

$STANDARD_INFORMATION vs. $FILE_NAME

There are two common misconceptions about NTFS:

  1. A typical file has 8 timestamps.
  2. Windows Explorer displays $STANDARD_INFORMATION timestamps.

A file with a single name has 12 timestamps: 4 timestamps come from the $STANDARD_INFORMATION attribute in a file record, 4 timestamps come from the $FILE_NAME attribute in the same file record, and 4 timestamps come from the $FILE_NAME attribute in an index record ($I30) of a parent directory.

If there is a short file name together with a long one, the number of timestamps is 20 (8 more timestamps come from two additional $FILE_NAME attributes in a file record and in an index record of a parent directory respectively).

You can also add an UUIDv1 timestamp from the $OBJECT_ID attribute, timestamps recorded in the USN journal and in the $LogFile journal. But these aren’t always present.

Things are more complicated with timestamps displayed by Windows Explorer.

Continue reading “$STANDARD_INFORMATION vs. $FILE_NAME”

Offline shadow copies

This was already described here, but let’s revisit the topic.

Let’s install the Windows Server 2016 operating system on a machine, install all available updates, configure the machine as a domain controller and an RDP server, create several domain user accounts. Then, create a shadow copy and delete it. After some time, create a new shadow copy and keep the machine running for a while, then create another shadow copy. How many shadow copies are there? Two (the oldest one was deleted, thus not counted).

Let’s simulate a remote attack against this domain controller. The attack involves dumping the ntds.dit file. In order to copy that file, I will use an approach outlined in this guide: create a shadow copy, copy the ntds.dit file from it, then delete this shadow copy to remove my tracks (all these actions are performed over an RDP connection, just like a real attack).

Finally, let the system run for some time and occasionally create two more shadow copies. How many shadow copies are there now?

Continue reading “Offline shadow copies”

Storage Reserve blocks some tools from thoroughly wiping unallocated space

Storage Reserve is a relatively new feature that keeps some disk space in a system volume available for downloading and installing Windows updates. Its implementation is simple – the current amount of free space visible to applications is decreased, so the “no space left” condition occurs before the space is really exhausted.

Take a look at these screenshots:

81-f
Windows 8.1

20h1-f
Windows 10

Both of them illustrate the same drive. On the first screenshot, this drive is attached to a Windows 8.1 installation. On the second one, the same drive (actually, exactly the same image of a virtual drive) is attached to a Windows 10 “20H1” installation. And the amount of free space reported by these operating systems is different!

Continue reading “Storage Reserve blocks some tools from thoroughly wiping unallocated space”

Extracting unallocated clusters from a shadow copy

Yes, shadow copies may contain a relatively small number of unallocated clusters. In this post, I will describe a new way to extract such clusters for further analysis.

The problem with unallocated clusters in shadow copies is that the volsnap driver doesn’t care about them. This driver can snapshot some unallocated ranges, but most of them are out-of-scope.

When reading unallocated clusters from a shadow copy, data from the current state of a volume can be returned. Obviously, this data has nothing to do with the shadow copy:

However unexpectedly when I ran the Encase Recover Folders feature across the HarddiskShadowcopy5 volume it found traces of the Sony folder and in fact many other files post dating the creation of the shadow copy.
<…>
The Encase Recover Folders feature parses unallocated clusters looking for folder metadata. It seems that it found data in unallocated clusters relating to the current volume. Therefore I believe that any deleted but recoverable data within the shadow copies needs to be treated with caution.

Null bytes instead of real data can be returned as well.

There is no way to distinguish between “real” and “fake” unallocated data when reading a shadow copy using the device exposed by the volsnap driver (“HarddiskVolumeShadowCopy<N>“).

Continue reading “Extracting unallocated clusters from a shadow copy”