Hunting for Junction Folder Persistence

Posted on 29 November 2017 by Jayden Zheng

Imagine opening a folder in Windows and then - in the background - a malicious file is executed without you realizing. This is the technique that was part of the CIA Vault 7 leak from WikiLeaks [1].

 

This technique combines COM CLSID (ClassID) hijacking and Junction Point, which is a type of hard link that acts like a representation of a directory to obtain userland persistence.

 

Windows has a set of junction folders that were assigned with unique CLSID in the Windows Registry; these folders can then be accessed by using their CLSID. When the folder is accessed, it will search for their CLSID key in the HKEY_CLASSES_ROOT (HKCR) registry hive to retrieve the appropriate DLL or other object to run. Since HKCR is a combination of HKLM and HKCU, it is then possible to hijack keys in HKCR by creating the same CLSID keys in HKCU. You can read more about HKCR from here [2].

 

In short, if you create a junction folder and append a unique CLSID to the folder’s name such as “Name.{CLSID}”, then create the registry key using the same CLSID in the HKCU:\Software\Classes\CLSID and add your DLL in there, it will run the DLL whenever the folder is accessed. To achieve persistence, the junction folder can be created in the Startup folder and on boot up, Windows Explorer will navigate the directory in there.

 

This blog post will provide a short analysis on how to detect the persistence methods that utilize CLSID hijacking with junction folders, specifically those that were created in the Start Menu directory. You can then use the same logic to hunt for those junction folders in another directory. At the end, we will share the PowerShell script we used for hunting in this scenario.

What to look for, and how to look for it

The following example creates a junction point that links to the Recycle Bin with the folder name of Bin. After the folder is created, Windows Explorer will only display the folder name by default. 

2 junction folder payload execute

1 empty junction folder bin

If the attacker creates an innocent-looking empty junction folder, and adds the necessary registry entries, the user might take the bait and unknowingly access the folder, which triggers the payload. The Autoruns tool from Windows Sysinternals will not detect this, which increases the difficulty for blue teamers to spot this.

 

We figured out that by using command line interface, it is possible to see the CLSID in the file name. This sparked the idea that we might be able to navigate the Startup directory and extract out folders that consist of CLSID in the folder name.

3 clsid folder b

Since we knew that it is required to create the registry key into the HKCU hive to perform the CLSID hijacking, we then extract out the CLSID from the folder name and search for a match in the HKCU:\Software\Classes\CLSID. Once a match is found, the suspected CLSID registry key will be extracted and displayed for analysis.

 

We have provided a script that currently checks for junction folders that were created in the Startup folder, which you can use this to check for any anomalies for any registry keys associated with this technique.

function Get-JunctionFolder {
<#
    .SYNOPSIS

        Author: Jayden Zheng (@fuseyjz)

        Checks the start menu directory for any folder name with CLSID.

    .EXAMPLE

        PS C:\> Get-JunctionFolder

        Return the InProcServer32 value of each CLSID registry key found.
#>

param (
    # Get %APPDATA%
    $AppData = [Environment]::GetFolderPath('ApplicationData')
    )

    # Check Start Menu directory for any filename contain CLSID
    Get-ChildItem -Path "$AppData\Microsoft\Windows\Start Menu\" -Recurse | Where-Object {$_.Name -match '{[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}}'} | ForEach-Object {

        $FileName = $_.Name
        $GetCLSID = $FileName.split(".")[1]
        $Path = $_.FullName

        # Retrieve Registry Key by comparing above found CLSID
        $Result = Get-ChildItem -Path "HKCU:\Software\Classes\CLSID" -Recurse | Where-Object {$_.PsPath -match $GetCLSID} | Get-ItemProperty | Where-Object {$_.PSChildName -match "InProcServer32"} | Select '(default)', PSPath
    
        # Split output
        $SplitResult = $Result -split ';'
        $RawDll = $SplitResult[0] -split '='
        $RawReg = $SplitResult[1] -split '::'
        $Dll = $RawDll[1]
        $Reg = $RawReg[1]

        # Print to screen
        if ($Result) {
            Write-Host "Path: $Path"
            Write-Host "Dll: $Dll"
            Write-Host "Reg: $Reg `n"
        }    
    }
}

4 windows powershell junction folder b

Conclusion

Although this technique requires the DLL to be dropped on the disk, with the way it persists there is a possibility that blue teamers might miss it. The provided script only focuses on the scenario where the junction folders were created in the Startup folder and it is likely there will be other ways to persist using this. Hopefully this gives you the idea of how to detect this technique and allows you to customise the script to your own needs.

 

References

[1] https://wikileaks.org/ciav7p1/cms/page_13763373.html

[2] https://msdn.microsoft.com/en-us/library/windows/desktop/ms724475(v=vs.85).aspx