{
	"id": "d316896e-859e-44d2-bd41-41495ea203d3",
	"created_at": "2026-04-06T00:08:20.107711Z",
	"updated_at": "2026-04-10T13:11:49.790912Z",
	"deleted_at": null,
	"sha1_hash": "3ee19d63795a90927931c690192218a59e1e2341",
	"title": "Compromised WordPress Sites Distribute Adwind RAT | blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4260104,
	"plain_text": "Compromised WordPress Sites Distribute Adwind RAT | blog\r\nBy Sudeep Singh\r\nPublished: 2020-04-29 · Archived: 2026-04-02 11:40:48 UTC\r\nWith more than 60 million websites, including 33.4 percent of the top 10 million global websites, built on the WordPress\r\nplatform, it is big news when a new attack aimed at this popular tool surfaces. And, as you can probably guess, the Zscaler\r\nThreatLabZ team recently noticed another campaign targeting WordPress sites.\r\nSince the first week of April 2020, we observed several instances of malicious Java archive (JAR) files hosted on\r\ncompromised WordPress websites. These JAR files used several layers of encryption to protect its final payload—the\r\nAdwind remote access Trojan (RAT).\r\nIn this blog, we describe two aspects of this campaign. In the first part, we describe the intelligence information we gathered\r\nfrom this campaign, which was used for threat attribution. In the second part, we explain in detail all the steps used for\r\ndecrypting the multiple layers of encryption that were used to protect the final payload.\r\nCompromised sites used for hosting the payload\r\nWe observed a common pattern shared among all the compromised websites in this campaign, which are used to host the\r\nmalicious JAR payload. All these websites used the Content Management System (CMS) from WordPress. Attackers often\r\nexploit vulnerabilities in WordPress plugins to get access to the admin panel of the CMS. Once the access is obtained, they\r\ncan host their payload on the server.\r\nThe WordPress version can be confirmed by checking the meta HTML tag in the source code with the “name” attribute field\r\nset to “generator” as shown below for one of the compromised sites observed in this campaign.\r\nFigure 1: WordPress version in the HTML source code.\r\nMost of the compromised websites in this campaign were running a fairly recent version of WordPress—5.3.x. Only a few\r\nsites were running outdated versions, such as 4.5.x or 3.3.x.\r\nThe file names for the payload varied between themes ranging from Coronavirus to payment invoices and shipping delivery\r\nservices, such as DHL and USPS, as shown below:\r\nCovid-19Update.jar\r\nReylontransport-covid19-statement20.jar\r\nRescheduleUSPS.jar\r\nDHLPaket.jar\r\nThreat attribution\r\nOn some of the compromised WordPress sites used to host the malicious JAR files, we were able to find PHP web shells that\r\nattackers used to control the web server as shown in Figure 2.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 1 of 13\n\nFigure 2: PHP web shell on a compromised WordPress site.\r\nThere are some other web shells present in the same directory. After inspecting the different web shells, we located a PHP\r\nmailer script that would send a test email to attacker-specified email addresses, as shown in Figure 3.\r\nFigure 3: PHP mailing script found on the compromised server.\r\nEmail addresses:\r\nSabersebry99@freemail.hu\r\nSabersebry99@citromail.hu\r\nTechnical analysis of the encrypted JAR\r\nThere were multiple layers of encryption used in the JAR files in this campaign, which made it clear that some form of\r\ncrypting service was used by the threat actor to protect the final JAR payload. After decrypting several layers, we found a\r\nreference to “Qarallax”, which leads us to believe that the cryptor used can be attributed to the Qarallax crypt service.\r\nIn this section of the blog, we will go in to the details of the different layers of encryption and how we unpacked them one\r\nby one to reveal the final payload.\r\nFor the purpose of analysis, we have chosen the JAR file with MD5 hash: 0a5f34440389ca860235434eea963465\r\nFilename of the JAR file: Covid-19Update.jar\r\nDecryption: Stage 1\r\nThis JAR file contains two encrypted resources:\r\nResource 1: /cloud/file.update\r\nResource: 2: AaxIv/WEPcXKp/UBLah/kCQuJbJn\r\nThese resources will be loaded and decrypted at runtime. To understand the decryption process, let us look at the source\r\ncode of rr.class present inside this JAR file. This class file is responsible for loading the above resources and calling the\r\ndecryption routines. The code section is shown in Figure 4 with relevant comments added to the code.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 2 of 13\n\nFigure 4: Code for decrypting the resources in stage 1.\r\nIt is also important to note that the strings referenced in the above code are defined inside the gf.class file. All these strings\r\nare encrypted as shown in Figure 5.\r\nFigure 5: Encrypted strings in stage 1.\r\nThe string decryption routine is shown in Figure 6.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 3 of 13\n\nFigure 6: String decryption routine in stage 1.\r\nThis string decryption routine was reused in the later stages as well. So we rewrote it in Python to make the decryption\r\nprocess of further layers easier. The code for string decryption is mentioned in the Appendix I section of this blog.\r\nThe different steps involved in decryption in above code are:\r\n1. The resource, “/cloud/file.update” is read using getClass.getResourceAsStream() into a byte array.\r\n2. This resource is decrypted using the AES key: “Psjduiwo8wosld9O” using the AES block cipher mode:\r\nAES/ECB/PKCS5PADDING.\r\n3. The result of the above decryption is an XML file, which is shown in Figure 7.\r\nFigure 7: XML file obtained after decryption. It contains the AES key to decrypt the second resource.\r\n4. This resource is loaded using the loadFromXML() method which allows individual properties from the XML to be\r\naccessed to continue the decryption process.\r\nDecryption: Stage 2\r\nThe XML file, which was obtained after decrypting stage 1, is used to decrypt the second layer as defined below.\r\n1. The SERVER entry in this XML file corresponds to the second encrypted resource called:\r\n/AaxIv/WEPcXKp/UBLah/kCQuJbJn.Tje in the JAR file. The PASSWORD entry in the above XML file corresponds\r\nto the AES key, which will be used to decrypt this second resource.\r\n2. The AES key used for decrypting the second resource is: xslNGppgnJmTwGGH.\r\n3. Second resource is decrypted to a Gzip file, which gets decompressed to another JAR file.\r\nDecryption: Stage 3\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 4 of 13\n\nIn this stage, we will look at the decrypted JAR file obtained from stage 2. The class files and resource file structure for this\r\nJAR is as shown in Figure 8.\r\nFigure 8: JAR file structure of stage 3.\r\nThis JAR file has one encrypted resource called “/this/file.grt”.\r\nExecution of this JAR file begins in the method: j2t.ple.IL as shown in Figure 9.\r\nFigure 9: The main method in stage 3.\r\nThe strings in this method were encrypted using the same string encryption method as in stage 1. The only difference was in\r\nthe initial one byte XOR key, which was changed to 0x58.\r\nAfter decrypting the strings in the main method, we can see a reference to the Qarallax project. Qarallax provides\r\ncrypting services for encrypting JAR files on underground hacking forums, leading us to correlate this to Qarallax.\r\nNow let us look at the method, Il() defined in il_1.class file. This method performs the resource decryption as shown in\r\nFigure 10.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 5 of 13\n\nFigure 10: Code for performing decryption of resources in stage 3.\r\nThe different steps involved in the decryption are:\r\n1. It loads the encrypted resource: “/this/file.grt” using getClass.getResourceAsStream() into a byte array.\r\n2. It uses the DES key: R5uE7enKM8wK0qOk8s9di to decrypt the above resource.\r\n3. The result of decryption is an XML file as shown in Figure 11.\r\nFigure 11: The XML file after decryption in stage 3.\r\n4. The SERVER_BIN file in the above decrypted XML corresponds to the next stage encrypted file.\r\nPASSWORD_CRYPTED corresponds to an encrypted AES key, which will be used to decrypt the SERVER_BIN file.\r\nPRIVATE_PASSWORD is the RSA private key, which is used to decrypt the AES key.\r\n5. Each of the above properties are loaded from the XML using loadFromXML() and getProperty() methods.\r\n6. The RSA private key is stored as a serialized Java object. It is unserialized using the readObject() method.\r\n7. The unserialized RSA key is used to decrypt the AES key defined in the PASSWORD_CRYPTED section of the XML.\r\n8. The decrypted AES key is used to decrypt the SERVER_BIN file, which results in the next stage decrypted file.\r\nDecryption: Stage 4\r\nThe decrypted payload obtained from stage 3 is the final JAR payload, which was protected with multiple layers of\r\nencryption. The JAR class file structure for this payload is as shown in Figure 12.\r\nFigure 12: The JAR file structure in stage 4.\r\nThis file contains multiple encrypted resources.\r\nKey1.json – RSA private key stored as a serialized Java object.\r\nKey2.json – Encrypted AES key.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 6 of 13\n\nConfig.json – Encrypted config file of the Java RAT.\r\nLet us look at the main method—server.main.Start()—of this JAR file. We can see the use of encrypted strings in this JAR\r\nfile as shown in Figure 13.\r\nFigure 13: The encrypted strings in stage 4.\r\nFigure 14 shows the string decryption routine.\r\nFigure 14: The string decryption routine in stage 4.\r\nThis string decryption routine is different from the previous stages we analyzed. It is a variant of XOR decryption, which\r\nderives the decryption key in an interesting way.\r\nThe first two lines of the decryption routine are:\r\n        StackTraceElement stackTraceElement = new LinkageError().getStackTrace()[1];\r\n        String string = new\r\nStringBuffer(stackTraceElement.getClassName()).append(stackTraceElement.getMethodName()).toString();\r\nThese lines are used to fetch the class name and the method name from which the string decryption routine was called. To\r\nfind the calling class name and method name, it generates an exception using LinkageError() and then fetches the first stack\r\nframe using getStackTrace()[1]. From this stack frame, the calling class name and method name are derived.\r\nAs an example, when the string decryption routine is called by the method \"ii\" in the class \"Start\", then the XOR decryption\r\nkey will be: \"Startii\".\r\nUpon further analysis, we discovered that this string decryption routine is the same as the one provided by the Java\r\nobfuscator called Allatori. Usually class files obfuscated with Allatori obfuscator use the method name:\r\nALLATORIxDEMOxhthr().\r\nHowever, in this case, the method name was also obfuscated to remove any reference to Allatori.\r\nWe rewrote the string decryption routine in Python to decrypt all the strings in this JAR file. The Python script is provided in\r\nthe Appendix II section of this blog.\r\nAfter decrypting the strings, the resulting code is shown in Figure 15.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 7 of 13\n\nFigure 15: The code after decrypting the strings.\r\nDecryption of the config file\r\nAs a first step, we will decrypt the resources to get access to the config file. The steps involved in decryption are:\r\n1. Loads the serialized object from the resource: “/server/resources/Key1.json” using getClass.getResourceAsStream().\r\n2. Unserializes the Java object using readObject() to get access to the RSA private key.\r\n3. Loads the encrypted AES key from the resource called: \"/server/resources/Key2.json\".\r\n4. Loads the encrypted config file from the resource called: “/server/resources/config.json\".\r\n5. Decrypts the AES key using the RSA private key.\r\n6. Decrypts the encrypted resource using the decrypted AES key.\r\nThe resulting decrypted config file is as shown below.\r\n{\"securityRetry\":20,\"vbox\":true,\"security\":[],\"nickName\":\"quarantoes\",\"installation\":\r\n{\"jarName\":\"aDaGm\",\"moduleFolder\":\"pWnmd\",\"moduleEntry\":\"tUjeninoYOKbbABjEQOfwMmkkAV/iPYMlXQvBnHKdoBEfaulmhiFQGfShHjNdiX\r\n[{\"delay\":2,\"port\":9932,\"dns\":\"212.114.52.236\"}]}\r\nWe provide a description of the key fields present in the above configuration file.\r\nVbox: Indicates whether the presence of VirtualBox should be checked or not.\r\nnickName: This is a unique identifier used while building the RAT. In our case, it is “quarantoes”.\r\nInstallation: A JSON that contains key-value pairs describing the location where the JAR file needs to be copied to on the\r\nfile system.\r\njreFolder: Indicates the folder where all the files required for running the JAR are stored.\r\njarRegistry: The name of the Windows registry key used for persistence.\r\ndelay: Indicates the number of seconds to delay the execution.\r\nVmware: Indicates whether the presence of VMWare should be checked or not.\r\nPort: The port number on which the RAT communicates with the server.\r\nDNS: IP address of the callback server.\r\nActivities performed by the RAT\r\nBelow are the main activities performed by the RAT.\r\n1. It checks the OS name and if it is not Windows, then the RAT does not execute.\r\n2. It copies itself to the path: C:\\Users\\user\\pMbbW\\aDaGm.class. The directory name in this path is selected from the\r\n“mainFolder” parameter of the config file and the filename is selected using the “jarName” parameter in the config\r\nfile. The file extension for the JAR file is selected as “.class” based on the configured value for parameter:\r\n“jarExtension” in the config file.\r\n3. It sets the Windows registry key for persistence to ensure that the above JAR file is executed automatically using\r\njavaw.exe upon reboot.\r\nKey path: HKEY_USERS\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\r\nKey name: UKikhtn\r\nKey value: \"C:\\Users\\user\\Oracle\\bin\\javaw.exe\" -jar \"C:\\Users\\user\\pMbbW\\aDaGm.class\"\r\nThe key name is fetched from the config file as well.\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 8 of 13\n\n4. It loads the DLL from the resource section: “/server/resources” based on the system architecture. For 32-bit system, it\r\nloads x86.dll and for 64-bit system, it loads amd64.dll.\r\nThis DLL will be loaded and copied to a temporary location on the file system with the file extension, “.xml”. The DLL is\r\nthen loaded using the System.load() command as shown in Figure 16.\r\nFigure 16: The code for loading the DLL.\r\n5. It checks the value of the “active” key in the decrypted config.json file. If the value is set to true, then the RAT delays the\r\nexecution by the “delay” number of seconds as configured in the config.json file.\r\n6. It checks for the presence of a virtualization environment, such as VMWare, Virtualbox and Qemu. If it finds the presence\r\nof such an environment, then it exits the execution.\r\nWe will not be describing the functionality of this binary in detail in this blog since the final payload is a well-known jRAT\r\n(Java-based RAT).\r\nCloud Sandbox Detection\r\nFigure 17 shows the Zscaler Cloud Sandbox successfully detecting this JAR-based threat.\r\nFigure 17: Zscaler Cloud Sandbox detection.\r\nIn addition to sandbox detections, Zscaler’s multilayered cloud security platform detects indicators at various levels, as seen\r\nhere: Java.Backdoor.Adwind.\r\nConclusion\r\nThis threat actor leverages compromised websites to serve heavily encrypted variants of a Java-based RAT, which makes the\r\ndetection difficult over the network.\r\nAs an extra precaution, users should not run JAR files from untrusted and unknown sources since JAR files contain\r\nexecutable code and have the capability of infecting a system.\r\nWeb administrators who use WordPress installations should ensure that they are running the latest version of WordPress\r\nplugins and themes to prevent any vulnerability from being exploited.\r\nThe Zscaler ThreatLabZ team will continue to monitor this campaign, as well as others, to help keep our customers safe.\r\nMITRE ATT\u0026CK TTP Mapping\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 9 of 13\n\nTactic Technique\r\nPersistence Registry Run Keys / Startup Folder - T1060\r\nObfuscation Obfuscated Files or Information - T1027\r\nSoftware Packing T1045\r\nProcess Discovery Query and kill system processes - T1057\r\nSecurity Software Discovery T1063\r\nSystem Information Discovery T1082\r\nSystem Network Configuration Discovery T1016\r\nWindows Management Instrumentation T1047\r\nUncommonly Used Port T1065\r\nIndicators of Compromise (IOC)\r\nURLs hosting JAR files\r\nhxxp://haus-pesjak[.]at/Covid-19Update.jar\r\nhxxps://digitaltextile.com[.]ru/lk/Deutsche%20Telekom.jar\r\nhxxps://digitaltextile.com[.]ru/n/DHL%20paket.jar\r\nhxxp://haus-pesjak[.]at/04-07-20Intuitinvoices.jar\r\nhxxp://teddyshatsworld[.]pl/Reylontransport-covid19-statement20.jar\r\nhxxp://thaivictory.co[.]th/pageconfig/album/dir/5/order.jar\r\nhxxp://cherryemoore[.]com/USPS/RedeliveryUSPS.jar\r\nhxxps://feylibertad[.]org/Amazon-PO20023938.jar\r\nhxxp://mahalowood[.]com/USPS/USPSReschedulerLabel.jar\r\nhxxps://newsha.jsonland[.]ir/wp-includes/css/DHLPaket.jar\r\nhxxps://www.stillval[.]com/USPS/RescheduleUSPS.jar\r\nhxxps://thediscoveryrun[.]com/UPS/ShippingInfo.jar\r\nhxxp://jeddahcrumbly[.]com/DHLPAKET.jar\r\nhxxps://dev.medialogistics2020[.]ca/wp-content/plugins/ubh/Quickbooks-INV5066.jar\r\nHashes of the samples\r\n7e4bdf62d3ecd78b3f407f6ec1158678\r\n0a5f34440389ca860235434eea963465\r\n1da18ec639f7ec2a8aad58655d846e23\r\nd7489b47e17630e5594a320b43b201db\r\nda52c24302a03626d2175123b751f466\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 10 of 13\n\nb766cf6695730b74a107cb73157262b1\r\n919f2d0043f063a90702fb36887699e8\r\nd470d5a428f99818278fb2816a8d03e9\r\n8f5e55fbb1bee93dc5912dcbd0092519\r\n4a97b2d004d72b69aa64f621b5b74775\r\n051b4da1f0079c6f60d6c8eb62b3f586\r\n2020551b5373121053abdbf3eaafa02d\r\na4da22e269b93148eb9857036b9a072a\r\n876eb4208ef2eec6e9f12b13f764a975\r\n1d77e96974e1e2301ed78cec19e8710b\r\nNetwork Indicators\r\n212.114.52[.]236:9932\r\nunks123.duckdns[.]org:46865\r\nlay.dubya[.]us:8181\r\nfresh.ygto[.]com:1010\r\ngwiza1988.hopto[.]org:6025\r\npraisesalways.ddns[.]net:1010\r\nwawa.cleansite[.]us:1010\r\ndlee889.mywire[.]org:5858\r\nAppendix I\r\nString decryption routine\r\n#! /usr/bin/python\r\n# -*- coding: utf-8 -*-\r\nimport sys\r\n# Replace encoded_string with the string to be decoded.\r\ninput =\r\n# Replace one_byte_key with the respective value found in the Java class file\r\nkey =\r\nl = len(input) - 1\r\noutput = []\r\ncounter = l\r\nwhile counter \u003e= 0:\r\n         b1 = ord(input[l]) ^ key\r\n         t = (l ^ key) \u0026 0x3f\r\n         output.append(chr(b1))\r\n         l = l - 1\r\n         if l\r\n                   break\r\n         b2 = ord(input[l]) ^ t\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 11 of 13\n\nkey = (l ^ t) \u0026 0x3f\r\n         output.append(chr(b2))\r\n         l = l - 1\r\n         counter = l\r\noutput.reverse()\r\nprint(''.join(output))\r\nAllatori string decryption routine ported to Python\r\n#! /usr/bin/python\r\nimport os\r\nimport sys\r\ndef decode(encrypted, c_method):\r\n         base_string = c_method\r\n         n2 = len(encrypted)\r\n         n3 = n2 - 1\r\n         # Replace n4_val and n5_val with the respective values used in the Allatori obfuscator.\r\n         # These are one byte values\r\n         n4 =\r\n         n5 =\r\n         n6 = n = len(base_string) - 1\r\n         string2 = base_string\r\n         result = []\r\n         while (n3 \u003e= 0):\r\n                   n7 = n3\r\n                   n3 = n3 - 1               \r\n                   result.append(chr(n5 ^ (ord(encrypted[n7]) ^ ord(string2[n]))))\r\n                   if (n3\r\n                   n8 = n3\r\n                   n3 = n3 - 1\r\n                   result.append(chr(n4 ^ (ord(encrypted[n8]) ^ ord(string2[n]))))                  \r\n                   m = n\r\n                   n = n - 1\r\n                   if (m\r\n                            n = n6;\r\n                   n9 = n3\r\n         return result\r\nif __name__ == \"__main__\": \r\n         # Replace encrypted_string with the string to be decrypted\r\n         encrypted_str =\r\n         # Replace calling_class_name and calling_method_name with the names of the Class and Method from where the\r\ndecryption routine was invoked\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 12 of 13\n\nc_method = +\r\n         print ''.join(decode(encrypted_str, c_method))[::-1]\r\nExplore more Zscaler blogs\r\nSource: https://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nhttps://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat\r\nPage 13 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.zscaler.com/blogs/research/compromised-wordpress-sites-used-distribute-adwind-rat"
	],
	"report_names": [
		"compromised-wordpress-sites-used-distribute-adwind-rat"
	],
	"threat_actors": [],
	"ts_created_at": 1775434100,
	"ts_updated_at": 1775826709,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3ee19d63795a90927931c690192218a59e1e2341.pdf",
		"text": "https://archive.orkl.eu/3ee19d63795a90927931c690192218a59e1e2341.txt",
		"img": "https://archive.orkl.eu/3ee19d63795a90927931c690192218a59e1e2341.jpg"
	}
}