Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
cyber-decoy — Broker de leurres expérimentaux | Kitploit
Outils/GitHubGitHub/secdev02/cyber-decoy
Outils DéfensifsSécurité des ConteneursSécurité RéseauRenseignement sur les MenacesDétection d'IntrusionAnalyse de Journaux
GitHubsecdev02/cyber-decoy

cyber-decoy

Broker de leurres expérimentaux

Voir le dépôt
3il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

cyber-decoy

Un leurre réseau conteneurisé (honeypot) qui annonce SSH, RDP et SMB, observe chaque connexion entrante avec eBPF, et proxy inverse chaque session dans un conteneur leurre isolé.

La conception sépare deux préoccupations :

  1. Observation. Un classifieur TC eBPF attaché à l'interface du broker enregistre chaque SYN TCP entrant, y compris les scans contre des ports que le leurre ne sert pas. Cela donne une visibilité complète sur l'activité de sondage.
  2. Interaction. Un proxy inverse en espace utilisateur dans le broker accepte les connexions sur les ports annoncés et ouvre une connexion correspondante vers le conteneur leurre pour ce service, redirigeant les octets dans les deux sens et journalisant la session complète.

Cet outil est un outil défensif pour détecter et étudier les activités non autorisées sur les réseaux que vous possédez ou que vous êtes autorisé à surveiller. Déployez-le uniquement là où vous avez cette autorité.

Architecture

root@kitploit:~
flowchart TB
    A["Attacker / Scanner"]

    subgraph host["Decoy Host"]
        direction TB

        NIC["broker eth0<br/>published: 22, 3389, 445"]

        subgraph brk["broker container"]
            direction TB
            E["eBPF TC classifier<br/>logs every SYN<br/>sees true source IP"]
            P["reverse proxy<br/>CONNECT to backend"]
            L["structured JSON logs"]
        end

        subgraph dec["decoynet (internal, no host route)"]
            direction LR
            S["ssh-decoy<br/>OpenCanary ssh<br/>port 2222"]
            D["rdp-decoy<br/>OpenCanary rdp<br/>port 3389"]
            M["smb-decoy<br/>Impacket SMB server<br/>port 445"]
        end
    end

    A --> NIC
    NIC --> E
    NIC --> P
    E --> L
    P --> S
    P --> D
    P --> M

Quatre conteneurs au total :

Les leurres vivent sur un réseau Docker internal (decoynet) sans route vers l'hôte ou le monde extérieur. Seul le broker peut les atteindre. Rien de ce qu'un attaquant fait à l'intérieur d'un leurre ne peut atteindre directement le réseau hôte.

Fonctionnement du routage eBPF

Le broker publie les ports 22, 3389 et 445 vers l'hôte, donc les paquets entrants arrivent sur l'eth0 du broker. Deux choses se produisent alors pour chaque paquet :

  • Le programme d'entrée eBPF TC (broker/bpf/decoy.bpf.c) analyse les en-têtes Ethernet, IP et TCP, et pour chaque nouvelle tentative de connexion (SYN positionné, ACK effacé) écrit un conn_event dans un tampon circulaire : IP source et port, port de destination, drapeaux TCP, et si le port est un service annoncé. Le paquet est transmis inchangé (TC_ACT_OK).
  • Le proxy en espace utilisateur accepte la connexion sur l'écouteur correspondant et effectue l'équivalent d'un CONNECT vers le backend leurre pour ce service, puis relaie les octets dans les deux sens.

La table eBPF advertised_ports est peuplée au démarrage depuis config.yaml, afin que le classifieur puisse marquer si un sondage a touché un port servi ou non sollicité. Cela rend visibles les scans de ports horizontaux même si seuls trois ports sont proxyés.

Si vous souhaitez annoncer « tout est ouvert » et diriger des ports de destination arbitraires vers le broker, étendez le classifieur pour réécrire le port de destination ou utilisez une redirection TPROXY / bpf_sk_assign. La version actuelle laisse le chemin du paquet intact et se limite à l'observation, ce qui est le défaut le plus sûr.

Structure du dépôt

root@kitploit:~
cyber-decoy/
├── README.md
├── docker-compose.yml         # 4-container stack
├── docker-compose.override.yml # local macOS dev: no eBPF caps, port 22 remap
├── Makefile                   # build / up / down / bpf helpers
├── LICENSE
├── scripts/
│   └── setup.sh               # host preflight checks
├── broker/
│   ├── Dockerfile             # compiles eBPF object + Go binary
│   ├── config.yaml            # advertised services (configurable)
│   ├── go.mod
│   ├── main.go                # entrypoint
│   ├── bpf/
│   │   └── decoy.bpf.c        # eBPF TC classifier
│   └── internal/
│       ├── config/config.go   # config loader
│       ├── proxy/proxy.go     # TCP reverse proxy
│       └── bpf/loader.go      # loads + attaches eBPF, streams events
└── decoys/                     # all three run OpenCanary
    ├── ssh/
    │   ├── Dockerfile
    │   └── opencanary.conf     # ssh module, port 2222
    ├── rdp/
    │   ├── Dockerfile
    │   └── opencanary.conf     # rdp module, port 3389
    └── smb/
        ├── Dockerfile          # single Python process, non-root
        ├── smb_decoy.py        # Impacket SimpleSMBServer + JSON logging
        └── requirements.txt    # impacket (pinned)

Prérequis

  • Hôte Linux avec noyau 6.6 ou plus récent pour le chemin d'attachement eBPF TCX. Sur les noyaux plus anciens, le proxy fonctionne toujours ; seule l'observation eBPF est ignorée (le broker enregistre un avertissement et continue).
  • Docker Engine avec le plugin Compose (v2.24+ si vous utilisez le docker-compose.override.yml fourni, qui repose sur les balises !reset / !override).
  • Un système de fichiers BPF monté : sudo mount -t bpf bpf /sys/fs/bpf.

Architecture

L'image broker détecte son architecture de construction et transmet la macro __TARGET_ARCH_* correspondante à clang, de sorte qu'elle se compile à la fois sur x86_64 et aarch64 (Apple Silicon, Graviton). Notez que gcc-multilib n'est délibérément pas installé : c'est un paquetage x86 uniquement sans candidat arm64, et l'inclure casse la construction sur arm64 avec le code de sortie apt 100. Seuls clang et libbpf-dev sont nécessaires pour compiler l'objet eBPF.

Développement sur macOS

Docker Desktop sur macOS exécute les conteneurs dans une VM LinuxKit plutôt que sur votre noyau hôte, donc l'attachement eBPF TC/TCX ne fonctionnera généralement pas là-bas. Ce n'est pas fatal : eBPF est au mieux fourni par conception, donc le broker enregistre ebpf disabled: attach failed et le proxy inverse ainsi que les trois leurres fonctionnent et journalisent normalement. Vous pouvez développer et tester l'ensemble du chemin de proxy localement, puis obtenir une véritable observation eBPF lorsque vous déployez sur un hôte Linux.

docker-compose.override.yml est chargé automatiquement et rend cela agréable : il supprime les capacités eBPF (inutiles dans la VM) et remappe le port hôte 22 vers 2022, puisque le propre sshd du Mac occupe le 22.

root@kitploit:~
docker compose up --build                    # local dev, override applied
docker compose -f docker-compose.yml up -d   # real deployment, override bypassed

Exécutez d'abord la vérification préliminaire :

root@kitploit:~
./scripts/setup.sh

Démarrage rapide

root@kitploit:~
# 1. Build all four images (compiles the eBPF object inside the broker image)
make build

# 2. Start the stack
make up

# 3. Watch what happens
make logs

Ensuite, sondez-le depuis une autre machine (ou localhost pour un test de fumée) :

root@kitploit:~
ssh -p 22 user@DECOY_HOST          # hits the SSH decoy
nc DECOY_HOST 3389                 # hits the RDP decoy
nc DECOY_HOST 445                  # hits the SMB decoy
nc DECOY_HOST 8080                 # unadvertised: observed by eBPF, no proxy

Le broker émet du JSON pour les événements de sonde eBPF et les sessions proxyées ; chaque leurre émet des événements JSON OpenCanary. Pour voir arriver les identifiants :

root@kitploit:~
docker compose logs -f ssh-decoy | grep 4002

Contrairement à un simple bannière, ssh -p 22 user@DECOY_HOST effectue désormais un véritable échange de clés et demande un mot de passe. Chaque tentative est capturée. Vérifiez que l'empreinte du service tient sous la détection de version :

root@kitploit:~
nmap -sV -p 22,3389,445 DECOY_HOST

Arrêtez avec :

root@kitploit:~
make down

Configuration

Les services sont définis dans broker/config.yaml. Chaque entrée est indépendamment activable et remappable :

root@kitploit:~
services:
  - name: ssh
    enabled: true
    listen_port: 22
    backend: ssh-decoy:2222

Pour ajouter un service, ajoutez une entrée ici, publiez le port dans docker-compose.yml, et ajoutez un conteneur leurre. Pour en désactiver un, définissez enabled: false (et éventuellement supprimez son port publié).

Notez que le port hôte 22 est généralement occupé par le vrai démon SSH de l'hôte. Pour un laboratoire, vous pouvez remapper le côté publié dans docker-compose.yml, par exemple "2022:22", et pointer votre scanner vers celui-ci.

Les backends leurres

