{
	"id": "3941031a-646f-413a-ade2-c8765be868c1",
	"created_at": "2026-04-06T00:07:50.603174Z",
	"updated_at": "2026-04-10T13:11:29.362359Z",
	"deleted_at": null,
	"sha1_hash": "cc3146354d196162127b1fbbac5159c4f30f4b77",
	"title": "Darkside Ransomware",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1925808,
	"plain_text": "Darkside Ransomware\r\nBy Chuong Dong\r\nPublished: 2021-05-06 · Archived: 2026-04-05 21:25:59 UTC\r\nReverse Engineering  · 06 May 2021\r\nOverview\r\nThis is my report for one of the latest Windows samples of Darkside Ransomware v1.8.6.2!\r\nSince there is not a lot of in-depth analysis on Darkside out there, I decided to just write one myself.\r\nDarkside uses aPLib algorithm to compress its configuration and a hybrid-cryptography scheme of custom RSA-1024 and Salsa20 to encrypt files and protect its keys.\r\nDespite using code obfuscation and sophisticated techniques for privilege escalation and encryption, the\r\nransomware is slower in encryption speed compared to others such as Babuk or Conti due to its recursive file\r\ntraversal.\r\nFigure 1: Darkside Ransomware leak site.\r\nIOCS\r\nThis particular sample that I used for my analysis is a 32-bit .exe file.\r\nThere are a Linux version that is more enjoyable to analyze but I’m too lazy to cover both…\r\nMD5: 9d418ecc0f3bf45029263b0944236884\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 1 of 52\n\nSHA256: 151fbd6c299e734f7853497bd083abfa29f8c186a9db31dbe330ace2d35660d5\r\nSample:\r\nhttps://bazaar.abuse.ch/sample/151fbd6c299e734f7853497bd083abfa29f8c186a9db31dbe330ace2d35660d5/\r\nFigure 2: VirusTotal information.\r\nRansom Note\r\nThe ransom note is encrypted and stored inside the aPLib-compressed configuration.\r\nThe GUID checksum is generated and appended to the end of each ransom note file name.\r\nFigure 3: Darkside ransom note.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 2 of 52\n\nStatic Code Analysis\r\nGenerate KEY_BUFFER\r\nUpon execution, Darkside generates a global 256-byte buffer. This buffer is significant since it is used to resolve\r\nAPIs and decrypt encrypted strings/buffers in memory.\r\nLet us call this buffer KEY_BUFFER. This buffer is generated using two hard-coded 16-byte keys in memory.\r\nFigure 4: 16-byte keys used to generate KEY_BUFFER\r\nHere is the function to generate KEY_BUFFER.\r\nIt first has a loop to write the 4 DWORDs from key1 into KEY_BUFFER and subtract 0x10101010 from each\r\nDWORD each time. Then, it has another loop to add bytes in key2 to bytes in KEY_BUFFER and swap them\r\naround.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 3 of 52\n\nFigure 5: KEY_BUFFER generation algorithm.\r\nI didn’t bother to understand this fully because it’s just a simple algorithm to generate a buffer. You can find my\r\nIDAPython implementation to automatically generate it here.\r\nBuffer Decryption Algorithm.\r\nAll strings and data buffers are encrypted in memory throughout the malware. Before using them, Darkside will\r\nallocate a heap buffer, decrypt the target data, and write it in before using it.\r\nThe decryption consists of a simple loop with byte swappings and a single XOR operation, which uses the data\r\nfrom the generated KEY_BUFFER.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 4 of 52\n\nFigure 6: Darkside’s data decryption algorithm.\r\nThis function, however, is only designed to decrypt at most 255 bytes because the size of the length parameter is\r\njust 1 byte.\r\nTo support bigger buffers, Darkside dedicates a wrapper function that calls decrypt_buff() for buffer_length / 255\r\ntimes with the length parameter of 255.\r\nIn case where the buffer length is not evenly divided by 255, the malware performs a modulus operation of\r\nbuffer_length % 255 and uses it as the length parameter for decrypt_buff() to decrypt the rest of the bytes.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 5 of 52\n\nFigure 7: Darkside’s large data decryption algorithm.\r\nDynamic API Resolve\r\nThe dynamic API resolve function repeats the following operations.\r\nFirst, it uses the decrypt_large_buffer() function to decrypt a library table in memory.\r\nThis table is divided into blobs with different sizes. The size of each blob is the 4-byte value that comes before it.\r\nFigure 8: Encrypted blob layout for all encrypted buffer in memory.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 6 of 52\n\nIn this table, each blob’s data is the encrypted version of a string, and this string can either be a DLL name or an\r\nAPI name.\r\nThe table is laid out in such a way that a blob with a DLL name comes first, and blobs with API names exported\r\nfrom that particular DLL come after.\r\nIf we perform the decryption on the entire table and eliminate the bytes representing the blobs’ size, we will get\r\nthis.\r\nFigure 9: Decrypted library table layout\r\nAfter decrypting a DLL name, it then calls LoadLibraryA to load that library and begin importing the address\r\ninto an API array in memory. The malware also wipes each decrypted string from memory whenever it finishes\r\nusing it.\r\nThis operation is repeated until it has gone through all libraries in the table.\r\nFigure 10: Dynamically importing APIs from the table.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 7 of 52\n\nThe function to import the APIs for each library executes a loop that decrypts an API’s name, calls\r\nGetProcAddress, and writes each API’s address into the array every time.\r\nFigure 11: Function to import APIs from a library.\r\nAs we can see, the API array is built in a sequential order from the first to the last API blob, and it is simple to\r\nwrite a script to decrypt all APIs names and write to the API array accordingly to automatically resolve all APIs.\r\nYou can view my IDAPython script to automatically import them into IDA here.\r\nAfter running the script, the table will look like this, which makes static analysis much simpler.\r\nFigure 12: Before and after importing APIs.\r\nConfiguration Resolve\r\nThe encrypted configuration is stored in memory and ends with the DWORD 0xDEADBEEF. Because calling\r\ndecrypt_large_buffer() requires knowing the encryped buffer size, this DWORD is necessary to iteratively find\r\nthe configuration size.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 8 of 52\n\nFigure 13: Configuration decryption.\r\nAfter calling decrypt_large_buffer(), the decrypted configuration has this specific layout.\r\n- Offset 0x0 - 0x7F: RSA-1024 exponent\r\n- Offset 0x80 - 0x103: RSA-1024 modulus\r\n- The rest: aPLib-compressed configuration.\r\nUsing the constants in comparison operations throughout the algorithm, it is quite simple to spot that Darkside\r\ndecompresses using the aPLib algorithm.\r\nFigure 14: aPLib decompress constants.\r\nSince aPLib libraries are wildly available, I just grabbed a Python implementation on Github to decompress and\r\nparse the configuration into a JSON file. You can get my script to generate this JSON file here.\r\nBelow is the full configuration of this sample in JSON format.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 9 of 52\n\n{\r\n \"VICTIM_ID\": \"[0x30, 0x36, 0x30, 0x31, 0x30, 0x38, 0x65, 0x66, 0x62, 0x35, 0x31, 0x30, 0x63, 0x39, 0x38, 0x0,\r\n \"ENCRYPTION_MODE\": \"Full\",\r\n \"AVOID_PROCESS_FLAG\": true,\r\n \"ENCRYPT_ALL_DRIVES_FLAG\": true,\r\n \"ENCRYPT_NET_SHARED_RESOURCE_FLAG\": true,\r\n \"CHECK_RUSSIAN_COMP_FLAG\": true,\r\n \"DELETE_SHADOW_COPIES_FLAG\": true,\r\n \"WIPE_RECYCLE_BIN_FLAG\": true,\r\n \"SELF_DELETE_FLAG\": true,\r\n \"UAC_ELEVATION_FLAG\": true,\r\n \"AdjustTokenPrivileges_FLAG\": true,\r\n \"LOGGING_FLAG\": false,\r\n \"DIRECTORY_TO_AVOID_FLAG\": true,\r\n \"FILE_TO_AVOID_FLAG\": true,\r\n \"FILE_EXTENSION_FLAG\": true,\r\n \"DIR_TO_REMOVE_FLAG\": true,\r\n \"SQL_SQL_LITE_FLAG\": true,\r\n \"PROCESS_TO_KILL_FLAG\": true,\r\n \"SERVICE_TO_KILL_FLAG\": true,\r\n \"THREAT_WALLPAPER_FLAG\": true,\r\n \"RANSOM_NOTE_FLAG\": true,\r\n \"CHANGE_ICON_FLAG\": true,\r\n \"BUILD_MUTEX_FLAG\": true,\r\n \"THREAD_OBJECT_FLAG\": false,\r\n \"C2_URL_FLAG\": true,\r\n \"DIRECTORY_TO_AVOID\": \"$recycle.bin, config.msi, $windows.~bt, $windows.~ws, windows, appdata, application dat\r\n \"FILE_TO_AVOID\": \"autorun.inf, boot.ini, bootfont.bin, bootsect.bak, desktop.ini, iconcache.db, ntldr, ntuser.\r\n \"FILE_EXTENSION_TO_AVOID\": \"386, adv, ani, bat, bin, cab, cmd, com, cpl, cur, deskthemepack, diagcab, diagcfg,\r\n \"DIR_TO_REMOVE\": \"backup\",\r\n \"SQL_STRING\": \"sql, sqlite\",\r\n \"PROCESS_TO_AVOID\": \"vmcompute.exe, vmms.exe, vmwp.exe, svchost.exe, TeamViewer.exe, explorer.exe\",\r\n \"PROCESS_TO_KILL\": \"sql, oracle, ocssd, dbsnmp, synctime, agntsvc, isqlplussvc, xfssvccon, mydesktopservice, o\r\n \"SERVICE_TO_KILL\": \"vss, sql, svc$, memtas, mepocs, sophos, veeam, backup, GxVss, GxBlr, GxFWD, GxCVD, GxCIMgr\r\n \"C2_URL\": \"securebestapp20.com, temisleyes.com\",\r\n \"THREAT_STRING\": \"All of your files are encrypted! \\r\\n \\r\\n Find %s and Follow Instructions!\",\r\n \"RANSOM_NOTE\": \"----------- [ Welcome to DarkSide ] -------------\u003e \\r\\n \\r\\n What happend? \\r\\n -------------\r\n}\r\nPrivilege Escalation\r\nAfter exporting the configuration, the malware then checks if it has admin privileges by calling IsUserAnAdmin.\r\nIf the user is not an admin, it performs a check on the user’s token information to verify if their token has the first\r\nsubauthority value of SECURITY_BUILTIN_DOMAIN_RID and the second subauthority value of\r\nDOMAIN_ALIAS_RID_ADMINS.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 10 of 52\n\nFigure 15: Function to check token’s privileges.\r\nThis check is necessary for the next step, where Darkside performs UAC elevation to relaunch itself with higher\r\nprivileges. This is an old elevation trick to perform UAC bypass via ICMLuaUtil Elevated COM Interface.\r\nMicrosoft has great documentation for this here.\r\nThe bypass is only performed if the UAC_ELEVATION_FLAG in the configuration is set to 1.\r\nFigure 16: CoCreateInstanceAsAdmin implementation.\r\nThis function executes CoGetObject with the object name being Elevation:Administrator!new:{3E5FC7F9-\r\n9A51-4367-9063-A120244FBEC7}.\r\nBy checking with Registry Editor, we can see that this CLSID belongs to cmstplua.dll in system32, and\r\nCoGetObject will retrieve an ICMLuaUtil interface with an administrator’s credentials.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 11 of 52\n\nFigure 17: Registry Editor result for {3E5FC7F9-9A51-4367-9063-A120244FBEC7}.\r\nUsing this interface, Darkside calls the interface’s ShellExec function to execute the malware again with the\r\nupdated privileges.\r\nFigure 18: Elevated ShellExec call to relaunch the ransomware.\r\nAdjust Token Privileges\r\nIf the AdjustTokenPrivileges_FLAG is set to 1 in the configuration, Darkside will get the current process’s\r\ntoken through OpenProcessToken and change the privilege to SE_PRIVILEGE_ENABLED to enable the\r\ntoken’s privilege.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 12 of 52\n\nFigure 19: Adjust Token Privileges function.\r\nSecurity Context Impersonation\r\nIf possible, Darkside tries to have its process impersonate the security context of a logged-on user on the system.\r\nFirst, it checks if the logged-on user has an account with the referenced domain name of NT AUTHORITY,\r\nAUTORITE NT, or NT-AUTORITÄT. This is done by calling GetTokenInformation to retrieve the user’s SID and\r\nthen LookupAccountSidW to look up the referenced domain name.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 13 of 52\n\nFigure 20: Function to check if the user’s token has NT AUTHORITY.\r\nIf the user’s token has NT AUTHORITY, Darkside then retrieves the user’s token by calling\r\nWTSGetActiveConsoleSessionId and WTSQueryUserToken.\r\nFigure 21: Function to retrieve user’s token.\r\nDarkside stores this token in memory and calls ImpersonateLoggedOnUser upon file encryption.\r\nGUID Checksum\r\nDarkside first has a function to perform CRC32 hashing and XOR operations. This function uses 0xDEADBEEF\r\nas the first CRC32 value and performs XOR operations with the data blob in between.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 14 of 52\n\nFigure 22: Function to generate CRC32 checksum.\r\nTo generate the victim’s checksum using their GUID, Darkside goes through 4 rounds of this CRC32 checksum\r\nfunction on the victim’s machine GUID. It also has a function to convert the final checksum from bytes into hex\r\nstring form.\r\nFigure 23: Function to generate GUID checksum.\r\nFile Logging\r\nIf the LOGGING_FLAG in the configuration is set to 1, the ransomware will begin logging every operation into\r\na log file.\r\nFirst, it generates the log file name by formatting the GUID checksum into LOG%s.TXT.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 15 of 52\n\nFigure 24: Function to generate log file name.\r\nNext, Darkside creates the log file in the same folder as the malware executable using GetModuleFileNameW\r\nand CreateFileW.\r\nFigure 25: Function to create log file in current directory.\r\nRansom Note Readme File\r\nIf the RANSOM_NOTE_FLAG in the configuration is set to 1, the ransomware will generate a README file\r\nname. This file with the ransom note inside will be dropped on every directory that it encrypts.\r\nThe README file name is generated by formatting the GUID checksum into README%s.TXT.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 16 of 52\n\nFigure 26: Function to generate README file name.\r\nCommand Line Parameters\r\nDarkside can take command line parameters of -path and a directory name. This can be uses to specifically\r\nencrypt the chosen directory using normal encryption.\r\nFigure 27: Darkside checking for -path parameter.\r\nIf -path is not provided but instead the parameter is a file name, the malware only encrypts that specific file.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 17 of 52\n\nFigure 28: Darkside checking for file parameter.\r\nIn the case where the folder/file path in the parameter is a link (.lnk), Darkside calls a function to find the full\r\npath to the folder/file from that link.\r\nThis function uses CoCreateInstance with the CLSID of {00021401-0000-0000-C000-000000000046} to query\r\nan interface from windows.storage.dll.\r\nIt probably uses IStorageFolderHandleAccess and IStorageFileHandleAccess interfaces to extract the full path\r\nfrom the link, but I’m not too sure about this.\r\nI’m kind of terrible at COM objects, so if anyone understands how this works, please hit me up!\r\nFigure 29: Function to query interfaces from windows.storage.dll to process .link files.\r\nRun-once Mutex\r\nIf the BUILD_MUTEX_FLAG in the configuration is set to 1, the ransomware will build a run-once mutex\r\nstring. By calling OpenMutex on the mutex, it can check to make sure that there is only one Darkside instance\r\nrunning at any point in time.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 18 of 52\n\nThe function to generate this mutex first retrieves the current malware file path and reads the file’s content into a\r\nheap buffer using GetModuleFileNameW, CreateFileW, GetFileSize, and ReadFile.\r\nThe file buffer checksum is then calculated by going through one round of CRC32_checksum_generator\r\nfunction.\r\nThe mutex string is decrypted by decrypt_large_buffer and added into the string\r\nGlobal\\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. All the “X”s in the string is then replaced with the hex\r\nstring of the file buffer checksum.\r\nThe Global part means that the mutex is visible in all terminal server sessions.\r\nFigure 31: Function to build mutex string.\r\nSingle File/Folder Encryption\r\nBecause the function to encrypt a single file/folder is only used when parameters are given, it is most likely for\r\ntesting purposes only. Therefore, this function is not too complex.\r\nFirst, it checks if CHECK_RUSSIAN_COMP_FLAG is set to 1 in the configuration. If it is, then it proceeds to\r\ncheck if the victim’s computer’s language is Russian by parsing the outputs of GetUserDefaultLangID and\r\nGetSystemDefaultUILanguage.\r\nIf the computer’s language is Russian, it exits immediately. I don’t think I need to go into details about why this\r\ncode block is here ;).\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 19 of 52\n\nFigure 31: Exiting immediately if computer’s language is Russian.\r\nI. Encrypt UNC Server Path\r\nNext, it checks if the file path is a path to a UNC server by calling PathIsUNCServerW. If it is, the UNC\r\nencryption function is called. In this function, Darkside enumerates through all network shared using\r\nNetShareEnum, builds a valid UNC network path for each, and calls the main_encryption function to encrypt\r\nthem.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 20 of 52\n\nFigure 32: UNC server enumeration and encryption function.\r\nII. Encrypt Normal Path\r\nIf a path does not lead to a UNC server, Darkside will build the valid path accordingly by checking if the path is a\r\nnetwork path, a path to a mounted network drive, or just a normal path on the system.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 21 of 52\n\nFigure 33: Building final file/folder path.\r\nHere is what goes into the log file if LOGGING_FLAG is 1.\r\nFigure 34: Encryption stats logging.\r\nBefore calling the main_encryption function to encrypt this final path, Darkside will try calling\r\nImpersonateLoggedOnUser(USER_TOKEN) if it has NT AUTHORITY to impersonate the user while\r\nperforming file encryption.\r\nFull Encryption\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 22 of 52\n\nWhen command line parameters are not provided, Darkside will perform a full encryption on the victim’s\r\nmachine, which includes many other operations such as contacting the C2 server, deleting shadow copies,\r\nterminating processes and services, …\r\nThis function also has the same code block to check for Russian language on the victim computer.\r\nI. Connecting To C2 \u0026 Sending Victim Information\r\nIf CONFIG_C2_URL_FLAG is set to 1 and the C2 URL is provided in the configuration, it will send the\r\nvictim’s OS information to the C2 server.\r\nThe function to extract user’s OS information uses functions such as GetUserNameW, GetComputerNameW,\r\nMachinePreferredUILanguage to find these informations.\r\nFigure 35: Extracting OS information.\r\nAfter having extracted everything, it will write all the datas into a string format into this JSON form.\r\n\"os\":{\r\n \"lang\":\"en-US\",\r\n \"username\":\"cdong49\",\r\n \"hostname\":\"DESKTOP-739L404\",\r\n \"domain\":\"WORKGROUP\",\r\n \"os_type\":\"windows\",\r\n \"os_version\":\"Windows 10 Education N\",\r\n \"os_arch\":\"x64\",\r\n \"disks\":\"C:69/99\",\r\n \"id\":\"c46289476b8ceea97117\"\r\n}\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 23 of 52\n\nNext, it will build a wrapper string to include the malware version and the victim’s UID with this OS information.\r\nFigure 36: Building full string for user’s information.\r\nThe final string will be in this JSON form.\r\n{\r\n \"bot\":{\r\n \"ver\":\"1.8.6.2\",\r\n \"uid\":\"060108efb510c98\"\r\n },\r\n \"os\":{\r\n \"lang\":\"en-US\",\r\n \"username\":\"cdong49\",\r\n \"hostname\":\"DESKTOP-739L404\",\r\n \"domain\":\"WORKGROUP\",\r\n \"os_type\":\"windows\",\r\n \"os_version\":\"Windows 10 Education N\",\r\n \"os_arch\":\"x64\",\r\n \"disks\":\r\n \"C:69/99\",\r\n \"id\":\"c46289476b8ceea97117\"\r\n }\r\n}\r\nThis string will be hashed by a manual hashing function. Again, I didn’t bother to understand this because it’s just\r\na hashing function and does not contribute anything to my understanding of the malware. It’s just here to make\r\nsure the information is not sent in plaintext.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 24 of 52\n\nFigure 37: Network data hashing function.\r\nThe hashed information string and the victim UID are then written into this format string, which is later used as\r\nthe network packet’s content to be sent to C2.\r\nrandom_num1=hash(information_string)\u0026random_num2=victim_UID\r\nFigure 38: Building network packet’s content.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 25 of 52\n\nAt this point, Darkside uses InternetOpenW and InternetConnectW to open a handle to an Firefox/80.0\r\nInternet application and connect to the C2 server at port 443.\r\nFigure 39: Connecting to C2.\r\nAfter a connection is established, it sends a POST request to the C2 using HttpOpenRequestW, decrypts the\r\nHTTP header, sets internet options using InternetSetOptionW, and finally sends the packet with the generated\r\ncontent buffer above.\r\nFigure 40: Sending victim’s information to C2.\r\nFinally, Darkside calls HttpQueryInfoW to query the status code and check to see if the packet is sent\r\nsuccessfully.\r\nII. Wiping Recycle Bin\r\nIf the WIPE_RECYCLE_BIN_FLAG in the configuration is set to 1 and the current process is ran as an\r\nADMIN, Darkside will try to wipe all recycle bin folders that it can find in the machine’s drives.\r\nFirst, to find a recycle bin folder in a given drive path, the function iteratively calls FindFirstFileExW and\r\nFindNextFileW to find a folder that contains ”*recycle*” in its name.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 26 of 52\n\nFigure 41: Function to find the recycle bin folder in a drive.\r\nAfter finding the path to the recycle bin, Darkside loops through each directory inside and calls a recursive\r\nfunction to completely empty it.\r\nFigure 42: Function to wipe the recycle bin folder.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 27 of 52\n\nThe recursive function is pretty simple. It uses FindFirstFileExW and FindNextFileW to find files and folders\r\ninside. If it finds a file, it will call DeleteFileW to delete it. If it finds a folder, it will recursively call itself again to\r\ndelete the folder’s contents and call RemoveDirectoryW to delete it.\r\nFigure 43: Recursive function to empty a given folder.\r\nIII. Deleting Shadow Copies\r\nIf the DELETE_SHADOW_COPIES_FLAG in the configuration is set to 1, Darkside will try to delete all\r\nshadow copies on the system. There are two different functions to handle this task based on the machine’s system\r\narchitecture.\r\nIf the machine is an 64-bit Windows machine, it decrypts a CMD command and execute it using\r\nCreateProcessW.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 28 of 52\n\nFigure 44: Executing a Powershell script to delete shadow copies.\r\nBelow is the decrypted CMD command.\r\npowershell -ep bypass -c \"(0..61)|%{$s+=[char][byte]('0x'+'4765742D576D694F626A6563742057696E33325F536861646F77\r\nThis command loops 61 times, extracts 2 characters at a time, converts it into a byte, and converts that byte into an\r\nASCII character.\r\nDecoding this string will produce this Powershell command, which gets each Win32_Shadowcopy object on the\r\nsystem and delete it.\r\nGet-WmiObject Win32_Shadowcopy | ForEach-Object {$_.Delete();}\r\nIf the machine is an 32-bit Windows machine, things are a bit fancier.\r\nDarkside will call CoInitializeEx, CoInitializeSecurity, and CoCreateInstance to create a single object of the\r\nclass IWbemLocator with the specified CLSID {4590F811-1D3A-11D0-891F-00AA004B2E24} to query from\r\nwbemprox.dll.\r\nUsing the object IWbemLocator, it calls the ConnectServer function to connect to the local “root/cimv2”\r\nnamespace and obtains a pointer to the IWbemServices object.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 29 of 52\n\nFigure 45: Using COM object to connect to ROOT/CIMV2.\r\nWith this IWbemServices object, Darkside executes the SQL query SELECT * FROM Win32_ShadowCopy to\r\nretrieve an enumerator of all the shadow copies in the local server.\r\nIt then loops through each of the shadow copy objects, gets its ID, and calls the object’s DeleteInstance function\r\nto delete itself.\r\nThis will eventually deletes all the shadow copy storage areas in the computer.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 30 of 52\n\nFigure 46: Extracting and deleting all shadow copies.\r\nIV. Killing Target Services\r\nIf the SERVICE_TO_KILL_FLAG in the configuration is set to 1, Darkside will traverse through all services\r\non the machine and kill any service that is in the configuration’s SERVICE_TO_KILL list.\r\nThis is done by calling OpenSCManagerW to open the service control manager and EnumServicesStatusExW\r\nto enumerate all services with SERVICE_WIN32 status.\r\nFigure 47: Opening service control manager.\r\nDarkside iteratively loops through these services and checks if each exists in the SERVICE_TO_KILL list. If it\r\nis, then the service is stopped and deleted with the ControlService and DeleteService calls.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 31 of 52\n\nFigure 48: Looping and killing services.\r\nIV. Killing Target Processes\r\nIf the PROCESS_TO_KILL_FLAG in the configuration is set to 1, Darkside will traverse through all processes\r\non the machine and terminate any process that is in the configuration’s PROCESS_TO_KILL list.\r\nThis is done by calling NtQuerySystemInformation to query an array of\r\nSYSTEM_PROCESS_INFORMATION structs with each containing a process name.\r\nDarkside iteratively loops through these processes and checks if each exist in the PROCESS_TO_KILL. If it is,\r\nthen the process is terminated using TerminateProcess.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 32 of 52\n\nFigure 49: Looping and terminating services.\r\nV. Encrypting All Local Drives\r\nIf the ENCRYPT_ALL_DRIVES_FLAG in the configuration is set to 1, Darkside will loop through all drives\r\nwith the drive type of DRIVE_FIXED, DRIVE_REMOVABLE, or DRIVE_REMOTE on the system. It then builds\r\nthe appropriate folder path for each drive and call main_encryption.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 33 of 52\n\nFigure 50: Encrypting all fixed, removable, and remote drives on the system is initiated.\r\nVI. Encrypting Shared Folders\r\nIf the ENCRYPT_NET_SHARED_RESOURCE_FLAG in the configuration is set to 1, Darkside will attempt\r\nto get all paths to shared folders on the network and encrypt them using main_encryption.\r\nFirst, it calls a function to extract all network host addresses with two sub-functions.\r\nThe first sub-function calls GetAdaptersInfo and inet_addr to extract the addresses of other hosts on the\r\nnetwork. It then calls the second sub-function and provide these addresses as the parameter.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 34 of 52\n\nFigure 51: Sub-function to find host address and call second sub-function.\r\nThe second sub-function launches threads using CreateThread to call SendARP and gethostbyaddr to find other\r\nhosts’ name on the network through their addresses.\r\nFigure 52: Second sub-function to find host name.\r\nAfter finding all host names and putting them into a global array, Darkside calls NetShareEnum to enumerate\r\nthrough all network shared folders, builds the appropriate network paths, and calls main_encryption to encrypt\r\nthem.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 35 of 52\n\nFigure 53: Shared folders enumeration and encryption.\r\nVII. Sending C2 Server Encryption Stats\r\nAfter the encryption is finished and if the CONFIG_C2_URL_FLAG is set to 1 in the configuration, Darkside\r\nwill send the C2 server the final encryption stats.\r\nFirst, it decrypts the format string for this packet and starts writing the victim ID, UID, encrypted file count,\r\nencryption size, skipped file count, and elapsed time into this format string.\r\nIt then uses this formatted string as the buffer to call the function documented here.\r\nFigure 54: Function to send encryption stats to C2 server.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 36 of 52\n\nMain Encryption\r\nWe finally come to the juiciest part of the ransomware, the main encryption function! This function is fairly\r\ncomplex, so I’ll divide my analysis into parts again.\r\nI. Initial Operations\r\nBefore the encryption takes place, the malware checks if the system has at least 0x6400000 bytes or 100 MBs of\r\nfree space. This space is necessary for dropping a ransom note in every directory and because the encryption also\r\nincreases each file by a set ammount.\r\nFigure 55: Checking if the system has enough space prior to encryption.\r\nIf the CONFIG_C2_URL_FLAG in the configuration is set to 1, Darkside also starts recording the time that it\r\nbegins encryption by calling GetTickCount.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 37 of 52\n\nFigure 56: Starting time count.\r\nII. Creating Worker Threads\r\nDarkside uses multithreading with I/O completion port to communicate between the main thread and the worker\r\nthreads and speed up encryption. This can potentially be really good, but there is unfortunately one design flaw\r\nthat slows the entire process down.\r\nFirst, Darkside creates 2 I/O completion ports by calling CreateIoCompletionPort, which are used by the main\r\nthread to send file data to be encrypted to worker threads.\r\nNext, it spawns a set number of threads based on the processor count of the system. It will spawn 2 threads for\r\neach processor count, but this maxes out at 64 threads even if there are more than 32 processors.\r\nFigure 57: I/O ports and worker threads creation.\r\nIt’s best to have one thread per processor, but because the multithreading design of Darkside does not maximize\r\nthe system’s processing power, it doesn’t matter that much.\r\nEach of these threads is added to a global thread array to make cleaning up more organized by calling\r\nWaitForMultipleObjects with the array as its parameter.\r\nIII. Recursive Directory Traversal\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 38 of 52\n\nThe only mistake in this ransomware is that its main thread uses a depth-first search algorithm of recursive\r\ntraversal, which slows down the encryption speed significantly despite the good multithreading setup.\r\nFirst, in the recursive function, the main thread calls SetEntriesInAclW and SetNamedSecurityInfoW to\r\naccess/audit control and security information of the directory that is being processed. Below is the hard-coded\r\nEXPLICIT_ACCESS_W struct with the new security and access information.\r\nFigure 59: the EXPLICIT_ACCESS_W struct to set access/audit control information for directories.\r\nNext, if the RANSOM_NOTE_FLAG in the configuration is set to 1, Darkside will drop a ransom note in the\r\nprocessed directory using this function.\r\nFigure 60: Function to drop ransom note in encrypted directories.\r\nThe file/directory checks come after this. First, to begin calling FindFirstFileExW on the current directory, it\r\nmust add the characters ”\\\\*” to the end of the directory name. As it loops through the folder to find sub-directories and files using FindNextFileW, it first checks to avoid the two directory names ”.” and *..”, which\r\nlink to the current directory and parent directory. These two can cause the program to go into an infinite recursion\r\nif the malware does not avoid them.\r\nIt also checks the file attribute to avoid the sub-directories/files that have the attribute\r\nFILE_ATTRIBUTE_ENCRYPTED.\r\nAfter these checks, if the current path points to a directory and the DIRECTORY_TO_AVOID_FLAG is set to\r\n1, then another check is performed to make sure that the sub-folder’s name is not in the\r\nDIRECTORY_TO_AVOID list.\r\nOnce all the checks are completed, its sub-directory path is passed as the parameter to the recursive function.\r\nThe recursive function is called upon encountering a folder to traverse through all of its sub-folders.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 39 of 52\n\nFigure 61: Checking for directories and call recursive function.\r\nIf the current path points to a file, Darkside checks the following:\r\nIf the file name is not a README file.\r\nIf its extension is not .TXT.\r\nIf its content is not the the ransom note (through compare CRC32 file hashes).\r\nIf FILE_TO_AVOID_FLAG is 1 and the file name is not in CONFIG_FILE_TO_AVOID.\r\nIf FILE_EXTENSION_TO_AVOID_FLAG is 1 and the file extension is not in\r\nFILE_EXTENSION_TO_AVOID.\r\nIf all of these are true, Darkside proceeds with processing the file.\r\nIf SQL_SQL_LITE_FLAG is 1 and the filename is in SQL_STRING, it sets the ENCRYPTION_MODE to\r\nFull Encryption.\r\nFigure 62: File checks.\r\nAfter the file checks, Darkside’s main thread starts processing and sends the file data to the worker threads.\r\nIV. Check If File Is Encrypted\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 40 of 52\n\nFirst, the file path is properly fixed, and a sub-function is called to check if the file has been encrypted or not. This\r\ncheck is done by reading the last 0x90 bytes into a heap buffer and generate a checksum for the first 0x80 bytes\r\nusing CRC32_checksum_generator. This checksum is compared against the last 0x10 bytes of the buffer, and if\r\nthey match, it means the file is encrypted.\r\nThis also gives us a hint that after the encryption, a blob with the encrypted Salsa matrix as the first 0x80 bytes\r\nand the key’s checksum as the last 0x10 bytes is appended at the end of each file.\r\nFigure 63: Function to check if a file is encrypted or not.\r\nV. Terminate Process That Uses File\r\nIf PROCESS_TO_AVOID_FLAG is set to 1 in the configuration, Darkside calls a function to find and close\r\nanother process that currently uses the file.\r\nThis function has an while loop to continuously check all processes by calling OpenProcess to get a process\r\nhandle, spawn a thread to call NtQueryInformationFile to get the file owned by this process, and compare that\r\nfilename with the to-be-encrypted filename.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 41 of 52\n\nFigure 64: Finding a process that is using the to-be-encrypted file.\r\nIf that process is accessing the to-be-encrypted filename, Darkside will iteratively check to make sure that the\r\nprocess is not in the PROCESS_TO_AVOID list and terminate it once the check is done.\r\nFigure 65: Terminating the process that is accessing the to-be-encrypted file.\r\nVI. Generate Encrypted File Name\r\nThe filename is copied into a new buffer, and the GUID checksum is appended to the end of the filename. This\r\nbuffer is later used as the encrypted filename, so Darkside again tries to terminate any process that uses this file.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 42 of 52\n\nFigure 66: Generating the encrypted file name.\r\nVII. Send File Data To Worker Threads\r\nDarkside makes 2 calls to CreateIoCompletionPort to create I/O completion ports associated with the encrypted\r\nfile handle.\r\nFigure 67: Creating I/0 completion ports associated with the file handle.\r\nIt then creates a buffer to add necessary data to send to the worker threads using these I/O completion ports.\r\nImportant data includes file-related information such as ENCRYPTION_MODE, file handle, and file size.\r\nThe buffer also includes the Salsa20 matrix, its RSA-1024 encrypted version, and the checksum of the encrypted\r\nkey.\r\nOnce this I/O buffer is ready, it is sent to the worker threads using calls to PostQueuedCompletionStatus.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 43 of 52\n\nFigure 68: Generating I/0 buffer and send it to worker threads.\r\nVIII. Salsa20 \u0026 Matrix Generation\r\nDarkside makes multiple calls to RtlRandomEx to generate a 64-byte buffer.\r\nFigure 69: Randomly generating Salsa20 matrix.\r\nThe reason why this buffer is not a Salsa20 key is because it is way too long (typically Salsa20 key is at most 32-\r\nbyte long) and because Darkside actually modifies its Salsa20 implementation to not use any key.\r\nTypically, a pair of key-nonce is required to generate this Salsa20 initial state matrix.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 44 of 52\n\nFigure 70: Randomly generating Salsa20 matrix.\r\nHowever, Darkside skips this step completely and uses the randomly generated buffer as its Salsa20 matrix.\r\nThis does not impact the cryptography result of Salsa20 since it’s ultimately a XOR-cipher. To decrypt the file,\r\nthey just need to have access to this random buffer and use it as the Salsa20 matrix.\r\nIX. RSA-1024 Encryption\r\nDarkside’s custom RSA-1024 implementation is used to encrypt the Salsa20 matrix before appending it to the\r\nend of the encrypted file.\r\nThe RSA-1024 public key is embedded in Darkside encrypted configurations, and it’s divided into two blobs.\r\nThe first is the RSA-1024 exponent in little endian, which I’m not sure why. Since the author hand-coded this\r\nRSA-1024 implementation, I guess it makes things easier for them?\r\nThe second is the RSA-1024 modulus.\r\nFigure 71: Randomly generating Salsa20 matrix.\r\nBelow is a part of the RSA-1024 encryption function.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 45 of 52\n\nFigure 72: RSA-1024 encryption to produce cipher tex by calculating (data^exponent)%modulus.\r\nIt is quick to recognize that this is RSA-1024 encryption with the mathematic functions. Note that the RSA-1024\r\nexponent is being read from front to back with the AND operation, which tells us that it is in little endian.\r\nThe mathematical operations modulus of big numbers are also confusing because they perform raw modulus\r\ncalculation using addition and subtraction.\r\nFigure 73: Function to calculate (A*B)%N.\r\nFor multiplication, it rotates B to the left by 1 every time and add A to the result when there is no carry after the\r\nrotation.\r\nFor modulus, it keeps subtracting N from the result until it gets a carry (subtraction results in a negative number),\r\nwhich it then adds N back into the result.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 46 of 52\n\nThe functions to add/subtract big numbers also tell us that the result of RSA-1024 encryption is also in little\r\nendian since operations are performed from the lowest index to the highest one on each number.\r\nFigure 74: Result buffer is calculated in little endian format.\r\nX. I/O Worker Threads\r\nThe worker threads share the same functionality, each of which loops infinitely until the main thread signals to\r\nclose them using CloseHandle.\r\nThe threads constantly call GetQueuedCompletionStatus on their own I/O completion port until they receive a\r\nblob containing information about a file from the main thread.\r\nFigure 75: Worker thread calling GetQueuedCompletionStatus to receive data blob.\r\nHere is some important offset in the data blob.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 47 of 52\n\n0x5: current file offset low\r\n0x6: current file offset high\r\n0x7: number of bytes to jump to next block depending on ENCRYPTION_MODE (0x80000 for FULL, -1\r\nfor FAST, and dynamically changed based on file size for AUTO)\r\n0x9: number of times to begin encrypting 0x80000 bytes\r\n0xB: File handle\r\n0xC: Encryption state\r\n0x2d: File size\r\n0xD: Random Salsa20 Matrix\r\n0x1D: RSA_1024(Salsa20_matrix)\r\n0x3d: CRC32_checksum_generator(RSA_1024(Salsa20_matrix))\r\n0x41: File buffer\r\nUpon receiving this, they check the byte at offet 0xC of the blob to determine between 4 encrypting states.\r\nThe pre-encryption state occurs when blob[0xc] is 0, and the thread just calls ReadFile to read 0x80000 bytes\r\nfrom the current file offset into the file buffer. It then sets blob[0xc] to 1 to transition into the encryption state. If it\r\nreaches the EOF and the last error number is ERROR_HANDLE_EOF, the thread skips to post-encryption state.\r\nFigure 76: Pre-encryption code block.\r\nThe encryption state occurs when blob[0xc] is 1, and the thread will encrypt the file buffer normally using\r\nSalsa20. Darkside encrypts one 0x80000-byte block at a time and jumps to the next block right after. If blob[0x7]\r\nis not -1, it will jump to the next blob by appending blob[0x7] to the current file offset. This is to skip the\r\nencrypting portions of the file when it is too large. If blob[0x7] is -1, the encryption state is changed to the post-encryption state. The encrypted file buffer is then written back into the file using WriteFile and the thread goes\r\nback to the pre-encryption state with the updated file offset.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 48 of 52\n\nFigure 77: Encryption code block.\r\nThe post-encryption state occurs when blob[0xc] is 2. In this state, the encrypted Salsa20 matrix and its checksum\r\nare written into the end of the file using WriteFile. After this operation, the thread enters the cleaning up state.\r\nFigure 78: Post-encryption code block.\r\nThe cleaning up state occurs when blob[0xc] is 4. The thread just closes the file handle and go back to calling\r\nGetQueuedCompletionStatus to receive a new file blob.\r\nFigure 79: Cleaning up code block.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 49 of 52\n\nSelf Deletion\r\nAt the end of the program, if SELF_DELETE_FLAG is set to 1 in the configuration, Darkside will execute a\r\ncommand to delete itself.\r\nFirst, it gets the short path of the current malware executable by calling GetModuleFileNameW and\r\nGetShortPathNameW.\r\nIt decrypts the environment variable name “ComSpec” and uses it to get the path to CMD.EXE.\r\nFinally, it calls ShellExecuteW to execute this command:\r\nCMD.EXE /C DEL /F /Q short_malware_path \u003e\u003e NUL\r\nThis CMD.EXE command executes the DEL command. The /F flag is enabling auto-completion of path names\r\nentered, which is necessary to extend the short path into a full path. The /Q just turns echo off for stealth!\r\nFigure 80: Cleaning up code block.\r\nDarkside Encryption Speed Discussion\r\nDarkside uses a unique combination of multithreading and recursive file traversal to find and encrypt files.\r\nHowever, its speed is not that impressive due to the use of recursion.\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 50 of 52\n\nFigure 81: CPU comparison between Babuk and Darkside.\r\nWe can clearly see that Darkside encryption speed is clearly lacking since it does not abuse 100% of the victim’s\r\nCPU.\r\nThis is because Darkside suffers from thread starvation. Each worker thread can execute the encryption code\r\nblock relatively fast, but some of them are starved by the main thread and never gets a chance to do work.\r\nBy design, the main thread’s job is to recursively traverse through folders in a depth-first search manner, so the\r\nworker threads can only encrypt what the main thread sends them.\r\nStarvation arises when the main thread can’t traverse and send files fast enough while the receiving threads\r\nalready finish their work. Therefore, unless the main thread has a constant throughput of 32 files being sent to I/O\r\ncompletion ports at any given point in time, some thread will definitely be starved, and the CPU will not be fully\r\nutitlized.\r\nBeside the fact that this throughput is almost impossible to obtain by a single thread, the total encryption time is\r\nstill skewed toward the time it takes for the main thread to finish traversing the system.\r\nThis design ultimately defeats the purpose of using multithreading and I/O completion port.\r\nYARA rule\r\nrule DarksideRansomware1_8_6_2 {\r\n meta:\r\n description = \"YARA rule for Darkside v1.8.6.2\"\r\n reference = \"http://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\"\r\n author = \"@cPeterr\"\r\n tlp = \"white\"\r\n strings:\r\n $hash_alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\r\n $gen_key_buff = {89 54 0E 0C 89 44 0E 08 89 5C 0E 04 89 3C 0E 81 EA 10 10 10 10 2D 10 10 10 10 81 EB 10 10\r\n $dyn_api_resolve = {FF 76 FC 56 E8 91 FE FF FF 56 E8 ?? 69 00 00 8B D8 FF 76 FC 56 E8 85 FB FF FF 8B 46 FC 8\r\n $get_config_len = {81 3C 18 DE AD BE EF 75 02 EB 03 40 EB F2}\r\n $RSA_1024_add_big_num = {8B 06 8B 5E 04 8B 4E 08 8B 56 0C 11 07 11 5F 04 11 4F 08 11 57 0C}\r\n $CRC32_checksum = {FF 75 0C FF 75 08 68 EF BE AD DE FF 15 ?? ?? ?? 00 FF 75 0C FF 75 08 50 FF 15 ?? ?? ?? 00\r\n condition:\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 51 of 52\n\nall of them\r\n}\r\nSamples\r\nI got my sample from MalwareBazaar!\r\nHuge shoutout to @JAMESWT_MHT for uploading the sample!\r\nSpecial Thanks\r\nA special thanks to Michael Gillespie for assisting me during the analysis and sharing his resources!\r\nReferences\r\nhttps://zawadidone.nl/2020/10/05/darkside-ransomware-analysis.html\r\nhttps://ghoulsec.medium.com/mal-series-13-darkside-ransomware-c13d893c36a6\r\nhttps://pastebin.com/mnvEUNaP\r\nhttps://raw.githubusercontent.com/k-vitali/Malware-Misc-RE/master/2020-12-01-darkside-ransom-1.3-vk-cfg.raw\r\nhttps://github.com/snemes/aplib\r\nSource: http://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nhttp://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/\r\nPage 52 of 52\n\nFigure 4: 16-byte Here is the function keys used to to generate generate KEY_BUFFER KEY_BUFFER.    \nIt first has a loop to write the 4 DWORDs from key1 into KEY_BUFFER and subtract 0x10101010 from each\nDWORD each time. Then, it has another loop to add bytes in key2 to bytes in KEY_BUFFER and swap them\naround.      \n   Page 3 of 52",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"http://chuongdong.com/reverse%20engineering/2021/05/06/DarksideRansomware/"
	],
	"report_names": [
		"DarksideRansomware"
	],
	"threat_actors": [],
	"ts_created_at": 1775434070,
	"ts_updated_at": 1775826689,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/cc3146354d196162127b1fbbac5159c4f30f4b77.pdf",
		"text": "https://archive.orkl.eu/cc3146354d196162127b1fbbac5159c4f30f4b77.txt",
		"img": "https://archive.orkl.eu/cc3146354d196162127b1fbbac5159c4f30f4b77.jpg"
	}
}