Skip to content

Insecure DLL Loading (LoadLibrary with relative name) in installer (install/lspadd.cpp) #1

@jpalanco

Description

@jpalanco

Summary:
The installer calls LoadLibrary("ws2_32.dll") (install/lspadd.cpp:~1288) which uses the default Windows DLL search order. Loading a DLL by plain filename allows an attacker who can place a malicious DLL in a directory searched earlier (current working directory, application directory if writable, or other search locations) to achieve arbitrary code execution in the installer's context.

Analysis:

  • The code intentionally performs dynamic loading of ws2_32.dll for compatibility with older OS versions, but it calls LoadLibrary with a bare filename. This relies on the system DLL search order rather than an explicit, secure path.
  • There are no surrounding mitigations visible (no SetDefaultDllDirectories, AddDllDirectory, GetSystemDirectory usage, or LoadLibraryEx flags) to restrict where the loader searches for the DLL.
  • Loading system libraries by name without restricting the search order is a well-known DLL preloading (DLL hijack) vulnerability. An attacker who can influence the process working directory, or place a DLL in another earlier-searched location, could cause the installer to load a malicious ws2_32.dll replacement and execute arbitrary code.

Recommendation (step-by-step):

  1. Prefer explicit, secure loading APIs: replace LoadLibrary("ws2_32.dll") with LoadLibraryEx using safe search flags, or resolve an absolute path before loading.
    • Example safe approach A (preferred where available):
      a. Call SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS) early in the process (if targeting Windows 7+ with KB2533623 or later) to restrict the global search order.
      b. If additional directories are needed, call AddDllDirectory for each trusted directory and then call LoadLibraryEx("ws2_32.dll", NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS).
    • Example safe approach B (minimal change):
      a. Determine the full path to system32 via GetSystemDirectory or GetSystemWow64Directory (when dealing with 32/64-bit differences).
      b. Construct an absolute path to ws2_32.dll (e.g., "%SYSTEMROOT%\System32\ws2_32.dll") and call LoadLibraryEx(fullPath, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR) or LoadLibraryEx(fullPath, NULL, 0).
  2. If supporting very old OS versions where SetDefaultDllDirectories is unavailable, fall back to constructing the absolute path to the system DLL as described in 1.b and use LoadLibraryEx with the full path.
  3. Add error handling and logging to detect unexpected load paths or failures (already present, but ensure logs indicate absolute path or error codes so issues can be triaged).
  4. Review the rest of the installer for other LoadLibrary or implicit load calls and apply the same safe-loading pattern consistently.

Impact Analysis:

  • Risk Level: High.
  • Exploitability: High in scenarios where an attacker can influence the installer's working directory, place files in locations searched earlier than the system directory, or trick an administrator into running the installer from an unsafe location. The attacker could achieve arbitrary code execution with the privileges of the installer process.
  • Consequences: Compromise of the host, persistence, elevation of privileges (depending on installer context), tampering with installation, supply-chain compromise.

Limitations:

  • The analysis is based on the provided snippet showing LoadLibrary("ws2_32.dll"). The exact build targets and runtime environment (OS versions, whether SetDefaultDllDirectories is called elsewhere during startup) are not known, so recommendations are designed to be safe across supported Windows versions.

File information:

  • File path: install/lspadd.cpp
  • Original line: 1288

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions