{
	"id": "eeffd5bc-230b-4ebf-9387-d5b956aa4eb1",
	"created_at": "2026-04-10T03:21:43.520536Z",
	"updated_at": "2026-04-10T13:12:53.468919Z",
	"deleted_at": null,
	"sha1_hash": "12d7a4d36489aa2eba001e0138cf3fccad5a7954",
	"title": "[Case Study: Latrodectus] Analyzing and Implementing String Decryption Algorithms - 0x0d4y Malware Research",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2592933,
	"plain_text": "[Case Study: Latrodectus] Analyzing and Implementing String\r\nDecryption Algorithms - 0x0d4y Malware Research\r\nBy 0x0d4y\r\nPublished: 2024-05-09 · Archived: 2026-04-10 02:54:03 UTC\r\nThis article has a slightly different objective than the last ones I published, it is not about an analysis of specific malware.\r\nToday’s article is about a case study of the Latrodectus string decryption algorithm (analyzed in the previous research).\r\nThe objective is to study how to identify a string decryption algorithm when reverse engineering a malware, and how we can\r\nimplement it in Python to statically decrypt them. Specifically, we will cover how to identify whether malware is using a\r\ncustom decryption algorithm to obfuscate strings.\r\nSo, let’s go!\r\nWhy Do Adversaries Encrypt Strings?\r\nIt may seem obvious, but it’s good to clarify why adversaries encrypt strings to use in their Malware.\r\nThe short and thick answer is, to achieve the technical objective of Obfuscation! The implementation of encryption to\r\nobfuscate strings allows adversaries to hide strings that reveal the objective of the actions that the malware will perform.\r\nThis technique is registered with MITRE ATT\u0026CK as Obfuscated Files or Information: Encrypted/Encoded File\r\n[T1027.013].\r\nLet’s use the example of WannaCry, which does not implement the string encryption technique. Below, we can see the\r\nsimple use of the strings command, present in every Linux system.\r\nAs you can see in the image above, without implementing this obfuscation technique, the malware is more vulnerable to\r\ndetections by security products, and our analysis is simpler :,) .\r\nNow let’s do the same test on a Latrodectus sample.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 1 of 10\n\nAnd as we can see above, it was not possible to detect with the strings command any inconsistencies in URLs or binaries, as\r\nwe analyzed Latrodectus previously, we know that it communicates with two C2 servers, so this means one thing,\r\nLatrodectus implements a encryption to obfuscate strings, and decrypts at runtime!\r\nNow that we understand why adversaries implement this obfuscation technique, let’s understand how we can identify the use\r\nof a decryption algorithm in malware.\r\nHow to Identify the Implementation of a Decryption Algorithm?\r\nFirstly, there is no single correct answer to this question, secondly, here comes the famous ‘it depends’!\r\nAdversaries will always seek to implement custom encryption algorithms to obfuscate strings and some payloads. This is\r\nbecause using known algorithms, whether through Windows APIs or by manually implementing a known algorithm, can\r\nreduce the adversary’s chances of passing through detections and slowing down our rate of analysis of their sample. This is\r\nbecause the algorithm is already known to us, therefore, it is easier to identify constants or the flow of a given algorithm.\r\nBut when the adversary goes down the path of implementing its own algorithm, it runs the risk of implementing something\r\nsimpler than what already exists. This is because the adversary certainly does not want to disrupt the functioning of the\r\nmalware. Another risk that the adversary may run is that, once identified by a researcher, detections to monitor the presence\r\nof a particular malware family will come into existence, in addition to automated extractors using scripts. Therefore, these\r\ncustom algorithms are short-lived.\r\nBut how can we identify that a malware has a string decryption routine? Let’s go.\r\nAs I said earlier, there is no single method of identification. So here are some tips, and then we will analyze how the\r\nbehavior is observed in Latrodectus.\r\nA single function is called dozens or hundreds of times during code execution (the amount will depend on the\r\nmalware);\r\nThe function will probably be receiving as an argument an offset that points to a block of data, probably encrypted.\r\nWhen looking at the function execution flow graph, you will probably find one or more loops that perform operations\r\non the data. The likely operation you will encounter will be the XOR operation, which will have the encrypted data\r\nand the XOR key as protagonists of this operation.\r\nAnother tip I can give is to identify in your favorite Disassembler if there are several blocks of data that are called by\r\nthe same function during code execution.\r\nBelow we can see that in Latrodecuts it is possible to identify some of these patterns that I mentioned above.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 2 of 10\n\nFunction sub_18000ae78 is called 121 times during Latrodectus execution. Another pattern that we can detect is that this\r\nfunction receives a set of data as an argument, and stores the result of the function’s manipulation in a buffer.\r\nBelow we can observe the encrypted data block that is passed as an argument (data_18000fa00), in addition to being able to\r\nobserve the other encrypted data blocks.\r\nIf we look at the execution flow in graphical mode, we will also detect another pattern, a loop that manipulates data through\r\nXOR operations.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 3 of 10\n\nNow that we have been able to identify the string decryption function, let’s analyze how it works statically and dynamically.\r\nHere, we begin our hands-on adventure. First, when we are going to do our dynamic analysis as a complement to the static\r\none, we need to locate the exact decryption function in the debugger, so as not to get lost. In the debugger we do not have\r\nthe Decompiler crutch, so it is important that during dynamic analysis using a debugger, you have the\r\ndisassembler/decompiler open.\r\nIn the decompiler, we can see below the exact moment when our decryption function is called for the first time in the code.\r\nAnd below, we can observe the same moment. As our notes will not be present in the debugger, it is recommended that you\r\nset seven breakpoints and write comments, to remember where each action is done.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 4 of 10\n\nTo validate where we are, below we can see the content of the encrypted data block that the xor_decrypt function (renamed\r\nby me, for documentation purposes) receives as an argument.\r\nIf we do the same thing with address 7FFF11D2FA00, we will observe the same data.\r\nWhen we enter the function (Step-In in the debugger), we can also validate that the execution flow through graphical mode\r\nis the same. You can observe the comparison in the sequence of images, and see that we are in fact in the correct function.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 5 of 10\n\nWe can also use Decompiler to give us a hand in analyzing this algorithm. In our pseudo-code, we can see that first there is\r\nan XOR operation between some bytes within the data block itself. Then, rcx_1 is used as a conditional for the while loop to\r\ncontinue executing, as long as var_14 (set to 0) is less than rcx_1. This is where we can assume from experience that right\r\nnow the algorithm is calculating the value of the block of data that will be decrypted. After all, the block needs to have an\r\nend.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 6 of 10\n\nTo validate, we can check in the debugger. Below, we can see the suspicions of what we saw in the pseudo-code above. The\r\nalgorithm selected two bytes present in the data block, 0x7e and 0x6e, and performed an XOR operation between these two\r\nvalues.\r\nThe value of this XOR operation was 0x10, as we can see in the RCX register.\r\nIf we check in our Disassembler, byte 0x7e is the first byte of the every data block, and 0x6e is the fifth byte of this specific\r\ndata block. In the image below, we can also redo the operation through the Binary Ninja Python console, where the value\r\nwill also give 0x10, which in decimal is 16. And if we further analyze the block of data in question, we will also be able to\r\nobserve that 0x10 is the exact size of this specific data block, before null values. In other words, in fact, the algorithm sets\r\nthe size of the current data block that will be decrypted, and uses the value of its size as a conditional for the while loop.\r\nAs we proceed, the decryption algorithm calls a function that we can also observe in the pseudo-code. This function simply\r\nadds 1 byte (going from 0x7e to 0x7f) to the first byte of the encrypted data block.\r\nNext, the algorithm will perform an XOR operation with the byte appended to 1 (0x7f) and with byte 0x0d, which is the\r\nseventh byte of the encrypted data block.\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 7 of 10\n\nWe can validate this information in our Disassembler, where it is possible to observe that the algorithm skips the initial 6\r\nbytes of the encrypted data block.\r\nWhen we perform the XOR operation between the values 0x7f and 0x0d, the result (stored in RAX) will be a string\r\nidentified as ‘r‘.\r\nHaving analyzed this behavior, we reached the following conclusion:\r\nThe first byte of all blocks to be decrypted is the initial byte, which will always have its value increased by 1 for each\r\nsubsequent byte (starting from the seventh byte of the encrypted data block) in which the XOR operation will be\r\nperformed. That is, each byte will have a different XOR key.\r\nThe fifth byte of each encrypted data block will be used together with the first byte of the block to calculate the size\r\nof the block that must be decrypted\r\nIn other words, the first six bytes of each encrypted data block are not decrypted, they are what we can call the\r\ncontrol header.\r\nBelow, we can validate our assumption. Below, I manually made the algorithm execution flow.\r\nUpon obtaining a certain set of bytes, I went to CyberChef to transform the hex data into readable output, and… Voilà!\r\nAs we know from the Latrodectus analysis in my previous post, the string above is part (I just streamed it in a few bytes, out\r\nof laziness) of the runnung string, which is used to create the Mutex on the infected system.\r\nLatrodectus Decryption Algorithm Flowchart\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 8 of 10\n\nIn order to improve understanding of the algorithm, below is a flowchart I made just to illustrate the flow of executing the\r\nLatrodectus string decryption algorithm.\r\nOnce you understand the algorithm, you can implement this algorithm in a script, with the aim of extracting the strings from\r\nthe sample you are analyzing.\r\nPython Script for String Decryption and Extraction\r\nI created a Python script that will run the Latrodectus decryption algorithm, print the entire flow of its execution for\r\ndebugging and study.\r\nBelow is the video of the execution of the script.\r\nPython-Only – Latrodectus String Extractor\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 9 of 10\n\nThe source code of the script can be found on my github, at the link below:\r\nPython Only Script\r\nBinary Ninja Script -\u003e from Leandro, that helps a lot to do my own, and this research.\r\nConclusion\r\nWell, I hope this type of article pleased you, the reader, and that you learned something new!! See you around!\r\nSource: https://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\n0:00 / 0:40\r\nhttps://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://0x0d4y.blog/case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus/"
	],
	"report_names": [
		"case-study-analyzing-and-implementing-string-decryption-algorithms-latrodectus"
	],
	"threat_actors": [],
	"ts_created_at": 1775791303,
	"ts_updated_at": 1775826773,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/12d7a4d36489aa2eba001e0138cf3fccad5a7954.pdf",
		"text": "https://archive.orkl.eu/12d7a4d36489aa2eba001e0138cf3fccad5a7954.txt",
		"img": "https://archive.orkl.eu/12d7a4d36489aa2eba001e0138cf3fccad5a7954.jpg"
	}
}