Émile MARIÉ
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Audit des logiciels SomeClient.exe et SomeServer.exe Le but de ce rapport est de réaliser un audit des logiciels SomeClient.exe et SomeServer.exe et de voir si ces logiciels présentent des vulnérabilités importantes au point d'impacter la sécurité des utilisateurs. ## Contexte de l'audit Le but de cette section est d'expliquer le contexte de l'audit. Cela comprend le but des logiciels testé, leur fonctionnement ainsi que les conditions dans lequels ils furent audités. ### But des logiciels SomeClient.exe et SomeServer.exe Cet ensemble de logiciel a été mise au point par la société SomeSoftware. Leur but est d'offrir un service d'hébergement des données avec un client. Le logiciel du serveur (SomeServer.exe) offre la possibilité à quiconque qui se connecte dessus avec le logiciel client dédié (SomeClient.exe) de téléverser des fichiers dessus. Il propose un fonctionnement similaire au protocole réseau FTP (File Transfer Protocol) dans son utilisation. Il offre également un système de permissions pour restreindre l'accès à certaines ressources selon l'accréditation de l'utilisateur connecté. Voici d'ailleurs l'interface de connexion du logiciel client : ![](https://i.imgur.com/5em5ekE.png) Et un exemple d'utilisation une fois que l'utilisateur est connecté au serveur : ![](https://i.imgur.com/pAdgCgg.png) Maintenant, nous allons voir comment ces deux logiciels fonctionnent ensemble techniquement parlant. ### Schéma d'architecture des logiciels SomeClient.exe et SomeServer.exe Avant de commencer l'audit, voici un schéma qui explique le fonctionnement des logiciels SomeClient.exe et SomeServer.exe : ![](https://i.imgur.com/e3Xs4Tj.png) 1) Le client se connecte au serveur. Par défaut ce dernier est en écoute sur le port 4444. il peut s'authentifier en mode "Basic Authentication" ou bien en utilisant le certificat du serveur. 2) Le serveur, si les identifiants soumis par le client sont valides, envoie au client, les données contenues dans la base de données, à savoir la liste des fichiers présents. 3) A partir de cette étape, le client peut, selon ses accréditations, téléverser, modifier où changer les droits d'accès d'un fichier. Il peut également créer un répertoire et naviguer dans les dossiers du serveur. 4) Une fois qu'il a fini, le client peut se déconnecter du serveur pour fermer la connexion. Notez ici que le serveur peut fonctionner de deux façons différentes. Il peut être exécuté à la main avec l'aide d'un terminal de commande ou bien être installé sur la machine. S'il est installé sur la machine, cela veut dire qu'il sera lancé par défaut au démarrage du serveur Windows. La capture d'écran de la fonction (renommé installSomeServer) montre la façon dont le logiciel du serveur s'installe sur l'ordinateur : ![](https://i.imgur.com/j5uTJDe.png) Nous pouvons voir ici qu'une valeur est créé dans ce chemin de registre : 'SYSTEM\CurrentControlSet\services\eventlog\Application\SomeServer' De plus, le processus chargé de démarrer le serveur aura pour nom, "SomeServer". ### Les conditions mises en place pour l'audit Pour mener à bien cette audit, nous avons créé les utilisateurs suivants que nous utiliserons au cours de nos scénarios : - test:password1 (Accrédité "Public") - employe:password2 (Accrédité "Restreint") - chef:password3 (Accrédité "Confidentiel") - manitou:password4 (Accrédité "Secret") - supermanitou:password5 (Accrédité "Top Secret", il possède également le rôle d'administrateur sur le serveur) Enfin, nous avons également créé puis téléversé les fichiers et dossiers suivants sur le serveur : #### Fichiers présent sur le serveur - fichier_public.txt (Classifié "Public") - fichier_restreint.txt (Classifié "Restreint") - fichier_confidentiel.txt (Classifié "Confidentiel") - fichier_secret.txt (Classifié "Secret") - fichier_top_secret.txt (Classifié "Top Secret") #### Dossiers présent sur le serveur - Public (Classifié "Public") - Restreint (Classifié "Restreint") - Confidentiel (Classifié "Confidentiel") - Secret (Classifié "Secret") - Top Secret (Classifié "Top Secret") Tout cela nous permettra de tester les deux logiciels au cours des différents scénarios proposés ci-dessous. ## 1er scénario : Authentification des utilisateurs en mode "Basic Authentication" Au cours de ce scénario, nous allons voir s'il est possible d'obtenir les identifiants d'un utilisateur lorsque ce dernier cherche à se connecter au serveur en mode "Basic Authentication" (Sous réserve qu'un attaquant puisse enregistrer l'activité réseau au moment d'une connexion). ### Analyse de paquets via Wireshark Nous avons capturé avec Wireshark, l'ensemble des paquets réseaux transitant entre le client et le serveur au moment où un utilisateur se connecte. En mode "Basic Authentication", nous avons pu constaté que les identifiants ne circulent pas en clair. Nous allons quand même voir s'il n'est pas possible à tout hasard d'obtenir malgré tout les informations envoyées par l'utilisateur au serveur. ### Analyse du processus de chiffrement des données sur le client via IDA Premièrement, on utilise le logiciel "Resource Hacker" afin d'identifier les différents champs composant l'interface du logiciel client. ![](https://i.imgur.com/AKT2O3r.jpg) On remarque que l'ID 1002 correspond à l'input dans "Nom d'utilisateur" tandis que l'ID 1003 correspond à l'input "Mot de passe" On recherche donc la fonction permettant de récupérer le titre où le texte associé à un `control` dans un dialog box. Il s'agit de `GetDlgItemTextA`. ![](https://i.imgur.com/Raa61bp.png) Ensuite on recherche les occurences de `GetDlgItemTextA` et on trouve rapidement la partie où le `control` 1002 est utilisé, c'est-à-dire le champ "Nom d'utilisateur". ![](https://i.imgur.com/pMWzxwR.png) Enfin, on peut créer des "enums" afin de mapper des valeurs numériques avec des noms plus parlant pour ajouter de la sémantique et simplifier la compréhension du code. Au lieu d'avoir des valeurs numériques, on aura donc directement le nom de l'élément auquel il fait référence. ![](https://i.imgur.com/LcBYmUP.png) Ensuite on revient sur la vue assembleur, on sélectionne la valeur des ID à mapper, on appuie sur la touche `m` et on choisit l'enum à mapper. Dans le cas de l'ID `1002`, on mappera `ID_EDIT_USERNAME`. Par la suite, nous remarquons que l'adresse de l'username est stocké dans le registre `edi`. Tandis que l'adresse du mot de passe est stocké dans eax et correspond à `edi+0x80`. Ainsi, nous allons créer une structure accueillant les deux variables d'une taille de `0x80`. ![](https://i.imgur.com/WqCEUFC.jpg) Pour ce faire, une fois la structure créée, nous avons appuyer sur `d` afin de créer une variable puis sur `*` afin de modifier sa taille à `0x80`. Enfin on la renomme avec `n`. On revient ensuite sur la vue assembleur afin de se rendre sur l'adresse de `ID_EDIT_PASSWORD`, on sélectionne `0x80` et on appuie sur `t` afin de référencer l'adresse de la variable `context_t.password`. On parcourt ensuite la suite du programme et on retrouve un autre appel à notre mot de passe. Celui-ci est poussé sur la pile et une fonction est appelée ensuite. ![](https://i.imgur.com/hcOb3xv.png) Ensuite on redéfinit avec `y` la fonction `sub_44D950`. À cette étape, nous formulons une hypothèse: il s'agirait d'un `thiscall` car `ecx` est toujours passé en paramètre pour cette convention d'appel, il contient un pointeur sur un objet. ![](https://i.imgur.com/rUcZIIQ.png) En effet on remarque qu'à l'origine, la déclaration de la fonction est la suivante : `int __stdcall sub_44D950(int, int, int);` On modifie donc alors la définition de la fonction de cette façon : `int __thiscall sub_44D950(void *this, void *, char *username, char *password);` Effectivement, l'instruction `push ecx` correspond bien au mot de passe et l'instruction `push edi` au nom d'utilisateur et ainsi de suite. Ensuite on se rend dans la fonction en question, on remarque que `ecx` est déplacé dans `esi`. Plus tard, un offset est déplacé dans le registre `esi` correspondant à notre objet. L'offset correspond finalement à la vtable de l'objet. ![](https://i.imgur.com/rSRImBG.png) En regardant dans les RTTI, on remarque plusieurs méthodes virtuelles. Il s'agit d'un tableau de pointeurs de fonctions, soit notre "vtable". ![](https://i.imgur.com/6sFRDGU.png) ![](https://i.imgur.com/htzViSn.png) On remarque une méthode `SockerClientEncrypted` : ![](https://i.imgur.com/VAilAER.png) Afin de comprendre le code, on créé une structure `SocketClientEncrypted` dans la quelle on ajoute la vtable, l'username et le password. Pour rappel, la "vtable" définit les méthodes virtuelles utilisées. Avant de créer cette structure, nous devons connaître la taille qui lui est allouée. En revenant en arrière, on remarque l'appel de la fonction `new` pour laquelle on pousse une taille de 234 octets. ![](https://i.imgur.com/MMYxvxm.png) Nous crééons donc une structure `SocketClientChiffre` de taille `0x234`. Le premier paramètre est donc un pointeur vers la vtable. ![](https://i.imgur.com/w6EQU4v.png) On revient sur la vue assembleur et on remarque qu'aux offsets `+18` et `+1C` sont respectivement attribués les pointeurs vers `username` et `password`. Nous avons donc créés ces deux valeurs dans notre structure. ![](https://i.imgur.com/MxxRL3O.png) Ensuite, une fonction est appelée, lorsque l'on entre dedans on remarque que des constantes sont utilisées. ![](https://i.imgur.com/HaEKwpa.png) Avec un peu de recherche, on apprend que ces constances sont appelées dans la fonction `rand` .https://en.wikipedia.org/wiki/Linear_congruential_generator. La fonction `rand` comme son nom l'indique, permet d'obtenir un nombre aléatoire. Ensuite, on remarque qu'une fonction `memset` est appelée afin d'allouer un espace mémoire de 256 bits dans `eax` avec la valeur `0`. Sachant que `eax` pointait vers l'offset `0x2C` de `SocketClientEncrypted` ![](https://i.imgur.com/C6LKtlJ.png) Ensuite, nous remarquons que 3 autres variables de 4 octets sont initalisées ainsi qu'une nouvelle variable de 256 bits: ![](https://i.imgur.com/MyvVKrk.png) Pour finir, à l'offset 230 nous avons une nouvelle variable: ![](https://i.imgur.com/4PDl2Hq.png) Maintenant que nous avons vu comment les informations de l'utilisateur sont traités par le logiciel client, nous allons voir comment ce dernier initialise la connexion avec le serveur distant. ### Send Hello ou initier la connexion avec le serveur En entrant dans la vtable `SocketClientEncrypted` la première méthode virtuelle est `Connect`. Il semblerait qu'il s'agisse d'une initiation de connexion vers le serveur dans l'attente d'une réponse. Ensuite, la fonction `SendHello` contient une instruction permettant d'affecter dans un registre la valeur `SomeClient v1.0.0`. ![](https://i.imgur.com/XgcyT74.png) En lançant Wireshark, on observe que lorsque le paquet `Hello` est transmis, le client envoie la chaîne de caractères "SomeClient v1.0.0". Une fois que la connexion est initialisé avec le serveur, nous allons voir comment le client et le serveur s'échangent les données nécessaire à la génération d'une clef de chiffrement. ### Envoi de la Seed au serveur Après la fonction `SendHello`, on remarque une nouvelle fonction prenant en paramètre: - un entier ayant pour valeur 6 - l'objet SocketClientEncrypted pointé par ecx (thiscall) - et un pointeur ![](https://i.imgur.com/ZWnJsvj.png) Rapidement, la fonction `send` de l'API Windows attire notre attention. Celle-ci prend en paramètres: - un pointeur vers une socket - un pointeur vers un buffer - une taille On crée donc une entrée `socket` dans notre sructure `socketClientChiffre`à l'offset `04`. Ensuite, on retype la fonction de la manière suivante: `int __thiscall envoyerSeedPacket(socketClientChiffre *socket, char *buffer, int size);` De plus, en regardant les paquets transmis dans Wireshark, nous remarquons que le second paquet envoyé par le client a des données d'une taille de 6 octets. ![](https://i.imgur.com/ZoOn2r9.png) Ici, la seed vaut donc `0x4573` comme nous sommes en little endian. Cette valeur est importante puisqu'elle sera utilisé par le client et le serveur pour la génération d'une clef de chiffrement. D'ailleurs, nous allons voir comment les données venant du serveur sont réceptionnées par le client. ### Réception des données venant du serveur Ensuite, on observe une nouvelle fonction prenant en paramètres: - un entier ayant pour valeur 8 - un pointeur vers un buffer - un pointeur vers un socket ![](https://i.imgur.com/GrGjkWF.png) Nous comprenons donc que cette fonction permet de recevoir la réponse du serveur. Afin de confirmer cette hypothèse, nous rentrons dans la fonction et remarquons un appel à une autre fonction de l'API Windows, `recv`. Cette fonction prend les mêmes paramètres que la fonction `send`. Ainsi on en déduit que la réponse du serveur a pour taille, 8 octets. Elle est stockée dans le buffer. Ensuite, pour connaître le contenu de la réponse du serveur, nous nous penchons sur les instructions suivantes. En effet, la réponse est déplacée dans `eax` puis dans un champ de notre objet que nous ne connaissons pas encore. ![](https://i.imgur.com/Q5IU1xs.png) Nous le verrons dans la partie suivante, mais il s'agit d'une seconde seed. Cette fois nous cherchons un paquet dont les données font 8 octets. Et deux paquets après l'envoi de la seed par le client, nous trouvons la réponse. ![](https://i.imgur.com/j9Azxxy.png) Ainsi la seed vaut `0x29`. ### Création des clés de chiffrement ![](https://i.imgur.com/rDpeV8k.png) ![](https://i.imgur.com/FZIpb3A.png) Nous savons qu'il s'agit d'une fonction `srand` car elle prend en paramètre notre seed et est appelée avant un `rand`. La fonction `srand` permet d'initialiser la valeur de départ de la fonction `rand`. Ensuite, nous rentrons dans une boucle permettant de prendre le premier octet du nombre aléatoire généré par le `rand` puis le déplace dans un champ de notre objet de taille `256`. Ainsi on itère sur le nombre aléatoire jusqu'à remplir le champ. Le même processus est réalisé à la suite mais à un offset différent de notre objet, il s'agit d'une seconde seed. Puis chaque octet du nombre aléatoire constitue une nouvelle clé. Nous avons créé les valeurs correspondantes dans notre structure et les avons renommées. ![](https://i.imgur.com/OMsCUG8.png) Nous savons désormais que la première fonction établit un canal de communication avec le serveur et échange les seed. Maintenant, nous allons voir le mécanisme utilisé par le client et le serveur pour sécuriser l'authentification d'un utilisateur. ### Authentification de l'utilisateur auprès du serveur Nous analysons maintenant la fonction appelée après connect. Celle-ci est une nouvelle fois un `thiscall`car elle prend en paramètre l'objet this via`ecx`. ![](https://i.imgur.com/VySeybR.png) Ensuite, on remarque que la fonction s'alloue `0x80` octets de mémoire. ![](https://i.imgur.com/NR7riHI.png) Juste après, la fonction utilise deux fois `strncpy` pour copier deux buffer de taille `0x40` octets. Il s'agit du nom d'utilisateur et du mot de passe. Mais également une variable valant 2 octets est créée à l'offset `0x2`. ![](https://i.imgur.com/g7fm30w.png) De plus, une nouvelle fonction est appelée via la vtable de l'objet et prends en paramètres: - Un entier `0x82` - L'adresse contenant le word valant 2 - L'objet SocketClientEncrypted via `ecx` Il paraît évident que la fonction va traiter les champs "Nom d'utilisateur" et "Mot de passe". Soit `0x80` + `0x2`. Mais aussi, la taille du paquet envoyé par le client après l'échange des seeds est de `0x82`. Ensuite, la fonction `send` est appelée, nous allons entrer dedans. ![](https://i.imgur.com/Mvy0Z38.png) Ci-dessous, nous remarquons qu'une variable permettant de définir à quel offset de la clé nous sommes est chargée dans `edx`. Cela signifie que pour un paquet de taille n chiffré, le paquet suivant commencera à chiffrer avec l'octet n+1 de la clé. ![](https://i.imgur.com/R2uvSxb.png) De plus, la suite du code nous indique que chaque octet du message subit une opération binaire de type "XOR" avec un octet de la clé. Le résultat est déposé dans l'espace mémoire alloué au début de la fonction. ![](https://i.imgur.com/e9o1o0x.png) Les données chiffrées sont ensuite envoyés au serveur. Nous pouvons désormais tenter de réimplémenter le mécanisme de chiffrement pour déchiffrer la capture réseau qui nous a été fourni. ## Réimplémentation Afin de déchiffrer les données capturées dans Wireshark, nous avons copié le chiffré susceptible de contenir le mot de passe ainsi que le nom de l'utilisateur. Nous l'avons ensuite placé dans ce programme qui réimplémente en C++, le mécanisme de chiffrement utilisé par le client et le serveur : ```c++ #include <iostream> #include <string> #include <cstdlib> #include <ctime> #include <format> using namespace std; int main() { srand(0x4573); string cipher = "f394dcbdda0cf729de14e5c61584910e9c12bb4fd99d987d3edcd3286ff2d1aca74339a85885b4b1111af147a59ded078abb71237f44dc107181227ea0c9158dfe4fa6708477a274cc5fb500e5a5deda92700ef66b69a7f14d8c02ecc8f78f0bbd61bd8681b905f59885ad1d08c5831ebbc866ed2444070526a6f15a31a7c78fae20"; // Contenu extrait de la trame fourni qui contient le login et mot de passe de l'utilisateur à trouver string key; for(int i = 0; i < 256; i++) { int k = rand(); key += std::format("{:02x}", k%256); } string res = ""; for(int i = 0; i < cipher.length(); i+=2) { res += (char)(stoi(cipher.substr(i,2),nullptr,16) ^ stoi(key.substr(i,2),nullptr,16)); } cout << res << endl; return 0; } ``` Afin de compiler et exécuter ce code, voici les instructions à suivre: ``` cl /EHsc script.cpp script ``` Nous l'avonc compilé et exécuter à travers Visual Studio Code, voici le résultat: ``` PS C:\Users\emile\Documents> & 'c:\Users\emile\.vscode\extensions\ms-vscode.cpptools-1.12.4-win32-ia32\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-q3ywy3gi.yjb' '--stdout=Microsoft-MIEngine-Out-gt1trhol.f4y' '--stderr=Microsoft-MIEngine-Error-1jql3toi.4bt' '--pid=Microsoft-MIEngine-Pid-wykhel3l.35n' '--dbgExe=C:\msys64\mingw64\bin\gdb.exe' '--interpreter=mi' jackENSIBS{W3ll_d0ne_C@pt41n} ``` ### Les recommandations à appliquer Nous avons pu constaté ici que le logiciel, lorsqu'on utilise le mode "Basic Authentication", est vulnérable à une écoute passive du réseau par un attaquant. Pour mitiger le risque lié à cette vulnérabilité, il est recommandé d'appliquer les mesures suivantes : - S'assurer que le lien réseau reliant le client au serveur est sécurisé et ne fait pas l'objet d'une écoute quelconque. - Attendre une mise à jour des développeurs pour qu'ils corrigent la vulnérabilité. Nous allons maintenant passer au 2ème scénario pour tester les permissions d'accès aux fichiers et répertoires présents sur le serveur. ## 2ème scénario : Les permissions d'accès aux fichiers et répertoires Au cours de ce scénario, nous allons chercher à voir s'il est possible de contourner les permissions d'accès mises en place. En d'autres termes, voir si un utilisateur possédant une accréditation "Restreinte" peut avoir accès à des fichiers au moins classifiés "Confidentiel" par exemple. L'entiéreté de ce scénario sera réalisé à partir du compte "employé" qui est seulement accrédité pour accéder aux données dites "Restreinte". ### Vérification des permissions d'accès aux fichiers et répertoires Pour vérifier cela, nous allons nous connecter au serveur avec le compte "employé" : ![](https://i.imgur.com/KPXRrla.png) Maintenant que nous sommes connectés, nous avons pouvons voir l'ensemble des fichiers disponible sur le serveur : ![](https://i.imgur.com/hNHgJPH.png) Nous arrivons sur ce menu, un fichier retient rapidement notre attention, il s'agit du fichier nommé "fichier_top_secret.txt" classifié "Top Secret" : ![](https://i.imgur.com/AAgyVu0.png) Etant connecté sous l'identité "employe", je ne devrais pas être en mesure de le télécharger. Essayons quand même de le faire. ![](https://i.imgur.com/A47D7Kd.png) J'ai pu télécharger le fichier sans message d'erreur comme le montre cette capture d'écran des logs du serveur : ![](https://i.imgur.com/eAh1Nci.png) En ce qui concerne le fichier ? J'ai bien réussi à récupérer son contenu : ![](https://i.imgur.com/tdCqjKY.png) Tant qu'on y est, je peux modifier les permissions d'accès des fichiers sans que le serveur me bloque, faute de privilèges suffisants. L'ensemble de ces actions furent réalisés avec le compte "employé" : ![](https://i.imgur.com/XbTvxDI.png) Comme le montre les logs du serveur, tout s'est bien passé sans la moindre erreur : ![](https://i.imgur.com/97eXP2S.png) Alors pourquoi le serveur accepte sans problème toutes ces requêtes sur des fichiers auquel le compte "employé" n'est pas censé avoir accès ? Nous allons essayer de voir cela ensemble. Si l'on analyse le code-source du logiciel client, on constate qu'il existe bien des messages qui sont prévus par le développeur pour avertir l'utilisateur qu'il ne peut pas réaliser certaines actions faute des autorisations suffisantes : ![](https://i.imgur.com/aBqqZAC.png) Toutefois, on peut supposer ici (au vue de la fonction qui fut renommé "erreurIdentification") que le client ne fait qu'interpréter le code de retour renvoyé par le serveur. Cela signifie alors que le problème se situe du côté du serveur et non du côté du client. Pour s'en assurer, allons jeter un coup d'oeil sur le code-source du serveur : ![](https://i.imgur.com/GwuLgt3.png) Voici un extrait du code source en assembleur du serveur où il gère les requêtes du client lorsque ce dernier souhaite télécharger un fichier. Au vue des lignes de codes présentes, nous pouvons voir la fonction qui, selon nous, permet de gérer les différentes erreurs qui seront renvoyés au client. Les erreurs peuvent être de toute nature. Voici d'ailleurs la fonction qui permet de renvoyer un code d'erreur au client : ![](https://i.imgur.com/WkKYp02.png) Nous ne sommes pas parvenus à identifier le bloc d'instructions censé avertir le client qu'il n'a pas les autorisations pour réaliser certaines actions. Selon nous, il existe différentes théories qui peuvent expliquer la raison de ce bogue : - Il n'existe pas de fonction permettant de vérifier les permissions de l'utilisateur connecté - La fonction qui vérifie les permissions du compte client est bien implémenté mais aucune instruction au sein du serveur y fait référence d'une façon ou d'une autre. Pour lever le doute ici, il faudra faire appel à un analyse plus expérimenté. ### Les recommandations à appliquer pour utiliser au mieux ce logiciel En raison de la nature préoccupante de cette faille de sécurité, nous considérons qu'il n'est pas sûr d'utiliser ce produit pour héberger des données ayant une classification supérieure ou égale à "Restreinte". Voici alors les recommandations à appliquer en cas d'adoption de ce logiciel : - Ne pas stocker de données classifiés à partir de "Restreinte". - Attendre une mise à jour des développeurs pour corriger ce problème. Nous n'avons pas de preuve de concept à vous proposer pour ce scénario, vous avez juste besoin d'un identifiant et mot de passe valide et vous aurez accès à l'ensemble des fichiers, peu importe votre niveau d'accréditation et la classification des fichiers présents sur le serveur. ## Liste des problèmes rencontrés au cours de notre audit Non seulement nous avons pu constater au cours des différents scénarios que ce logiciel était vulnérable mais il comporte également un ensemble de problème. Il est important pour les développeurs de ce produit de corriger au plus vite ce que nous avons pu relever. ### Impossibilité de téléverser un fichier dans un dossier Le logiciel offre la possibilité de créer sur le serveur distant des répertoires pour qu'on puisse y stocker nos fichiers. Or, lorsqu'on crée un dossier puis qu'on téléverse un fichier dedans, voici le message d'erreur que l'on obtient : ![](https://i.imgur.com/5LZxiTB.png) Le logiciel client plante et doit être fermé. Nous considérons que ce problème rencontré au cours de l'audit est suffisamment important au point d'entraver l'usage normal de ce produit. Nous recommandons ici d'attendre une mise à jour des développeurs pour qu'ils corrigent ce problème. ### Le port d'écoute du serveur distant Nous avons pu constater au cours de notre audit que le serveur écoute par défaut sur le port 4444. Ce numéro de port réseau est le même qui est utilisé par Metasploit par défaut pour lançer des attaques à travers les réseaux informatique. Cela veut dire que le trafic réseau échangé entre le client et le serveur peut être confondu avec une tentative de piratage informatique. Afin d'éviter d'alerter inutilement le SOC de toute entité souhaitant utiliser le produit, il est recommandé aux techniciens chargés du déploiement de changer avant tout démarrage du logiciel, le port d'écoute du serveur. ### Les transferts de fichiers Au cours de cet audit, nous nous sommes intéressés à la façon dont les fichiers sont transférés entre le client et le serveur. Pour cela, nous avons téléversé un fichier sur le serveur à des fins de test (flag.jpg). ![](https://i.imgur.com/BJp7YL2.png) On suppose ici que le programme, pour envoyer un fichier au serveur, fait appel à la fonction "readFile". Lorsqu'on cherche toutes les occurrences de cette dernière, on tombe assez rapidement sur la fonction qui gère l'interface permettant de créer un répertoire, supprimer un fichier, ajouter un fichier... Nous parvenons alors à voir la fonction suivante qui gère l'affichage de la fenêtre du côté du client : ![](https://i.imgur.com/jq1e4v8.png) Après quelques tests, on identifie la partie du code qui s'occupe du fichier pour le transférer au serveur : ![](https://i.imgur.com/cjRBsRM.png) Nous pouvons y voir une allocation de mémoire pour prendre le contenu du fichier ainsi que l'appel d'une fonction pour ouvrir le fichier de notre choix. Cependant, là où cela devient intéressant, c'est que le code utilisé pour lire le contenu du fichier à envoyer se situe ici, dans la fonction "dialogueChoixFichierAEnvoyer" (Renommé par nos soins) : ![](https://i.imgur.com/LWQiDKr.png) Nous constatons qu'il fait appel à la fonction "Send" de l'objet SocketClientChiffreVtable pour envoyer le fichier au serveur. Or, nous avons démontré au cours du premier scénario que la méthode de chiffrement utilisée peut être cassé à condition d'avoir une capture réseau avec dedans, une interaction entre le client et le serveur. #### Les recommandations à appliquer Nous avons pu constaté ici que le logiciel, lorsqu'on utilise le mode "Authentification basique", est vulnérable à une écoute passive du réseau par un attaquant. Cela lui permet de récupérer les identifiants mais également les fichiers transférés au serveur. Pour mitiger le risque lié à cette vulnérabilité, il est recommandé d'appliquer les mesures suivantes : - S'assurer que le lien réseau reliant le client au serveur est sécurisé et ne fait pas l'objet d'une écoute quelconque. - Attendre une mise à jour des développeurs pour qu'ils corrigent la vulnérabilité. ## Conclusion Nous avons pu, au cours de cet audit, tester les logiciels SomeClient et SomeServer développés par l'entreprise SomeSoftware. Au vu des résultats obtenus, nous conseillons, si cela est possible, d'attendre des mises à jours de la part des développeurs ou bien d'appliquer les recommandations proposées pour sécuriser au mieux l'usage de ce produit. ## Auteurs de l'audit L'audit a été réalisé par le groupe N° 8, à savoir Emile MARIÉ (Cyberdef5 TD1/TP1) et Corentin OLLIVIER (Cyberdef5 TD1/TP2).

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully