Netsed

De Wiki doc


Netsed est un outil permettant de modifier des chaînes de caractères dans des datagrammes sur un réseau IP (v4 ou v6). Il applique pour cela des règles sous formes d'expressions régulières à un flux réseau en écoute sur un port (UDP ou TCP) et renvoi le résultat sur un autre port (UDP ou TCP).

L’intérêt principal est de permettre à un client non configurable (pas d'accès administrateur, paramètres non modifiables, pas d'accès à la machine...) de requêter un serveur avec de bonnes informations malgré des paramètres erronés. Prenons par exemple un site WEB configuré avec une authentification AuthBasic via un .htaccess Apache2 et un client (un objet connecté sans possibilité de configuration) requêtant ce serveur avec un mauvais mot de passe. Avec Netsed, il est possible d'intercepter les requêtes et de les modifier avant de les retransmettre à la cible (on fournira donc le bon mot de passe). Dans la plupart des cas, il faudra réaliser une attaque de l'homme du milieu afin de pouvoir recevoir le flux réseau ne nous étant pas destiné. Je vais passer outre cette complication en effectuant les opérations directement sur le routeur de sortie sous Debian Buster.

L'architecture réseau suivante sera utilisée:


<img src="https://doc.lesmorin.fr/fichiers/r%c3%a9seaux/alt%c3%a9ration_de_paquets/netsed/Sch%c3%a9ma_Netsed.svg"></img>


Sur le serveur WEB

Installation du service

apt install apache2

Configuration du service

Création du répertoire d'accueil, d'une page, d'un fichier de mots de passes, du site et activation du tout

mkdir /var/www/test
echo "<h1>Bonjour.</h1>" > /var/www/test/index.html
htpasswd -c /var/www/test/mdp.pwd toto
chown -R www-data: /var/www/test

Note: l'utilisateur sera "toto" avec le mot de passe "test".

vim /etc/apache2/sites-available/test.conf
<VirtualHost *:80>

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/test

	<Directory "/var/www/test">
		AuthType Basic
		AuthName "Restricted Content"
		AuthUserFile /var/www/test/mdp.pwd
		Require valid-user
	</Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
a2dissite 000-default.conf
a2ensite test.conf
systemctl restart apache2.service

Sur le client

Installation de curl

apt install curl

Test du site

curl http://toto:test@[2001:db8:1::1:2]

Ceci doit renvoyer le contenu de votre page.

Pour la suite nous allons renseigner un mot de passe erroné

curl http://toto:testo@[2001:db8:1::1:2]

Ceci renvoi une erreur d'accès.

Sur le routeur

Installation des paquets

apt install netsed tcpdump

Note: Tcpdump n'est pas utile pour le fonctionnement de Netsed. Nous l'utiliserons pour visualiser la chaîne de caractères à modifier (les mots de passes AuthBasic sont en base64).

Visualiser le flux

Afin de savoir quelle chaîne de caractères nous allons devoir inclure dans notre règle de modification, nous lançons tcpdump en tronquant les 1024 premiers octets afin d'afficher l'entête HTTP dans notre console.

tcpdump -ni any -vvvs 1024 port 80

Il faut ensuite relancer la requête côté client pour la capturer.

La section qui nous interesse est la suivante:

	GET / HTTP/1.1
	Host: [2001:db8:1::1:2]
	Authorization: Basic dG90bzp0ZXN0bw==
	User-Agent: curl/7.64.0
	Accept: */*

Notez la ligne Authorization: Basic dG90bzp0ZXN0bw==. La chaîne de caractères dG90bzp0ZXN0bw== est en fait le couple "utilisateur:mot de passe" (toto:testo dans notre cas) encodé en base64. Gardez cette chaîne de caractère dans un coin, on en aura besoin plus tard. Il aurai également été possible d'obtenir directement cette ligne avec la commande suivante: tcpdump -nAli eth0 -s 0 | grep -i "Authorization".

Il est possible de décoder la chaîne de caractère

echo -n "dG90bzp0ZXN0bw==" | base64 -d

Notez également que si vous connaissez déjà les informations à l'avance, vous pouvez encoder la chaîne vous même sans avoir à faire de tcpdump

echo -n "toto:testo" | base64

Altération du paquet

Maintenant que nous avons la chaîne de caractères envoyée par le client au serveur WEB. Il faut générer celle que nous souhaitons voir réellement transmise

echo -n "toto:test" | base64

Ce qui donne dG90bzp0ZXN0.

L'altération se déroulera comme suit. Notre routeur n'étant pas le destinataire de l'information, il va falloir demander à Netfilter de transférer le flux à destination du serveur WEB sur le port 80 TCP à un port arbitraire que nous définirons à 8200. Nous mettrons alors Netsed en écoute sur celui-ci afin de traiter les paquets pour qu'il les modifies selon notre règle. Opération faite, l'outil va alors retransmettre le paquet sur le port 80 TCP afin que la communication puisse avoir lieu entre les deux machines.

Transfert des paquets

Nous transfèrerons les paquets à destination du port 80 sur le port 8200 (qui seront écoutés par Netsed pour y appliquer ses règles)

ip6tables -t nat -A PREROUTING -i eth0 -s 2001:db8::1:1 -p tcp --dport 80 -j REDIRECT --to-port 8200

ou

nft add rule ip6 nat PREROUTING iifname "eth0" ip6 saddr 2001:db8::1:1 tcp dport 80 counter redirect to :8200

Application des règles

La syntaxe de Netsed est la suivante:

netsed {proto} {lport} {rhost} {rport} {rule} [rule ...]

Lorsqu'il est lancé, l'outil ne rend pas la main et inspect chaque paquet envoyés par Netfilter sur le port 8200 pour y appliquer les règles fournies. Il transmet alors le résultat à l'hôte {rhost} sur le port {rport} afin que le noyau les réinjectes dans le circuit de routage avec des informations d'acheminement cohérentes.

Ici, nous voulons remplacer la chaîne de caractères toto:testo par toto:test:

netsed tcp 8200 2001:db8:1::1:2 80 's/dG90bzp0ZXN0bw==/dG90bzp0ZXN0'

Désormait, le client utilisant la commande curl http://toto:testo@[2001:db8:1::1:2] reçoit bien le contenu de notre page malgré un mot de passe erroné. S'il venait à entrer le bon mot de passe ou un autre mauvais mot de passe, la requête serai transmise sans aucune forme d'altération puisque le paquet ne correspondrai pas avec notre règle, rendant tout ceci transparent. Cependant, il est important de prendre en compte le fait que Netfilter redirige les paquets à destination du port 80 vers le port 8200. Il est donc indispensable que Netsed soit lancé et écoute sur ce port sans quoi les requêtes du client se verront refusées. Pour revenir à la normal, il suffit de supprimer la règle de reroutage définit dans la table nat.

Enfin, vous pourrez visualiser la mofication en temps réelle lorsque le paquet traverse vos interfaces via Tcpdump:

tcpdump -ni any -vvvs 1024 port 80

Vous constaterez qu'en arrivée du routeur, l'entête HTTP ressemble à ceci:

	GET / HTTP/1.1
	Host: [2001:db8:1::1:2]
	Authorization: Basic dG90bzp0ZXN0bw==
	User-Agent: curl/7.64.0
	Accept: */*

et qu'elle est renvoyée en sortie avec la chaîne de caractère modifiée:

	GET / HTTP/1.1
	Host: [2001:db8:1::1:2]
	Authorization: Basic dG90bzp0ZXN0
	User-Agent: curl/7.64.0
	Accept: */*

Sources