{
	"id": "885d8f78-5e50-402d-b3d9-5070dde91c56",
	"created_at": "2026-04-06T00:14:57.133912Z",
	"updated_at": "2026-04-10T03:37:16.400592Z",
	"deleted_at": null,
	"sha1_hash": "044f070a516b2b3972eb5a298eda2b12cca0906d",
	"title": "Malware-analysis-and-Reverse-engineering/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md at main · Dump-GUY/Malware-analysis-and-Reverse-engineering",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2024805,
	"plain_text": "Malware-analysis-and-Reverse-engineering/APT29_C2-\r\nClient_Dropbox_Loader/APT29-DropboxLoader_analysis.md at\r\nmain · Dump-GUY/Malware-analysis-and-Reverse-engineering\r\nBy Dump-GUY\r\nArchived: 2026-04-05 20:19:54 UTC\r\nStatic Code Analysis – “AcroSup64.dll”\r\nUpon library loading “AcroSup64.dll”, the first function (functions “DllEntryPoint” and “dllmain_dispatch” are\r\nnot important in this case) which is performing the intended malicious behavior and gets automatically executed is\r\n“DllMain”.\r\nRight in start of function “DllMain”, we can see that first anti-analysis check is performed. Code is checking if\r\nmain process module filename is “NV.exe” same as the delivered original filename of program responsible for\r\nloading “AcroSup64.dll”. Be aware that through whole this analysis - all code is already annotated and retyped in\r\nIDA IDB and functions are renamed according to their capabilities.\r\nWe can also see the first thread execution hijacking which is processed via calling directly “NtCreateThreadEx”\r\nsyscall. New thread is created in suspended state with flags set also to hide from debugger. Decoy start routine\r\n“RtlNewSecurityObjectWithMultipleInheritance” of newly created thread is replaced with setting the thread\r\ncontext of this thread – specifically via setting RCX register (NOT RIP as this new suspended thread is not\r\ninitiated yet) pointing to code where the execution will be directed. This serves well as AV evasion and anti-debug\r\ntechnique. RCX is the first argument to function “RtlUserThreadStart” (thread start location) and this argument\r\nsets new thread entry routine different than the decoy one.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 1 of 14\n\nThe “NtCreateThreadEx” syscall is dynamically resolved and gets executed directly via “syscall” assembly\r\ninstruction where desired syscall number is set in RAX register, as we can see in the picture below:\r\nResolving of syscalls is done via function “resolve_and_hash_all_syscalls” only once, on first execution.\r\n“resolve_and_hash_all_syscalls” function is hashing syscall names and populates it to table named as\r\n“hashed_syscalls_table”. This table later serves as lookup table to find specific syscall number for routine.\r\nFunction “resolve_and_hash_all_syscalls”:\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 2 of 14\n\nWhenever we see this kind of advanced technique (dynamic resolving of syscall via syscall name hashing and\r\ncreating “hashed_syscalls_table” which serves as lookup table + direct syscall call via stub code similar like in\r\nntdll.dll) we should do a little OSINT if this technique is based on some already published one.\r\nIn this case, our assumption was correct and this technique is based on “SysWhispers2” published on Github\r\n[GITHUB - SysWhispers2]. C2-Client Dropbox Loader was reusing most of the original code from\r\n“SysWhispers2” also the syscall name hashing algorithm so with this information we can take some structures and\r\nimplement it in IDA to get better understanding of this code like in pictures below:\r\nUsing “hashed_syscalls_table” as lookup table for desired syscall hash to retrieve its syscall number:\r\nHashing syscall names and populating + reordering the “hashed_syscalls_table”:\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 3 of 14\n\nThe main point of this kind of retrieving syscall numbers for routines is based on the fact that syscall numbers are\r\nin ascending order strictly connected to order of syscall´s virtual addresses “Zw*” inside of ntdll.dll – meaning\r\nthat lowest virtual address of syscall = lowest number of syscall (highest virtual address of syscall = highest\r\nnumber of syscall). We can confirm this fact/idea with simple [python script] + ntdll.dll in IDA:\r\nNow when we have knowledge how this technique works, we can focus on syscall name hashing algorithm which\r\nafter annotating and retyping looks similar like below:\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 4 of 14\n\nThis hashing routine we can easily reproduce in [IDA Python script] and create ENUM for all Syscall hashes:\r\nSo whenever we see hashed syscall name, we can apply newly created ENUM and after we find out the correct\r\ninvoked routine, we can retype whole function.\r\nWe can get back to the first thread execution hijacking - “Pre_C2client_MAIN_redirect_exec” is the function\r\nwhere thread execution hijacking directs to. This function can be seen in the picture below. Function is trying to\r\nfind “NV.exe” module name in memory and if found, another thread execution hijacking occurs. This time it\r\nhijacks already existing thread (no new thread created) and because of that, code can just set RIP register of thread\r\ncontext. Newly set RIP register is pointing to function named “C2_Client_MAIN” where all the main malicious\r\nC2 activity is implemented.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 5 of 14\n\nStart of function “C2_Client_MAIN” can be seen in the picture below. First what this function is doing, is calling\r\nfunction “Map_dll_restore_text_section”. After this, C2_client tries to authenticate itself to Dropbox service and if\r\nauthentication is successful (there is unintentional exception – see below “http_dropbox_authenticate” function\r\nanalysis), it sets persistence and continue with Dropbox communication otherwise it waits 5.5 minutes and try to\r\nauthenticate itself again. All is performed in endless loop.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 6 of 14\n\n“Map_dll_restore_text_section” function serves well as AV evasion, anti-debug and anti-hooking technique as this\r\nfunction is searching for all already loaded modules (WININET.dll is the last one if found), finding them on disc,\r\nmanually maps their “.text” (code) section into memory and replace with it the one “.text” section in\r\ncorresponding library already loaded in memory. With this, malware destroys all installed inline hooks of AV and\r\nset breakpoints of debugger if any. So the AV solution will be blind from the user-space (ring 3) perspective.\r\nWe can see function “Map_dll_restore_text_section” in the picture below:\r\nBack to the main function “C2_Client_MAIN”, “http_dropbox_authenticate” function is responsible for decoding\r\nstrings related to authenticate the C2_Client on Dropbox service. It uses hardcoded token for authentication and if\r\nthe token is still valid (not expired/revoked) it will receive another temporary token for further communication\r\nwith Dropbox.\r\nOne probably unintentional bug in code (function “http_dropbox_authenticate”) there is possibility that code will\r\ntry to set persistence and continue in further communication (with wrong string content interpreting as bearer\r\naccess token) even if authentication is not successful. This is caused by obtaining authentication response\r\nfulfilling certain format condition as explained in the picture below:\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 7 of 14\n\nDecoded strings of function “http_dropbox_authenticate” can be seen in the picture below and contains\r\ninformation like HTTP User-Agent, HTTP Host name (api.dropbox.com), URL path, Basic authorization HTTP\r\nheader and mainly the Token itself.\r\nWe can also see that before the code reach the part of setting persistence (after authentication) it obtains current\r\nlogged-in username (in NameSamCompatible format) calculates MD5 hash of it and converts it to hexstring. This\r\nhexadecimal string of Username MD5 is very important because it is later used to decrypt downloaded payload\r\nfrom Dropbox before execution.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 8 of 14\n\nAccording to usage of Username MD5 hexstring which is used for downloaded payload decryption, we can\r\nassume how C2 Dropbox server (serving payload to Dropbox) operates “per-victim” and is using infected\r\ncurrently logged-in Username MD5 hexstring for “per-victim” payload encryption. The expected functionality of\r\ninfrastructure according to C2 Dropbox client code is in the picture below:\r\nFunction “set_persistance” is spawning new process to open “blank.pdf” file. After that it starts to copy files\r\n“NV.exe”, “AcroSup64.dll” and “vcruntime140.dll” into the\r\n“%USERPROFILE%\\AppData\\Roaming\\AdobeAcroSup” directory and sets persistence via ordinary auto-start\r\nlocation for current user “run” registry\r\n“HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run” with value name “Adobe\r\nAcroSup” and value data pointing to “%USERPROFILE%\\AppData\\Roaming\\ AdobeAcroSup\\NV.exe”.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 9 of 14\n\nFunction “C2_Client_MAIN” continue execution and after “set_persistance” function it gets currently logged-in\r\nUsername and Computername and creates string from it in format “Computername::Username”. In next step, this\r\nstring is xored with hardcoded value “ME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUU” (which looks\r\nvery similar to original LAME MP3 encoder header) as in the picture below.\r\nIn next step, it calculates MD5 hash from string “Computername::Username”, converts it to hexstring format and\r\nuses it to create filename for uploading to Dropbox “Rock_ComputerNameUsernameMD5HashHexstring.mp3” –\r\nregistering Client to C2 Dropbox Server (ex. “Rock_70a1e27ba30dd415155e68409d512a2d.mp3”).\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 10 of 14\n\nNext function “pre_process_body_add_mp3header_xorkey” is preparing body content of\r\n“Rock_ComputerNameUsernameMD5HashHexstring.mp3” to upload. The body content contains xored\r\n“Computername::Username”, xor key “ME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUU” and to avoid\r\ndetection - fictive MP3 header is added to the start of body content. The example structure of this body content is\r\nin the picture below:\r\nThis body is uploaded by function “http_dropbox_upload”:\r\nDecoded strings from function “http_dropbox_upload” (ex. HTTP User-Agent, HTTP Host\r\n“content.dropboxapi.com”, URL Path “/2/files/upload”) can be seen in the picture below:\r\nThe next step is preparing filename to download from Dropbox. This file is uploaded to Dropbox by C2 Dropbox\r\nServer. Filename to download is in format “Rock_ComputerNameUsernameMD5HashHexstring.mp3.backup”\r\n(ex. “Rock_70a1e27ba30dd415155e68409d512a2d.mp3.backup”) so the same as filename which was uploaded by\r\nClient but with “.backup” added.\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 11 of 14\n\nFunction responsible for downloading payload with filename\r\n“Rock_ComputerNameUsernameMD5HashHexstring.mp3.backup” is “http_dropbox_download”. Decoded\r\nstrings of function “http_dropbox_download” (ex. HTTP User-Agent, HTTP Host “content.dropboxapi.com”,\r\nURL Path “/2/files/download”) can be seen in the picture below:\r\nFunction responsible for processing downloaded payload is “process_exec_downloaded_payload”. Before\r\nstepping into this function we can see some first structure checks of obtained payload which will later help to\r\nrecreate example structure of delivered payload.\r\nFunction “process_exec_downloaded_payload” is responsible for processing downloaded payload, decrypting it\r\nwith xor key “Username MD5 hash hexstring” (ex. \"70c29c906cfa19759fa4776ea7c0973e\") and creating new\r\nthread to execute it.\r\nFirst what we can see is xor decryption of downloaded payload which avoids processing first 21 bytes and last 36\r\nbytes. Xoring starts with 22. byte of downloaded content and ends (content_length -57 +21). According to this, we\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 12 of 14\n\ncan assume example of the downloaded payload format (“X” – unknown, “PAYLOAD_CODE_ENCRYPTED” –\r\nencrypted code with unknown length which will be later executed) as in the picture below:\r\nIn next step, this function is allocating enough executable memory for decrypted code. After this, syscalls\r\n“NtWriteVirtualMemory” and “NtCreateThreadEx” are resolved in similar manner as syscalls before via\r\n“resolve_syscall” function using already created table named “hashed_syscalls_table”. This table is used as\r\nlookup table to find specific syscall number for routine.\r\nSyscall “NtWriteVirtualMemory” is used to to write decrypted code to newly allocated executable memory.\r\nSyscall “NtCreateThreadEx” is used to create new thread in suspended state with flags set also to hide from\r\ndebugger.\r\nDecoy start routine “RtlNewSecurityObjectWithMultipleInheritance” of newly created thread is replaced with\r\nsetting the thread context of this thread – specifically via setting RCX register (NOT RIP as this new suspended\r\nthread is not initiated yet) pointing to decrypted code, already written to executable memory. Again this\r\ncombination of directly called syscalls and thread execution hijacking serves as AV evasion and anti-debug\r\ntechnique. RCX is the first argument to function “RtlUserThreadStart” (thread start location) and this argument\r\nsets new thread entry routine (downloaded, decrypted code) different than the decoy.\r\nAfter the downloaded and decrypted payload is executed in new thread, execution in current thread comes back to\r\nthe main function “C2_Client_MAIN”.\r\nAnother uploading to Dropbox is processed. This uploading is overwriting the same filename which was\r\ndownloaded “Rock_ComputerNameUsernameMD5HashHexstring.mp3.backup” (ex.\r\n“Rock_70a1e27ba30dd415155e68409d512a2d.mp3.backup”).\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 13 of 14\n\nThis serves probably to confirm execution of downloaded code. The content for Dropbox uploading which will be\r\noverwriting filename - “Rock_ComputerNameUsernameMD5HashHexstring.mp3.backup” is created again with\r\nfictive MP3 header, padding and “ME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUU” string which was\r\npreviously used as xor key. Structure of this content can be seen in the picture bellow:\r\nAll the main functionality of function “C2_Client_MAIN” - (without function “Map_dll_restore_text_section” –\r\nperformed only once) is executed in endless loop when after each loop the execution sleeps for 5.5 minutes.\r\nSource: https://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-D\r\nropboxLoader_analysis.md\r\nhttps://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://github.com/Dump-GUY/Malware-analysis-and-Reverse-engineering/blob/main/APT29_C2-Client_Dropbox_Loader/APT29-DropboxLoader_analysis.md"
	],
	"report_names": [
		"APT29-DropboxLoader_analysis.md"
	],
	"threat_actors": [
		{
			"id": "5b748f86-ac32-4715-be9f-6cf25ae48a4e",
			"created_at": "2024-06-04T02:03:07.956135Z",
			"updated_at": "2026-04-10T02:00:03.689959Z",
			"deleted_at": null,
			"main_name": "IRON HEMLOCK",
			"aliases": [
				"APT29 ",
				"ATK7 ",
				"Blue Kitsune ",
				"Cozy Bear ",
				"The Dukes",
				"UNC2452 ",
				"YTTRIUM "
			],
			"source_name": "Secureworks:IRON HEMLOCK",
			"tools": [
				"CosmicDuke",
				"CozyCar",
				"CozyDuke",
				"DiefenDuke",
				"FatDuke",
				"HAMMERTOSS",
				"LiteDuke",
				"MiniDuke",
				"OnionDuke",
				"PolyglotDuke",
				"RegDuke",
				"RegDuke Loader",
				"SeaDuke",
				"Sliver"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "a241a1ca-2bc9-450b-a07b-aae747ee2710",
			"created_at": "2024-06-19T02:03:08.150052Z",
			"updated_at": "2026-04-10T02:00:03.737173Z",
			"deleted_at": null,
			"main_name": "IRON RITUAL",
			"aliases": [
				"APT29",
				"Blue Dev 5 ",
				"BlueBravo ",
				"Cloaked Ursa ",
				"CozyLarch ",
				"Dark Halo ",
				"Midnight Blizzard ",
				"NOBELIUM ",
				"StellarParticle ",
				"UNC2452 "
			],
			"source_name": "Secureworks:IRON RITUAL",
			"tools": [
				"Brute Ratel C4",
				"Cobalt Strike",
				"EnvyScout",
				"GoldFinder",
				"GoldMax",
				"NativeZone",
				"RAINDROP",
				"SUNBURST",
				"Sibot",
				"TEARDROP",
				"VaporRage"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "46b3c0fc-fa0c-4d63-a38a-b33a524561fb",
			"created_at": "2023-01-06T13:46:38.393409Z",
			"updated_at": "2026-04-10T02:00:02.955738Z",
			"deleted_at": null,
			"main_name": "APT29",
			"aliases": [
				"Cloaked Ursa",
				"TA421",
				"Blue Kitsune",
				"BlueBravo",
				"IRON HEMLOCK",
				"G0016",
				"Nobelium",
				"Group 100",
				"YTTRIUM",
				"Grizzly Steppe",
				"ATK7",
				"ITG11",
				"COZY BEAR",
				"The Dukes",
				"Minidionis",
				"UAC-0029",
				"SeaDuke"
			],
			"source_name": "MISPGALAXY:APT29",
			"tools": [
				"SNOWYAMBER",
				"HALFRIG",
				"QUARTERRIG"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "20d3a08a-3b97-4b2f-90b8-92a89089a57a",
			"created_at": "2022-10-25T15:50:23.548494Z",
			"updated_at": "2026-04-10T02:00:05.292748Z",
			"deleted_at": null,
			"main_name": "APT29",
			"aliases": [
				"APT29",
				"IRON RITUAL",
				"IRON HEMLOCK",
				"NobleBaron",
				"Dark Halo",
				"NOBELIUM",
				"UNC2452",
				"YTTRIUM",
				"The Dukes",
				"Cozy Bear",
				"CozyDuke",
				"SolarStorm",
				"Blue Kitsune",
				"UNC3524",
				"Midnight Blizzard"
			],
			"source_name": "MITRE:APT29",
			"tools": [
				"PinchDuke",
				"ROADTools",
				"WellMail",
				"CozyCar",
				"Mimikatz",
				"Tasklist",
				"OnionDuke",
				"FatDuke",
				"POSHSPY",
				"EnvyScout",
				"SoreFang",
				"GeminiDuke",
				"reGeorg",
				"GoldMax",
				"FoggyWeb",
				"SDelete",
				"PolyglotDuke",
				"AADInternals",
				"MiniDuke",
				"SeaDuke",
				"Sibot",
				"RegDuke",
				"CloudDuke",
				"GoldFinder",
				"AdFind",
				"PsExec",
				"NativeZone",
				"Systeminfo",
				"ipconfig",
				"Impacket",
				"Cobalt Strike",
				"PowerDuke",
				"QUIETEXIT",
				"HAMMERTOSS",
				"BoomBox",
				"CosmicDuke",
				"WellMess",
				"VaporRage",
				"LiteDuke"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434497,
	"ts_updated_at": 1775792236,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/044f070a516b2b3972eb5a298eda2b12cca0906d.pdf",
		"text": "https://archive.orkl.eu/044f070a516b2b3972eb5a298eda2b12cca0906d.txt",
		"img": "https://archive.orkl.eu/044f070a516b2b3972eb5a298eda2b12cca0906d.jpg"
	}
}