juil
21

Forensic et Piratage : Un cas original

Introduction

Un ami, qui travaille dans une société d’infogérance, me parle d’un fait troublant : Une de leur machine a été compromise, par bruteforce SSH apparemment. En effet, on constate dans le /var/log/auth.log, plus de 35.000 tentatives de connexion infructueuses. La ou cela sort de l’ordinaire, c’est que le mot de passe utilisé sur le compte piraté, le compte root, utilise un mot de passe de 13 caractères en alphanumérique étendu, et que chaque machine utilise un mot de passe différent, de robustesse équivalente. Bref, quelque chose ne colle pas. Ayant piqué ma curiosité au vif, je lui propose de lui prêter main forte afin d’y voir plus clair.

Mais avant tout, il s’agit la encore d’une preuve irréfutable que « AllowRootLogin » is the root of all evil !

En inspectant les logs de la machine (que l’attaquant n’a pas pris la peine de nettoyer, preuve d’un amateurisme manifeste), on constate bien des dizaines de millier d’essais de tentatives de connexion infructueuses, puis, tout d’un coup :

sshd[XXXX]: Accepted password for root from x.x.x.x port xxxx ssh2

Le pirate aurait-il réellement craqué en bruteforce un mot de passe robuste de 13 caractères ? Voila qui parait improbable, ou alors l’attaquant dispose d’une chance telle qu’il ferait mieux de jouer au loto ! Pour rappel, il avait à peu près 94^13 chances de trouver le mot de passe.

S’agissait-il d’une stratégie de sa part pour camoufler une autre attaque, plus évoluée ? Cela paraissait peu probable, mais envisageable … Quoi qu’il en soit, peu convaincus par l’explication actuelle, nous décidons de continuer nos investigations.

Mon ami et son équipe avaient déjà pu trouver une première toolkit laissée par le pirate. Celle-ci avait pu être détectée, car son scanneur de masse avait littéralement « mis à la rue » leur serveur mail, ce qui avait été le premier point d’alerte. Les processus n’ayant pas étés cachés, ils ont pu très rapidement mettre la main sur ce premier kit.


Analyse du premier kit déposé par l’attaquant

Voici le contenu de la toolbox déposée par l’attaquant :

index.html
LC_MESSAGES
LC_TIME
mech.jpg
pn
.r
.ssh
ssh.tgz
  • Le répertoire « pn » contient une série d’exploits plesk, ainsi qu’un bruteforcer de mots de passe plesk :
    • Un script shell, qui, en s’appuyant sur un scanneur de masse, tente du bruteforce sur le mot de passe administrateur PLESK.
    • Un exploit multi-target PLESK
  • Le répertoire « .r » contient lui ce qui semble être un bot IRC. Il ne semble pas s’agir d’un bot connu, mais comme celui-ci n’est pas strippé, il est assez facile de deviner son but avec un coup de GDB :
void do_banlist(char *, char *, char *, int);
void do_deop(char *, char *, char *, int);
void do_deopme(char *, char *, char *, int);
void do_idle(char *, char *, char *, int);
void do_invite(char *, char *, char *, int);
void do_join(char *, char *, char *, int);
void do_kick(char *, char *, char *, int);
void do_kickban(char *, char *, char *, int);

Par ailleurs, en regardant de plus près les fichiers de configuration du bot, on trouve assez rapidement des infos sur le covert channel, tel que le channel IRC ou se trouvent les différentes machines compromises. Au vu de la date de l’attaque, nous ne communiquerons pas de détails « techniques » sur le botnet de l’attaquant, afin d’éviter tout effet de bord.

  • Un répertoire « .ssh », qui contient la aussi, un bruteforceur (ssh-scan), accompagné du même scanneur de masse.

Bref, somme toute, uniquement des outils de « script kiddie », très bas niveau. Autant cela aurait pu être une bonne nouvelle, mais ici cela ne colle pas, les mots de passe sont bien trop robustes pour tomber avec un simple bruteforce.

Deuxième analyse

