Operation Duckhunt : Field Testing the FBI’s Anti-Qakbot Payload

Screen Shot 2023-09-04 at 3.34.14 PM.png

In a significant development, the FBI declared today that the Qakbot botnet has been successfully dismantled through a collaborative international law enforcement effort. This operation not only involved the confiscation of the botnet’s infrastructure, but it also involved the removal of the malware from compromised devices or not necessarily ?


What did FBI actually deliver #

After gaining access to top-tier control servers, there had to be a way to shut down the processes. For that, the FBI used a clinical approach instead of uploading a payload that ‘hacks’ its way around the same.
Essentially, most malwares are modular . The following diagram explains it well. This gives enough flexibility to the malware author to extend the functionality.

Screen Shot 2023-08-31 at 11.59.58 PM.png

After gaining access, the FBI supplied a DLL payload wrapped inside a shellcode. This payload runs within the malicious process itself and calls a named pipe, which the malware uses for interprocess communication (IPC) to make API calls and pass data, something exactly similar I have described in a technical breakdown of Tofsee Malware IPC exit packet Neutralizing Tofsee Spambot – Part 1.

For QakBot the IPC name is of the format
{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X} .

This GUID is almost unique for each infection as it is formed by different parameters like computername , hwid etc .

The IPC request for QakBot is simply defined as


_QakBotIPCRequest, is used for communication within a system. It includes two short integers, OperationID and ArgLen, followed by a byte array named Headers. ArgLen determines the size of the Headers array, which contains tokenized data in a specific format. This data includes a ‘COMMANDID’ token for the execution of certain functions based on an index and additional parameters to the function, separated by spaces.

Newer QakBot versions implement seven different types of command types using OperationID. If COMMANDID is set to 1, the sub ID is taken from the Function Data, which itself exposes a list of API functions implemented by QakBot. The cmdHandler is then defined as follows:

carbon (3).png

Cmd Number noThreadExec Description
1 false Cmd1_ConfSetUp
3 true Cmd3_nullFn
4 true Cmd4_nullf
5 false Cmd5_StealCerts
6 true Cmd6_EnableWebInjects
7 true Cmd7_EnableWebInjects_0
8 true Cmd8_InstallJSAutoUpdater
0Ah true Cmd10_TerminateProcessByName
0Ch true Cmd12_ActivateProxy
0Dh false Cmd13_SmbSpreader
0Eh true Cmd12_RebootQakBot
12h true Cmd18_Uninstall
13h true Cmd19_UpdateQakbotBinary
14h true Cmd20_RetrieveWebinjects
15h false Cmd21_UploadLogs
16h true Cmd22_Updatevar
17h true Cmd23_nullFn
19h true Cmd25_LoadProxy
1Ah true Cmd26_LoadWebinjects
1Bh true Cmd27_LoadUnknownModule
1Ch true Cmd27_LoadUnknownModule_0
1Dh true Cmd27_LoadUnknownModule_1
23h true Cmd35_LoadVNC
1Eh true Cmd27_LoadUnknownModule_2
1Fh true Cmd27_LoadUnknownModule_3
21h true Cmd33_ExecuteCommandLine
22h true Cmd34_InjectExplorer

“As a test, let’s try to implement an IPC call that invokes command number 0x12 (33) Cmd33_ExecuteCommandLine. This function is self-explanatory and doesn’t require reverse engineering. It will execute a command on the infected system. For this experiment, we will use the classic ‘calc.exe’ for demonstration.”

#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv) {
    // replace with your pipe name
    const char* pipeName = "\\\\.\\pipe\\{pipename}";

    // Prepare the data to send

    struct _QakBotIPCRequest
        short OperationID;
        short Undef1[3];
        char FuncData[0x100];

    }QakIPC = { 1,0,0,0,0 };

    DWORD bytesRead;

    sprintf(QakIPC.FuncData, "%s %s", argv[1], argv[2]);

    // Call Named Pipe
    BOOL success = CallNamedPipeA(

    if (success) {
        printf("Pipe Data sent ");
    else {
        printf("PIPE error []");
        return 1;

    return 0;

If we pass CMD 33 and the cmd.exe parameter to it, it seamlessly executes the Windows Calculator.

Screen Shot 2023-09-02 at 4.25.28 PM.png

FBI implemented the terminator payload using main call ID number 4 , which was present in the newer updated versions of QakBot ( dont know much about the number of QakBot versions , if someone knows please do let me know ) .
Screen Shot 2023-09-02 at 8.01.36 PM.png

the data packet they used was

short OperationID = 0x30004;

Op ID is 0x04; however, the rest was not necessary.

Let’s test the FBI’s missiles in a live environment to check their effectiveness. In order to do that, the FBI payload was supplied as a shellcode, which eventually decodes into a DLL. This shellcode loader includes a fully-fledged DLL reflective loader in it; however, we are only interested in extracting the DLL.

Extraction is rather simple, and roughly this is how it is represented in Python with XorSalt as 165AB0219D76757208FD8319357D4DF0.

    def DecodeDLL(cls,buffer, XorSalt):
        dst = array.array("B")

        for i in range(0, len(buffer)):
            ox = ord(buffer[i]) ^ ord(XorSalt[i & 0xf])
            ox = ox - (i & 0x0f)
            if ox < 0:
                ox = -ox

        return dst.tostring()

Output file is a dll file and need to be converted into an exe to run ( sure there are other ways around )

Screen Shot 2023-09-02 at 10.55.59 PM.png

for this purpose , we will use the DLL2EXE by hasherezade

C:\Users\Administrator\Desktop>dll_to_exe.exe fbi.dll FBI.exe

after successfully converting dll to exe , lets try to test it on a live QakBot infection and see how effectively it kills the malware .

Checking for the presence of wermgr.exe process

Screen Shot 2023-09-03 at 2.36.28 PM.png

To make it easier , I have converted the exe into a GUI application that lets you easily remediate the QakBot Infection if it is still running on your infected PC .

Screen Shot 2023-09-04 at 2.04.20 PM.png

Download the Anti-Qakbot executable from GitHub

The Mysterious Cmd18 #

Some earlier versions of QakBot implemented an IPC call for command 18, which actually removes the scheduled task persistence mechanism as well. Why the FBI didn’t go this way to kill the earlier versions, who knows?“

Screen Shot 2023-09-04 at 3.27.23 PM.png

Screen Shot 2023-09-04 at 3.22.28 PM.png


Now read this

Relocating BaseAddress Agnostic Memory Dumps

Often times we need a loaded base address of a memory image that needs to be disk realigned in order to load it and parse the binary successfully in binary analysis tools like IDA or debuggers . During linking phase the Preferred Base... Continue →