Secure coding

Cryptography errors Exploitation Case Study

January 5, 2021 by Srinivas

In the previous articles of this series on Cryptography errors, we discussed how Cryptography is used in applications and how the use of Cryptography can go wrong in applications. We also discussed how insecure practices while using Cryptography in applications can be exploited. In this article, we will discuss a case study of how insecure use of cryptography can be exploited in applications. The interesting part of this article is that we will discuss how a ransomware decryptor was written by taking advantage of a vulnerable implementation used in Linux.Encoder ransomware.

Linux.Encoder – The First Linux Ransomware

This ransomware operated the same way as any windows based ransomware. It encrypted important user data and left any operating system specific critical files that are required for the operating system to boot. 

The encryption flaw

The Linux.Encoder ransomware’s design to generate the encryption key and IV that are used with AES algorithm is found to be flawed. Researchers from bitdefender found that the keys and IV are derived from the libc rand() function seeded with the current system timestamp during the encryption. If we have the encrypted files available, we can easily retrieve the timestamp using the last modified time and pass it to libc rand() function to derive the encryption key and IV. Using this technique the bitdefender team managed to write a decrypter, which helped victims to decrypt the files without paying any ransom to the malware author.

Simulating the flaw

The following example simulates the same flaw using simple python scripts. 

encrypt.py

from Crypto.Cipher import AES

from Crypto.Util.Padding import pad

import time

import hashlib

output-file = ‘file.encrypted’ 

data = b’This is clear text data from the original file’ 

current-time = str(int(time.time()))

print (current-time)

key = hashlib.sha256(current-time.encode(“utf-8”)).digest()

print (key)

cipher = AES.new(key, AES.MODE_CBC) 

ciphered_data = cipher.encrypt(pad(data, AES.block_size)) 

file_out = open(output-file, “wb”) 

file_out.write(cipher.iv)

file_out.write(ciphered_data) 

file_out.close()

 

The preceding script simulates the Linux.Encoder ransomware upto some extent by generating an encryption key using the current system time. Instead of using a random value generator, we are using the SHA256 hash of the time stamp as the key. Once the key is generated, the clear text data is encrypted and it is saved in a file named file.encrypted. When this script is run, it looks as follows.

$ python3 encrypt.py 

1607180166

b’\xf9\x91@\xfd\xd31\xe5\xf8\xfb.\x84\xff\xe9Y\xaf\x8d\xb7\x12^\xcd\xc8\xc6v\xd9\x119\xfa\x11P\xba\xaf\x19′

 

As we can notice in the preceding output, the timestamp and the key generated from the timestamp are printed. The following excerpt shows that a new encrypted file is created on the disk.

 

$ ls file.encrypted 

file.encrypted

 

Now, let us go through the following code snippet to understand how the bitdefender researchers managed to derive the key from the encrypted files.

 

decrypt.py

 

from Crypto.Cipher import AES

from Crypto.Util.Padding import unpad

import os

import hashlib

input_file = ‘file.encrypted’

current-time = str(int(os.path.getmtime(‘file.encrypted’)))

print (current-time)

key = hashlib.sha256(current-time.encode(“utf-8”)).digest()

print (key)

file_in = open(input_file, ‘rb’) 

iv = file_in.read(16) 

ciphered_data = file_in.read()  

file_in.close()

cipher = AES.new(key, AES.MODE_CBC, iv=iv)

original_data = unpad(cipher.decrypt(ciphered_data), AES.block_size)

print (original_data.decode(‘UTF-8’))

 

If you notice the code in the preceding excerpt, os.path.getmtime function is used to read the last modified time of the encrypted file, which will give the timestamp at the time of encryption. This time stamp is used to generate SHA256 hash once again, which will produce the decryption key. Once the decryption key is obtained, we will be able to decrypt the encrypted file.The following output shows the text from the decrypted file.

 

$ python3 decrypt.py

1607180166

b’\xf9\x91@\xfd\xd31\xe5\xf8\xfb.\x84\xff\xe9Y\xaf\x8d\xb7\x12^\xcd\xc8\xc6v\xd9\x119\xfa\x11P\xba\xaf\x19′

This is clear text data from the original file

 

Clearly, using system time is not the right way to generate encryption keys as it can easily be retrieved from the encrypted files. This simple example shows why this is a flawed approach, which is seen even in real world software. Interestingly, in this case study we have seen how it is exploited for a good reason.

Conclusion

When malware authors with malicious mindset can make mistakes when using Crypto, anyone can make mistakes. Linux.Encoder ransomware is a great example of how the use of Cryptography can go wrong in software applications. Getting cryptography wrong in your applications is very easy and developers must understand how to use the crypto APIs and libraries properly. Using cryptographic libraries in an incorrect way will defeat the whole purpose of using crypto. In the next article, we will discuss some of the security best practices that can be followed to avoid such issues. 

 

Sources

  1. https://labs.bitdefender.com/2015/11/linux-ransomware-debut-fails-on-predictable-encryption-key/
  2. https://www.crypteron.com/blog/the-real-problem-with-encryption/
  3. https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
  4. https://vms.drweb.com/virus/?i=7704004&lng=en
Posted: January 5, 2021
Articles Author
Srinivas
View Profile

Srinivas is an Information Security professional with 4 years of industry experience in Web, Mobile and Infrastructure Penetration Testing. He is currently a security researcher at Infosec Institute Inc. He holds Offensive Security Certified Professional(OSCP) Certification. He blogs atwww.androidpentesting.com. Email: srini0x00@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *