{
	"id": "1e00bc18-5bf3-4e59-a455-c7c02db790bd",
	"created_at": "2026-04-06T00:12:55.972004Z",
	"updated_at": "2026-04-10T03:22:08.857277Z",
	"deleted_at": null,
	"sha1_hash": "234f760f133204e9942569c02da002f12cfcbd53",
	"title": "Deep Analysis of QBot Banking Trojan",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1068662,
	"plain_text": "Deep Analysis of QBot Banking Trojan\r\nBy Abdallah Elshinbary\r\nPublished: 2020-07-15 · Archived: 2026-04-05 22:00:02 UTC\r\nQBot is a modular information stealer also known as Qakbot or Pinkslipbot. It has been active for years since\r\n2007. It has historically been known as a banking Trojan, meaning that it steals financial data from infected\r\nsystems.\r\nInfection FlowPermalink\r\nQBot can be delivered in various different ways including Malspam (Malicious Spam) or dropped by other\r\nmalware families like Emotet.\r\nThe infection flow for this campaign is as follows:\r\nFirst, the victim receives a phishing email with a link to a malicious zip file.\r\nThe zip file contains a very obfuscated VBS file which downloads and launches Qbot executable.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 1 of 23\n\nThe VBS file tries to download Qbot from different places:\r\nhttp://st29[.]ru/tbzirttmcnmb/88888888.png\r\nhttp://restaurantbrighton[.]ru/uyqcb/88888888.png\r\nhttp://royalapartments[.]pl/vtjwwoqxaix/88888888.png\r\nhttp://alergeny.dietapacjenta[.]pl/pgaakzs/88888888.png\r\nhttp://egyorg[.]com/vxvipjfembb/88888888.png\r\nNotice the misleading URL, it looks like it’s downloading a PNG image but the raw data says something else.\r\nUnpackingPermalink\r\nQBot is packed with a custom packer, but the unpacking process is really simple. It allocates memory for the\r\nunpacked code using VirtualAlloc() and changes memory protection using VirtualProtect() . So we just\r\nneed 2 breakpoints at VirtualAlloc() and VirtualProtect() .\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 2 of 23\n\nEncrypted StringsPermalink\r\nMost of QBot strings are encrypted (stored in a continuous blob) and they are decrypted on demand. The\r\ndecryption routine accepts one argument which is the index to the string then it XORs it with a hardcoded bytes\r\narray until it encounters a null byte.\r\nWe can use IDAPython to decrypt the strings and add them as comments.\r\nimport idc\r\nimport idautils\r\ndec_routine = 0x4065B7\r\nenc_strings = 0x40B930\r\nbytes_arr = 0x410120\r\ndef decrypt_string(idx):\r\n if idx \u003e= 0x36F4:\r\n return # out of bounds\r\n res = \"\"\r\n while True:\r\n c = idc.get_wide_byte(enc_strings+idx) ^ idc.get_wide_byte(bytes_arr + (idx\u00260x3F))\r\n if c == 0: break\r\n res += chr(c)\r\n idx += 1\r\n return res\r\nxrefs = idautils.CodeRefsTo(dec_routine, 0)\r\nfor x in xrefs:\r\n ea = idc.prev_head(x)\r\n t = idc.get_operand_type(ea, 1)\r\n if t == idc.o_imm:\r\n idx = idc.get_operand_value(ea, 1)\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 3 of 23\n\ndec = decrypt_string(idx)\r\n idc.set_cmt(ea, dec, 1)\r\nAnd here is the result, that’s much easier to work with.\r\nThis should take care of most of the strings, the rest of strings indexes are calculated dynamically at runtime.\r\nWe decrypt all strings by looping through the encrypted blob and decrypt strings one by one.\r\nidx = 0\r\nwhile idx \u003c 0x36F4:\r\n dec = decrypt_string(idx)\r\n idx += len(dec)+1\r\n print(dec)\r\nAnti-AnalysisPermalink\r\nQBot spawns a new process of itself with the \"/C\" parameter, this process is responsible for doing Anti-Analysis\r\nchecks.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 4 of 23\n\nThe parent process checks the exit code of this spawned process. If the exit code is not 0, it means that QBot is\r\nbeing analyzed (and so it exits).\r\nSo let’s go over the anti-analysis techniques.\r\nChecking VMPermalink\r\nIn VMWare, communication with the host is done through a specific I/O port (0x5658) , so QBot uses the in\r\nassembly instruction to detect VMWare by reading from this port and checking the return value in ebx if it’s\r\nequal to VMXh (VMware magic value).\r\nIf we are outside VMWare, a privilege error occurs and this code will return 0.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 5 of 23\n\nAnother Anti-VM trick is to check hardware devices against known devices names used by VMs and Sandboxes.\r\nHere is the list of devices names.\r\nExpand to see more\r\n  VMware Pointing\r\n  VMware Accelerated\r\n  VMware SCSI\r\n  VMware SVGA\r\n  VMware Replay\r\n  VMware server memory\r\nChecking ProcessesPermalink\r\nQBot loops through running processes and compares their executable names against known analysis tools.\r\nExpand to see more\r\n  Fiddler.exe\r\n  samp1e.exe\r\n  sample.exe\r\n  runsample.exe\r\n  lordpe.exe\r\n  regshot.exe\r\nChecking DLLsPermalink\r\nSandbox detection can be done by enumerating loaded DLLs and comparing them against known DLLs used by\r\nsandboxes. Here it’s just using 2 of them.\r\nivm-inject.dll # Buster Sandbox Analyzer\r\nSbieDll.dll # SandBoxie\r\nChecking FilenamePermalink\r\nSome sandboxes may change the sample file name. So QBot checks if its process name contains one of these\r\nstrings.\r\nsample\r\nmlwr_smpl\r\nartifact.exe\r\nChecking CPUPermalink\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 6 of 23\n\nThe last check is done using CPUID instruction. First it is executed with EAX=0 to get the CPU vendor and\r\ncompares it with GenuineIntel (Intel processor).\r\nThen it is executed with EAX=1 to get the processors features.\r\nOn a physical machine the last bit will be equal to 0. On a guest VM it will equal to 1.\r\nBack To ParentPermalink\r\nAfter the Anti-Analysis checks, QBot drops a copy of itself along with a configuration file at\r\n\"%APPDATA%\\Microsoft\\\u003crandom_folder_name\u003e\" .\r\nFinally, QBot starts the dropped copy in a new process and overwrites itself with a legitimate executable, here it’s\r\n\"calc.exe\" .\r\nConfiguration FilePermalink\r\nThe dropped configuration file is accessed frequently by Qbot, this file is RC4 encrypted. By setting a breakpoint\r\nbefore the contents of the file gets encrypted I got the following data:\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 7 of 23\n\nField Description\r\n10=spx143 Campaign ID\r\n11=2 Number of hardcoded C2\r\n1=13.59.00-24/06/2020 Date of Qbot install in HH:MM:ss-dd/mm/yyyy\r\n2=1592996340 Victim Qbot install\r\n50=1 N/A\r\n5=VgBCAE8AWABTAFYAUgA7ADIA Victim network shares\r\n38=1593047244 Last victim call to C2 (Unix time)\r\n45=187.163.101.137 C2 IP\r\n46=995 C2 port\r\n39=45.242.76.104 Victim external IP\r\n43=1593006172 Time of record (Unix time)\r\n49=1 N/A\r\nPersistencePermalink\r\nQBot achieves persistence by creating a new registry value under the key\r\n\"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" . It also registers a scheduled task that runs every 5\r\nhours.\r\nProcess InjectionPermalink\r\nQBot tries to inject its unpacked code in one of these processes (\"explorer.exe\", \"mobsync.exe\",\r\n\"iexplorer.exe\") and it uses Process Hollowing technique to achieve that.\r\nIt first starts a new suspended process with CreateProcessW() then it writes the injected code into the target\r\nprocess using ZwCreateSection() , ZwMapViewOfSection() and ZwWriteVirtualMemory() .\r\nFinally it sets the thread context to jump to the injected code and resume execution with ResumeThread() .\r\nCore ModulePermalink\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 8 of 23\n\nThe injected code loads and decrypts one of its resources \"307\" . After dumping it, I found out that it’s a DLL\r\n(this is the core module).\r\nFrom now on, we will be analyzing the core DLL of QBot.\r\nThe core module has 2 resources both RC4 encrypted.\r\nThe first resource gets loaded into memory then RC4 decrypted.\r\nThe contents of the decrypted resource are:\r\n10=spx143 (Campaign ID)\r\n3=1592482956 (Timestamp)\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 9 of 23\n\nAfter some digging, I found out how the resources are decrypted. The first 20 bytes of each resource are the RC4\r\nkey of this resource, and the rest are the actual encrypted data.\r\nSo by using this find, we can decrypt the other resource \"311\" .\r\nGreat!!! Now we have the list of C2 servers (150 servers!).\r\nThe reason there is many controllers is that these are actually just proxies of infected bots acting as intermediate\r\nnodes between the victim and the real C2 and thus hiding the backend infrastructure of the attacker.\r\nSo it works like this:\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 10 of 23\n\nC2 CommunicationPermalink\r\nQBot obfuscates its communication with the C2 server by encrypting the payloads using RC4 and encoding the\r\nresult using Base64.\r\nThe communication is also done over SSL, you can notice that the traffic has unusual certificate issuer data.\r\nWe can use Fiddler to intercept and decrypt the HTTPS traffic.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 11 of 23\n\nThe RC4 key for encrypting the payload is the SHA1 hash of the first 16 bytes of the Base64-decoded payload + a\r\nhardcoded salt (The salt is stored as an encrypted string).\r\nHere is an implementation of the decryption algorithm:\r\nHARDCODED_SALT = b\"jHxastDcds)oMc=jvh7wdUhxcsdt2\" # decrypted string\r\ndef decrypt_payload(encrypted_blob):\r\n b64_decoded = base64.b64decode(encrypted_blob)\r\n decryption_key = b64_decoded[:0x10] + HARDCODED_SALT\r\n sha1hash = hashlib.sha1()\r\n sha1hash.update(decryption_key)\r\n decryption_key_hash = sha1hash.digest()\r\n rc4 = ARC4(decryption_key_hash)\r\n return rc4.decrypt(b64_decoded[0x10:])\r\nThe decrypted payload is in JSON form.\r\nDecrypted C2 Request: {“8”:9,”1”:17,”2”:”pnmfcq111232”}\r\nDecrypted C2 Response: {“8”:5,”16”:770897804,”39”:”V4UnoDQSEblewhh63UfUqAns”,”38”:1}\r\nCommands ListPermalink\r\nAfter establishing communication, the C2 server will send commands indexes to be executed.\r\nHere is the list of commands and their corresponding indexes (I have renamed the important commands).\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 12 of 23\n\nIt’s worth mentioning that dynamic imports of the core DLL are stored in the same format as commands \"\r\n\u003caddress, API_index, DLL_index\u003e\" , the API and DLL indexes are passed to the string decryption routine which\r\nreturns their corresponding names then it uses LoadLibrary and GetProcAddress to resolve the imports.\r\nLet’s go through some of the interesting commands.\r\nCommand 13: Lateral MovementPermalink\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 13 of 23\n\nQBot can spread through the network by enumerating network shares using WNetOpenEnumW() and\r\nWNetEnumResourceW () then it drops a copy of Qbot into the shared folders.\r\nThen the dropped executable is registered as an auto-start service on the target machine. The names for the service\r\nand the dropped file are randomly generated strings.\r\nFinally, Qbot deletes the created service and dropped file from the target machine (as it’s successfully infected).\r\nCommand 21: Collecting Installed ApplicationsPermalink\r\nQBot can collect installed applications by enumeration subkeys of the registry key\r\n\"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\" .\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 14 of 23\n\nThe collected data is appended to the end of a string containing additional information about the victim’s machine\r\nand time of collection.\r\nt=i1 time=[\u003ctime_of_collect\u003e] ext_ip=[\u003cexternal_IP\u003e] dnsname=[?] hostname=[\u003ccomputer_name\u003e] user=[]\r\ndomain=[] is_admin=[\u003cYES/NO\u003e] os=[\u003cwindows_ver\u003e] qbot_version=[\u003cqbot_ver\u003e] install_time=\r\n[\u003cqbot_install_time\u003e] exe=[\u003cinjected_process\u003e] prod_id=[NULL] iface_n=[\u003cinterface_IP\u003e/\u003cinterface_IP\u003e]\r\nUP] soft=[\u003capp1;ver\u003e|\u003capp2;ver\u003e|...]\r\nExample of collected data:\r\nThen the data is RC4 encrypted and written to \"wdqlxw32.dll\" at the same directory of QBot.\r\nFinally, \"wdqlxw32.dll\" is Zlib compressed and RC4 encrypted again then it’s saved to \"cwdqlxw32.dll\" and\r\nthe original \"wdqlxw32.dll\" is deleted.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 15 of 23\n\nThe compressed file is then transfered to the C2 server (RC4 encrypted and Base64 encoded) in the key \"36\"\r\nand the compressed file \"cwdqlxw32.dll\" is also deleted.\r\nCommand 31: Fetching PluginsPermalink\r\nAs we said before, QBot is known to be a modular malware. It can load additional plugins received from the C2\r\nserver (plugins are RC4 encrypted and Base64 encoded).\r\nQBot tries to inject the received plugin in 3 different processes depending on the machine architecture.\r\nIt creates a new suspended process then writes the plugin to the process memory using WriteProcessMemory()\r\nand then resumes the injected process.\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 16 of 23\n\nAt the time of writing this, Qbot has 3 different plugins (“Password grabber”, “Cookie grabber”, “UPnP module”).\r\nConclusionPermalink\r\nQBot is considered to be a sophisticated malware, it’s receiving regular updates from time to time and it’s not\r\nlikely to go away anytime soon.\r\nThere is still more features that I didn’t cover such as WebInjects so maybe I will come back to Qbot later I guess\r\n:)\r\nIOCsPermalink\r\nHashesPermalink\r\nVBS File: b734caf792c968ca1870c3ec7dda68ad5dc47fef548751afb8509752c185a756\r\nQBot: 112a64190b9a0f356880eebf05e195f4c16407032bf89fa843fd136da6f5d515\r\nURLsPermalink\r\nhttp://st29[.]ru/tbzirttmcnmb/88888888.png\r\nhttp://restaurantbrighton[.]ru/uyqcb/88888888.png\r\nhttp://royalapartments[.]pl/vtjwwoqxaix/88888888.png\r\nhttp://alergeny.dietapacjenta[.]pl/pgaakzs/88888888.png\r\nhttp://egyorg[.]com/vxvipjfembb/88888888.png\r\nC2 DomainsPermalink\r\n39.36.254.179:995\r\n24.139.132.70:443\r\n24.202.42.48:2222\r\n72.204.242.138:443\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 17 of 23\n\n172.242.156.50:995\r\n72.204.242.138:20\r\n68.174.15.223:443\r\n74.193.197.246:443\r\n96.56.237.174:990\r\n64.19.74.29:995\r\n70.168.130.172:443\r\n189.236.166.167:443\r\n68.4.137.211:443\r\n76.187.8.160:443\r\n76.86.57.179:2222\r\n73.226.220.56:443\r\n67.250.184.157:443\r\n75.183.171.155:3389\r\n173.172.205.216:443\r\n173.3.132.17:995\r\n172.78.30.215:443\r\n207.255.161.8:32103\r\n75.137.239.211:443\r\n68.49.120.179:443\r\n206.51.202.106:50003\r\n82.127.193.151:2222\r\n207.255.161.8:2222\r\n207.255.161.8:2087\r\n24.152.219.253:995\r\n187.19.151.218:995\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 18 of 23\n\n197.37.48.37:993\r\n188.241.243.175:443\r\n72.88.119.131:443\r\n89.137.211.239:443\r\n108.30.125.94:443\r\n187.163.101.137:995\r\n100.19.7.242:443\r\n45.77.164.175:443\r\n80.240.26.178:443\r\n66.208.105.6:443\r\n207.246.75.201:443\r\n199.247.22.145:443\r\n199.247.16.80:443\r\n95.77.223.148:443\r\n68.60.221.169:465\r\n5.107.220.84:2222\r\n41.228.212.22:443\r\n86.233.4.153:2222\r\n68.200.23.189:443\r\n201.146.127.158:443\r\n79.114.199.39:443\r\n87.65.204.240:995\r\n71.74.12.34:443\r\n217.162.149.212:443\r\n195.162.106.93:2222\r\n75.165.112.82:50002\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 19 of 23\n\n201.248.102.4:2078\r\n96.41.93.96:443\r\n89.247.216.127:443\r\n84.232.238.30:443\r\n103.238.231.40:443\r\n174.34.67.106:2222\r\n98.115.138.61:443\r\n91.125.21.16:2222\r\n84.247.55.190:443\r\n193.248.44.2:2222\r\n74.135.37.79:443\r\n78.96.190.54:443\r\n86.126.97.183:2222\r\n2.50.47.97:2222\r\n68.39.160.40:443\r\n96.232.203.15:443\r\n86.144.150.29:2222\r\n71.220.191.200:443\r\n24.231.54.185:2222\r\n80.14.209.42:2222\r\n24.164.79.147:443\r\n70.183.127.6:995\r\n47.153.115.154:993\r\n184.180.157.203:2222\r\n50.104.68.223:443\r\n67.165.206.193:995\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 20 of 23\n\n200.113.201.83:993\r\n47.153.115.154:465\r\n24.42.14.241:995\r\n189.160.203.110:443\r\n188.27.76.139:443\r\n207.255.161.8:32102\r\n49.207.105.25:443\r\n71.210.177.4:443\r\n117.242.253.163:443\r\n50.244.112.106:443\r\n69.92.54.95:995\r\n41.34.91.90:995\r\n72.204.242.138:53\r\n41.97.138.74:443\r\n72.29.181.77:2078\r\n71.88.168.176:443\r\n2.50.171.142:443\r\n67.83.54.76:2222\r\n86.125.145.90:2222\r\n47.153.115.154:995\r\n24.122.157.93:443\r\n47.146.169.85:443\r\n72.181.9.163:443\r\n187.155.74.5:443\r\n71.209.187.4:443\r\n74.75.216.202:443\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 21 of 23\n\n24.44.180.236:2222\r\n24.43.22.220:993\r\n108.188.116.179:443\r\n100.4.173.223:443\r\n76.170.77.99:443\r\n70.95.118.217:443\r\n134.0.196.46:995\r\n68.225.56.31:443\r\n72.204.242.138:32102\r\n72.204.242.138:50001\r\n108.190.151.108:2222\r\n72.204.242.138:465\r\n50.244.112.10:443\r\n173.22.120.11:2222\r\n24.43.22.220:995\r\n24.43.22.220:443\r\n92.17.167.87:2222\r\n72.209.191.27:443\r\n72.204.242.138:80\r\n72.204.242.138:443\r\n71.187.170.235:443\r\n96.56.237.174:32103\r\n71.187.7.239:443\r\n184.98.104.7:995\r\n70.124.29.226:443\r\n137.99.224.198:443\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 22 of 23\n\n73.23.194.75:443\r\n151.205.102.42:443\r\n64.224.76.152:443\r\n72.204.242.138:32100\r\n173.187.101.221:443\r\n72.179.13.59:443\r\n208.93.202.49:443\r\n70.174.3.241:443\r\n96.37.137.42:443\r\n76.111.128.194:443\r\n67.209.195.198:3389\r\n61.3.184.27:443\r\n24.42.14.241:443\r\n74.56.167.31:443\r\n5.193.61.212:2222\r\n117.216.177.171:443\r\nReferencesPermalink\r\nDemystifying QBot Banking Trojan - BSides Belfast\r\nhttps://www.virusbulletin.com/virusbulletin/2017/06/vb2016-paper-diving-pinkslipbots-latest-campaign\r\nhttps://www.fortinet.com/blog/threat-research/deep-analysis-qbot-campaign\r\nhttps://www.vkremez.com/2018/07/lets-learn-in-depth-reversing-of-qakbot.html\r\nhttps://www.hexacorn.com/blog/2016/07/01/enter-sandbox-part-12-the-library-of-naughty-libraries/\r\nhttps://www.cyberbit.com/blog/endpoint-security/anti-vm-and-anti-sandbox-explained/\r\nSource: https://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nhttps://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/\r\nPage 23 of 23",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/"
	],
	"report_names": [
		"qbot-banking-trojan"
	],
	"threat_actors": [],
	"ts_created_at": 1775434375,
	"ts_updated_at": 1775791328,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/234f760f133204e9942569c02da002f12cfcbd53.pdf",
		"text": "https://archive.orkl.eu/234f760f133204e9942569c02da002f12cfcbd53.txt",
		"img": "https://archive.orkl.eu/234f760f133204e9942569c02da002f12cfcbd53.jpg"
	}
}