{
	"id": "808c6295-1f73-42ac-8fb1-9cebf3dcb30f",
	"created_at": "2026-04-06T00:11:13.823517Z",
	"updated_at": "2026-04-10T03:21:28.642319Z",
	"deleted_at": null,
	"sha1_hash": "dedf2a36e364e2f2dea3f37663c4f983ff19606f",
	"title": "Research Spotlight: The Resurgence of Qbot",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 656114,
	"plain_text": "Research Spotlight: The Resurgence of Qbot\r\nBy Earl Carter\r\nPublished: 2016-04-28 · Archived: 2026-04-05 13:49:53 UTC\r\nThursday, April 28, 2016 17:05\r\nThe post was authored by Ben Baker.\r\nQbot, AKA Qakbot, has been around for since at least 2008, but it recently experienced a large surge in\r\ndevelopment and deployments. Qbot primarily targets sensitive information like banking credentials. Here we are\r\nunveiling recent changes to the malware that haven’t been made public yet.\r\nQbot’s primary means of infection is as a payload in browser exploit kits. Website administrators often use FTP to\r\naccess their servers, so Qbot attempts to steal FTP credentials to add these servers to its malware hosting\r\ninfrastructure. Qbot can also spread across a network using SMB, which makes it very difficult to remove from an\r\nunprotected network.\r\nPacker\r\nQbot uses a packer that can change drastically between samples. The packer’s strings and code blocks are\r\nrandomized in ways that make it difficult to create a detection signature. Randomization is a common theme in\r\nQbot since filenames, domain names, and encryption keys are randomly generated.\r\nThankfully, the code obfuscation doesn’t complicate the behavior of the packer’s code. The unpacking code\r\nconsistently built an entire PE file in memory (likely an MD5 match with the original unpacked executable), then\r\nused a custom loader to execute the unpacked file. The unpacked executable could be reliably extracted from\r\nmemory when the loader called the Windows API VirtualProtect. Since the unpacking code uses VirtualProtect to\r\nenable execution for the unpacked memory sections, it is possible to dump the unpacked code before it is given a\r\nchance to execute and infect the VM.\r\nWe took advantage of the packer’s predictability by using a Pykd script to debug each packed file. We set a\r\nbreakpoint on VirtualProtect, then scan the process’s memory to dump the unpacked executable. We terminate the\r\nprocess before the unpacked code runs, so the VM shouldn’t need to be reverted between samples. This script\r\nunpacks multiple samples per second, enabling us to unpack large numbers of samples.\r\nWe analyzed 618 packed samples, which unpacked to 73 unique samples. Each sample is packed multiple\r\ndifferent ways to make hash signatures less effective.\r\nInstallation\r\nOnce the packer finishes loading the unpacked executable in memory, Qbot checks to see if it has already been\r\ninstalled. If Qbot is not running from “%appdata%\\Microsoft\\[RandomName]\\ [RandomName].exe”, it copies\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 1 of 9\n\nitself there and executes the copy.\r\nQbot generates random strings by seeding a Mersenne Twister random number generator with the CRC32\r\nchecksum of a string or SHA1 hash, then repeatedly generating random integers to use as indices in an alphabet\r\narray to pick letters. The name of the install folder is generated using a seed generated from the ProductId (found\r\nin HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductId), the name of the\r\ncomputer (found via the Windows API GetComputerNameA), and the hard drive serial number (found via the\r\nWindows API GetVolumeInformationA).\r\nQbot uses a deterministic string generator which makes it so the sample will always generate the same filenames\r\nand mutexes if it’s run on the same computer. For example, if a sandbox uses static Product ID, Computer Name,\r\nand Volume serial numbers, the filenames will appear static even though they would be different for any other\r\ncomputer. This makes it difficult to create generic IOCs for customers, but easy to create sandbox IOCs for\r\nidentifying Qbot.\r\nOnce Qbot is executed in its install directory, it executes a new instance of the Windows executable\r\n“Explorer.exe”. The injected process loads the resource “IDB_BITMAP1” which contains a malicious DLL. The\r\nresource is decrypted using the first 20 bytes as an RC4 key. The decrypted data contains the DLL in a compressed\r\nform, preceded by the SHA1 hash of the compressed data.\r\nThe compression appears to be custom, but is similar to LZSS with offset-length pairs pointing to bytes in the\r\nexisting decompressed data as a dictionary. Files are broken into compressed blocks, each starting with a 24 byte\r\nheader in the form of:\r\nMagic Bytes[8]: “\\x61\\x6C\\xD3\\x1A\\x00\\x00\\x00\\x01”\r\nCompressed Data Size[4]\r\nCompressed Data CRC32[4]\r\nDecompressed Data Size[4]\r\nDecompressed Data CRC32[4]\r\nThe DLL is broken into 3 compressed blocks, which means Qbot checks 6 CRC32 checksums along with the\r\nSHA1 hash from when it was first decrypted. That’s a lot of error checking just to load one DLL.\r\nLogging\r\nQbot logs to an encrypted file in the install path. The log file can be identified as having a DLL extension, and a\r\nfilename one letter short of the directory name where Qbot is installed in. For example, if Qbot is installed in\r\n“%appdata%\\Microsoft\\Oykyjxjx”, the log file will be “%appdata%\\Microsoft\\oykyjxjx\\oykyjxj.dll”. The log file\r\nis encrypted with an RC4 key generated by converting the folder name to lowercase, then taking the SHA1 hash\r\nof the resulting string.\r\nWe’ve created a short Python script for decrypting the log file so incident responders can get additional\r\ninformation about infections. This will print out configuration information including initial infection time and FTP\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 2 of 9\n\nexfil server information.\r\nUpdater\r\nQbot updates itself using an obfuscated script with the extension “.wpl”. This script attempts to download an\r\nencrypted executable hosted from numerous domains in URIs like\r\n\"http[:]//\u003cmaliciousdomain.com\u003e/viewtopic.php\". The script hex decodes the server response, then uses the first\r\n20 bytes as an RC4 key to decrypt the remaining bytes. The decrypted buffer contains a 20-byte SHA1 hash,\r\nfollowed by the updated version of the Qbot executable.\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 3 of 9\n\nInfo Theft\r\nQbot primarily targets sensitive information like banking credentials. It does so by stealing data like stored\r\ncookies or credentials, and by injecting code into web browsers to manipulate live browsing sessions. Qbot lets\r\nmalicious actors piggyback on the victim’s browsing sessions, enabling them to bypass security like simple\r\nimplementations of two-factor authentication.\r\nQbot recently added Webinjects to its arsenal of info stealing techniques. Webinjects, commonly associated with\r\nZeus and Spyeye, make it easy to inject malicious javascript in browser sessions while logging or redirecting the\r\nvictim’s activity. Webinjects can be very powerful, in some cases automating large banking transactions without\r\nany interaction from the user.\r\nQbot contains code for parsing advanced Webinjects like automated transfers, but all 618 Qbot samples we\r\nanalyzed simply redirected the browsers when the victim attempts to logout of an online banking page. Stolen\r\ncookies and session tokens remain active for much longer if the victim is unable to logout of the targeted sites.\r\nSample Qbot Webinject config:\r\n“set_url https://*.\u003cBankDomain\u003e.com/*logoff* GPR http://\u003cMaliciousSite\u003e/fakes/onlineserv_cm_logoff.html”\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 4 of 9\n\nIn this example of a Webinject, any hooked browser attempting to navigate to the logoff page for the targeted bank\r\nwould be intercepted. The “GPR” flags indicate GETs and POSTs will be intercepted and Redirected to the\r\nmalicious URL. This R flag seems to be rarely used by other malware that support Webinjects. Malware forum\r\nposts about Webinjects focus mainly on injecting malicious code or simply logging HTTPS parameters like\r\ncredentials.\r\nCommand and Control\r\nFTP Exfil\r\nQbot exfiltrates data over FTP to a list of servers hardcoded in its config file. The exfil files are compressed, then\r\nRC4 encrypted with a randomly generated key, similar to how resources are encrypted inside the executables. I’m\r\nintentionally leaving out how to decrypt these files, since disclosing that info could enable anyone to retrieve\r\nsensitive information stolen by Qbot.\r\nThe exfil files are uploaded to the FTP servers with file names like “article_covezh618946_1450458170.zip”\r\nwhere “article” is hard coded, “covezh618946” is  randomly generated, and 1450458170 is seconds since Linux\r\nEpoch (Dec 18, 2015 in this case).\r\nThe decrypted exfil file contains a lot of information about the victim’s machine, a chunk of which is formed with\r\na call to the function wvnsprintf using the format string:\r\n\" ext_ip=[%s] dnsname=[%s] hostname=[%s] user=[%s] domain=[%s] is_admin=[%s] os=[%s] qbot_version=\r\n[%s] install_time= %s] exe=[%s]\"\r\nThe qbot_version string is generated by a previous call to wvnsprintf using the format string \"%04x.%u\" with\r\nparameters that trace back to the first 2 DWORDs in the data section. Extracting these DWORDs directly proved\r\nto be an easy and consistent way to extract Qbot’s version information without running the malware.\r\nHTTP DGA\r\nQbot's DGA generates a string like \"2.mar.2016.00000001\" where 00000001 is constant and the first digit is the\r\ntens digit of the day of the month (though 2 is also used for days 30 and 31). This means there are only 3 DGA\r\nseeds for each month. Qbot gets the date by sending an innocent looking HTTP request to Google, and parsing the\r\ndate from the HTTP 301 response.\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 5 of 9\n\nThe date string is CRC32 checksummed and used as a seed for the Mersenne Twister random number generator,\r\nwhich Qbot uses to create a predictable list of domains. Qbot generates a list of 5 domains at a time, and randomly\r\npicks from them until it finds an active domain. If none of the first set of domains are active, it will generate a new\r\nset and repeat as necessary.\r\nQbot checks DNS responses for any strings containing \"sinkhole\" or \".csof.net\" and skips those results. It also\r\nchecks for monitoring tools like Wireshark, and will alter the seed if any are found. The altered seed causes the\r\nmalware to generate a fake list of domains.\r\nEvolution\r\nWe automated unpacking 618 Qbot samples via Pykd, then created Python scripts to decrypt and decompress the\r\nembedded resources. We extracted DLLs and config data, as well as Qbot version information and Compile Times\r\nfor each file. Compile times are often used to attribute malicious activity, though it is important to note compile\r\ntimes can be manipulated.\r\nQbot compile times show a surge of activity in January and February, when developers released multiple versions\r\nper day on at least 4 days during this period. Qbot’s authors appear to have stopped development on 3/08/2016,\r\nalthough their servers continued to host Qbot executables packed as late as 3/25/2016.\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 6 of 9\n\nThis graph shows 132 unique compile timestamps showing time of day for each binary. The unpacked binaries all\r\nhave compile times between 6am and 8pm GMT. This time distribution looks more like a full-time job than a side\r\nproject. The packed binaries have compile times with a lot more variance, suggesting the packing is either done by\r\nanother person with a much more flexible schedule or with the assistance of some kind of automation. Developing\r\nsource code requires a lot more experience than running a packing tool, so packing could be done by less\r\ntechnically skilled members of the team.\r\nThe packed compile times mostly fall between 8am and 10pm GMT, 2 hours shifted from the average work day\r\nfor the unpacked samples. If the packing process was completely automated, we would expect to see these\r\ncompile times distributed more randomly (with some binaries compiled between midnight and 6am) or with a\r\npredictable schedule such as once a day at a specific time.\r\n55% of packed binaries have compile timestamps within the range of 2h3m and 2h6m after their unpacked\r\ncounterparts. This consistency of time shift may mean these files were packed according to a very consistent\r\nprocess that takes just over 2 hours, or that the computer doing the packing could have its system clock off by 2\r\nhours.\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 7 of 9\n\nThis graph shows the day of the week using offsets from Sunday (e.g. 1 = Monday, 2 = Tuesday, etc.). The\r\ncompile times for the unpacked binaries form a nice Monday-Friday work week. Over this 17 week period, only\r\none set of binaries was compiled during a weekend.\r\nThe packed binaries continue to show a much greater variance in compile times, with binaries compiled on 6\r\nSaturdays in a row. There is at least one packed binary compiled per day between Jan 27 and Feb 6, showing work\r\non 11 consecutive days.\r\nWe also analyzed the Rich Headers associated with Qbot binaries. Rich Headers are undocumented sections in\r\nVisual Studio executables that contain information about the compiler and linker version used to build the\r\nexecutable. Rich Headers can vary greatly between two seemingly identical development environments, so they\r\nmay give clues into how many computers are used in a development project.\r\nThe 154 unpacked binaries contained only 6 unique Rich Headers in, some of which were almost identical and\r\nwere likely caused by minor compiler updates on the same computer. These headers suggest the unpacked binaries\r\nwere compiled in 3 unique environments (likely different computers or Virtual Machines). The packed binaries\r\ncontained 44 unique Rich Headers, 35 of which seemed to be slight variants of the others. The packed binaries\r\nappear to be compiled from 9 unique environments, none of which matched the 3 Rich Headers from the\r\nunpacked binaries.\r\nThe differences in these Rich Headers further supports the theory that packing is done on different computers than\r\nthe ones that develop and compile the main Qbot source code. The Rich Header data suggests there are 12 unique\r\nenvironments for compiling and packing binaries, which could give a hint to the size of the team developing and\r\npacking Qbot.\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 8 of 9\n\nDeveloping and maintaining malware and a malicious infrastructure requires a lot of time and effort. The\r\nmalicious actors behind large scale crimeware like Qbot work as a team, and approach their nefarious activities as\r\na full time job.\r\nCoverage\r\nFor the most current rule information, please refer to your Defense Center, FireSIGHT Management Center or\r\nSnort.org.\r\nAdvanced Malware Protection (AMP) is ideally suited to prevent the execution of the malware used by these\r\nthreat actors.\r\nCWS or WSA web scanning prevents access to malicious websites and detects malware used in these attacks.\r\nThe Network Security protection of IPS and NGFW have up-to-date signatures to detect malicious network\r\nactivity by threat actors.\r\nSource: https://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nhttps://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.talosintelligence.com/2016/04/qbot-on-the-rise.html"
	],
	"report_names": [
		"qbot-on-the-rise.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434273,
	"ts_updated_at": 1775791288,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/dedf2a36e364e2f2dea3f37663c4f983ff19606f.pdf",
		"text": "https://archive.orkl.eu/dedf2a36e364e2f2dea3f37663c4f983ff19606f.txt",
		"img": "https://archive.orkl.eu/dedf2a36e364e2f2dea3f37663c4f983ff19606f.jpg"
	}
}