{
	"id": "d889d0db-0093-43cc-9c31-867e833fcb6f",
	"created_at": "2026-04-08T02:22:21.127927Z",
	"updated_at": "2026-04-10T03:20:18.767755Z",
	"deleted_at": null,
	"sha1_hash": "91304a4cb497aee23b46cfdcac4b9ec5b6384d80",
	"title": "Deep Dive into UPAS Kit vs. Kronos",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 99617,
	"plain_text": "Deep Dive into UPAS Kit vs. Kronos\r\nBy deugenio\r\nPublished: 2018-06-12 · Archived: 2026-04-08 02:05:52 UTC\r\nResearch By: Mark Lechtik \r\nIntroduction\r\nIn this post we will be analyzing the UPAS Kit and the Kronos banking Trojan, two malwares that have come\r\nunder the spotlight recently due to the back story behind them.\r\nBackground\r\nIn May 2017, WannaCry wreaked havoc in over 150 countries and brought down companies across all industries.\r\nLuckily, the attack was brought to a halt by the British security researcher, Marcus Hutchins, through the\r\ndiscovery of the first of several kill-switches.\r\nThe tide of thanks rapidly turned, however, when Hutchins was then arrested and investigated by the FBI for his\r\nalleged role in creating and distributing a previous and unrelated malware, the Kronos banking Trojan. But\r\nHutchins’ woes didn’t end there, though, for he has recently come under renewed investigation for being the\r\nsupposed author of another malware, UPAS Kit.\r\nUntil now, although much analysis has been done on Kronos, there is no online availability for the same on UPAS\r\nKit. So Check Point Research decided to take a closer look.\r\nDisclaimer: Our research does not seek to imply or to make any claims with regards to Marcus Hutchins’ role, or\r\notherwise, to these two malwares, but is rather a mere comparison between them. Neither does our research show\r\nany conclusive evidence that point to whether Kronos and UPAS Kit were written by the same person.\r\nInitialization Phase\r\nResolving ntdll.dll functions\r\nUPAS Kit makes usage of multiple low-level ntdll functions and resolves their addresses during run-time. While it\r\nmay serve as a means to thwart analysis, this is not a very sophisticated trick on its own. The procedure\r\nresponsible for this loading action iterates over a table of functions containing entries of the following structure:\r\n          typdef struct _ntdll_function_entry{\r\n                         CHAR *function_name;\r\n                        PVOID function_address;\r\n            }ntdll_function_entry;\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 1 of 14\n\nIt simply takes the string field of each entry and resolves the corresponding address using the Win32 API function\r\nGetProcAddress. This can be seen in the following figure:\r\nFigure 1: Resolution of ntdll function by UPAS Kit]\r\nIn fact, a similar method is used in the Kronos malware to achieve the same goal. However, in this case the\r\nfunction names are not kept in cleartext in the binary, but rather as string hashes. Also, some of the resolved\r\nfunctions serve the purpose of being utilized as syscalls, thus making it a lot harder to detect the malware’s\r\nactivity, whether it is by sandboxes\\emulators or even manually. To do this, Kronos leverages a slightly different\r\nfunction entry struct, as shown below:\r\n         typedef struct _ntdll_function_entry{\r\n                     CHAR *function_name_hash;\r\n                      PVOID function_address;\r\n                       DWORD encoded_syscall_number;\r\n                       DWORD is_used_as_syscall_flag;\r\n }ntdll_function_entry;\r\nThis certainly doesn’t imply that the latter is an extended mechanism of the first method, however if we compare\r\nthe order of loaded functions (i.e. the order in which the table entries reside within the binary), it can be seen that\r\nthere is some overlap between the two cases.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 2 of 14\n\nFigure 2: Comparison of loaded ntdll functions order.\r\nAnti-VM\r\nIn order to avoid execution in analysis environments, the malware employs two techniques. The first one avoids\r\ndetection by the ThreatExpert sandbox, whereby the system volume serial number is retrieved using the function\r\nGetVolumeInformationW, and checked against the value 0xCD1A40 (which corresponds to the aforementioned\r\nsandbox). The second technique is fairly well-known, and that is a check of VMWare’s artifact in a response from\r\na virtual I/O port used for communication between the guest and host. It’s noteworthy that once an unwanted\r\nenvironment is detected by the malware, it responds by spawning an error box with the message shown below:\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 3 of 14\n\nFigure 3: Anti-VM techniques used by UPAS Kit.\r\nAlso, it should be noted that the equivalent checks made by Kronos differ quite a lot. These work to seek for the\r\nexistence of various processes or loaded modules in the malware’s address space that might indicate the nature of\r\nthe environment in which it’s executed. These types of checks cover more scenarios than the former case, which\r\nmay imply that the evasion procedures were written by different authors, or the same one taking a different\r\napproach to the problem.\r\nGlobal Mutex\r\nThe mutex name generated by the bot is the result of the action – MD5(system_volume_serial ||\r\n“LPLl3h3lDh1d3djP7P3”). In the event there was an error in the generation of the mutex name, a hardcoded\r\nvalue (“A5DEU79”) will be set to it.\r\nFigure 4: Mutex name generation.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 4 of 14\n\nIn this case, a similarity can be spotted between Kronos and UPAS Kit in the implementation of the MD5\r\nfunction, as indicated by Ignacio Sanmillan (@ulexec) from Intezer. But what’s more evident is that it creates a\r\nmutex name in a similar manner, by calculating MD5(system_volume_serial), and in case this fails assigns it to\r\nMD5(“Kronos”).\r\n Self-Installation\r\nIn order to remain persistent, UPAS Kit conducts several common actions.\r\nFirst it copies itself into a new directory under %APPDATA%, named ‘Microsoft’ as well as to the %TEMP%\r\ndirectory. The name of the copied file will be the first seven characters of the global mutex name described above\r\nfor %APPDATA%, and the same for %TEMP% only with “_l.exe” and “_a.exe” appended to it. Then, the current\r\nfile name will be checked and compared against the newly generated name, such that if the two don’t match then\r\nthe malware will get executed from the new path in %APPDATA%. If the check succeeds (i.e. at the second time\r\nthe malware runs from the %APPDATA% path), the current file path will be written to the well-known registry\r\nrun-keys Software\\Microsoft\\Windows\\CurrentVersion\\Run (under both HKLM and HKCU), where the name of\r\nthe key is identical to the name of the copied file. Finally, the malware will establish the current system\r\narchitecture using the function IsWow64Process, or GetNativeSystemInfo if the former is not available, and return\r\nit to the main function.\r\nFigure 5: Architecture check.\r\nThe naming convention used for both the file, registry key and mutex is similar for Kronos, where it uses the first\r\neight characters of MD5(system_volume_serial) for this purpose.\r\n Process Injection\r\nThe injection conducted by the malware depends on the system architecture. In 32 bit systems it would create the\r\n‘explorer.exe’ process and inject its own image into it, whereas in 64 bit systems it would do so for the 32 bit\r\nversion of ‘iexplore.exe’, which resides at “%ProgramFiles(x86)%\\Internet Explorer“. The injection function\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 5 of 14\n\nitself gets a PID and the main thread handle of the target process, as well as an address of the function to execute\r\nafter the injection takes place.\r\nIn order to conduct a successful injection, UPAS Kit uses a simple trick. First it copies its current virtual image to\r\na buffer, after which it attempts to allocate memory with the image’s size at an arbitrary address in the remote\r\nprocess. The retrieved base address of the allocation will be used to relocate the injected image, which resides at\r\nthe copied buffer, and write it to the target process. Then, it will prepare a hardcoded call stub and overwrite three\r\nof its DWORDs so that it will call the function that should be executed upon injection. These DWORDs are\r\noutlined in the following figure:\r\nFigure 6: Call stub and replaced bytes.\r\nThe struct that is pushed on the stack serves to convey some parameters that should be used later by the hook\r\nfunctions. These parameters include:\r\n         typedef struct _config_struct{\r\n                     DWORD whitelisted_process_pid;\r\n                     CHAR whitelisted_run_key_name[16];\r\n                     wchar_t whitelisted_malware_binary_path[260];\r\n                     wchar_t mutex_name[260];\r\n                     DWORD ntdll_load_status;\r\n                     DWORD some_flag;\r\n         }config_struct;\r\nFinally, in order to trigger the execution of the requested function in the remote process, the malware will set the\r\nentry point of the remote process by adjusting the value of EAX in the Context struct to that of the call stub\r\nfunction, and then resume execution by calling the NtSetContextThread function. If this fails, it will attempt to\r\nspawn the target function (and not the call stub) directly with the CreateRemoteThread function.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 6 of 14\n\nFigure\r\n7: Beginning execution in the injected process.\r\nIn contrast to the above, Kronos conducts a different type of injection, as described here. Having said that, it is\r\npossible to notice a similarity between both injection implementations, in that both present an attempt to elevate\r\nthe malware’s process token to SeDebugPrivilege, which is not mandatory for the injection to succeed. The call\r\nfor the token elevation function, as well as the function itself (which is identical in both binaries), are shown\r\nbelow:\r\nFigure 8: Injection comparison between Kronos and UPAS Kit.\r\nInjected Payload\r\nOnce again, the payload executed after injection will differ depending on the underlying system architecture. For\r\n32 bit processes the injected payload will carry out the following actions:\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 7 of 14\n\nAssign global variables based on the config_struct passed to it (as described in the previous section)\r\nLoad dll‘s raw image\r\nCreate a mutex using the mutex name set by the injecting process\r\nCheck if an uninstall flag is on, and if not –\r\nCreates a thread to inject itself to all other processes, setting the hooking function as the one that\r\nshould be executed upon injection.\r\nCreates a thread which is in charge of spreading the malware through USB media.\r\nEnters an infinite loop of communication with the C2 server.\r\nThe 64 bit payload is very similar, only it doesn’t check for the uninstall flag (hence can’t conduct an uninstall of\r\nthe malware if requested), and doesn’t inject itself to all other processes, rendering the rootkit not useful. A\r\ncomparison of both payloads can be seen in the following figure:\r\nFigure 9: Function invoked after initial injection of UPAS Kit to explorer.exe\\iexplore.exe.\r\nWe will focus on both hooking mechanism and C2 communication in the subsequent sections, so we’ll address\r\nonly the lateral movement through USB media here. The way it’s done is by registering a new window class (with\r\nthe name of the mutex described before) and entering an endless message loop.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 8 of 14\n\nFigure 10: Registration of window class for USB spreading thread.\r\nEach intercepted message will be handled by a function that will inspect if it represents the insertion of new media\r\nand if so will initiate the spreading action and report on it to the C2 server.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 9 of 14\n\nFigure 11: Window class handler for USB spreading thread.\r\nThe spreading itself happens by copying the malware file to the USB drive and generating a new autorun.inf file\r\nwith the string “[autorun]\\r\\nopen=\u003cmalware_filename\u003e_a.exe\\r\\n”. Then, the spreader will look for any .lnk files\r\nand will replace their path with:\r\n‘/C start \\”\\” \\”\u003coriginal_filename\u003e\\\\\\” \u0026\u0026 start \\”\\” \\”\u003cmalicious_filename\u003e_l.exe\\”‘.\r\nThis will cause both the original and malware files to be executed as a result of pressing the corresponding\r\nshortcut. The replacement is done using the IShellLinkW COM class, as outlined below:\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 10 of 14\n\nFigure 12: Replacement of path in .lnk files.\r\nUser Land Rootkit Functionality\r\nUPAS Kit uses a pretty straight forward inline hooking mechanism, which works using the following flow:\r\na). Checks if the target function is already hooked (by comparing it’s first byte to 0xE9, which is the jmp\r\ninstruction)\r\nb). If it isn’t, it starts disassembling the first bytes of the function, until it processes at least 5 bytes. To do so, it\r\nuses a simple disassembly engine which merely counts the number of disassembled bytes per instruction. These\r\nbytes are referred to as the stolen bytes.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 11 of 14\n\nc). Prepares a buffer with 21 NOP bytes (0x90), and then reads the stolen bytes into it. Also, it modifies the last 5\r\nbytes with a jump to the address that follows the stolen bytes. The buffer’s protection is then set to be the same\r\none used for the original bytes (i.e. should be executable).\r\nd). Sets the stolen bytes part of the original function to 0, and replaces the first 5 bytes with a jump to the hook\r\nfunction.\r\nThe following ntdll.dll functions are hooked and are intended to hide the malware’s artifacts, thus making it\r\ncovert:\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 12 of 14\n\nNtResumeThread: Intercepted to inject the malware binary into newly created processes.\r\nNtQuerySystemInformation: Checks if the requested information class is SystemProcessInformation, and if\r\nso compares the requested PID to the whitelisted explorer.exe PID. If these match, it will set the following\r\nSYSTEM_PROCESS_INFORMATION entry (corresponding to the process that precedes the rogue\r\nexplorer.exe) to point to the subsequent process to explorer.exe.\r\nNtQueryDirectoryFile: Hides the directory in which the malware copy resides\r\nNtEnumerateValueKey: Hides the registry run key corresponding to the malware\r\nNtDeleteValueKey: Same as above\r\nNtSetValueKey: Avoids the action if the requested key is the malware’s run key\r\nNtSetInformationFile: Checks if the file information class corresponds to one of the following:\r\nFileDispositionInformation, FileRenameInformation, FileEndOfFileInformation or\r\nFileAllocationInformation. If so, compares the file name to the whitelisted malware’s copy binary, and if\r\nthey match avoids the action.\r\nNtOpenProcess: Avoids the action if the requested PID is that of the rogue explorer.exe process.\r\nNtWriteFile: Avoids the action if the target file is the malware’s binary.\r\nIt’s important to note that the hooking method used by Kronos is quite different. Although both conduct inline\r\nhooking, Kronos uses a much more stable and safe implementation. Inline hooking introduces a concurrency issue\r\nwhereby a context switch that occurs before all stolen bytes are overwritten may cause a system crash if the\r\nhooked function is called (since it’s code is not in a consistent state). Therefore, the Kronos hooking method uses\r\nan atomic write of the prologue bytes using the instruction ‘lock cmpxch8b’. In this sense, the hooking engine of\r\nUPAS Kit is a lot simpler, and instead carries out an unsafe write with WriteProcessMemory function.\r\nHowever, once again some similarity can be spotted, and that is in the hook functions themselves. Eight of the\r\nabove hooks appear in a similar form within Kronos, and serve the exact same purposes. This suggests that part of\r\nthe rootkit component in those binaries was possibly reused.\r\nCnC Communication\r\nThe interaction with the C\u0026C server is done using the HTTP protocol. Most of the communication is done after\r\nthe malware executed all other actions (i.e. injection, hooking and USB spreading). In this sequence of\r\ncommunication the malware beacons the server indefinitely and updates it with the following information:\r\nSystem architecture\r\nflag that indicates whether the malware copies at the %TEMP% directory still exist\r\nOS version\r\nBot version (in this case 1.0.0.0)\r\nThe server, in turn, may respond with one of two commands: ‘uninstall’ and ‘download’. The latter can also\r\ninclude one of two subcommands: ‘update’ and ‘execute’, which are self-explanatory. Several commands can be\r\nsent in one response, delimited by the “|” character, and the command sequence will begin after the first\r\nappearance of a “!” character. The arguments of each command are delimited by a space.\r\nAnother possible message sent to the C2 server is an update on an infected USB, which will be sent once the\r\nautorun file and malware binary are copied into it.\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 13 of 14\n\nIn essence, this is the central role of UPAS Kit, i.e. serve as a covert and infectious downloader of other modules.\r\nSome of the modules for this malware offered for sale back in 2012 can be seen in the following thread from the\r\nexploit.in forum:\r\nAlthough we didn’t investigate the additional modules, it seems from their description that they are similar to ones\r\nleveraged by ZeuS and some of its variants.\r\nReferences\r\nAnalyses of Kronos:\r\nhttps://www.lexsi.com/securityhub/overview-kronos-banking-malware-rootkit/?lang=en\r\nhttps://blog.malwarebytes.com/cybercrime/2017/08/inside-kronos-malware/\r\nAnalysis of the UPAS Kit CnC panel:\r\nhttps://malware.dontneedcoffee.com/2012/08/inside-upas-kit1.0.1.1.html\r\nIOCs\r\nAnalyzed UPAS Kit sample: 1e87d2cbc136d9695b59e67f37035a45a9ad30f5fccc216387a03c0a62afa9d4\r\nAnalyzed Kronos sample (analyzed in Lexsi’s article):\r\n4181d8a4c2eda01094ca28d333a14b144641a5d529821b0083f61624422b25ed\r\nSource: https://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nhttps://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"ETDA"
	],
	"references": [
		"https://research.checkpoint.com/deep-dive-upas-kit-vs-kronos/"
	],
	"report_names": [
		"deep-dive-upas-kit-vs-kronos"
	],
	"threat_actors": [],
	"ts_created_at": 1775614941,
	"ts_updated_at": 1775791218,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/91304a4cb497aee23b46cfdcac4b9ec5b6384d80.pdf",
		"text": "https://archive.orkl.eu/91304a4cb497aee23b46cfdcac4b9ec5b6384d80.txt",
		"img": "https://archive.orkl.eu/91304a4cb497aee23b46cfdcac4b9ec5b6384d80.jpg"
	}
}