En s’appuyant sur l’analyse de la toolkit de l’attaquant, nous nous rendons sur le channel du pirate, et découvrons qu’il n’y a pas une, mais 49 machines (y compris les machines virtuelles) qui ont étés compromises dans sa société, bref, la piste du bruteforce deviens de moins en moins crédible, mais nous retrouvons bien, sur la plupart des machines piratées des traces de tentatives de connexion en SSH, et, sur TOUTES les machines, au moins une authentification ssh en root réussie … de quoi y perdre son latin.

Nous décidons donc d’exploiter d’autres pistes :

  • Logiciels vulnérables présents sur tous les serveurs compromis
  • Points communs qui pourraient expliquer la compromission de masse.
  • Présence d’utilisateurs autres, qui disposeraient des mêmes mots de passe sur les différentes machines

De cette piste, ne ressort rien de viable. Quelques logiciels vulnérables (notamment Rsync) présents sur plusieurs machines, mais des machines sans ce logiciel ont aussi étés compromises. Bref, rien de concluant.


Un autre point intéressant rentre alors dans la réflexion : Le RADIUS. En effet, dans la société, a été mis en place, il y a peu de temps, un système radius avec OTP et Ubikey (http://www.yubico.com/products/yubikey/). Il s’agit d’un système d’authentification otp/bi-facteur. Ce dernier avait été éliminé de facto, puisque l’attaquant semblait être d’un niveau technique trop faible pour ne serait-ce que songer à effectuer ce genre d’attaques. Certes, il ne faut jamais sous évaluer l’attaquant, mais vu les conditions et les éléments qui avaient étés relevés… Vu que les autres pistes n’avaient rien données, nous avons décidé d’investiguer de ce coté la. Il s’avère, au final que l’erreur n’était pas du tout la où on l’attendait. Le RADIUS était effectivement fautif, mais pour une raison tout à fait surprenante :

- Le script qui gérait l’authentification radius avec l’Ubikey,lorsqu’il recevait un challenge trop long, exitait avec le code « 9″. Or, pour radius, exit 9 correspond à « aller au module suivant ». Or le module suivant était « send-accept » (un module qui valide la tentative d’authentification). Ce qui s’est donc passé, est que le pirate, avec un mot de passe extrêmement long, déclenchait une erreur « HMAC Verification failed », et le script exitait avec le code 9, radius passait la main au module suivant (send-accept) et le pirate voyait son authentification réussir.

La finalité est que, le pirate, par chance, disposait d’un mot de passe extrêmement long (plus de 128 caractères), qui provoquait l’erreur 9 , et le pirate pouvait donc s’authentifier sur TOUTES les machines du réseau en utilisant ce mot de passe. La vulnérabilité est pour le moins originale, « dans la vraie vie ». Le bon point est que le pirate a réussi ses compromissions par pure chance, et pense (après discussion avec lui), avoir trouvé le mot de passe « root » de toutes les machines, puisque, qui dit radius, dit authentification centralisée, dit, toutes les machines peuvent être compromises avec ce même mot de passe.

Et jamais deux sans trois !

Une fois le vecteur d’attaque, il est FINALEMENT possible de chasser le pirate des machines. En effet, tant que le vecteur d’infection n’a pas clairement été identifié, il est « risqué » de fâcher le pirate. Il n’est pas possible de le bloquer tant que l’on n’a pas identifié le vecteur d’attaque, rien ne l’empêchant de revenir depuis une autre IP (sans même parler de la forte probabilité de mise en place d’un covert channel), et, pour peu qu’il soit irrité par cette tentative, de RM les machines. Maintenant qu’il est possible d’empêcher le pirate de compromettre à nouveau les machines, le script RADIUS étant fixé, il est possible de nettoyer les machines et de mettre le pirate à la porte. Et la, une nouvelle surprise nous attends. En effet, en regardant la configuration des covert channel IRC, nous avions vu deux serveurs apparaitre : Undernet, et Quakenet. Or, certaines machines normalement « nettoyées » étaient toujours présentes sur les channels, ce qui signifiait qu’il y avait une autre backdoor que celle identifié originellement. Après quelques recherches, il s’est avéré que l’attaquant avait installé Suckit ou T0rn sur la plupart des machines. Ces rootkits ont pu être principalement détectées grâce aux dates de modification des fichiers, notamment le binaire de suckit qui sert à l’injection dans /dev/kmem.


Le mot de la fin

J’ai décidé de vous faire part de ce cas, car j’ai trouvé celui-ci assez original, et il montre bien que la sécurité d’un système d’information n’est jamais plus forte que celle de son maillon le plus faible !

juil
19

Howto IDS/IPS

IDS/IPS Mise en place et techniques anti-IDS

Préconisations, Installation, configuration.
Par Ayoub FIGUIGUI (afi@nbs-system.com) le 17/07/2010

(Lire la suite…)

juin
17

Magento – Séparation des bases de données production et backoffice

Il est possible, via une petite modification du fichier index.php de magento, d’utiliser deux bases de données séparées pour la production et la backoffice. Ces deux base de données devront être en master/master.

Cela permet de séparer les requêtes « gourmandes » du backoffice et ainsi d’avoir une production allégée des opérations de maintenance. Nous assumerons que le document root de production s’appelle « prod » et celui du backoffice « bo« . Ci-dessous la procédure de séparation des bases de données, toute les commandes ci-dessous sont executées depuis le document root de la production.

  • Créer deux répertoires de configuration pour la production et le backoffice. Ces deux répertoires seront de préférence hors du document root du site.
  • mkdir -p ../includes/{prod,bo}_etc
  • Le document root de « bo » est un lien vers « prod« .
  • ln -s ../bo prod
  • Copions l’intégralité des fichiers et répertoire présent dans « app/etc/ » vers les deux répertoires créés dans « ../includes« .
  • cp -a app/etc ../include/prod_etc cp -a app/etc ../include/bo_etc 
  • On révise les droits sur le répertoire « ../includes » pour autoriser le serveur WEB à lire/écrire ces fichiers. (L’écriture n’est pas forcement nécessaire) chown -R websrv:websrv ../includes find ../includes -type f -exec chmod 600 {} ';' find ../includes -type d -exec chmod 700 {} ';'

  • Le repertoire app/etc est « hard codé » dans la vérification d’installation magento. Nous laisserons donc un fichier local.xml avec la date définie lors de l’installation. Voici le contenu de notre fichier :

  • Rajoutons maintenant ces quelques lignes dans le fichier **index.php**. cela permet à magento de prendre un répertoire de configuration spécifique à chaque document root. # # $doc_root = $_SERVER["DOCUMENT_ROOT"]; $arrDocRoot = explode( "/", $doc_root ); $cur = $arrDocRoot[ count( $arrDocRoot ) - 1 ]; $arrDocRoot[ count( $arrDocRoot ) - 1 ] = "includes"; $arrDocRoot[] = $cur."_etc"; $etc_dir = implode( "/", $arrDocRoot ); $options = Array( 'etc_dir'=>$etc_dir ); Mage::run($mageRunCode, $mageRunType, $options); # # # Mage::run($mageRunCode, $mageRunType);

  • Nous pouvons désormais configurer distinctement notre instance de production et de backoffice. Le lien symbolique « bo » pointant » sur « prod » nous permettant d’éviter les problèmes de synchronisation entre les deux répertoires. (Notons qu’un montage « bind » aurait produit le même résultat)
mai
6

Nouveau site pour NBS System

Bonjour à tous !

Voici notre nouveau site enfin en ligne.
C’est toujours une épreuve et un combat mais c’est fait, nous sommes maintenant au point.

Vous trouverez nos activités réorganisées et remise en page pour plus de clarté. Si vous détectez des erreurs ou des 404, n’hésitez pas à nous le signaler.

Le site s’agrémente maintenant d’un blog, nous y reposterons prochainement les deux howtos IPtables et OpenVPN ainsi que les articles de sécurité de l’ancien site. Dans le futur proche, vous y trouverez également des informations sur la société, sur les technologies en cour de développement ou d’étude dans nos laboratoires de R&D ainsi que des billets postés par nos experts.

Merci de votre visite, l’équipe de NBS System vous souhaite un agréable surf sur notre nouveau site.

mai
4

Howto Openvpn 2

mai
4

Howto Iptables / Netfilter

IPtables HOWTO français

Préconisations, Installation, configuration.
Par Philippe Humeau (philippe.humeau@nbs-system.com) le 18/03/2005

(Lire la suite…)