{
	"id": "27d8494c-5181-4de2-97fd-50b021e8fa25",
	"created_at": "2026-04-06T00:20:13.892858Z",
	"updated_at": "2026-04-10T03:24:17.023586Z",
	"deleted_at": null,
	"sha1_hash": "4e234f6d82adf98bd26de5c5fcd3c216b960dea4",
	"title": "From Macros to No Macros: Continuous Malware Improvements by QakBot | Splunk",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 6649445,
	"plain_text": "From Macros to No Macros: Continuous Malware Improvements\r\nby QakBot | Splunk\r\nBy Splunk Threat Research Team\r\nPublished: 2022-12-01 · Archived: 2026-04-02 12:13:26 UTC\r\nSplunk is committed to using inclusive and unbiased language. This blog post might contain terminology that we\r\nno longer use. For more information on our updated terminology and our stance on biased language, please visit\r\nour blog post. We appreciate your understanding as we work towards making our community more inclusive for\r\neveryone.\r\nIn 2007 we saw the initial beginnings and rise of QakBot, the same year when Windows XP and Windows Server\r\n2003 were still the primary operating systems in the enterprise. QakBot, or QuackBot, made its presence known as\r\na banking trojan and a loader. Over time, it continually developed and became a standard in malicious software\r\ncircles. Today, we see QakBot used by a varied group of adversaries in a variety of ways, such as deploying\r\nransomware, persistence, and stealing credentials. Before an adversary has access to an endpoint or the ability to\r\nmove laterally, they have to gain initial access. That initial access vector continues to evolve and keep pace with\r\noperating systems, browsers, and antivirus vendors to ensure the deliverability of malicious payloads.\r\nIn this blog, the Splunk Threat Research Team (STRT) showcases a year's evolution of QakBot. We also dive into\r\na recent change in tradecraft meant to evade security controls. Last, we reverse engineered the QakBot loader to\r\nshowcase some of its functions.\r\nIntroduction\r\nIn February 2022 Microsoft pushed an update to disable macros by default in Office products. A huge win within\r\nthe industry is to prevent the vast amount of initial access vectors into an organization. It wasn’t long before\r\nadversaries began to update their tradecraft to use everything except macros. Similar to what was mentioned by\r\nBleeping Computer in February, DarkReading mentioned in this article, the change went to HTML Applications\r\n(.hta) and was very successful. Over time, we began to hear of Mark-of-the-Web (MOTW) bypasses. Windows\r\nMOTW is a simple feature in the OS that labels items and scrutinizes them as they are downloaded. As outlined\r\nby Outflank in 2020, the role of MOTW in security measures is used by Windows SmartScreen, and Protected\r\nview sandbox in Excel and Word, to name a few. How does an adversary bypass these controls? Some\r\ndownloaded files do not get scrutinized, therefore evading MOTW and allowing for process execution. One\r\npopular format that we see today includes the delivery of ISO files within an HTML file. Most containers, like\r\nISO or VHDX, are not scrutinized by MOTW.\r\nWant to simulate Mark of the Web Bypasses? Check out Atomic Red Team T1553.005.\r\nBelow is a timeline of changes from June to October. Proxylife monitors and tracks QakBot campaigns and daily\r\nshares the indicators for each campaign. We began looking at how QakBot operated in June, four months after\r\nMicrosoft disabled macros, and we can see the pattern of using .html files with embedded zip, and img files.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 1 of 23\n\nThe simple flow chart below shows the basic infection flow of this QakBot sample.\r\nTo follow this evolution we monitor Proxylife as well as other sources (Proxylife monitors Qakbot’s evolution and\r\nshares campaign indicators).\r\nBased on this and other sources, below is a timeline of changes from June to October captured by Proxylife\r\nupdates. We began looking at how QakBot operated in June, four months after Microsoft disabled macros, and we\r\ncan see the pattern of using .html files with embedded zip and img files.\r\nImmediately following, we see that on June 13, 2022 the campaign changed to using HTML smuggling with an\r\nembedded ZIP+.LNK file. Adversaries change their tradecraft frequently when attempting to see what sticks as far\r\nas evasion goes, and this is a great view into that.\r\n \r\nReference tweet\r\nJumping forward three months, we can see the more widespread use of HTML smuggling with ZIP and ISO\r\nattachments. In this particular sample, the .LNK will execute a javascript file that loads the .cmd (batch script) to\r\ncontinue on.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 2 of 23\n\nReference tweet\r\nWhile reviewing the QakBot samples outlined above, we found a particularly distinct sample that was being\r\nutilized. Once we began digging into the HTML we noticed that it had evasive techniques built in that piqued our\r\ninterest. We found that ProxyLife had shared this sample on Twitter, along with the other campaigns that utilized\r\nHTML smuggling, along with a password-protected zip that contained the ISO.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 3 of 23\n\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 4 of 23\n\nReference tweet\r\nWhat we don’t see here is the functionality being used to evade controls. It’s easy to say “HTML smuggling” or\r\n“ISO containers”, but what is the core behavior underneath it all that is making each of these different?\r\nReverse Base64 html file (2nd stage)\r\n2nd stage contained embedded password protected zip file\r\nISO file contained within Zip, including LNK and QakBot loader\r\nWe will explore this sample and showcase everything in more detail.\r\nHTML smuggling\r\nThis has become the de facto standard for the delivery of malicious payloads as of late. What is HTML\r\nsmuggling? As defined by MITRE ATT\u0026CK T1027.006, “HTML documents can store large binary objects known\r\nas JavaScript blobs (immutable data that represents raw bytes) that can later be constructed into file-like objects.\r\nData may also be stored in Data URLs, which enable embedding media type or MIME files inline of HTML\r\ndocuments.”\r\nBelow we showcase two ways to view these campaigns, one from the victim perspective and the other from within\r\nthe code.\r\nVictim Perspective\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 5 of 23\n\nFor the end user, this particular sample requires the downloading and opening of the HTML file. Once opened, the\r\nattachment.zip saves to disk, and the end user must now enter the password to decrypt the contents. Once\r\ndecrypted, mount the ISO (by double-clicking) and finally click the A.LNK file.\r\nView Within Code\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 6 of 23\n\n(For a larger resolution of this diagram visit this link)\r\nStage 1 HTML\r\nThis HTML file contains a reversed base64 encoded string initialized in div id = “MS860aTc” which contains the\r\nstage 2 javascript. To be able to execute this stage 2 javascript, it creates an HTML element with the tag “embed”\r\nthat will be appended to the code body of this HTML using “document.body.appendChild(element)”. The width\r\nand height frame properties of the “embed” element are also hidden (value = 1) to hide the stage 2 javascript\r\nexecution from the user.\r\nFigure 1 is the screenshot of the main code of the stage 1 HTML file with annotations\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 7 of 23\n\nFigure 1\r\nStage2 HTML File\r\nThe stage 2 HTML contains javascript that will decode a base64 encoded (password protected) zip file initialized\r\nin variable “gdhpoIyu”. After decoding, it will try to convert the decoded base64 data into an unsigned integer\r\nbyte array that will be used to create a blob file object as a ZIP file. Then it will use a javascript static method\r\nURL.CreateObjectURL with the new blob file object as a parameter that will be loaded using the\r\nwindows.location.assign() method.\r\nFigure 2 shows the stage 2 HTML javascript code and the portion of the base64 encoded zip file that contains the\r\nmalicious ISO file.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 8 of 23\n\nFigure 2\r\nFigure 3 shows the effect of the stage 2 HTML file as you run the main HTML (stage 1). Notice that it\r\nautomatically dropped the zip file in the compromised host.\r\nFigure 3\r\nISO File\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 9 of 23\n\nOnce the ZIP is extracted and decrypted using the password “PG1”, we will be able to get the “A7490.iso” that\r\ncontains an A.LNK file and a hidden tools folder.\r\nHidden Folder Contents\r\nWithin the hidden tools folder is protracted.cmd (bat file) and the malicious bucketfuls.dat (.dll) that will be\r\nloaded.\r\nLNK and Batch Script\r\nTo the victim, the .LNK will be the only thing inside the ISO as the tools directory is hidden.\r\nBelow is the breakdown of the two files which showcases how the adversary attempts to evade detection.\r\nLNK\r\nWithin the LNK it gives away the .cmd file that will run from within the hidden tools directory -\r\nNote the re gs and v arguments, at first glance it doesn’t make sense and seems out of place until we look at the\r\n.cmd file.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 10 of 23\n\nFigure 4\r\nThe .cmd file uses a few tricks to evade controls. First, lines 4-7 are using set, which will _set_ environment\r\nvariables for the different strings. On line 6 we see the % symbols, which are passed in from the LNK file (re gs v)\r\nto complete the regsvr32.exe process name.\r\nLine 9 will set “copy” as a variable. The final call on line 16 will now look like this:\r\nThis will copy regsvr32.exe from system32 to the \\appdata\\local\\temp directory and rename regsvr32.exe to\r\nenvelopingConcussion.com.\r\nNow, envelopingConcussion.com will run tools\\bucketfuls.dat.\r\nIn Splunk:\r\nFigure 5\r\nNow we will switch gears and dive into the different QakBot capabilities found within the DLL that gets loaded.\r\nSystem Owner/User Discovery\r\nFigure 6 is a screenshot of QakBot code that will execute several Windows commands to collect system and\r\nnetwork information that will be sent to the remote C2 server.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 11 of 23\n\nFigure 6\r\nThe table below is the complete list of the Windows commands that it will execute on the compromised host.\r\nTable 1\r\nThis event can be seen using the Sysmon event logs in Splunk. Figure 7 shows how the QakBot malware injected\r\nin the wermgr.exe process executes the following Windows native commands that we’ve listed in the above table.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 12 of 23\n\nFigure 7\r\nAs part of this Tactic, it will also execute several WMI query commands to gain more system information about\r\nthe compromised host. Table 2 shows the list of WMI classes it uses in its WMI query to collect more information.\r\nTable 2\r\nAdditionally, it will also make Windows API calls to get the computer name, system metrics, Active Directory\r\ndomain status, system info, all processes and its modules, windows architecture (x32/x64), and OS version.\r\nFigure 8 shows a code snippet of how it gets the computer name and the volume information of the compromised\r\nhost.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 13 of 23\n\nFigure 8\r\nFigure 9 shows the short code snippet of how it sets up and executes the WMI command listed in the table above\r\nto perform system discovery on the compromised host.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 14 of 23\n\nFigure 9\r\nPersistence\r\nQakBot will also create a registry run key entry or Scheduled Task to execute itself upon the reboot of the\r\ncompromised host. Figure 10 shows the code snippet of this sample that creates scheduled tasks or creates registry\r\nrun keys.\r\nFigure 10\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 15 of 23\n\nWe also saw a function in its code capable of creating services for its malicious code to gain privileges or persist\r\non the target host machine. Unfortunately, this TTP was not triggered during our testing. Figure 11 is a screenshot\r\nof how it registers a service control handler for its file.\r\nFigure 11\r\nExecution\r\nThis QakBot sample can execute the dropped .DLL copy of itself or a .DLL plugin downloaded from its\r\nCommand and Control (C2) server using several techniques available in Windows Operating System such as\r\nLiving on The Land Application (LOLBIN) or through scripts.\r\nFigure 12 shows how it uses the WMI command in .VBScript to copy files.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 16 of 23\n\nFigure 12\r\nBelow is a short table of commands we saw during our analysis for its Execution Tactics\r\nTable 3\r\nDefense Evasion, Privilege Escalation - Process Injection\r\nWhen The .DLL stager or the .DLL loader is executed by the .batch script inside the .ISO file using regsvr32.exe,\r\nIt will inject its malicious code to a legitimate Windows OS process to perform defense evasion.\r\nFigure 13 shows the code and how it creates a suspended process (the wermgr.exe) as the first step of the process\r\nhollowing technique.\r\nFigure 13\r\nAfter creating a suspended process, it will create a new section on that process that can fit its QakBot .DLL code.\r\nThen, it will map and allocate memory pages on that section and write its malicious code on that mapped section\r\nusing WriteProcessMemory() API. Figure 13.1 is the code snippet of this process.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 17 of 23\n\nFigure 13.1\r\nBelow is the list of possible processes where it can inject the QakBot core .DLL during its executions:\r\n%SystemRoot%\\SysWOW64\\OneDriveSetup.exe\r\n%SystemRoot%\\SysWOW64\\dxdiag.exe\r\n%SystemRoot%\\SysWOW64\\explorer.exe\r\n%SystemRoot%\\SysWOW64\\mobsync.exe\r\n%SystemRoot%\\SysWOW64\\msra.exe\r\n%SystemRoot%\\SysWOW64\\wermgr.exe\r\n%SystemRoot%\\SysWOW64\\xwizard.exe\r\n%SystemRoot%\\System32\\OneDriveSetup.exe\r\n%SystemRoot%\\System32\\dxdiag.exe\r\n%SystemRoot%\\System32\\mobsync.exe\r\n%SystemRoot%\\System32\\msra.exe\r\n%SystemRoot%\\System32\\wermgr.exe\r\n%SystemRoot%\\System32\\xwizard.exe\r\n%SystemRoot%\\explorer.exe\r\nAnti-Analysis and Anti-Debugging\r\nAside from Process Injections, it also has several functions that check if it is being debugged, being run in a\r\nsandbox, or being analyzed in a research lab.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 18 of 23\n\nThis QakBot variant has 2 conditions that serve as a killswitch for its execution.\r\n1. It checks if the file “C:\\INTERNAL\\__empty” exists. This file can be used to check the existence of\r\nWindows Defender emulation. If this file exists it will right away return 0 that will exit its code execution.\r\n2. The second one is checking the environment variable “SELF_TEST_1”. If this environment variable\r\nexists it will exit the process.\r\nFigure 14 shows the screenshots of its code that checks the following killswitch\r\nFigure 14\r\nFigure 15 shows its code snippet and how it checks if its code is being debugged using the Process Environment\r\nBlock Structure. If the BeingDebugged flag is True, it will xor encrypt the 2 decryption key tables in addresses\r\n0x1001E16B0 and 0x1001E050 then exit its process.\r\n \r\nFigure 15\r\nIt also enumerates all the running processes on the compromised host and checks if one of those processes is on\r\nthe list below (Table 4) which is related to security, malware analysis tools, and sandbox.\r\nTable 4\r\nIt also has a list of processes it checks (Table 5) related to antivirus products such as AVG, Dr. Web, Fortinet,\r\nTrendMicro, F-Secure, ByteFence Anti-Malware, BitDefender, Avast, Windows Defender, Comodo Internet\r\nSecurity and ESET.\r\nTable 5\r\nIt also checks antivirus .DLL’s component if it is loaded on the compromised host. Figure 16 shows the function\r\nthat checks if the Avast module (awshooka.dll and aswhookx.dll) is installed or running on the compromised host.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 19 of 23\n\nFigure 16\r\nCommand and Control (C2)\r\nThis malware is capable of communicating to its C2 server to send the collected data in the compromised\r\nWindows OS and also to download configuration files, plugins, or other malware.\r\nFigure 17 shows the code snippet that contains a function renamed as “mw_internet_crack_send_request” that will\r\nsend a request to its C2 using HttpSendRequestA() API. Then it will be followed by another function that will read\r\nthe reply from the HTTP Request and save it to a file that could be either a configuration file or other malware to\r\nbe executed in the target or compromised host.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 20 of 23\n\nFigure 17\r\nThis malware also uses a named pipe to communicate to its other process running on the compromised host.\r\nFigure 18 is a code snippet showing how it creates named pipes and reads data or files sent or transferred on that\r\nrandomly generated named pipe.\r\nFigure 18\r\nFigure 19 shows how Sysmon Event=17, 18 (CreateNamedPipe And ConnectNamedPipe) captured the creation\r\nand connection of the injected QakBot in legitimate wermgr.exe process to its randomly generated named pipe.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 21 of 23\n\n`sysmon` EventCode IN (17, 18) Image= \"*\\\\wermgr.exe\" EventType IN ( \"CreatePipe\", \"ConnectPipe\")\r\n| stats min(_time) as firstTime max(_time) as lastTime count by Image EventType ProcessGuid ProcessId PipeName\r\n| `security_content_ctime(firstTime)`\r\n| `security_content_ctime(lastTime)`\r\nFigure 19\r\nIn addition to all this, we are also sharing the decrypted data section of this QakBot variant that contains more\r\nTTPs.\r\nhttps://gist.github.com/tccontre/360dbda059562b67b983d58ae70ac371\r\nAs defenders, it doesn’t end here. QakBot and other frameworks will continue to improve, evading next-generation controls in place. We must continue to dissolve these loaders into their smallest form and share with the\r\ngreater security community their tradecraft to help everyone defend their organization.\r\nAutomate with Splunk SOAR Playbooks\r\nAll of the previously listed detections create entries in the risk index by default, and can be used seamlessly with\r\nrisk notables and the Risk Notable Playbook Pack. The community Splunk SOAR playbooks below can be used in\r\nconjunction with some of the previously described analytics:\r\nDetection\r\nSplunk Threat Research Team has curated new and old analytics and tagged them to the QakBot Analytic Story to\r\nhelp security analysts detect adversaries leveraging the QakBot malware. This analytic story introduces 43\r\ndetections across MITRE ATT\u0026CK techniques.\r\nFor this release, we used and considered the relevant data endpoint telemetry sources such as:\r\nProcess Execution \u0026 Command Line Logging\r\nWindows Security Event Id 4688, Sysmon, or any Common Information Model compliant EDR\r\ntechnology.\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 22 of 23\n\nWindows Security Event Log\r\nWindows System Event Log\r\nWhy Should You Care?\r\nWith this article the Splunk Threat Research Team (STRT) enables security analysts, blue teamers and Splunk\r\ncustomers to identify one of the CISA TOP malware strains . This article helps the community discover QakBot\r\ntactics, techniques and procedures. By understanding QakBot behaviors, we were able to generate telemetry and\r\ndatasets to develop and test Splunk detection analytics designed to defend and respond against this threat.\r\nLearn More\r\nYou can find the latest content about security analytic stories on GitHub and in Splunkbase. Splunk Security\r\nEssentials also has all of these detections available now.\r\nFor a full list of security content, check out the release notes on Splunk Docs.\r\nFeedback\r\nAny feedback or requests? Feel free to put in an issue on GitHub and we’ll follow up. Alternatively, join us on the\r\nSlack channel #security-research. Follow these instructions if you need an invitation to our Splunk user groups on\r\nSlack.\r\nContributors\r\nWe would like to thank the authors Teoderick Contreras, Michael Haag and collaborators Lou Stella, Mauricio\r\nVelazco, Rod Soto, Jose Hernandez, Patrick Bareiss, Bhavin Patel, and Eric McGinnis for their contributions to\r\nthis post.\r\nWe would like to extend a huge thank you to @proxylife for sharing his research and this malware sample that\r\nhelped the STRT produce this analysis.\r\nSource: https://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nhttps://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html\r\nPage 23 of 23",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.splunk.com/en_us/blog/security/from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html"
	],
	"report_names": [
		"from-macros-to-no-macros-continuous-malware-improvements-by-qakbot.html"
	],
	"threat_actors": [
		{
			"id": "dfee8b2e-d6b9-4143-a0d9-ca39396dd3bf",
			"created_at": "2022-10-25T16:07:24.467088Z",
			"updated_at": "2026-04-10T02:00:05.000485Z",
			"deleted_at": null,
			"main_name": "Circles",
			"aliases": [],
			"source_name": "ETDA:Circles",
			"tools": [],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434813,
	"ts_updated_at": 1775791457,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/4e234f6d82adf98bd26de5c5fcd3c216b960dea4.pdf",
		"text": "https://archive.orkl.eu/4e234f6d82adf98bd26de5c5fcd3c216b960dea4.txt",
		"img": "https://archive.orkl.eu/4e234f6d82adf98bd26de5c5fcd3c216b960dea4.jpg"
	}
}