Showing posts with label Windows. Show all posts
Showing posts with label Windows. Show all posts

Monday, 19 December 2016

Evil-Maid attacks with Hibernation

I have shared the speech I gave in the last RootedCon Valencia, about an Evil-Maid attack technique exploiting Windows hibernation files.

This technique is not new (and I didn't discover it for the first time), but it isn't very well documented.

I have also written about this kind of attacks in Areopago21 blog (in Spanish).

In this post I am going to focus on the hands-on part.

Summarizing: If we get physical access to a computer powered on (but locked) or in suspension. We can try to recover the critical volatile information (session identifiers, clear-text passwords, cryptographic keys, etc.) from the hibernation file.

In order to obtain the hibernation file, we need to extract it from the hard drive. We could boot the computer from an external device (forensic Linux distro, Hirens bootcd, etc.) or we could take out the hard drive from the computer. If the hard drive is encrypted, it gets more complicated.

This file is in the root of the drive: c:\hiberfyl.sys. Even for Windows, this file is hidden by default and it is locked, so we can’t read it.

The hibernation file is never deleted, only its headers are modified when it is used for rebooting. This way, if the computer has been hibernated at any time in the past, we will have this file. If not, we need to force an hibernation.

This is possible even if the computer is locked, if the user has activated the hibernation option:


Unfortunately, starting from Windows 7, the hibernation feature is disabled by default. Although some laptop manufactures enable it.

However, there is a way to force hibernation. If the battery reaches critical level, the computer is hibernated automatically. This is configured by default in all Windows version up to Windows 10.


Once we have the hibernation file, we can work with it:

The basic tool for the task is Volatility; with it we can do the following things:
• Obtaining information about the hibernation file: vol.exe hibinfo -f hiberfil.sys
• Convert it to raw format: vol.exe imagecopy -f hiberfil.sys -O hiberfil.bin
• Convert it to DMP format (Windbg compatible): vol.exe raw2dmp -f hiberfil.sys -O hiberfil.dmp
• Obtaining the browsing history: vol.exe iehistory -f hiberfil.sys
• Obtaining local password hashes: vol.exe hashdump -f hiberfil.sys
• Obtaining Truecrypt cryptographic keys: vol.exe truecryptpassphrase -f hiberfil.sys

Example of usage:


We also have multiple community plugins for other tasks: mimikatz, bitlocker, bitcoin, etc.

For the conversion we can also use the tools from Matt Suiche (just released), previously known as MoonSols Windows Memory Toolkit. They work better than Volatility and they support Windows up to version 10.

Despite we have a Mimikatz plugin for Volatility, it is very limited so it’s better to work directly with Mimikatz. For that we have to:
• Convert the hiberfil.sys file to a format compatible with Windbg (DMP):
  o vol.exe raw2dmp -f hiberfil.sys -O hiberfil.dmp –profile=Win7SP0x64
• Load the DMP into Windbg:
  o .symfix => Configures the Microsoft symbol repositories.
  o .reload => Reloads the needed symbols.
  o .load wow64exts => Loads the module for debugging WOW64 processes.
  o !wow64exts.sw => Activates WOW64 extensions.
• Load Mimikatz module in Windbg:
  o .load c:\Users\rpinuaga\Desktop\bad-hibernation\demo\mimilib64.dll => Loads the Mimikatz module.
  o !process 0 0 lsass.exe => Looks for the lsass process (Local Security Authority Subsystem Service).
  o .process /r /p fffffa800424e910 => Configures the context to the lsass process.
  o !mimikatz

And it’s done, here we have the results:


Note: Volatility only supports hibernation files from Windows up to version 7 (starting in Windows 8 the format changes a bit). The new tool from Matt Suiche in theory allows it, but last time I checked the file resulting from the conversion was not recognized by Volatility.

Friday, 30 October 2015

Microsoft Time Synchronization

Have a look to other posts of this serie:

[5] Attacking HTTP Strict Transport Security
[6] Attacking the Public Key Infrastructure
[7] Other Attacks
[8] Helper tools

Of course, I couldn't finish my examples without talking about Microsoft. From the desktop OS vendor that I have tested, Microsoft has the most robust one in terms of security. It works in a different way for standalone computers than in domain members, so let's cover both circumstances:

In a standalone Windows box, time synchronization takes place each 7 days (Sundays at 1-2am or so) so the only one option to intercept an NTP request is to be there on Sunday or Monday, whenever the victim boots the computer for the first time after the synchronization time. In addition, Windows has a clock drift limitation of 15 hours, so we can't change the clock more than 15 hours on each synchronization, which is a real problem for most attacks that we will see in the following posts.

The 15 hours value is not a harcoded value, it is stored in the registry, in a couple of keys called "MaxPosPhaseCorrection" and "MaxNegPhaseCorrection", and they change in different systems, for example, in a Windows 7/8 is 15 hours but in a Windows Server 2012 is 48 hours, and in older servers is different as well. It could also change when some changes happen in the box, for example when a box become a domain member.


In combination, both controls make Windows boxes pretty secure in terms of time synchronization. However, if any of both are changed by the user, there are some attack vectors that could be used. For example, there are many tutorials in the internet explaining how to change the time synchronization scheduled task, because they think (and probably they're right) that once a week is not enough for a good clock accuracy.


So, under this circumstance, a new attack vector came to my mind. What happen if the user configure his system to synchronize the time more often than the maximum clock drift allowed? The answer is than an attacker could intercept that NTP request and change the clock just a few seconds before the next scheduled time synchronization, then intercept the following NTP requst and do the same, and again, and again, and again until he reach the desired time. I called this attack "Time Skimming", because it's a similar idea than a stone skimming in a lake, and it's implemented in Delorean:



There's another way to force time synchronization, but it requires some kind of social engineering. When the user manually request a time synchronization using the "Internet Time Settings", but it's not as easy as in Mac OS X, since it takes several clicks.

Domain members work in a different way. The Max[Pos|Neg]PhaseCorrction value is set to 0xFFFFFFFF which means "accept any clock drift". That is a risk, but they include a packet signature in order to authenticate the source of the response:


They use the NTP standard in a creative way. Key ID should be a value that identify which key should be used to sign the response. In a regular NTP request it should be 1 or 2, depending on the number of keys available. However, what Microsoft did was use this to identify the computers username in the active directory that is requesting the time synchronization. For example, if we have a KeyID 0x5e040000 we need to change its endianess and then we have 0x0000045e. The first bit of this is a key selector (0 or 1), and the rest is the Relative ID (RID) for the computer.


As you probably know, both computers and users are objects in active directory. Computers are a special kind of users. They set a password for this user when they join the domain, and those passwords are changed in a regular basis. A Domain Controller store the last two known hashed passwords, so the key selector that we mentioned before identify this.

/* Sign the NTP response with the unicodePwd */
MD5Init(&ctx);
MD5Update(&ctx, nt_hash->hash, sizeof(nt_hash->hash));
MD5Update(&ctx, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
MD5Final(signed_reply.signed_packet.data + sign_request.packet_to_sign.length + 4, &ctx);


Response packets are signed using MD5 ( md5(hashed_password+response_body) ), which is not the most robust hashing algorithm in the world, but I couldn't find a working attack for such a small message, so at this point I think a Microsoft domain time synchronization is the most robust that I have seen in my research.