Hunting for Junction Folder Persistence
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].
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.
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.
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" } } }
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
Categories