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

Beyond good ol’ Run key, Part 21

MFC localization DLLs are similar in nature to Visual Basic ones (I talked about them in my last post).

The MFC framework went through many versions over the years, but the localization piece is still there and for many years it was initialized incorrectly by loading the resource DLLs as actual code (using LoadLibrary API). It eventually got fixed in the mfc110.dll (now it is using LoadLibraryEx API and forces to load the resource DLLs as data only), so while the new versions are secure the older versions can be potentially leveraged as a persistence mechanism.

As mentioned, there are many versions of MFC DLLs (refer to wiki link I provided in the first sentence of this post) so let’s walk through them one by one.

  • mfc40.dll
    • Loads MFC40LOC.dll
  • mfc42.dll
    • Loads MFC42LOC.dll
  • mfc70.dll
    • Loads MFC70<LNG>.dll & MFC70LOC.dll
  • mfc71.dll
    • Loads MFC71<LNG>.dll & MFC71LOC.dll
  • mfc80.dll
    • Loads MFC80<LNG>.dll & MFC80LOC.dll
  • mfc90.dll
    • Loads MFC90<LNG>.dll & MFC90LOC.dll
  • mfc100.dll
    • Loads MFC100<LNG>.dll & MFC100LOC.dll
    • Uses LoadLibraryEx, yet still loads the resource DLLs as code
    • Note: often accompanied by existing resource files for major languages: mfc100chs.dll, mfc100cht.dll, mfc100deu.dll, mfc100enu.dll, mfc100esn.dll, mfc100fra.dll, mfc100ita.dll, mfc100jpn.dll, mfc100kor.dll, mfc100rus.dll
  • mfc110.dll
    • Loads MFC110<LNG>.dll & MFC110LOC.dll
    • Note: often accompanied by existing resource files for major languages: mfc110chs.dll, mfc110cht.dll, mfc110deu.dll, mfc110enu.dll, mfc110esn.dll, mfc110fra.dll, mfc110ita.dll, mfc110jpn.dll, mfc110kor.dll, mfc110rus.dll
    • Note: This is the first version of MFC library that loads the resource DLL in a proper, secure way, via LoadLibraryEx using a LOAD_LIBRARY_AS_DATAFILE flag – as such, it doesn’t execute any code (that is, the persistence mechanism described here won’t work)
  • mfc120.dll
    • Loads MFC120<LNG>.dll & MFC120LOC.dll, but also loads them as data so persistence mechanism won’t work either
    • Note: often accompanied by existing resource files for major languages: mfc120chs.dll, mfc120cht.dll, mfc120deu.dll, mfc120enu.dll, mfc120esn.dll, mfc120fra.dll, mfc120ita.dll, mfc120jpn.dll, mfc120kor.dll, mfc120rus.dll

Note #1:

  • LNG is a 3-letter language code: ENU, CHS, JPN, FRA, etc. (e.g. MFC70ENU.dll)

Note #2:

  • The newer versions (>=70) of MFC load MFCxxxLOC.dll DLLs only if the LCID is set to LOCALE_SYSTEM_DEFAULT – since the loading of localization DLLs happens in a loop (all LCIDs are enumerated until loading of a localized DLLs succeeds), one of the enumerated LCIDs is actually set to LOCALE_SYSTEM_DEFAULT on Windows XP and both MFCxxx<LNG>.dll and MFCxxxLOC.dll are loaded, but I have not encountered the situation during tests where it would be set on Windows 7 (so you won’t see loading of MFCxxxLOC.dll on win7; this requires more research)

Note #3:

  • The Unicode and Debug versions of MFC libraries are behaving in an identical way e.g. for mfc110.dll you have:
    • mfc110.dll – ANSI
    • mfc110d.dll – ANSI, Debug
    • mfc110u.dll – Unicode
    • mfc110ud.dll – Unicode, Debug

To test, you can load the mfc DLL into OllyDbg, put a breakpoint on LoadLibraryA/W (and LoadLibraryExA/W for newer versions, and A/W for Ansi or Unicode respectively) and see what happens – the below screenshot shows various versions of MFC DLL loading the localization DLLs – first five are from English OS and the last two from Russian:

mfc_loc