Operation Duckhunt : Field Testing the FBI’s Anti-Qakbot Payload
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 ?
Summary
FBI’s payload only terminated the payload from the memory.
Some earlier versions didn’t have the
CMD_0x04
implemented, so some of the infections would still be alive. To tackle this problem, FBI could have usedCmd18_UpdateQakbotBinary
to uninstall the binary from the infected machine.As some of the infections would still be alive (due to many reasons), I have released a remediation tool Anti-Qakbot
to detect and kill the QakBot process on an infected system.
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.
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:
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.”
#define WIN32_LEAN_AND_MEAN
#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(
pipeName,
(LPVOID)&QakIPC,
sizeof(QakIPC),
NULL,
0,
&bytesRead,
NMPWAIT_WAIT_FOREVER
);
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.
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 ) .
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
dst.append(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 )
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
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 .
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?“