Filezilla DLL Side-Loading

By Jesús Domínguez from Metabase Q’s Ocelot Team

// Summary

Metabase Q’s Offensive Security Team, Ocelot, recently evaluated the protection capabilities of an XDR during an APT Simulation exercise – part of Ocelot’s portfolio. In this exercise, the Ocelot team found that FileZilla, one of the most popular and worldwide known FTP file transfer software, was vulnerable to DLL Side-Loading or Relative path DLL Hijacking. By exploiting this vulnerability, they were able to bypass Endpoint detection.

In this blog, we share the process followed so that organizations can proactively find this type of vulnerability in their production environments.

// Finding the vulnerability

We were given a machine similar to the one provided to employees with all the security features installed. The machine had the following configuration:

“`

Edition Windows 10 Pro

Version 20H2

It was installed on ‎/‎11/‎08/2021

Compilation of SO 19042.1348

Experience Windows Feature Experience Pack 120.2212.3920.0

“`

The main target are binaries with a weak implementation of LoadLibrary, in which the complete path of the DLL module to be loaded into memory is not indicated. Instead, the current directory from which the program is executed is searched, which should be one of the last searched options, as shown in Figure 1.

  • Vulnerable call: LoadLibrary(“myDLL.dll”)
  • Not vulnerable call: LoadLibrary(“C:\Program Files\FileZilla FTP Client\myDLL.dll”)
Figure 1: Traditional DLL search

One of the key steps is to find a vulnerable executable with the above criteria, so we automated that process with the following script:

  1. Obtained a list of binaries in the terminal
  2. Used dumpbin.exe to get a list of the imports (https://docs.microsoft.com/en-us/cpp/build/reference/dumpbin-reference?view=msvc-170)
  3. Searched for “LoadLibrary.*” in the imports
  4. Checked which binary has that import

As a result of the automatic search, an important list of targets was obtained. Among them, we found the FileZilla program with the following properties:

“`
Installer obtained from:

https://filezilla-project.org/download.php?type=client

Name: FileZilla_3.56.2_win64_sponsored2-setup.exe

Arch: x64

MD5: 736e6ecd0817ff84471eeadecdff44a9

Vulnerable Executable

Name: filezilla.exe

Arch: x64

MD5: bfeca8926efd4dda575763c9c4541136

“`

To confirm this flaw, the original executable was copied to %USEPROFILE%\Documents\filezilla.exe, to see which DLLs are vulnerable to DLL Side Loading.

Interestingly, before executing Filezilla.exe, an environment variable pointing to the Application’s directory must be generated to know where to read DLLs from. Due to the vulnerability discovered, it was not of help. See Figure 2.

Figure 2: Environment variable generation

When monitoring the execution of the program via ProcMon, the DLL libfilezilla-22.dll is observed to be searched in the Current Directory first and, therefore, found vulnerable. See Figure 3.

Figure 3: DLL search in different directories

‍The following list shows all DLLs that are searched in the same way and, thus, also vulnerable to DLL Side Loading:

“`

C:\Users\user_one\Documents\libfzclient-commonui-private-3-56-2.dll
C:\Users\user_one\Documents\wxbase30u_gcc_custom.dll
C:\Users\user_one\Documents\wxmsw30u_adv_gcc_custom.dll
C:\Users\user_one\Documents\wxmsw30u_aui_gcc_custom.dll
C:\Users\user_one\Documents\wxmsw30u_xrc_gcc_custom.dll
C:\Users\user_one\Documents\libsqlite3-0.dll
C:\Users\user_one\Documents\MPR.dll
C:\Users\user_one\Documents\NETAPI32.dll
C:\Users\user_one\Documents\POWRPROF.dll
C:\Users\user_one\Documents\libfzclient-private-3-56-2.dll
C:\Users\user_one\Documents\libfilezilla-22.dll
C:\Users\user_one\Documents\libgmp-10.dll
C:\Users\user_one\Documents\libgnutls-30.dll
C:\Users\user_one\Documents\zlib1.dll
C:\Users\user_one\Documents\WINMM.dll
C:\Users\user_one\Documents\wxmsw30u_core_gcc_custom.dll
C:\Users\user_one\Documents\libpng16-16.dll
C:\Users\user_one\Documents\wxbase30u_xml_gcc_custom.dll
C:\Users\user_one\Documents\libgcc_s_seh-1.dll
C:\Users\user_one\Documents\libstdc++-6.dll
C:\Users\user_one\Documents\libhogweed-6.dll
C:\Users\user_one\Documents\ncrypt.dll
C:\Users\user_one\Documents\libnettle-8.dll
C:\Users\user_one\Documents\NETUTILS.dll
C:\Users\user_one\Documents\SRVCLI.dll
C:\Users\user_one\Documents\NTASN1.dll
C:\Users\user_one\Documents\UMPDC.dll
C:\Users\user_one\Documents\Wldp.dll
C:\Users\user_one\Documents\TextShaping.dll
C:\Users\user_one\Documents\MSASN1.dll
C:\Users\user_one\Documents\WindowsCodecs.dll
C:\Users\user_one\Documents\profapi.dll
C:\Users\user_one\Documents\msftedit.dll
C:\Users\user_one\Documents\msvcp110_win.dll
C:\Users\user_one\Documents\apphelp.dll
C:\Users\user_one\Documents\CRYPTBASE.dll
C:\Users\user_one\Documents\msimg32.dll

“`

NOTE: This vulnerability was also found in the 32-bit version of FileZilla. We leave for the reader to implement the attack in that version as an exercise.

// Implementing the Attack

An attack with the libfilezilla-22.dll DLL (see Figure 4 for the location) was implemented. The first step is to identify the DLL exports used. The DLL Exports are all the functionality supported by DLLs. For the attack to succeed, the malicious DLL must support all the same exported functions but, what if there are dozens or even hundreds of them? We implemented a script to automate this process (The link to the script can be found on Appendix A).

Once implemented, any time FileZilla calls our malicious DLL, and any of its exports, since they are supported, it will run smoothly, allowing us to execute our malicious code as described in the next section.

Figure 4: The DLL is observed in its original Application Directory

The DLL exports (See Figure 5) can be seen via CFF Explore. See Appendix A for the complete list.

Figure 5: CFF to obtain all the DLL exports

// Gaining code execution in our DLL

Now that the DLL is ready to run smoothly, it’s time to add our malicious code for it to be executed.

When a DLL is loaded (LoadLibrary) or unloaded (FreeLibrary) from memory, the first thing that is executed is the DllMain, being this its Entry point. https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain

Example of DllMain:

// dllmain.cpp: Define the entry point in the DLL application
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

During the DLL’s loading, the DLL_PROCESS_ATTACH case is executed, and that is where our malicious code was placed. In this case, the execution of a reverse shell function that was obtained from https://github.com/dev-frog/C-Reverse-Shell/blob/master/re.cpp , and with some minor modifications the connection to our C2 was achieved.

Finally, our DLL is ready to be tested, so we follow the next steps:

Exploitation

  1. We show the application directory of FileZilla and libfilezilla-22.dll
  2. We show the normal operation of FileZilla without any malicious behavior
  3. The original FileZilla is copied to %USERPROFILE$\Documents\filezilla.exe
  4. The malicious DLL is copied to the same path %USERPROFILE$\Documents\LibFilezilla-22.dll
  5. FileZilla is executed from the Current Directory and therefore, loading the malicious DLL
  6. The connection to C2 is triggered and the Reverse shell is successfully executed

This vulnerability can be seen exploited in the next video:

// Recommendations

There are always security measures that can be taken to prevent these kinds of attacks. We recommend you to:

  • Perform recurrent and proactive pentests of executables running on customers’ endpoints to make sure none of them is vulnerable to DLL Side Loading
  • Update your software regularly to include patches that fix DLL side-loading vulnerabilities
  • Enforce a policy to regulate software installation, only accepting those from approved sources authorized by the Security Team
  • Test the Blue team’s Time to Detect (TTDs) and to response (TTRs) to these types of attacks with APT Simulation exercises. Request a demo at contact@metabaseq.com

About Metabase Q

Metabase Q protects organizations from financial and reputational losses with smarter cybersecurity. Through continuous audit and analysis, Metabase Q calibrates cyber defenses that deliver security effectiveness allowing organizations to grow and innovate unhindered by cyber threats. Financial institutions covering 80% of transactions in Mexico, 10 of the largest enterprises in Latin America as well as government agencies rely on Metabase Q to continuously protect their systems and data from cyberattacks. The Ocelot offensive cybersecurity team represents the best of the best, partnered together to transform cybersecurity in the region. Ocelot threat intelligence, research, and offensive skills power Metabase Q’s solutions.

To learn more about Metabase Q, the Ocelot offensive cybersecurity team, and APT Simulation Service, visit https://www.metabaseq.com/.

contact@metabaseq.com
+1 (628) 225-1281
+52 55 2211 0920

// Appendix A

Export list from  libfilezilla-22.dll x64 and malicious DLL code:

https://github.com/Ocelot-Offensive-Security/APT-Team/tree/main/FileZilla