Da Li’L World of DLL Exports and Entry Points, Part 6

I love looking at clusters of files, because it’s the easiest way to find patterns. In the last part of this series I focused on Nullsoft installers (DLLs!) only, and today, I will use the very same idea to describe clusters of DLL families I have generated from a very large corpora of clean samples (collected over last decade, or so).

What makes a summary like this interesting?

Some malware families like to ’emulate’ real software. They imitate clean .exe and .dll files by copypasteing their lists of imports, exports, internal strings, but then adding an extra import or export here and there; some go as far as to integrate their malicious code with the existing source code. So, the compiled embedded malicious code occupies like 5-10% of the actual binary, and the rest is all nice and dandy code ‘borrowed’ from some open source project. Detecting a malicious code inside such binaries is not trivial, but one thing that sometimes gives the badness away is that extra export. So, this post is about these extra exports…

The most popular exports combo in my sampleset is this:

148199
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer

No surprises here, it’s your traditional COM library at work.

The next two are variants of the above, but including an extra export:

27741
DllCanUnloadNow
DllGetClassObject
DllInstall
DllRegisterServer
DllUnregisterServer

24647
DllCanUnloadNow
DllGetClassObject
DllMain
DllRegisterServer
DllUnregisterServer

Now you know where it’s heading…

When you analyze a DLL, and it includes all the export functions from the sets above, BUT then export some additional functions, these functions are definitely of interest. This doesn’t mean all DLLs that export these ‘default’ sets + something extra that I am highlighting as ‘functions of interest’ are malicious. It’s just an easy win to focus on these extra exported functions first, even if just to discover that a legitimate programmer of a legitimate DLL was overzealous in over-exporting functions…

Here’s an example of a legitimate set with these ‘extras’:

2019
DeferredDeleteW
DllCanUnloadNow
DllGetClassObject
DllInstall
DllRegisterServer
DllUnregisterServer
InstallPackagesManagedW
InstallPackagesW
ReinstallPackageW
ResumeAsyncW
ResumeW
UninstallPackageW

or

1464
DllCanUnloadNow
DllGetClassForm
DllGetClassInfo
DllGetClassObject
DllGetInterface

Secondly, many of traditional DLL exports are _not_ meant to be executed from the likes of rundll32.exe.

What does it mean?

These popular DLL Export combos give you a list of functions that, if seen being invoked via command line, are most likely an indicator of something ‘funny’ going on. This is because these functions are (normally) not designed to be rundll32-friendly and are meant to be accessed programmatically only. There are exceptions, of course…. f.ex. tailored DllInstall is sometimes invoked by legitimate software and via rundll32.exe, but the main message here is that if you see rundll32.exe executing one of the non-rundll32-exe friendly functions, you better start investigating…

Last, but not least — remember that DLLs exporting via ordinals is a thing too, so keep this in mind during your analysis….

So, what other ‘healthy’ combos we can see out there?

  • QT Plug-ins export these two functions:
1847
qt_plugin_instance
qt_plugin_query_metadata
1612
gegl_module_query
gegl_module_register
  • NVIDIA Stereo API DLLs:
1582
GetStereoApi

There are many other combos like this, but in today’s era of AI knowing-it-all, ask your nearest chatGPT for the full list, mine is most likely already quite obsolete 🙂

Environment… is variable

I love environmental variables. They are often post-worthy, and sometimes they are just simply cool.

Yet, many are still not known. Many are still not described.

Looking for ‘easy’ research targets inside the Windows directory one can scan executables and DLLs looking for either a string or an import reference to the functions that operate on Environment variables:

  • RtlSetEnvironmentVariable
  • setenv
  • SetEnvironmentVariable
  • GetEnv
  • GetEnvironmentVariable
  • ExpandEnvironment

These produce really interesting hits!

Looking at the code of puiobj.dll (PrintUI Objects DLL) we can find a weirdly named environment variable F2ED815E-5F18-4860-A8F2-16471D53C5CF that takes a integer value that seems to be a flag controlling how printer queue jobs are presented.

Looking at curl.exe we see the familiar CURL_HOME reference that can alter the way curl works (configuration file location).

The xcopy.exe takes into consideration the value of COPYCMD.

In 2022 no one remembers mswsock.dll, but it also uses environment variables:

  • SanTcpBypass
  • SanResizeDisable
  • SanRecvPollCount

The same goes for oleaut32.dll:

