Beyond good ol’ Run key, Part 23

Today I will talk about something that can be called ‘the god of all persistence mechanisms’. One that is so powerful that can use pretty much any .exe on your system as a persistence mechanism.

It’s called dotlocal (.local).

If you run Process Monitor often enough you will (sooner or later) discover that anytime you launch an .exe the system will always try to find a file or a directory called <filename.exe>.local.

That – my friend – is a debugging feature.

It is a redirection mechanism designed to test COM objects and pretty much means that if either a file or directory named <filename.exe>.local exists the OS will understand it as a ‘testing in progress’ signal and will attempt to load DLLs from a different directory than usual. In other words, it will search for dependent DLL libraries in a path different from the typical DLL search order. This allows us to intercept pretty much any DLL dependency we wish except for these that are listed under KnownDLLs registry key (HKLM\CurrentControlSet\Control\Session Manager\KnownDlls).

For the sake of a demo, I will show you a very stupid example using the least malicious program on your system called… Notepad.

Notepad relies on a couple of libraries, most of them are present on the Known DLLs list (can’t be abused unless you remove them from the Registry and reboot the system); except for comctl32.dll. This library has many versions and thanks to that requires a dedicated entry in the manifest solving the so-called DLL hell problem:

<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>

The practical implication of this manifest file is that OS will try to load the following comctl32.dll file (on Windows XP)

x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\comctl32.dll

located inside the Windows directory (c:\WINDOWS\WinSxS\).

Introducing a directory c:\windows\system32\notepad.exe.local we can force the OS to leverage the dotlocal ‘feature’ and load the following ‘malicious’ library instead:

c:\WINDOWS\system32\notepad.exe.local\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\comctl32.dll

It works on Windows 10 too, except that it will be loaded from a different path:

c:\WINDOWS\system32\notepad.exe.local\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9841.0_none_38d154a85935aa0a\comctl32.dll

The following example shows the moment of a malicious DLL loaded via dotlocal mechanism into a Notepad session on Windows 10.

notepad10

Notepad obviously crashes, cuz I was lazy and just implemented a dummy comctl32.dll, but in a real-case scenario one could hide the presence of such a malicious DLL by using it as a proxy and redirecting all API calls to the legitimate comctl32.dll DLL.

notepad10_2

In other words, dropping the malicious comctl32.dll in these directories on respective systems will ensure that these malicious DLLs are loaded anytime someone starts Notepad.

Now, for the scary part. Notepad was a stupid example as it requires admin rights to write to c:\WINDOWS\system32\notepad.exe.local\ on Windows 10, but any file outside of areas protected by system is a much easier target.

Beyond good ol’ Run key, Part 22

Perl2exe executables are perl programs embedded inside the executable wrapper that allows making the script ‘portable’ and easy to execute without a need of installing any perl interpreter.

It turns out that the way it loads things is kinda ‘open-minded’ i.e. it tries to look for loadable stuff all over the place – because of this ‘feature’ it is possible to abuse it and create yet another (bizarre) persistence mechanism (actually, plenty of them).

As an example, we can look at a very old hdd.exe perl2exe program – I got it from a friend back in a day – it display info about the HDD properties. Running it under procmon shows a lot of interesting artifacts related to files and directories that are… not found on the system.

For the sake of the demonstration, I will show only 2 hijacks, but if you browse through the log below you will find a lot of other potential phantom file names and directories that could be abused this way.

Example #1

Creating a ‘(null)’ directory in the same place where the perl2exe file is executed and dropping a sitecustomize.pl perl script inside it will lead to the perl script being executed when perl2exe is launched:

  • (null)\sitecustomize.pl containing just a simple line
    • print “Foobar\n”;

sitecustomize

Example #2

You can create f.ex. PERL2EXE_STORAGE\auto\Cwd\Cwd.dll – while it is perl2exe-specific module (since it requires CWD module to be used), it’s quite a popular module anyway so it could be a good target:

CwdCwd2And in debug view:

Cwd3Last, but not least – the (edited) log…

CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\5.8.8\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\5.8.8
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\5.8.8
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\5.8.8
QueryOpen                     %SCRIPT_PATH%\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\5.8.8
QueryDirectory                %SCRIPT_PATH%\5.8.8
QueryOpen                     %SCRIPT_PATH%\5.8.8
CreateFile                    %SCRIPT_PATH%\MSWin32-x86-multi-thread
QueryDirectory                %SCRIPT_PATH%\MSWin32-x86-multi-thread
QueryOpen                     %SCRIPT_PATH%\MSWin32-x86-multi-thread
CreateFile                    %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\5.8.8
QueryOpen                     %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\5.8.8\MSWin32-x86-multi-thread
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\5.8.8
QueryDirectory                %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\5.8.8
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\5.8.8
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\MSWin32-x86-multi-thread
QueryDirectory                %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\MSWin32-x86-multi-thread
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\MSWin32-x86-multi-thread
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\(null)\sitecustomize.pl
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\(null)\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\(null)\sitecustomize.pl
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Cwd\Cwd.dll
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Cwd\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Cwd\Cwd.dll
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Cwd
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Cwd
CreateFile                    %SCRIPT_PATH%\auto\Cwd
CreateFile                    %SCRIPT_PATH%\auto
QueryOpen                     %SCRIPT_PATH%\auto\Cwd
CreateFile                    %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\auto\Cwd
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\auto
QueryOpen                     %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\auto\Cwd
CreateFile                    %SCRIPT_PATH%\auto\Cwd
CreateFile                    %SCRIPT_PATH%\auto
QueryOpen                     %SCRIPT_PATH%\auto\Cwd
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\DynaLoader\dl_findfile.al
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\DynaLoader\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\DynaLoader\dl_findfile.al
CreateFile                    %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736
CreateFile                    %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\
QueryOpen                     %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryDirectory                %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE
CreateFile                    %SCRIPT_PATH%\Cwd.dll
QueryDirectory                %SCRIPT_PATH%\Cwd.dll
QueryOpen                     %SCRIPT_PATH%\Cwd.dll
CreateFile                    %SCRIPT_PATH%\Cwd.dll
QueryDirectory                %SCRIPT_PATH%\Cwd.dll
QueryOpen                     %SCRIPT_PATH%\Cwd.dll
CreateFile                    %SCRIPT_PATH%\libCwd.dll
QueryDirectory                %SCRIPT_PATH%\libCwd.dll
QueryOpen                     %SCRIPT_PATH%\libCwd.dll
CreateFile                    %SCRIPT_PATH%\Cwd
QueryDirectory                %SCRIPT_PATH%\Cwd
QueryOpen                     %SCRIPT_PATH%\Cwd
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736
QueryAllInformationFile       %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\Cwd.dll
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\Cwd.bs
QueryDirectory                %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\Cwd.bs
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\Cwd.bs
CreateFile                    C:\bin\pwd
CreateFile                    C:\bin
QueryOpen                     C:\bin\pwd
CreateFile                    C:\usr\bin\pwd
CreateFile                    C:\usr\bin\
QueryOpen                     C:\usr\bin\pwd
CreateFile                    C:\QOpenSys\bin\pwd
CreateFile                    C:\QOpenSys\bin\
QueryOpen                     C:\QOpenSys\bin\pwd
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Win32\
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\auto\Win32\
QueryOpen                     %SCRIPT_PATH%\auto\Win32\OLE
CreateFile                    %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\auto\Win32\OLE
CreateFile                    %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\auto\Win32\
QueryOpen                     %USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\auto\Win32\
QueryOpen                     %SCRIPT_PATH%\auto\Win32\OLE
CreateFile                    %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736
CreateFile                    %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\
QueryOpen                     %SCRIPT_PATH%\-L%USERPROFILE%\LOCALS~1\Temp\p2xtmp-1736
CreateFile                    %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryDirectory                %SCRIPT_PATH%\PERL2EXE_STORAGE
QueryOpen                     %SCRIPT_PATH%\PERL2EXE_STORAGE
CreateFile                    %SCRIPT_PATH%\OLE.dll
QueryDirectory                %SCRIPT_PATH%\OLE.dll
QueryOpen                     %SCRIPT_PATH%\OLE.dll
CreateFile                    %SCRIPT_PATH%\OLE.dll
QueryDirectory                %SCRIPT_PATH%\OLE.dll
QueryOpen                     %SCRIPT_PATH%\OLE.dll
CreateFile                    %SCRIPT_PATH%\libOLE.dll
QueryDirectory                %SCRIPT_PATH%\libOLE.dll
QueryOpen                     %SCRIPT_PATH%\libOLE.dll
CreateFile                    %SCRIPT_PATH%\OLE
QueryDirectory                %SCRIPT_PATH%\OLE
QueryOpen                     %SCRIPT_PATH%\OLE
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736
QueryAllInformationFile       %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\OLE.dll
CreateFile                    %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\OLE.bs
QueryDirectory                %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\OLE.bs
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\OLE.bs
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\WS2_32.dll
QueryOpen                     %USERPROFILE%\Local Settings\Temp\p2xtmp-1736\WS2HELP.dll
SetDispositionInformationFile %USERPROFILE%\Local Settings\Temp\p2xtmp-1736