Les trois leurres exécutent OpenCanary (Thinkst), configurés pour que chaque conteneur active exactement un module. Les journaux sont émis au format JSON sur stdout, donc docker compose logs et tout expéditeur SIEM fonctionnent sans plomberie supplémentaire.

Types d'événements

OpenCanary étiquette chaque événement avec un logtype numérique. Ceux que vous verrez ici :

Un identifiant SSH capturé ressemble à ceci :

root@kitploit:~
{"dst_port": 2222, "logtype": 4002, "node_id": "decoy-ssh",
 "src_host": "10.0.0.66", "src_port": 42958,
 "logdata": {"USERNAME": "admin", "PASSWORD": "Passw0rd123"}}

Important : les leurres ne peuvent pas voir l'IP de l'attaquant

C'est une conséquence directe de l'architecture du broker, et c'est la chose la plus importante à comprendre pour lire ces journaux.

Le broker termine la connexion TCP de l'attaquant et en ouvre une nouvelle vers le leurre. Donc du point de vue d'OpenCanary, le client est le broker. Chaque src_host dans un événement leurre sera l'adresse du broker sur decoynet, pas la source réelle.

La véritable adresse IP source est toujours capturée, mais à un endroit différent :

Donc l'attribution nécessite de corréler les journaux du broker avec ceux du leurre, en joignant sur l'horodatage et le service. Le broker enregistre remote (la véritable adresse de l'attaquant) et backend pour chaque session, ce qui rend la jointure possible :

root@kitploit:~
docker compose logs broker    | grep 'session opened'   # who
docker compose logs ssh-decoy | grep '"logtype": 4002'  # what they tried

Si vous avez besoin de la véritable IP à l'intérieur du leurre lui-même, les options sont d'envoyer le protocole PROXY (les leurres ne le parsent pas, ce qui signifierait les patcher), ou de remplacer le proxy en espace utilisateur par une redirection transparente (TPROXY ou eBPF bpf_sk_assign) qui préserve l'adresse source d'origine. Les deux sont listés dans la feuille de route. En attendant, traitez le broker comme la source de vérité pour « qui » et le leurre comme la source de vérité pour « quoi ».

Le leurre SMB (Impacket, pas Samba)

Contrairement à SSH et RDP, ce leurre n'utilise pas OpenCanary. Le module smb d'OpenCanary n'est qu'un observateur de journaux : il suit un fichier et analyse les lignes smbd_audit émises par un vrai serveur Samba, ce qui signifiait exécuter Samba plus rsyslog plus opencanaryd sous supervisord, une chaîne de cinq maillons où n'importe quel maillon pouvait échouer silencieusement.

smb-decoy remplace tout cela par un seul processus Python basé sur SimpleSMBServer d'Impacket, une implémentation pure Python de SMB1/2/3. Il écoute sur 445, présente des partages appâts en lecture seule, répond à la négociation SMB2/3 (donc nmap -sV voit un vrai service), et journalise les connexions et les tentatives d'authentification NTLM sous forme d'un objet JSON par ligne sur stdout. Le nom d'utilisateur, le domaine et le poste de travail capturés du message d'authentification de l'attaquant sont le gain de capture d'identifiants.

Note de sécurité : Le smbserver d'Impacket comportait un path traversal critique, CVE-2021-31800, qui affectait spécifiquement les honeypots. Il a été corrigé dans la version 0.9.23. requirements.txt fixe une version actuelle et ne doit pas être rétrogradée en dessous. Le conteneur s'exécute également non-root, en lecture seule, avec toutes les capacités supprimées sauf NET_BIND_SERVICE.

Configuration des leurres

Chaque leurre possède un opencanary.conf (installé dans /etc/opencanaryd/). Paramètres utiles :

  • Bannière SSH : ssh.version dans decoys/ssh/opencanary.conf. Actuellement, elle annonce SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1. Faites-la correspondre au système d'exploitation que vous prétendez être ; une bannière Ubuntu sur une machine se prétendant Windows est un indice.
  • Noms de partages SMB : les appels addShare(...) dans decoys/smb/smb_decoy.py, plus les fichiers appâts créés dans decoys/smb/Dockerfile. Les noms de partages et de fichiers sont l'appât.
  • Ports : maintenez-les alignés avec backend dans broker/config.yaml.

Pour activer un autre module OpenCanary (ftp, telnet, mysql, vnc, redis, et d'autres sont disponibles), définissez <module>.enabled et <module>.port, ajoutez un conteneur leurre, et ajoutez un service correspondant dans broker/config.yaml.

Persistance de la clé d'hôte SSH

ssh-decoy monte un volume nommé sur /var/lib/opencanary (ssh.key_path), de sorte que la clé d'hôte générée survive aux redémarrages. Sans cela, OpenCanary génère une nouvelle clé à chaque démarrage et l'empreinte changeante est un indice évident.

Dépannage du leurre SMB

Le leurre SMB est maintenant un processus unique, donc le dépannage est simple.

root@kitploit:~
docker compose logs -f smb-decoy

Chaque ligne est du JSON. Vous devriez voir un smb_decoy_start au démarrage, puis des événements smb_connect, smb_auth_attempt et smb_tree_connect lorsque les clients interagissent. Testez-le depuis l'hôte avec n'importe quel client SMB :

root@kitploit:~
# macOS Finder: Go > Connect to Server
open 'smb://guest@localhost/HR-Payroll'
# or from Linux
smbclient -L //localhost -p 445 -N

Problèmes courants :

  • Pas de ligne smb_decoy_start et le conteneur se ferme : vérifiez que requirements.txt s'est installé proprement. Impacket a besoin de Python 3.8+ ; l'image utilise 3.12.
  • Se connecte mais pas de smb_auth_attempt : certains clients énumèrent les partages de manière anonyme sans jamais s'authentifier. Cela produit quand même smb_connect et smb_tree_connect. Forcez l'authentification en mappant un partage avec un nom d'utilisateur.
  • Comme pour les autres leurres, src_host est l'adresse du broker, pas l'attaquant réel. Corrélez avec les journaux du broker sur l'horodatage.

Notes de sécurité

  • Capacités. Le broker a besoin de NET_ADMIN (et BPF / PERFMON sur les noyaux récents) pour charger et attacher le programme eBPF. Le fichier Compose demande ces capacités limitées. Si votre hôte ou version de Docker les rejette, le repli est privileged: true sur le service broker, ce qui est plus large et ne devrait être utilisé que lorsque les capacités limitées ne fonctionnent pas.
  • Isolement. Les leurres se trouvent sur un réseau internal sans route hôte. Gardez-le ainsi. Traitez chaque conteneur leurre comme potentiellement compromis.
  • Rayon d'explosion. Exécutez toute la pile sur un hôte segmenté de la production. Un leurre est un appât ; supposez que les attaquants interagiront avec.
  • Légal. Ne surveillez et ne trompez que sur une infrastructure que vous possédez ou que vous êtes autorisé à défendre.

Idées de feuille de route

  • Préserver l'IP source de l'attaquant dans les leurres via TPROXY ou bpf_sk_assign, supprimant le besoin de corréler les journaux du broker et du leurre.
  • Entonnoir tous ports via réécriture de destination eBPF ou TPROXY.
  • Capture de session en PCAP par connexion.
  • Envoyer les événements à un SIEM (les journaux JSON sont déjà structurés pour cela).
  • Limitation de débit et quotas de connexion dans le broker.

Licence

MIT. Voir LICENSE.

Télécharger l’outil
ContainerRôleRéseau
brokerPorte d'entrée publique : observation eBPF et proxy inverseedge + decoynet
ssh-decoyModule ssh OpenCanary (vrai handshake, capture des identifiants)decoynet uniquement
rdp-decoyModule rdp OpenCanary (imite NLA, capture les noms d'utilisateur)decoynet uniquement
smb-decoySimpleSMBServer d'Impacket (vrai SMB2/3, capture l'authentification)decoynet uniquement
ContainerModule OpenCanaryÉcouteCe qu'il fait réellement
ssh-decoyssh2222Véritable échange de clés SSH via twisted.conch. Capture chaque paire nom d'utilisateur/mot de passe.
rdp-decoyrdp3389Imite un serveur avec NLA, renvoie toujours un échec de connexion, extrait le nom d'utilisateur mstshash.
smb-decoyImpacket445Serveur SMB2/3 pur Python. Présente des partages appâts et journalise les connexions et les tentatives d'authentification NTLM au format JSON.
logtypeConstante dans opencanary/logger.pySignification
1000LOG_BASE_BOOTDémarrage du démon
4000LOG_SSH_NEW_CONNECTIONConnexion SSH ouverte
4001LOG_SSH_REMOTE_VERSION_SENTLe client a envoyé sa chaîne de version
4002LOG_SSH_LOGIN_ATTEMPTTentative de connexion SSH (inclut USERNAME et PASSWORD)
5000LOG_SMB_FILE_OPENFichier SMB ouvert (inclut USER, SHARENAME, FILENAME)
14001LOG_RDPConnexion RDP / tentative de connexion
CoucheConnaît la véritable IP source ?Connaît ce qui a été tenté ?
Classifieur eBPF (probe observed)OuiNon, métadonnées SYN uniquement
Proxy broker (session opened)OuiNon, compteurs d'octets uniquement
Leurre OpenCanary (logtype 4002)NonOui, identifiants/fichiers