DLL Side-Loading & Proxying

Red Team Tip

Hello everyone!

Today, we’re going to explain a technique widely used by APT (Advanced Persistent Threat) groups, as well as Red Teams—the DLL Side-Loading & Proxying technique.

The key advantage of this technique is that when exploited correctly, it can be difficult for security solutions to detect, since it leverages a trusted application—as we’ll demonstrate today using Notepad++ as an example.

However, it's important to note that Notepad++ is just an example; this technique can be exploited through many other applications that allow DLL Side-Loading.

I hope you find this article useful! If you have any questions, feel free to ask. Alright, enough talk—let’s get started!

Befor We Started We Need to know , What is DLL Files ?

1- What Is DLL FIles ?

Look, a DLL stands for Dynamic Link Library, and it's a type of file in Windows that contains code and functions that other programs can use instead of writing the same code from scratch. It's like a ready-made library with functions that programs can call when needed instead of rewriting them.


2- What is DLL sideloading ?

In the previous writeup, we explored DLL sideloading as an operational security (OpSec) strategy for loading payloads. However, it's important to recognize that certain Endpoint Detection and Response (EDR) solutions can flag anomalies when a system binary is sideloaded from an unusual location.

For instance, in the last module, we used msdtc.exe, a legitimate system binary from C:\Windows\System32. Some EDRs can detect that this binary is being executed from an unexpected directory—such as C:\Users\User\Desktop—which may trigger security alerts, even if no malicious DLL is present.

To minimize detection risks, an alternative approach is to sideload DLLs using third-party, digitally signed applications. Since these applications do not originate from the Windows system directory, running them from a different location is less likely to raise suspicion in EDR systems.


3 - Sideloading with GUP.exe

we will focus on GUP.exe, an executable that is part of the WinGUp project. WinGUp is a configurable updater responsible for downloading and installing updates. It relies on the cURL library to connect to the internet and fetch update packages.

A key point of interest is that Notepad++, the widely used text and source code editor, utilizes WinGUp as its updater. This creates a potential vulnerability for DLL sideloading, particularly when the GUP.exe binary is involved.

By default, GUP.exe is located in: C:\Program Files\Notepad++\updater

Alongside GUP.exe, you'll also find:

  • libcurl.dll – The dynamic link library for handling network operations.

  • gup.xml – The update configuration file for Notepad++.

Because GUP.exe interacts with libcurl.dll, it presents an opportunity for DLL sideloading, which we will explore in this Writeup.

GUP.exe Did not find "libcul.dll"

We found that GUP.exe requires the libcurl.dll file to run. Now, let's create our own custom DLL file and name it the same as the original file. However, instead of its normal functionality, we'll make it display a MessageBox first. After that, we can modify it to execute any action we want.

Now, GUP.exe has successfully loaded the fake libcurl.dll that we created.

However, a new issue has emerged, which we will now explain in detail.

The error message indicates that GUP.exe was unable to resolve a function named curl_easy_setopt Now, let's check the error and see what GUP.exe requires in order to run properly.

Identifying the Target Function

To determine which function GUP.exe calls, we'll use the xdbg debugger. Start by opening the original GUP.exe from: C:\Program Files\Notepad++\updater

Then, set breakpoints on all the exported functions, as shown in the image below.

Once the breakpoints are set, resume execution beyond the GUP.exe entry point. The debugger will hit a breakpoint at the curl_easy_init function, confirming that this function is being executed.

Since curl_easy_init is actively used, it becomes a good candidate for injecting our payload.

After identifying the functions required by GUP.exe, we will create a modified version of libcurl.dll. This version will export the functions needed by GUP.exe, such as curl_easy_setopt, curl_easy_cleanup, and curl_easy_perform.

Now, let's test our new fake DLL file.

Don't forget to copy the gup.xml file as well, since GUP.exe requires it to run properly.

We'll place all these files in a folder—now let's see what happens!

Boooooooom !!!! It's Work

But of course, we're not just going to make a MessageBox after all this. Instead, we can make it connect to our C2 server or do anything else we want.

Obviously, don’t be a script kiddie and just copy the code—I’ll make you write it yourself!

Havoc C2 Server

And We Bypass AV :)

Bypass AV

But There Is a problem

If the user tries to open Notepad++ and attempts to update it, they will notice that the update message doesn’t appear. This will raise a lot of suspicion and could potentially cause our Red Team operation to fail.

Why does this happen?

This happens because the file responsible for handling updates is libcurl.dll.

However, in reality, we removed the original libcurl.dll and replaced it with a fake version containing our malicious commands.

So, when the victim tries to update Notepad++, our malicious payload will execute successfully, but the update message will not appear.

This is where DLL Proxying comes into play!

4 - DLL Proxying

DLL Proxying is a technique used to intercept function calls that are supposed to go to the original DLL file. This is done by creating an intermediary DLL, known as a Proxy DLL, which has the same exported functions as the original file. The idea is that this Proxy DLL loads the original file and then intercepts the calls directed to it. It can execute malicious code if desired before forwarding the calls to the original file, allowing the program to function normally without detecting any interference.

5 - Function Exporting and Proxy Mechanism

5.1 Why These Specific Functions?

These functions are exported because:

  • They are the same functions exported by the original libcurl, so any program that uses libcurl will interact with our proxy as if it were the original.

  • curl_easy_init() is one of the first functions invoked when using libcurl, making it an ideal entry point for executing malicious code.

  • The rest of the functions are exported only to maintain compatibility, even if they do not perform any malicious actions.

5.2 Details of the Exporting Mechanism

  • We use __declspec(dllexport) to ensure that our functions appear in the Export Table of the new DLL.

  • Each function has exactly the same name and signature as the original function to ensure that programs do not detect any differences.

  • When a program calls any function, our proxy receives the request first. If the function is curl_easy_init(), the malicious code is executed before forwarding the call to the original DLL as usual.

6 - Building The DLL Proxy

To make our fake libcurl.dll file redirect function calls that GUP.exe needs, the first step is to rename the original libcurl.dll to a different name, such as gup.dll.

Next, we'll keep our malicious DLL file named libcurl.dll as usual.

After that, we'll add the following code to inform the compiler that we want to export these functions properly.

gup is the new name for the libcurl.dll file, now called gup.dll.

@# represents the ordinal number, which is a unique identifier for each function inside gup.dll.

To find the ordinal number of a function, you can import gup.dll into PeBear.

The last function we need to build and export is curl_easy_init, which is responsible for executing the payload. Unlike other functions, curl_easy_init cannot be directly forwarded, as this would prevent the payload from executing. Therefore, we need to manually call the original function, as shown in the code below.

The RunPayload function runs in a separate thread to avoid waiting for its execution to complete. The goal is to ensure that curl_easy_init returns its result to GUP.exe as quickly as possible, minimizing any delays in function execution and maintaining the appearance of normal behavior.

Annnnnnnnnd !!!!!!!!! Boooooooom

You can connect to your own server Like Havoc c2.

Thank you all! I hope you enjoyed the article. If you have any questions, I'm here to help.

reference :

Remember My name : everythingBlackkk

Made by ❤

Github : https://github.com/everythingBlackkk

Linkedin : www.linkedin.com/in/everythingblackkk

X : https://x.com/iyassinmo

Last updated