Many of environment variable tricks are known by now. Today I posted on Twitter and Mastodon about the use of environment variables inside the LNK files which — while not really being a proper evasion since the shell functions are processed within a context of executing process — may give some new opportunities to attackers too.

But there is always more…

Environment variables are very, very prevalent and all over the place. Many of them are kinda invisible, f.ex. many batch files and the aforementioned LNK files rely a lot them, and many of them are batch-file specific, often used internally and not very well documented.

Here’s a snapshot of various environment variables (many of which are not very well known, I think) present inside the LNK and BAT files on a win10 system with a Visual Studio, Bon Jour, NPCAP, Powershell and Python present:

  • %ARGS%
  • %AUT%
  • %AUTDIR%
  • %CABOUTPUT%
  • %CD%
  • %CLIENTPATH%
  • %CRT%
  • %CURRDIR%
  • %CabOutput%
  • %CommandPromptType%
  • %CommonProgramFiles%
  • %DEVENVDIR%
  • %DIR%
  • %DIRECTIVEFILE%
  • %DevEnvDir%
  • %DoDump%
  • %Dot11Support%
  • %ERRORLEVEL%
  • %ExtensionSDKDir%
  • %FSHARPINSTALLDIR%
  • %Framework40Version%
  • %FrameworkDIR32%
  • %FrameworkDIR64%
  • %FrameworkDir%
  • %FrameworkDir32%
  • %FrameworkDir64%
  • %FrameworkVersion%
  • %FrameworkVersion32%
  • %FrameworkVersion64%
  • %HOMEDRIVE%
  • %HOMEPATH%
  • %IFCPATH%
  • %INCLUDE%
  • %KEY_NAME%
  • %LEGACY_MACHINE_SETUP_LOGS_PATH%
  • %LIB%
  • %LIBPATH%
  • %LOCALAPPDATA%
  • %LoopbackAdapter%
  • %MACHINE_AMD64_SETUP_LOGS_PATH%
  • %MACHINE_I386_SETUP_LOGS_PATH%
  • %NETFXSDKDir%
  • %NPCAP_DIR%
  • %OUTPUTDIR%
  • %OutputDir%
  • %PATH%
  • %PERMACHINECLIENTPATH64%
  • %PERMACHINECLIENTPATH86%
  • %PERMACHINE_START_MENU_PATH%
  • %PERUSER_START_MENU_PATH%
  • %PROCESSOR_ARCHITECTURE%
  • %PROGRAMDATA%
  • %PROMPT%
  • %PYTHONHOME%
  • %ProgramFiles%
  • %ProgramW6432%
  • %RANDOM%
  • %RETURNCODE%
  • %SDK%
  • %SENDMAIL%
  • %SID%
  • %SQUISHRUNNER%
  • %SQUISHSERVER%
  • %START_TYPE%
  • %ScriptName%
  • %SendMail%
  • %SyncLogsExclude%
  • %SyncSettingsExclude%
  • %SystemRoot%
  • %TARGET%
  • %TEMP%
  • %TEMPFILE%
  • %TESTCASE%
  • %TESTSUITE%
  • %TEST_INCLUDE%
  • %TEST_LIB%
  • %TMP%
  • %UCRTVersion%
  • %USERPROFILE%
  • %UniversalCRTSdkDir%
  • %VCIDEInstallDir%
  • %VCINSTALLDIR%
  • %VCLIB_GENERAL_OVERRIDE%
  • %VCToolsInstallDir%
  • %VCToolsVersion%
  • %VCVARS_USER_VERSION%
  • %VC_ATLMFC_IncludePath%
  • %VC_ExecutablePath_ARM_ARM%
  • %VC_ExecutablePath_ARM_ARM64%
  • %VC_ExecutablePath_ARM_x64%
  • %VC_ExecutablePath_ARM_x86%
  • %VC_ExecutablePath_x64_ARM%
  • %VC_ExecutablePath_x64_ARM64%
  • %VC_ExecutablePath_x64_x64%
  • %VC_ExecutablePath_x64_x86%
  • %VC_ExecutablePath_x86_ARM%
  • %VC_ExecutablePath_x86_ARM64%
  • %VC_ExecutablePath_x86_x64%
  • %VC_ExecutablePath_x86_x86%
  • %VC_IFCPath%
  • %VC_LibraryPath_ATL_ARM%
  • %VC_LibraryPath_ATL_ARM64%
  • %VC_LibraryPath_ATL_ARM64EC%
  • %VC_LibraryPath_ATL_ARM64EC_spectre%
  • %VC_LibraryPath_ATL_ARM64_spectre%
  • %VC_LibraryPath_ATL_ARM_spectre%
  • %VC_LibraryPath_ATL_x64%
  • %VC_LibraryPath_ATL_x64_spectre%
  • %VC_LibraryPath_ATL_x86%
  • %VC_LibraryPath_ATL_x86_spectre%
  • %VC_LibraryPath_VC_ARM%
  • %VC_LibraryPath_VC_ARM64%
  • %VC_LibraryPath_VC_ARM64EC%
  • %VC_LibraryPath_VC_ARM64EC_Desktop%
  • %VC_LibraryPath_VC_ARM64EC_Desktop_spectre%
  • %VC_LibraryPath_VC_ARM64EC_OneCore%
  • %VC_LibraryPath_VC_ARM64EC_OneCore_spectre%
  • %VC_LibraryPath_VC_ARM64EC_Store%
  • %VC_LibraryPath_VC_ARM64_Desktop%
  • %VC_LibraryPath_VC_ARM64_Desktop_spectre%
  • %VC_LibraryPath_VC_ARM64_OneCore%
  • %VC_LibraryPath_VC_ARM64_OneCore_spectre%
  • %VC_LibraryPath_VC_ARM64_Store%
  • %VC_LibraryPath_VC_ARM_Desktop%
  • %VC_LibraryPath_VC_ARM_Desktop_spectre%
  • %VC_LibraryPath_VC_ARM_OneCore%
  • %VC_LibraryPath_VC_ARM_OneCore_spectre%
  • %VC_LibraryPath_VC_ARM_Store%
  • %VC_LibraryPath_VC_x64%
  • %VC_LibraryPath_VC_x64_Desktop%
  • %VC_LibraryPath_VC_x64_Desktop_spectre%
  • %VC_LibraryPath_VC_x64_OneCore%
  • %VC_LibraryPath_VC_x64_OneCore_spectre%
  • %VC_LibraryPath_VC_x64_Store%
  • %VC_LibraryPath_VC_x86%
  • %VC_LibraryPath_VC_x86_Desktop%
  • %VC_LibraryPath_VC_x86_Desktop_spectre%
  • %VC_LibraryPath_VC_x86_OneCore%
  • %VC_LibraryPath_VC_x86_OneCore_spectre%
  • %VC_LibraryPath_VC_x86_Store%
  • %VC_VC_IncludePath%
  • %VIRTUAL_ENV%
  • %VS160COMNTOOLS%
  • %VSCMD_ARG_APP_PLAT%
  • %VSCMD_ARG_CHAMELEON%
  • %VSCMD_ARG_CLEAN_ENV%
  • %VSCMD_ARG_HELP%
  • %VSCMD_ARG_HOST_ARCH%
  • %VSCMD_ARG_NO_EXT%
  • %VSCMD_ARG_STARTDIR%
  • %VSCMD_ARG_TGT_ARCH%
  • %VSCMD_ARG_VCVARS_SPECTRE%
  • %VSCMD_ARG_VCVARS_VER%
  • %VSCMD_ARG_WINSDK%
  • %VSCMD_ARG_no_logo%
  • %VSCMD_BANNER_SHELL_NAME_ALT%
  • %VSCMD_BANNER_TEXT_ALT%
  • %VSCMD_DEBUG%
  • %VSCMD_SKIP_SENDTELEMETRY%
  • %VSCMD_START_DIR%
  • %VSCMD_TEST%
  • %VSCMD_VCVARSALL_INIT%
  • %VSCMD_VER%
  • %VSINSTALLDIR%
  • %WORKINGDIR%
  • %WORKINGDIRONEDRIVE%
  • %WindowsLibPath%
  • %WindowsSDKDir%
  • %WindowsSDKLibVersion%
  • %WindowsSDKNotFound%
  • %WindowsSDKVersion%
  • %WindowsSDK_ExecutablePath_x64%
  • %WindowsSDK_ExecutablePath_x86%
  • %WindowsSdkBinPath%
  • %WindowsSdkDir%
  • %WindowsSdkVerBinPath%
  • %cmd%
  • %computername%
  • %comspec%
  • %dir%
  • %errorlevel%
  • %findSDK%
  • %match%
  • %originPolicy%
  • %result%
  • %returnValue%
  • %scriptPath%
  • %systemroot%
  • %temp%
  • %windir%