{
	"id": "0c8c19b1-e1ea-4bb9-b88e-428d1742fdb6",
	"created_at": "2026-04-06T00:07:58.586552Z",
	"updated_at": "2026-04-10T03:36:47.754043Z",
	"deleted_at": null,
	"sha1_hash": "eb0293562f1e35b56d92c1bbd4795f78dea03d37",
	"title": "Unpacking Pyrogenic/Qealler using Java agent -Part 0x2",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 107365,
	"plain_text": "Unpacking Pyrogenic/Qealler using Java agent -Part 0x2\r\nBy Ayush Anand\r\nPublished: 2020-01-17 · Archived: 2026-04-05 21:43:39 UTC\r\nJanuary 17, 2020\r\nWe will learn how and when we can use Java agent to quickly unpack the Pyrogenic Infostealer. In the earlier\r\npost Pyrogenic Infostealer static analysis – Part 0x1 we statically analysed the Pyrogenic/Qealler Infostealer but\r\nthis requires more time and effort.  We will be using the same sample PaymAdviceVend_LLCRep.jar from\r\nANY.RUN (MD5: F0E21C7789CD57EEBF8ECDB9FADAB26B) used in Part 0x1. Let’s start with a basic\r\nintroduction to Java agent.\r\nCONTENTS\r\n1. Introduction to Java agent\r\n2. Unpacking using Java agent\r\n3. Dumped class file analysis\r\n4. When will it fail?\r\n5. Conclusion\r\n6. Targeted Application list\r\n7. References\r\nIntroduction to Java agent\r\nA Java agent is used to instrument programs running on the JVM and it can modify the Java bytecode at runtime\r\nwithout source code. In this post we will be using a Java agent to dump the classes during runtime without any\r\nbytecode modification but for more details please check this Java Agents Tutorial [1]. These are the minimum\r\nrequirement for Java agent to work:\r\n1. Java agent class file should have a premain method which acts as the entry-point.This method is executed\r\nbefore the real java application main method, premain method it’s like TLS callback.\r\n2. MANIFEST.MF should be defined with the Premain-Class attribute, which will point to class name with\r\npremain method. Another important point is there must be a new line at the end of the MANIFEST file.\r\nOtherwise, the last header is ignored.\r\n3. javaagent parameter should be specified to load java agent jar file with premain method e.g . java -\r\njavaagent:dumper.jar -jar malware.jar\r\nUnpacking using Java agent\r\ndumper.java \u0026 MANIFEST.mf are used to build Java agent dumper.jar. dumper.java code is copied from\r\nReversing an obfuscated java malware pdf [2]  and I will highly recommend to go through the pdf[2] to understand\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 1 of 7\n\nthe different methods which can be used to analyse Java malware.\r\ngrade\r\nNote: All java, MANIFEST and jar files are uploaded to GitHub repo[3].\r\ndumper.java\r\nimport java.io.*;\r\nimport java.lang.instrument.*;\r\nimport java.security.*;\r\n// This code is copied from \"Reversing an obfuscated java malware by Extreme Coders\"\r\npublic class dumper {\r\n //A java agent must have a premain method which acts as the entry-point\r\n public static void premain(String agentArgs, Instrumentation inst) {\r\n System.out.println(\"agent loaded\");\r\n // Register out trasnformer\r\n inst.addTransformer(new transformer());\r\n }\r\n}\r\nclass transformer implements ClassFileTransformer {\r\n // The transform method is called for each non-system class as they are being loaded\r\n public byte[] transform(ClassLoader loader, String className,\r\n Class \u003c ? \u003e classBeingRedefined, ProtectionDomain protectionDomain,\r\n byte[] classfileBuffer) throws IllegalClassFormatException {\r\n if (className != null) {\r\n // Skip all system classes\r\n if (!className.startsWith(\"java\") \u0026\u0026\r\n !className.startsWith(\"sun\") \u0026\u0026 !className.startsWith(\"javax\") \u0026\u0026 !className.startsWith(\"com\") \u0026\r\n System.out.println(\"Dumping: \" + className);\r\n // Replace all separator characters with _\r\n String newName = className.replaceAll(\"/\", \"_\") + \".class\";\r\n try {\r\n FileOutputStream fos = new FileOutputStream(newName);\r\n fos.write(classfileBuffer);\r\n fos.close();\r\n } catch (Exception ex) {\r\n System.out.println(\"Exception while writing: \" + newName);\r\n }\r\n }\r\n }\r\n // We are not modifying the bytecode in anyway, so return it as-is\r\n return classfileBuffer;\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 2 of 7\n\n}\r\n}\r\nMANIFEST.mf\r\nManifest-Version: 1.0\r\nPremain-Class: dumper\r\ngrade\r\nNote: If you know the basic of Java or any other object oriented programming language then it will be much\r\neasier to understand this dumped unpacked code.\r\n1. Uploaded the jar file in GitHub repo[3]which is generated using following command: javac dumper.java\r\njar cmf MANIFEST.MF dumper.jar dumper.class transformer.class\r\n2. Execute this command java -javaagent:dumper.jar -jar BankPaymAdviceVend_LLCRep.jar to run the\r\nmalware with java agent and it will dump all the accessed classes at runtime to the current working\r\ndirectory.\r\n3. Please decompile all the dumped class files which start with q0b4 and j/t/e package name files using\r\nByteCodeViewer FernFlower Java decompiler. One of the easiest way is to zip all classes and then use\r\nBCV. Then, import decompiled java source files from BCV into any Java IDE, this will help you in code\r\nnavigation.\r\n4. Start from the bottom and go up in the above pic then you will find the first proper package name\r\nq0b4/bootstrap/templates/Header which can be our starting point for unpacked code. We are Reverse\r\nengineers, we always start in reverse order :).\r\n5. Below pic shows all the unpacked classes dumped using Java agent dumper.jar. It starts from Header.java\r\nwhich uses a decrypt function to AES decrypt the classes at runtime and invoke the main method. It\r\ninvokes j.t.e.Main package main method.\r\ngrade\r\nOther approach is to dump all the classes present in obfuscatedEntryList using for loop and continue analysis\r\nDumped class file analysis\r\nMalware authors divided the source code in multiple sensible packages. They have made our job easier by giving\r\nproper names to functions, variables and classes. We will go through some of the classes Main, Server, MainEx\r\nand one util IPAddress class, as it will take too much time to go through each one of them.\r\nMain \u0026 Server class\r\nMain class invokes the loadLibrary method which sends the cmd to CC using sendCmd method.\r\nServer class contains function loadLibrary which is used above and pushCredentials which is used\r\nto send the stolen credential to CC.\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 3 of 7\n\nServer class contain the following list of available library and cmds:\r\npublic static final int PYTHON = 162144;\r\npublic static final int SQLITE = 4353152;\r\npublic static final int JNA = 224288;\r\npublic static final int JNA_PLATFORM = 3048576;\r\npublic static final int JNA_4 = 307200;\r\npublic static final int JNA_PLATFORM_4 = 308224;\r\npublic static final int BCPROV = 310272;\r\npublic static final int INI4J = 311296;\r\npublic static final int XML = 312320;\r\npublic static final int JSON = 313344;\r\npublic static final int W3DOM = 314368;\r\npublic static final int Q4_PASS_LIB = 315392;\r\npublic static final int JPOWERSHELL = 316416;\r\nprivate static final int LIBRARY_CMD = 16384;\r\nprivate static final int CREDENTIAL_CMD = 32768;\r\nprivate static final byte[] SEED = \"uisdfysdgfbsdyufbsiybfsdyb733grfsudbfjh\".getBytes();\r\nprivate static final int MAX_TRY_COUNT = 20;\r\nMalware author didn’t pack all the required Java libraries in the jar but it is requested when needed at runtime.\r\nThis significantly decreased the malware size to 153.27 Kb. Let’s discuss some of the library and commands used:\r\n1. 1. 1. Server JNA, JNA_4, JNA_PLATFORM, JNA_PLATFORM_4  – JNA (Java Native\r\nAccess ) provides simplified access to native library methods without requiring any\r\nadditional JNI or native code.  For example you can call printf, GetSystemTime Windows\r\nAPI function directly from Java Code.\r\n2. INI4j – Java API for handling configuration files in Windows .ini format\r\n3. JPOWERSHELL – Simple Java API that allows programs to interact with PowerShell\r\nconsole. It may be used when malware invokes any PowerShell commands.\r\n4. Q4_PASS_LIB – May be Qealler v4 Password Library loaded first using\r\nlist.add(server.loadLibrary(315392));\r\n5. LIBRARY_CMD – May be used to load the clean dll used sqlitejdbc.dll and jnidispatch.dll\r\n6. CREDENTIAL_CMD – This cmd is used to pushCredentials to CC\r\nMainEx class\r\nj.t.e.Main main method invokes the j.t.e.MainEx main method as shown above in Main class.  It\r\nsent credential and system info in JSON format to CC. All the communication are AES encrypted\r\nusing EncryptedCipherOutputStream and EncryptedCipherInputStream which extends\r\nCipherOutputStream \u0026 CipherInputStream respectively.\r\nMainEx class contains two important methods: run() and getSysinfo() as shown below.\r\n Malware steal credential from list of software mentioned in the run() method\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 4 of 7\n\nthis.addAll(ChromiumBased.chromiumBasedBrowsers);\r\nthis.addAll(MozillaBased.mozillaBasedBrowsers);\r\nthis.add(new IExplorer());\r\nthis.add(new UCBrowser());\r\nthis.add(new Composer());\r\nthis.add(new Credman());\r\nthis.add(new Outlook());\r\nthis.add(new Pidgin());\r\nthis.add(new PostgreSQL());\r\nthis.add(new Squirrel());\r\nthis.add(new Tortoise());\r\ngetSysinfo() collect osName, osVersion, osArch, javaHome, userName, userHome,\r\navailableProcessor, freeMemory, totalMemory, localIpAddress \u0026 globalIpAddress in JSON format\r\nwhich is encrypted and sent to CC with other info.\r\nIPAddress class\r\nIPAddress class is one of the classes present in package j.t.e.core.utils which gets the IP address of\r\nthe infected system and sends it to CC with other system info. It uses\r\nhttp://bot.whatismyipaddress.com for collecting the public IP of infected systems.\r\nWhen will it fail?\r\nUnpacking using Java agent will be unable to dump all the classes at runtime due to following conditions:\r\nWhen malware is unable to interact with CC then it will not be able to exhibit complete behaviour.\r\nMalware is using some anti analysis technique e.g checking for vmware etc.\r\nMalware is unable to run due to some supporting files, command line etc.\r\nConclusion\r\nUnpacking using a Java agent is quite simple and can speed up your analysis, you can use the dumper.jar uploaded\r\nin Github [3]. This method can be used in any Java based malware. We have also gone through some of the\r\ndumped Pyrogenic/Qealler source code to understand the stealer functionality. In the last part 0x3 we find\r\nsimilarity between Qealler/Pyrogenic variants based on static code analysis.\r\nTargeted Application list\r\nThis is the list of application collected from the dumped unpacked classes:\r\n1. ChromiumBased Browser\r\n7Star\r\namigo\r\nbrave\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 5 of 7\n\ncentbrowser\r\nchedot\r\nchrome canary\r\nchromium\r\ncoccoc\r\ncomodo dragon\r\nelements browser\r\nepic privacy browser\r\ngoogle chrome\r\nkometa\r\nopera\r\norbitum\r\nsputnik\r\ntorch\r\nuran\r\nvivaldi\r\nyandexBrowser\r\n2. MozillaBased Browser\r\nfirefox\r\nblackHawk\r\ncyberfox\r\ncomodo IceDragon\r\nk-Meleon\r\nicecat\r\n3. IExplorer\r\n4. UCBrowser\r\n5. Composer\r\n6. Windows Credential\r\n7. Outlook\r\n8. Pidgin\r\n9. PostgreSQL\r\n10. Squirrel\r\n11. Tortoise\r\nReferences\r\n1. Java Agents Tutorial\r\n2. Reversing an obfuscated java malware by Extreme Coders\r\n3. GitHub repo\r\nThanks for reading. Feel free to connect with me on or LinkedIn for any suggestions or comments.\r\nFor more updates and exclusive content, subscribe to our newsletter. Stay sharp. Keep defending.😊\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 6 of 7\n\nSource: https://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nhttps://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.securityinbits.com/malware-analysis/unpacking/unpacking-pyrogenic-qealler-using-java-agent-part-0x2/"
	],
	"report_names": [
		"unpacking-pyrogenic-qealler-using-java-agent-part-0x2"
	],
	"threat_actors": [
		{
			"id": "9f101d9c-05ea-48b9-b6f1-168cd6d06d12",
			"created_at": "2023-01-06T13:46:39.396409Z",
			"updated_at": "2026-04-10T02:00:03.312816Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"CHROMIUM",
				"ControlX",
				"TAG-22",
				"BRONZE UNIVERSITY",
				"AQUATIC PANDA",
				"RedHotel",
				"Charcoal Typhoon",
				"Red Scylla",
				"Red Dev 10",
				"BountyGlad"
			],
			"source_name": "MISPGALAXY:Earth Lusca",
			"tools": [
				"RouterGod",
				"SprySOCKS",
				"ShadowPad",
				"POISONPLUG",
				"Barlaiy",
				"Spyder",
				"FunnySwitch"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "18a7b52d-a1cd-43a3-8982-7324e3e676b7",
			"created_at": "2025-08-07T02:03:24.688416Z",
			"updated_at": "2026-04-10T02:00:03.734754Z",
			"deleted_at": null,
			"main_name": "BRONZE UNIVERSITY",
			"aliases": [
				"Aquatic Panda",
				"Aquatic Panda ",
				"CHROMIUM",
				"CHROMIUM ",
				"Charcoal Typhoon",
				"Charcoal Typhoon ",
				"Earth Lusca",
				"Earth Lusca ",
				"FISHMONGER ",
				"Red Dev 10",
				"Red Dev 10 ",
				"Red Scylla",
				"Red Scylla ",
				"RedHotel",
				"RedHotel ",
				"Tag-22",
				"Tag-22 "
			],
			"source_name": "Secureworks:BRONZE UNIVERSITY",
			"tools": [
				"Cobalt Strike",
				"Fishmaster",
				"FunnySwitch",
				"Spyder",
				"njRAT"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "6abcc917-035c-4e9b-a53f-eaee636749c3",
			"created_at": "2022-10-25T16:07:23.565337Z",
			"updated_at": "2026-04-10T02:00:04.668393Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Bronze University",
				"Charcoal Typhoon",
				"Chromium",
				"G1006",
				"Red Dev 10",
				"Red Scylla"
			],
			"source_name": "ETDA:Earth Lusca",
			"tools": [
				"Agentemis",
				"AntSword",
				"BIOPASS",
				"BIOPASS RAT",
				"BadPotato",
				"Behinder",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"Doraemon",
				"FRP",
				"Fast Reverse Proxy",
				"FunnySwitch",
				"HUC Port Banner Scanner",
				"KTLVdoor",
				"Mimikatz",
				"NBTscan",
				"POISONPLUG.SHADOW",
				"PipeMon",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"SAMRID",
				"ShadowPad Winnti",
				"SprySOCKS",
				"WinRAR",
				"Winnti",
				"XShellGhost",
				"cobeacon",
				"fscan",
				"lcx",
				"nbtscan"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d53593c3-2819-4af3-bf16-0c39edc64920",
			"created_at": "2022-10-27T08:27:13.212301Z",
			"updated_at": "2026-04-10T02:00:05.272802Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Earth Lusca",
				"TAG-22",
				"Charcoal Typhoon",
				"CHROMIUM",
				"ControlX"
			],
			"source_name": "MITRE:Earth Lusca",
			"tools": [
				"Mimikatz",
				"PowerSploit",
				"Tasklist",
				"certutil",
				"Cobalt Strike",
				"Winnti for Linux",
				"Nltest",
				"NBTscan",
				"ShadowPad"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434078,
	"ts_updated_at": 1775792207,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/eb0293562f1e35b56d92c1bbd4795f78dea03d37.pdf",
		"text": "https://archive.orkl.eu/eb0293562f1e35b56d92c1bbd4795f78dea03d37.txt",
		"img": "https://archive.orkl.eu/eb0293562f1e35b56d92c1bbd4795f78dea03d37.jpg"
	}
}