apt archive backdoor blog bug busybox coding coup2gueule crypto cv debian debiansux desktop distribution dotclear emacs engine filesystem firefox fonts forward fsck gcc geek gentoo git gmail gpg hardening heureux hg humeur ikiwi ilty imported integriste ipodsux kernel latex linux mail makefile migration mime mozilla music openbsd openssl password php police pub pwned python random repository rescue rockbox sansa sawfish security sh spam ssl sux sysadmin tech tempest unix vcs vieuxcon voip vulnerability windowmanager wm x11

Il n'est pas possible de poster de commentaires, mais vous pouvez toujours m'envoyer un mail pour que je mette à jour le billet.

(Note: Ce billet date d'environ six mois mais j'ai trop procrastiné pour le relire et le publier. Ca m'a aura au moins permis de mettre à jour certaines sections.)

Le système des capabilities sous UNIX est le parcellement du droit root en de multiples privilèges : lecture RAW du disque, capture du trafic sur la carte réseau, chargement de module, etc.

Ce travail a été débuté par le comité POSIX avec l'écriture de POSIX 1.e, mais après une dizaine d'années de travail, les sponsors ont quitté le navire et le comité a annonçé en 1998 : So the Standard Posix.1e is not likely to be "finished" or "released" anytime soon.

Bien que la standardisation ait été un échec, les développeurs des différents systèmes d'exploitation n'ont pas abandonné les capabilities pour autant, en particulier pour le noyau Linux qui a fait quelques avançées majeures l'année dernière, en particulier avec le 2.6.24 et le 2.6.25

Capabilities

Introduction

Toutes les capabilities existantes sont disponibles dans /usr/include/linux/capability.h elles sont au nombre de 34 (à l'heure actuelle) :

CAP_CHOWN              CAP_NET_ADMIN       CAP_SYS_RESOURCE
CAP_DAC_OVERRIDE       CAP_NET_RAW         CAP_SYS_TIME
CAP_DAC_READ_SEARCH    CAP_IPC_LOCK        CAP_SYS_TTY_CONFIG
CAP_FOWNER             CAP_IPC_OWNER       CAP_MKNOD
CAP_FSETID             CAP_SYS_MODULE      CAP_LEASE
CAP_KILL               CAP_SYS_RAWIO       CAP_AUDIT_WRITE
CAP_SETGID             CAP_SYS_CHROOT      CAP_AUDIT_CONTROL
CAP_SETUID             CAP_SYS_PTRACE      CAP_SETFCAP
CAP_SETPCAP            CAP_SYS_PACCT       CAP_MAC_OVERRIDE
CAP_LINUX_IMMUTABLE    CAP_SYS_ADMIN       CAP_MAC_ADMIN
CAP_NET_BIND_SERVICE   CAP_SYS_BOOT
CAP_NET_BROADCAST      CAP_SYS_NICE

On peut traçer une ligne dans ce groupe avec les capabilities correspondant une autorisation (c'est à dire "je suis autorisé à effectuer ce type d'action") et celles élévant les privilèges comme CAP_MAC_OVERRIDE qui permet d'inhiber l'effet des permissions du filesystem.

Les capabilities sont acquises soit par héritage du père, par des capabilities attachées au filesystem ou forçée par un processus externe.

La capability CAP_SET_CAP est nécessaire afin de modifier les capabilities.

Thread capabilities

Un processus, ou thread, possède en fait trois ensembles de capabilities :

  • Permissions effectives, les privilèges que le processus peut utiliser dès à présent.

  • Permissions permises, ce sont les privilèges que peut acquérir le processus s'il le désire. En d'autres termes, ce sont les permissions qui peuvent être déplaçées dans l'ensemble des permissions effectives.

  • Permissions héritées, les privilèges léguées.

Nous verrons dans les sections suivantes comment sont calculées automatiquement lors d'un execve().

capget permet de consulter les capabilities d'un processus, le noyau Linux offre également une entrée dans /proc :

# grep Cap /proc/self/status 
CapInh:000000000673b200
CapPrm:0000000000000000
CapEff:0000000000000000
CapBnd:ffffffffffffffff

File capabilities

Les file capabilities étaient jusqu'au 2.6.24 la pièce manquante dans l'implémentation de Linux qui lui permettait d'être complète. Ces privilèges prennent leurs sens lorsqu'un fait un execve sur ce fichier, le processus exécutant le programme verra ses thread capabilities modifiées en conséquence.

Il existe également trois ensemble de file capabilities :

  • Permissions permises (ou forçées), un processus gagnera automatiquement ces capabilities.

  • Permissions héritées (ou autorisées), cet ensemble permet de réduire les capabilities héritées d'un thread : un "ET LOGIQUE" sera fait entre les permissions héritées du processus et les permissions héritées du fichier.

  • Permission effective, cet "interrupteur" pousse les nouvelles permissions permises directement dans les permissions effectives du thread. Autrement, les permissions effectives sont écrasées à 0.

capability bounding set

Grossièrement, c'est l'ensemble des capabilities autorisées sur le système.

Transfert entre processus

Il n'y a que deux moyens pour modifier ses capabilities :

  • Manuellement, avec cap_set_proc ou prctl
  • Lors d'un execve()

Lors d'un fork(), tous les ensembles de capabilities sont copiées du père vers le fils sans modification. Nous ne nous intéresserons qu'aux règles de transmission des capabilities lors d'un execve.

Les règles de transfert sont les suivantes, extraites de la page de manuel capabilities(7) :

    P'(permitted) = (P(inheritable) & F(inheritable)) |
                    (F(permitted) & cap_bset)
    P'(effective) = F(effective) ? P'(permitted) : 0
    P'(inheritable) = P(inheritable)

where:

    P         denotes the value of a thread capability set  before  the
              execve(2)
    P'        denotes the value of a capability set after the execve(2)
    F         denotes a file capability set

    cap_bset  is  the  value  of the capability bounding set

On constate que les permissions héritées sont toujours conservées. Les capabilities permises sont quand à elles adaptées avec "P(inheritable) & F(inheritable)" mais sont surchargées par le contenu de F(permitted) (modulo le capability bounding set).

Enfin, les permissions effectives du thread dépend de la permission effective du fichier, si elle est activée, les nouvelles permissions permises sont poussées au processus, autrement, elles sont vidées.

Comportement du Capability bounding set

En d'autres termes, cela signifie que les file capabilities l'emportent toujours sur les thread capabilities. C'est d'ailleurs le seul moyen d'élever ses capabilities, ce qui peut être problématique : dans un environnement cloisonné comme une sandbox, on voudrait bannir cette possibilité d'élevation. C'est le rôle du capability bounding set qui a changé de comportement au 2.6.25.

Pre-2.6.25

Avant, cette variable était globale au système : tous les processus la partagaient. Cette approche avait au moins un avantage, c'était qu'au moment où une capability était supprimée, il était garanti qu'elle ne serait jamais distribuée à nouveau. Les sysadmins aimaient donc enlever la capacité CAP_SYS_MODULE afin d'empêcher tout chargement de module.

En réalité, la vérité est moins rose puisque d'une part, le capability bounding set n'a d'impact que sur le transfert des capabilities, tous les processus root, comme init, qui existaient avant la modification ont conservé la capability, si on est root sur un système, on peut toujours injecter du code dans init afin de charger notre module.

Deuxièmement, il est toujours possible de charger un module sans cette capability : à l'aide de CAP_SYS_RAWIO, on peut par exemple utiliser /proc/kcore et modifier à la volée la mémoire du noyau.

Post-2.6.25

Depuis le 2.6.25, la capability bounding set est devenu local à un thread. L'appel système prctl() a été enrichi de la commande PR_CAPBSET_DROP qui permet de supprimer des privilèges de son capability bounding set.

Étant donné que toutes les règles de transfert de privilèges respectent cette variable, il est dès lors impossible de récupérer une capability perdue.

Exemple:

# cat > dummy.c 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>

int main(void) {
    char *args[]= {"bash", "-i", NULL };

    if (prctl(PR_CAPBSET_DROP, CAP_NET_RAW, 0, 0, 0) != 0) {
         perror("prctl()");
         return 1;
    }

    execve("/bin/bash", args, NULL);

}
# gcc -o dummy dummy.c 
# ./dummy 
inside# getpcaps $$
Capabilities for `17817': =ep cap_net_raw-ep
inside# tcpdump -ni eth0
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)
inside# su - guest
guest@local:~$ su -
Password: 
local:~# getpcaps $$
Capabilities for `17966': =ep cap_net_raw-ep
local:~# tcpdump -ni eth0
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)

Ici, malgré les changements d'identité, il n'a pas été possible de récupérer la capability perdue.

Implémentation

Erreurs de jeunesse

Oubli de checks

Après de multiple séries de patches interminables, toutes les vérifications dans le noyau se basent sur une capability particulière plutôt que de simplement vérifier si on est root ou non.

Néanmoins, des vulnérabilités sont de temps en temps remontés sur le manque de check, comme c'était le cas samedi dernier.

Ce changement de méthode d'autorisation impose donc de conserver une compatibilité sur l'existant. Dans le cas normal, les choses sont relativement simples, mais dès qu'on se penche plus en avant sur les détails, les choses se compliquent : prendre en compte les binaires avec bit set-user-id, la complexité de l'appel système setuid(), etc.

L'introduction des capabilities a ouvert une vulnérabilité dans des logiciels mal programmés à cause d'une erreur de logique.

Vulnérabilité userspace

Pour émuler les capabilities sur des processus classiques, le noyau est obligé de donner des valeurs initiales aux différents ensembles de permission afin de calquer le comportement UNIX traditionnel, c'est pour cette raison que les permissions héritées de tous les processus avaient pI = ~0 (c'est à dire toutes les privilèges étaient hérités).

À l'époque, les règles de transition étaient les suivantes :

pI' = pI
pP' = (X & fP) | (pI & fI)
pE' = fE & pP'

Contrairement au comportement actuel, les capabilities permises étaient écrasées par les capabities héritées masquées par les file capabilities héritées (pI & fI) et ces permissions permises étaient rendues effectives (modulo fE).

Puisque par défaut pI = ~0, un processus pouvait s'enlever des privilèges de ses capabilities héritées, donc de ses permissions permises et donc de ses permissions effectives.

Les règles de transition pour émuler le bit setuserid0 était le suivant :

if (uid==0 or file-to-exec-is-setuid0) {
  fE = fI = ~0;
  fP = 0;
} else {
  fI = fP = fE = 0;
}

C'est à dire que si un processus lambda se supprimait une capability héritée (qu'on notera pI-) et qu'il executait un programme setuserid0, alors la formule de transition se transformait en :

pE' = (pI & fI) = pI- & ~0 = pI-

Quel intérêt ? Comme beaucoup de logiciels (ou de crackme :p), sendmail ne vérifiait pas le code de retour de setuid(), comme dans l'exemple suivant qui tournait avec uid=0 :

setuid(user);
execve(user_controlled_program);

Dans le noyau, setuid() vérifie la capability CAP_SETUID pour autoriser ou non le changement d'utilisateur.

L'attaquant avait alors à supprimer cette capability de son héritage, exécuter sendmail en demandant d'exécuter /bin/bash. Au moment du setuid(), le noyau refuserait et le programme continuerait son flot en restant uid=0.

Bien qu'ici, la vulnérabilité soit majoritairement la faute de sendmail et non du noyau, les développeurs du noyau ont modifiés les règles de transitions et de valeurs initiales d'émulation.

Intérêt

Supprimer tous les programmes setuserid0

Fedora a décidé de supprimer tous les binaires setuserid0 afin de d'utiliser les capabilities à la place, par exemple pour ping :

# ls -alh /bin/ping
-rwsr-xr-x 1 root root 33K 2007-12-10 05:20 /bin/ping
# chmod -s /bin/ping
# setcap cap_net_raw=e /bin/ping
# setcap cap_net_raw=ep /bin/ping
# ls -alh /bin/ping
-rwxr-xr-x 1 root root 33K 2007-12-10 05:20 /bin/ping
# getcap /bin/ping
/bin/ping = cap_net_raw+ep

L'intérêt est évident : si le programme est exploité par un attaquant, seul la capability est compromise et pas le reste du système (même s'il faut garder à l'esprit l'histoire du CAP_SYS_MOD et CAP_SYS_RAWIO).

Pourquoi cela n'est pas applicable sur toutes les distributions ? Deux raisons :

  • La première est que le noyau nécessite le support des file capabilities, ce qui a été ajouté dans le 2.6.24 (donc Debian Etch est hors concours).

  • La deuxième est que les file capabilities sont stockées dans les attributs étendus des fichiers (xattr). Ces xattr ne sont pas compatibles avec tous les filesystems. De plus, il faut que les outils d'installation (comme dpkg, ou tar au bout du compte) les supportent également.

Pour toutes ces raisons, il est difficile d'imposer cette solution. Alors il y a 284 jours (d'après le rapport de bug), un patch avait été soumis afin de supporter les capabilities dans start-stop-daemon, le logiciel qui démarre la majorité des daemons sous Debian.

start-stop-daemon / minijail

L'idée est : puisqu'on ne peut pas modifier les paquets existant, on peut toujours modifier la façon dont ils sont lançés.

L'option --dropcap permet alors de jeter certaines capabilities avant de lançer le daemon. In fine, le plan était de :

  1. Pousser les modifications dans start-stop-daemon
  2. Déterminer les capabilities nécessaires à chaque daemon d'un serveur classique
  3. Pousser ces données à chaque mainteneur de paquet

284 jours plus tard, la situation est restée bloquée au premier point par manque de temps (et de réaction côté Debian) :)

À vrai dire, c'est grâce à ChromeOS que je me suis rappellé de ce post en cours d'écriture et du travail non achevé pour start-stop-daemon. En effet, les développeurs de Google ont implémenté minijail qui implémente la relache de capabilities (et plein d'autres fonctions).

Posted Tue 08 Dec 2009 03:13:10 PM CET Tags:

L'année dernière, le noyau Linux a vu un nombre impressionnant de patches avec le mot "namespace" dedans, tout s'est vu "namespacisé" : de l'espace des PID, aux points de montages en passant par les politiques IPSec.

Dans ce post, on va se focaliser sur la partie réseau et son utilisation dans le cadre d'un processus qu'on voudrait restreindre (au sens d'une chroot améliorée). On utilisera indifférement les termes machines virtuelles (VM), container, jail, etc.

Chacun cherche son chat

La partie réseau a été particulièrement polémique chez les développeurs du noyau car il y a de nombreuses façons de réaliser cet espace de nommage : il y a autant de façons que de couches protocolaires comme le détaille l'article de J. Corbet.

Il y a les partisans d'une approche légère où la virtualisation est simplement faite au niveau des sockets et d'autre qui voudraient pouvoir complétement virtualiser la pile TCP/IP afin d'avoir des interfaces, adresses IP, routes et politiques IPSec complétement distinctes entre les machines virtuelles.

La solution qui a été finalement choisie est celle virtualisant la couche 2, cela permet ainsi d'avoir des interfaces complétement indépendantes entre les VM (et donc d'adresses IP, routages, etc.) et l'hôte.

Cette fonctionnalité est disponible dans le noyau Linux depuis le 2.6.27.

La création d'un namespace

Au niveau du noyau, il n'y a qu'un seul moyen de déclarer un nouvel espace de nommage, c'est via l'appel système unshare() (ou via clone() de manière indirecte). Cette fonction a pour effet de désassocier un namespace de son contexte d'exécution.

Son seul argument est le composant que l'on veut désassocier (réseau, système de fichier, descripteurs de fichiers). Cela signifie donc qu'un processus désirant se créér un nouvel espace de nommage est obligé d'être modifié afin d'appeller cet appel système. Un workaround est l'utilisation d'un programme qui va faire cet appel à unshare() puis faire un execve() du programme cible.

Néanmoins, cela implique alors la distribution de deux fichiers (un programme qui exécute l'autre) car il n'existe pas de logiciel standards pour cette tâche, on pourra toujours utiliser netunshare extrait de la suite lxc.

Gestion des interfaces

Lorsqu'on créé un nouvel espace de nommage, le processus se retrouve avec une seule interface, un nouveau loopback uniquement. Pour enrichir sa collection d'interface, il est donc nécessaire de soit créér une nouvelle interface virtuelle, soit transférer une interface déjà existante.

Création d'interface

La création d'une interface virtuelle unique n'a de sens que si elle est connectée à quelque chose (de la même façon qu'un tunnel, il faut qu'il y ait un bout dans la VM, l'autre vers l'extérieur), il faut donc choisir autre chose qu'une interface du style 'dummy' qui peut être considéré comme un puit sans fond.

Une solution de tunnel existe depuis longtemps sous Linux, les tunnels TUN/TAP, or ils ont pour but de fournir un tunnel entre un descripteur de fichier et une interface réseau. Il faudrait donc créér un programme qui ouvrirait deux tunnels et qui passerait son temps à passer les paquets d'un côté à l'autre.

C'est pour cette raison qu'a été implémenté les interfaces de type Virtual Ethernet (veth) qui crééent une paire d'interfaces liées entre elles : ce qui rentre par l'une sort par l'autre et vice versa.

# ip link
4: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ip link add type veth
# ip link
4: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether fe:d8:a2:71:23:ae brd ff:ff:ff:ff:ff:ff
10: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 3e:3e:90:3b:3f:c0 brd ff:ff:ff:ff:ff:ff

Si on créé une telle paire d'interface, on reste toujours avec le même problème : on a bien deux interfaces, mais elles restent confinées dans le container, il est donc nécessaire d'avoir un moyen de transférer une interface entre des espaces de nommage, ça tombe bien, c'est supporté :)

Transfert d'interfaces

Lorsqu'on transfère une interface, plutôt que de désigner explicitement un namespace, on précise à la place un PID, l'interface sera alors attachée au namespace de ce PID.

ip link set veth1 netns PID_DESTINATION

Lorsqu'un espace de nommage est détruit, toutes ses interfaces (sauf loopback) sont transférées automatiquement au namespace parent.

Possibilité

À l'intérieur d'un namespace, il est possible de faire tout ce que vous pouvez attendre d'un système normal : changement des routes, des adresses IP, etc.

L'intérêt de ce genre de cloisonnement est qu'une jail n'a qu'un seul point d'entrée et de sortie : l'interface réseau qui a été déportée par l'hôte.

C'est la grande différence avec vserver qui ne permet pas d'identifier clairement les flux entre VM en écrivant vos règles en terme d'interfaces (vous vous retrouvez obligé de jouer sur les adresses sources).

Ce qui n'est pas encore supporté

Pour le moment, Netfilter n'a pas encore le support des namespaces. Cela signifie qu'un container ne peut pas avoir ses propres règles de firewall, mais le problème principal est que Netfilter ne peut voir passer que les paquets sur l'espace de nommage initial. Cela signifie que si vous mettez en place un tunnel entre deux espaces de nommages, Netfilter ne pourra pas pas voir passer les paquets entre eux.

C'est pour cette raison qu'il est préférable de ne pas dédier une VM à la tâche de routeur : tout doit passer à travers l'hôte qui peut alors appliquer une politique de filtrage assurant le cloisonnement. Il faut alors travailler dans la cible FORWARD qui décidera de la politique à adopter.

Posted Tue 28 Apr 2009 05:38:45 PM CEST Tags:

Dans sa version 2.1.0, le serveur FTP sécurisé vsftpd de Chris Evans a intégré un mécanisme de sandboxing, son auteur le décrivant simplement comme :

An ambitious new built-in sandbox. Think of it as privsep++, but more
on this in an upcoming post and paper.

De quoi nous rendre curieux ! Hop, on télécharge les sources de la 2.0.7 et la 2.1.0 et on fait un diff entre les deux répertoires : pas grand chose, on peut juste observer qu'il y a des appels à ptrace_sandbox_alloc() et ptrace_sandbox_run() et c'est tout : cela signifierait donc que la sandbox est complètement transparent pour le code de l'application, une bonne chose !

Introduction à la sandbox

On constate néanmoins l'ajout de deux fichiers : ptracesandbox.c et ftppolicy.c. Les choses sérieuses commencent enfin...

D'après le nom de fichier, on peut se douter que la sandbox repose sur ptrace() (aka "the unique and arcane syscall"). Effectivement, elle utilise PTRACE_SYSCALL qui permet d'interrompre le processus traçé à l'entrée dans un appel système (dans la routine syscall_trace_entry et de passer la main au traceur. vsftpd implémente ainsi toute sa logique dans la fonction ptrace_sandbox_handle_event() qui vérifie la provenance du signal puis regarde quel appel système est demandé.

Vérification de l'appel système

Ce check n'est pas aussi simple que prévu, Chris Evans a ainsi trouvé la vulnérabilité CESA-2009-001 dans le noyau Linux le mois dernier permettant de contourner des mécanismes de protection basés sur ptrace() (comme systrace).

L'astuce est que sur les architectures supportant à la fois le mode 32 et 64 bits, les numéros d'appel systèmes ne sont pas les mêmes suivant le mode dans lequel on est (le syscall numéro 2 est open() en 32 bits, mais correspond à fork() en 64 bits). Il faut alors prendre des précautions particulières pour s'assurer que tout le monde parle la même architecture :

  • Si on a intercepté un int80 ou sysenter, on est sûr d'être en 32 bits.

  • Si c'est par l'instruction syscall, les dés sont lançés, il faut alors consulter le sélecteur CS afin de vérifier s'il référence une table dont on connait son "type" (32 ou 64 bits).

Une fois le numéro d'appel système (vraiment) connu, la sandbox va consulter deux tables, toutes deux indexées par numéro d'appel système. La première indique si le syscall est autorisé ou non, la deuxième donne le callback associé à l'appel système (par exemple, il y a un callback pour open() qui permet de vérifier l'utilisation de O_RDONLY).

Création de processus

Toutes les méthodes de création de processus sont interdites dans la policy. Chaque déviation à la politique est fatale pour le processus qui est tué par un SIGKILL, cette brutalité est ici problématique comme nous allons le voir. En effet, lorsque le traceur est prévenu, il est en mesure de modifier le numéro d'appel système que voulait exécuter le processus afin de le rendre inoffensif. Le noyau exécute alors l'appel système, puis rend la main au processus en délivrant tous les signaux en attente.

Ici, le problème est que lorsque la sandbox voit que c'est un fork() qui veut être exécuté, elle tue le processus (en fait, elle ajoute un signal SIGKILL dans la liste des signaux en attente) mais le noyau continue de dérouler la routine syscall et donc d'exécuter la création du fils.

Néanmoins, lorsque le parent est schedulé, le SIGKILL est délivré et il est effectivement tué. Mais le fils existe toujours! C'est pour cela que la sandbox utilise PTRACE_SETOPTIONS avec TRACE_{VFORK,FORK,CLONE} pour tracer par défaut tous les fils que pourrait créer un processus et les tuer quand bon lui semble.

C'est là que je suis perplexe puisqu'on a vu qu'on pouvait dire au noyau "Non en fait, le processus a voulu exécuter le syscall exit(), pas fork() mais tue le quand même après". Et c'est effectivement ce que fait la sandbox : avant de tuer le processus par trois moyens différents, elle ré-écrit les registres afin de pointer sur exit() donc tout est fait proprement et le SETOPTIONS précédent est ici superflu. Vu que Chris est sûrement paranoïaque, dans le doute, il a préfèré mettre ceinture et bretelles.

Protection du processus monitorant

On comprend bien que la sécurité de la sandbox repose uniquement sur le processus monitorant. Si celui-ci tombe, tous les mécanismes de sécurité sont compromit, c'est pour cette raison que lors de l'initialisation d'un nouveau processus, chaque fils fait un prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) afin que le noyau tue le processus si son père (le moniteur) meurt.

Conclusion

Y a pas à dire, Chris Evans a réalisé ici un véritable chef-d'œuvre ! C'est la première fois que je vois une sandbox qui fait vraiment son rôle sans être vulnérable à la première attaque. Le design a été particulièrement travaillé, tout est clean et on sent qu'il y a eu de la réflexion derrière chaque fonction.

Impressionnant ! En plus, tout le moteur n'est contenu que dans un seul fichier C rendant son importation dans d'autres projets très simple.

Posted Thu 19 Feb 2009 09:29:56 PM CET Tags:

D'humeur joyeuse, j'ai décidé de faire quelques analyses sur la quantité de spam reçu sur l'un des serveurs de messagerie que j'administre.

Voici le top 8 des raison de rejet sur plus de 113 000 messages considérés comme spam :

Top mail rejection reasons by message count
-------------------------------------------
  Messages   Mail rejection reason
     61119   Rejected RCPT: Unrouteable address
     30085   Spamassassin, score > 5
     13099   SMTP protocol synchronization error
      5653   Rejected RCPT: Sender verify failed
      1615   Rejected RCPT: Spoofed EHLO/HELO
       715   Connection refused
       446   Rejected HELO/EHLO: syntactically invalid argument
       417   Rejected RCPT: Too many bad recipients, now wait!

La première cause est assez facile à expliquer puisqu'elle résulte des robots spammeurs et leurs attaques par dictionnaire.

Le deuxième meilleur filtre reste le vénérable Spamassassin qui est configuré pour rejeter les messages lorsque le score dépasse les 5 points. Auparavant, le seuil était plus haut, autour de 8, mais au fur et à mesure, les spammeurs se sont adaptés et essayent désormais d'avoir un score le plus bas possible, si on analyse la distribution des scores, on obtient la figure suivante. Elle représente en ordonnée le nombre de messages qui ont été rejetés pour un score donné.

[[!img static/spamassassin-score.png ]]

Dommage que je n'ai plus accès aux logs d'il y a quelques années, je suis sûr qu'on aurait observé un glissement vers la droite de la courbe.

Les autres filtres sont beaucoup moins efficaces, en partie car ils ne sont matchés que lorsque le client a un comportement non légal avec les RFC :

  1. Problème de synchronisation : les clients sont censés attendre la bannière EHLO avant de se présenter eux-mêmes. Les robots spammeurs n'ont pas cette politesse et envoient tout le plus vite possible.

  2. Sender verify : c'est ce qu'on appelle un callout, à la réception d'un mail, vérifier que l'expéditeur pourrait bien recevoir une réponse (en gros, c'est vérifier que l'adresse existe bien).

  3. Usurpations d'identité dans les présentations, le client se fait passer pour nous.

  4. Trop de connexions simultanées depuis le même client

  5. Syntaxe invalide des clients

  6. Le client a généré trop d'erreurs de destinations (bruteforce)

Posted Tue 17 Feb 2009 10:17:47 PM CET Tags:

Rendez moi mon entropie !

Toute la cryptographie repose sur la génération de nombres aléatoires, on a ainsi pû en voir les effets à de nombreuses reprises. Tout le monde citera la fameuse débacle Debian/OpenSSL mais c'est un incident parmi tant d'autres... Par exemple, un des CVE d'aujourd'hui concerne un défaut dans l'initialisation de la graîne (CVE-2009-0255) dans un CMS, "hier" c'était le générateur pseudo-aléatoire Microsoft qui était prit la main dans le sac par newsoft et Kostya, etc.

Tout ça, ce sont des problèmes "résolvables" : il y a tout un tas de recommendations pour éviter que cela ne se reproduise, en théorie. Mais si on commençe à regarder ce que le futur nous prévoit, on se rend compte qu'on va vers un tas d'ennuis...

L'entropie & ses problèmes

Commençons par expliquer comment on fait aujourd'hui. Tout d'abord, à part avec du matériel dédié, on ne sait générer que des nombres pseudo-aléatoires. Pour cela, on va utiliser des sources de bruit environnementales (température, timing d'accès disque, bruit d'un capteur, accéléromètre, interruptions clavier, etc.). Bref, tout ça relève quand même de la bidouille, mais de la bidouille qui fonctionne :)

Les choses se compliquent avec les nouvelles générations de matériels. On peut considérer qu'on est progressivement en train de changer "on-the-fly" la moquette par du lino tout en laissant les meubles posés. Autrement dit, on se repose sur les hypothèses de la dernière décennie pour montrer la solidité d'un système d'aujourd'hui.

Hardware 2.0

L'exemple du temps d'accès disque est flagrant, il avait été montré en 1995 que le temps d'accès pouvait être considéré comme aléatoire grace aux turbulences à l'intérieur des disques dur donc cela validait son utilisation pour contribuer à l'entropie du système. Mais là où ça devient embetant, c'est que l'on n'a pas remit en question cette propriété pour les disques dur SSD qui sont pourtant dépourvus de système mécanique. Hypothèse fail

Les mini-ordinateurs (NAS, bornes d'accès Wifi, boxes Internet, etc.) sont dépourvus de disques dur (remplaçés par de la CF ou équivalent), n'ont pas de clavier et ont tous une configuration exactement identiques en sortie d'usine (à part l'adresse MAC et le numéro de série marqué en NVRAM), comment peuvent ils avoir une entropie suffisante pour générer des clefs robustes (administration HTTPS, clefs SSH, clefs Wifi, etc.) lors du premier démarrage ? Rien ne l'indique... Il y a quelques "work-arounds" comme l'obligation de se plugger en Ethernet à la box afin de l'administrer pour la première fois (ça charge ainsi un peu d'entropie) mais les cryptographes ne considèrent pas les évenements venant du réseau comme "sûr" pour alimenter l'entropie.

Hypothèses fail

Virtualisation

La virtualisation apporte aussi son lot de problème : on utilise par exemple les interruptions car on considère qu'elles sont décorrélées de l'horloge du processeur (puisqu'elles sont normalement déclenchées par un évenement externe). Or avec un hyperviseur logiciel comme Xen, ce n'est plus le cas puisque c'est le dom0 qui génère ces interruptions, donc l'hypothèse de départ est encore invalidée. FAIL

De plus, avec la virtualisation matérielle, étant donné que les guests et le host partagent quelques ressources matérielles, sommes-nous vraiment certains qu'un guest ne peut pas prévoir le PRNG de son host ou de son voisin ?

Mutualisation

Beaucoup plus simplement, on a vu que la mutualisation de virtual hosts PHP pouvait mener à en partager un peu trop : s'ils ne sont pas utilisés en CGI, deux scripts PHP de vhosts différents peuvent tourner dans le même processus. Grossièrement, cela signifie que si le premier script fixe la graine d'aléa, le deuxième script utilisera le PRNG laissé dans l'état précédent. FAIL

Solution

La solution ? L'utilisation de RNG matériel est la seule possibilité. Les chipsets Intel et Via intègrent déjà cette fonctionnalité en XOR-ant les sorties d'oscillateurs libres fonctionnant à des horloges différentes.

Il n'y a plus qu'à espérer que ces HW-RNG soient vraiment robustes et que les implémentations soient correctes (pas comme NetBSD qui croyait détecter un HW-RNG alors que ce hub ne fournissait qu'un flux de 0xff :)...

Mise à jour du 30 janvier 2009 : En fait, c'est newsoft qui avait souligné le problème de clef dans Windows en lisant la note du CERTA.

Posted Thu 29 Jan 2009 09:08:14 AM CET Tags:

Ça fait maintenant plus d'un mois que j'utilise le multi-tty dans Emacs et depuis, je n'arrête pas d'évangéliser à son sujet.

Si je devais donner une pseudo-définition, ca serait : le multi-tty permet de partager des buffers entre plusieurs instances d'emacsclient. Mais donnons plutôt un cas d'utilisation : chez vous, vous travaillez sur un fichier et vous partez au travail sans fermer votre Emacs mais vous avez vraiment envie d'y toucher, vos seules solutions sont :

  • Tuer emacs en espérant que vous n'aviez pas de changement non sauvegardés (ou alors se taper un diff avec les fichiers d'autosave)

  • Éditer le fichier comme une brute en forçant Emacs à piquer le fichier.

Dans tous les cas, c'est un plan lose. Alors qu'avec multi-tty, vous n'avez qu'à lancer votre emacsclient et changer de buffer pour récupérer le fichier oublié. Vous pouvez donc partager un buffer entre plusieurs emacsclients (chacun pouvant être en mode terminal ou X11), ce qui laisse la possibilité de faire une sorte de travail collaboratif sommaire si besoin.

Auparavant, cette fonctionnalité était un patch non officiel. Mais elle a été intégrée il y a quelques mois dans la version CVS d'Emacs, comme l'option --daemon d'Emacs qui permet de le faire tourner en mode serveur.

L'essayer, c'est l'adopter, en plus sous Debian, il suffit d'installer les paquets Debian de Romain Francoise :

deb http://emacs.orebokech.com sid main
Posted Sat 22 Nov 2008 05:42:40 PM CET Tags:

Ils sont marrant les codes de retour des serveurs SMTP d'AOL :

550 We would love to have gotten this email to mamanours@aim.com. 
    But, your recipient never logged onto their free AIM Mail account. 
    Please contact them and let them know that they're missing out on 
    all the super features offered by AIM Mail. And by the way, 
    they're also missing out on your email. Thanks. 
Posted Sat 22 Nov 2008 05:20:23 PM CET Tags:

Lors de la sortie d'OpenBSD 4.4, j'avais été choqué de lire dans l'interview de Kurt Miller que leur OS n'était toujours pas capable de faire du PIE. Pour ceux à qui ça ne leur dirait rien, c'est une option du compilateur permettant de rendre le code totalement "déplacable" dans la mémoire : toutes les instructions sont relatives (comme c'est le cas dans les bibliothèques), aucune adresse n'est marquée en dure.

Ainsi, lorsqu'un processus est lançé, on peut placer toutes les sections du binaire à des adresses aléatoires. Cela permet de boucler la boucle dans toutes les protections mémoires : l'ASLR est complète, protections NX, PaX, W^X, mise en lecture seule de la GOT & Co. Autant dire que la tâche est beaucoup plus compliquée pour exploiter un buffer overflow, à vrai dire, à part un off-by-one chanceux, je ne vois pas comment exploiter ça (vous avez le droit de m'envoyer vos idées).

Bon, tout ça pour en revenir à OpenBSD qui se dit être l'OS le plus sécurisé et tout ça et annoncer aujourd'hui qu' ils commencent tout juste à avoir une toolchain complète supportant le PIE. Ca me fait penser aux affaires dans le passé où on s'est rendu compte que W^X ne s'appliquaient pas à toutes les sections, etc.

Conclusion : A false sense of security is worse than a true sense of insecurity.

Posted Wed 19 Nov 2008 09:31:19 AM CET Tags:

Astuce du jour (ou de l'année vu ma fréquence de posts) pour vsftpd qui n'est pas capable d'écouter à la fois en IPv6 et en IPv4. La solution, c'est de savoir que c'est pas possible.

Il faut en fait passer par (x)inetd qui n'a pas de telle limitation et qui passera la main() à vsftpd en temps voulu.

Posted Sun 16 Nov 2008 06:24:37 PM CET Tags:

Faisons une constation assez simple : si votre lecteur portable (tournant sous Rockbox bien évidemment) a un disque de grande capacité, vous l'avez chargé une fois et vous tournez avec la même musique depuis maintenant 4 mois car vous avez la flemme de faire le DJ.

On va donc emprunter une fonctionnalité qui parait-il se trouve sur Itunes : remplir son lecteur avec des fichiers complétement aléatoires.

Ce qui donne le script (zsh) suivant :

#! /bin/zsh

setopt extendedglob
MUZBUS="\/media\/muzbus"
MUSIC="/music"

muzfiles=($MUSIC/**/*mp3(.))
fillme=$(df "${(Q)MUZBUS}" | awk -F" " "/${MUZBUS}/ { print \$4*1024}")

zmodload -F zsh/stat b:zstat
i=0

while [ "$fillme" -gt "0" ]; do
    rndfile="$muzfiles[(($RANDOM % $#muzfiles))]"
    size=$(zstat +s "$rndfile")
    fillme=$((fillme - size))
    print -l -- "$i -- $rndfile"
    cp -- "$rndfile" "${(Q)MUZBUS}/music/"
    ((i++))
done

Attention ! Ne lançez pas ce script sous Debian, ils ont quelques problèmes d'aléa :)

Posted Sun 15 Jun 2008 03:53:09 PM CEST Tags:

Je suis en train d'évaluer quelques distributions dîtes sécurisées, et la première à laquelle je me suis intéressé est Gentoo Hardened.

C'est la distribution qui semble la plus "maintenue", avec une quantité de "paquets" importante et une base d'utilisateurs importante, sa communauté semble bien étoffée par des personnes telles que Solar Designer ou même pageexec.

De plus, pas mal de personnes que je respecte utilise cette distribution, ca doit pas être si mauvais ?

Attention, j'ai essayé de tester le truc en restant en mode non-troll, j'ai vraiment essayé, je le jure... Mes critères de jugement ont été les suivants : imaginons que je sois le sysadmin d'une moyenne entreprise avec un parc d'une trentaine de serveurs hétérogènes en architecture, modèle, technologie (une pré-image d'installation unique est donc impossible).

Le seul critère (subjectif) qui compte, c'est l'efficacité du truc.

Installation

Wahoo. Comment dire, si on vient du monde Linux (par opposition aux installs BSD), l'installation est loin d'être une promenade de santé, tout est très spartiate.

Autant il est facile d'installer une Debian en moins de 20 minutes, autant c'est impossible avec une Gentoo. Quand bien même c'était ma 3ème installation comparé à la centaine de Debian que j'ai pû mettre en place, il est impossible de faire aussi efficace qu'un Debian-Installer (mon seul référentiel).

Et puis tout irait bien si ça c'était bien passé, ça aurait été trop facile. Eh ben non! Tout a pété avec leurs maudits "Broken packages" ou "Masked package". Heureusement, je testais dans une machine virtuelle donc j'étais confortablement installé dans mon fauteuil, à une température correcte, en tee-shirt+caleçon (oui, c'est mon bleu de travail favori) et surtout, j'avais un navigateur Web pour regarder la documentation, bug reports et mailing list. Je n'imagine même pas en salle machine, coinçé entre deux rangées de baies où les ventilateurs expulsent l'air chaud dans le dos alors que je tape sur un KVM merdique mi-azerti, mi-dvorak, mi-stupide (oui ça fait 3/2 tout ça, mais les KVM ont un nombre bizarre de touches).

À l'issu de l'install, je me réconfortais en me disant qu'au moins, j'aurais vraiment le strict minimum installé.

localhost ~ # df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda1              37G  2.4G   33G   7% /
udev                   10M  100K   10M   1% /dev
shm                    60M     0   60M   0% /dev/shm

Oups. Disk usage failed! WTF? J'imagine que ce sont les sources, portage ou je ne sais quoi qui sont supprimables sans problème, mais je suis pourtant sûr d'avoir suivi le Gentoo Handbook à la lettre (sinon je m'en sortais jamais), comment est-ce possible d'en arriver à 2.4 Go !

Dans les trucs qui choquent encore, c'est que la liste des terminaux graphiques reconnus est vraiment "light", si vous vous connectez en ssh à partir d'un terminal rxvt-unicode, vous vous retrouverez avec un shell ne permettant pas d'utiliser vim, quelques shortcuts comme ^L, etc. Ca coûte rien qu'ils soient installé par défaut for god sake!

Passons à la configuration.

Configuration du système

Conf système et réseau

Le réseau... Comment on configure ce truc? Me dites pas que... Bienvenue dans les années 70, avec les adresses, routes et gateway dans des variables d'environnement sourcées par les scripts /etc/rc*.

Et si! Il est vrai que sur un serveur, c'est peut-être largement suffisant, mais si on considère le cas d'un routeur, ou d'un serveur un peu bizarre (machines virtuelles) avec des bridges et vlans c'est ingérable. On en revient alors à écrire un script qui fait tout ça, mais c'est tout autant ingérable, le /etc/network/interfaces que je connais sous Debian est irréprochable sur ce coup, en particulier quand on a lu sa doc.

La création d'utilisateur est resté BSDienne avec un useradd où il faut connaître par coeur toutes les options de ligne de commande sous peine de revenir éditer les fichiers passwd et shadow à la main. Le adduser Debian est peut-être écrit en Perl, mais il est pratique.

On voulait un système durçi, va falloir recompiler le noyau pour activer toutes les options de sécurité (PaX, Grsecurity, SELinux). C'est là où je me dis que finalement, make-kpkg, c'est vachement bien : en tant qu'administrateur conscencieux, on aurait compilé le noyau du serveur sur une autre machine et on aurait utilisé un scp tout crassou vers le serveur après ? Holly sh*t. Y a des tas de façons de se louper quelque part...

Mais en bon seigneur, j'avoue avoir bien aimé le /etc/modules.autoload.d/ qui permet de spécifier les modules à charger au boot, simple, clair, efficace.

Light is right, uh?

Ouch, quel sens du mauvais goût ! Le seul éditeur texte qui est installé par défaut est nano, ok, il y a toujours la vieille querelle vi-emacs, en tant qu'utilisateur des deux, je hais nano, passons.

Travail de base, protégeons au minimum la machine en écrivant quelques règles de firewall :

# iptables
bash: iptables: command not found

Youpi! Quand je vous disais que c'était une installation light! Y a plus qu'à downloader les sources et dépendances, heureusement que c'est pas un Windows XP SP1 branché en live sur un modem ADSL, sa durée de vie serait pas longue...

Ça permet alors de se faire une première idée du système de package, emerge. C'est un autre style : y a des smileys partout, c'est super verbeux, y a des jolis choix de couleurs (non c'est une blague).

Vu que j'y comprends rien, je me mets à lire la page de manuel et qu'est-ce qu'on peut lire : Les dépendances inverses ne sont pas gérées, si je comprends bien, je peux très bien supprimer la zlib sans qu'emerge ne s'en émeuve ? F34r.

Et on continue sur les rebondissements, on se retrouve à réaliser des workarounds tels que ceux-ci (indiqués dans le handbook) :

# emerge checkpolicy policycoreutils # FEATURES=-selinux emerge selinux-base-policy

Enfin ça, c'est ce qu'il y a marqué car je n'ai jamais réussi à déployer le bousin, j'obtiens toujours un truc comme ça :

localhost ~ # FEATURES=-selinux emerge selinux-base-policy
Calculating dependencies |
!!! All ebuilds that could satisfy ">=sys-apps/checkpolicy-1.30.12" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/checkpolicy-1.34.4 (masked by: package.mask, ~amd64 keyword)
/usr/portage/profiles/default/linux/package.mask:
# Shouldn't be merging these SELinux packages on this profile
# but this keeps repoman happy since they require >=glibc-2.4
# 20061009 pebenito

- sys-apps/checkpolicy-1.34.3 (masked by: package.mask, ~amd64 keyword)
- sys-apps/checkpolicy-1.34.0 (masked by: package.mask)

For more information, see MASKED PACKAGES section in the emerge man page or 
refer to the Gentoo Handbook.
(dependency required by "sec-policy/selinux-base-policy-20070928" [ebuild])

J'ai beau eu modifier plusieurs fichiers, je tombe toujours sur une erreur fatale. Alors que j'ai suivi toute la procédure.

Je vous laisse le meilleur pour la fin, la gestion des mises à jour des fichiers de configuration expliquée par la page de manuel :

When Portage  installs a  file into  a protected directory  tree like  /etc, any
existing  files will not  be overwritten.  If a  file of  the same  name already
exists, Portage will  change the name of the to-be-installed  file from 'foo' to
'._cfg0000_foo'.   If  '._cfg0000_foo'   already  exists,   this   name  becomes
'._cfg0001_foo', etc. In this way,  existing files are not overwritten, allowing
the  administrator  to  manually  merge  the  new config  files  and  avoid  any
unexpected changes. 

Soyons honnête, heureusement qu'il existe des outils qui aident comme l'indique le man :

Tools such  as dispatch-conf, cfg-update,  and etc-update are also  available to
aid in  the merging  of these  files. They provide  interactive merging  and can
auto-merge trivial changes.  

Finalement, ce test qui devait être "juste" s'est transformé en un joli bash en règle alors qu'il y a plein de trucs intéressants dans cette distribution. Désolé.

Posted Sun 01 Jun 2008 11:11:53 PM CEST Tags:

Période de recrutement oblige, c'est le moment de remettre au gout du jour son CV, sauf que dégainer OpenOffice juste pour ça m'embarassait quelque peu...

Ca faisait longtemps que je cherchais une classe LaTeX belle, pratique et structurée et je l'ai enfin trouvé : moderncv, je vous laisse voir un exemple de CV.

La killer-feature, c'est le support de la bibliographie BibTeX, bien pratique pour lister les publications.

L'essayer, c'est l'adopter.

Posted Mon 26 May 2008 11:01:57 AM CEST Tags:
$ cat > fakegetpid.c
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void) {
        return 1;
}
^D
$ gcc -shared fakegetpid.c -o fakegetpid.so
$ LD_PRELOAD=$PWD/fakegetpid.so ssh-keygen -t rsa -N '' -f 
% ssh-keygen -f foobar -t rsa -N ''
Generating public/private rsa key pair.
Your identification has been saved in foobar.
Your public key has been saved in foobar.pub.
The key fingerprint is:
a9:65:93:0d:02:1d:e4:43:03:da:06:ab:24:73:13:7e foo@bar
% ssh-keygen -f foobar -t rsa -N ''
Generating public/private rsa key pair.
foobar already exists.
Overwrite (y/n)? y
Your identification has been saved in foobar.
Your public key has been saved in foobar.pub.
The key fingerprint is:
a9:65:93:0d:02:1d:e4:43:03:da:06:ab:24:73:13:7e foo@bar

Les deux fingerprints sont identiques !

Donc si je résume, la seule graine d'aléa est en fait le PID du processus. Ce qui signifie qu'il n'existe que 2^32 bits possibilités de clef sur x86, bruteforcons... pendant 400 ans.

$ cat > fakegetpid.c
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

pid_t getpid(void) {
        pid_t fakepid;
        fakepid = atoi(getenv("FAKEPID"));

        return fakepid;
}

^D
$ gcc -shared fakegetpid.c -o fakegetpid.so
% export FAKEPID
% for FAKEPID in $(seq 0 $((2**32))); do
      LD_PRELOAD=$PWD/getpid.so ssh-keygen -t rsa -N '' -f foo.$((FAKEPID))  |grep foo@bar
  done
70:e2:6b:54:e8:46:b7:64:b7:9a:d6:a8:5d:3e:41:2f foo@bar
65:23:e0:30:76:cb:9c:f6:a9:72:64:1c:f0:4d:90:b9 foo@bar
fd:21:36:80:2b:df:ac:e8:09:7a:2d:62:cc:38:88:ec foo@bar
17:e5:ba:34:97:1d:2f:63:be:0a:7e:25:eb:3c:b0:fb foo@bar
bd:6f:c2:ca:3f:ad:49:d1:4b:20:ac:6f:27:35:5a:0d foo@bar
a6:9b:60:e0:ce:13:9b:68:6a:36:60:3e:60:82:62:2c foo@bar
ca:d7:2f:8f:c0:42:12:df:d2:5f:78:41:86:6e:63:0e foo@bar
29:ea:08:3a:61:91:55:e9:cb:93:46:b2:55:cc:87:e6 foo@bar
b5:6d:f1:3f:47:ce:ab:11:d1:1a:6f:0f:e6:a5:04:8d foo@bar
13:c2:e7:0f:f1:cf:a8:22:8f:7b:a4:b0:f3:83:64:25 foo@bar

Ensuite, vous loadez toutes ces clefs dans votre ssh-agent et boum!

Update@23:04: H D Moore s'en mêle et a eu la même idée, sauf que lui n'a pas oublié que les PID étaient sur 15 bits et pas sur 32 bits, soient 32 768 possibilités ce que j'avais réussi à calculer en quatre heures (j'ai pas 31 Xeon moi !).

Pour ceux que ça intéresse, je suis sur le point d'avoir les clefs pour 0 < PID < 300 000. Ok, ca n'a aucun intérêt.

Posted Wed 14 May 2008 01:28:34 PM CEST Tags:

OMG ! Le DSA-2008-0166 qui vient de sortir est peut-être l'un des pire jamais existé. Sa conclusion est assez claire :

It is strongly recommended that all cryptographic key material which has
been generated by OpenSSL versions starting with 0.9.8c-1 on Debian
systems is recreated from scratch.

Si on fait un interdiff avec la version précédente, on obtient ça :

diff -u openssl-0.9.8c/crypto/rand/md_rand.c openssl-0.9.8c/crypto/rand/md_rand.c
--- openssl-0.9.8c/crypto/rand/md_rand.c
+++ openssl-0.9.8c/crypto/rand/md_rand.c
@@ -271,10 +271,7 @@
                else
                        MD_Update(&m,&(state[st_idx]),j);

-/*             
- * Don't add uninitialised data.
                MD_Update(&m,buf,j);
-*/
                MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
                MD_Final(&m,local_md);
                md_c[1]++;
diff -u openssl-0.9.8c/debian/changelog openssl-0.9.8c/debian/changelog
--- openssl-0.9.8c/debian/changelog
+++ openssl-0.9.8c/debian/changelog
@@ -1,3 +1,19 @@
+openssl (0.9.8c-4etch3) stable-security; urgency=high
+
+  * Re-introducing seeding of the random number generator.  Patch from the
+    maintainer.
+
+ -- Florian Weimer <fw@deneb.enyo.de>  Thu, 08 May 2008 01:58:40 +0200
+

WTF ? Pourquoi le maintaineur Debian modifie le code en lui-même ? Autant je comprends qu'il le fasse quand ça l'arrange pour le packaging, mais ce n'est pas son rôle de "corriger" le code tout seul comme un grand. Tout pour ça pour corriger un bug esthétique !

J'entends d'ici Theo De Raadt qui rigole.

Ubuntun, rigolez pas, vous êtes autant vulnérable.

Posted Tue 13 May 2008 03:16:57 PM CEST Tags:

Ce récit d'un sauvetage de système me fait un penser à la bourde qu'il m'était arrivée il y a quelques mois en cassant libssl à distance.

Dans les bonnes pratiques de l'admin, installez toujours busybox-static sur chaque serveur, vous ne le regretterez jamais...

Certains osent aussi dire qu'il faut toujours avoir une backdoor SSLifiée statique. Ca me rappelle un serveur qui avait compilé ce genre de truc sur une très ancienne version d'OpenSSL et qui n'avait jamais mis à jour sa backdoor...

Posted Fri 18 Apr 2008 07:22:45 PM CEST Tags:

De plus en plus de constructeurs s'intéressent à l'ouverture de leurs produits sur des plateformes libres, chaque semaine, nous entendons des nouvelles du type "Des spécifications ont ou vont être libérées" (Via, AMD, Intel et Xorg, etc) "Un développeur vient de rejoindre le constructeur X", etc.

Aujourd'hui, c'est un développeur qui est débauché par Atheros pour intégrer le support des célèbres cartes Wifi dans le noyau upstream. Il est vrai que la moitié des annonces d'ouverture des constructeurs ne débouchent pas forcément sur quelque chose de concret mais les derniers mois ont de quoi nous réjouir : on a de vrai drivers Xorg pour les cartes Intel et ATI, le support des cartes Wifi s'améliorent de jour en jour (les Intel avec leur nouvelles piles iwlwifi, le projet ath5k, etc.), la gestion de l'énergie fait des bonds en avant avec la publication des spécifications ACPI de certaines cartes mères, etc.

Question trollesque : Y a t'il un effet Vista ? Dans la mesure où les constructeurs sont désormais obligés de payer^Wcertifier leurs drivers et que personne ne veut de Vista, est-ce que les constructeurs n'espéraient pas faire développer leurs pilotes par la communauté pour baisser les coûts (non je ne crois plus à la philantropie) ?

Y a t'il un rapport avec une déclaration qu'avait fait Dell ou HP annonçant que leur matériel sera totalement supporté sous Linux ?

Posted Thu 17 Apr 2008 05:42:18 PM CEST

J'ai enfin recompilé tous les paquets Debian avec les fonctionnalités de "protection de code" activées (stack guard, prévention de formats strings, mise en read-only de sections ELF et génération d'un binaire PIE). Bref tout ce qui vous rend très confiant si vous tournez sous un noyau PaXé.

Puisqu'un bon parano n'utilisera pas un repository tier et recompilera ses propres packages, j'ai documenté la procédure de recompilation ici. Pour les autres qui me truste :

server$ gpg --export nico@chdir.org| sudo apt-key add -
server# echo "deb http://debian.chdir.org/debian/ stable/" >> /etc/apt/sources.list
server# apt-get update
server# apt-get upgrade

Vu que je l'utilise en production, je devrais le tenir très à jour. Si vous avez des remarques sur le document ou des idées de flags à rajouter...

Posted Fri 18 Jan 2008 12:12:28 PM CET Tags:

Pourquoi ne pas utiliser Google Mail ? Par pure paranoïa, mais c'est trop bête de se passer de plusieurs gigaoctets d'espace libre non ? Autant s'en servir comme mécanisme de sauvegarde, avec l'aide de procmail, GnuPG et MIME-construct on peut faire tout ce qu'on veut :)

Pour forwarder les mails que vous recevez vers un autre compte, vous pouvez tout bêtement utiliser procmail avec une règle "pipant" les messages dans GnuPG comme cela :

:0c
| gpg -r mamanours@gmail.com --encrypt | mail -s "Bla" mamanours@gmail.com

Le problème est que vous recevez les mails chiffrés, certes, mais complétement détruits, votre MUA ne l'interprète plus comme un mail mais comme une suite d'octets au déchiffrement, donc si le message est codé en Quoted Printable, il ressemble plus ou moins à de la boue au final, et je ne vous parle même pas de la tête que font vos pièces jointes qui ne sont plus manipulables sans reconstruire les parties MIME avec un logiciel tier.

Non, la solution, c'est d'implémenter la même logique qu'un vrai MUA : forwarder les mails avec du MIME, et chiffrer le résultat avec du MIME encore :

#! /bin/bash

TMPCLAIR="$(mktemp)"
FINALADDR="nico@chdir.org"
TXTINTRO="$HOME/.etc/introduction_forward-me-gpgified"

### ALWAYS wipe the $TMP
trap "wipe -qsf -- $TMPCLAIR" TERM QUIT EXIT

mime-construct --part-header 'Content-Disposition: inline' --type 'message/rfc822' --file - --subpart --output > "$TMPCLAIR"

gpg -r "$FINALADDR" --encrypt < "$TMPCLAIR" | mime-construct --multipart     \
                    'multipart/encrypted; protocol="application/pgp-encrypted"' \
      --type 'application/pgp-encrypted' --file "$TXTINTRO" \
      --type 'application/octet-stream' --file -            \
      --to "$FINALADDR" --subject "$RANDOM"

Avec un fichier $HOME/.etc/introduction_forward-me-gpgified contenant juste :

Version: 1

Et votre règle Procmail ressemblant à :

:0c
| forward-me-gpged-mail

Désormais, lorsque votre MUA ouvre un mail forwardé, il interprète correctement les en-têtes du message (codage, chiffrement s'il y en a encore, etc.) et normalement, les pièces jointes sont directement accessibles (pas eu le temps de tester).

Note: Donc pour ceux qui ont le mauvais goût de forwarder leurs mails corporate vers Gmail, utilisez au moins quelque chose dans ce goût là!

Posted Mon 14 Jan 2008 09:46:43 PM CET Tags:

Mais pourquoi je ne l'ai pas fait avant ? C'est la question que je me pose depuis que j'ai redémarré mon Sandisk Sansa e280 après avoir mis un firmware Rockbox à la place du truc officiel qui était très... "girly" pour rester poli.

Désormais l'interface est réactive, tout est configurable (par exemple, pourquoi est-ce que l'ancien tenait tant à garder la roulette allumée ?), y a plein de jeux et d'applications (par exemple un métronome ! Inutile donc indispensable non ?) et je n'ai plus de bugs. Le plus difficile en fait, c'est d'oublier ses réflexes, oublier le fait que l'interface va réagir en 3 ms au lieu de 30 et donc ne pas anticiper ce qu'on compte faire !

En plus, l'installation est triviale en suivant le manuel Sansa e200 ! Si votre lecteur est supporté, sautez le pas, ca vaut le coup ! Ok, je dis ça mais j'ai pas encore vérifié la durée de la batterie de 15h30 annoncée (d'après les spécifications commerciales de SanDisk, ca devrait tenir ~20h), mais il semblent que les développeurs tentent de l'optimiser encore plus.

Si vous voulez plus de détails, allez voir son status sur le Wiki et si vous cherchez un lecteur MP3, faîtes un tour sur le guide d'achat listant comment les modèles sont supportés.

Posted Sat 29 Dec 2007 11:31:36 PM CET Tags:

Petit moment de nostalgie lorsque j'ai voulu tester Weave, cette extension, prometteuse, nécessite Firefox 3 (beta), ça m'a alors rappelé l'époque où on attendait fébrilement chaque Milestone du projet Mozilla. Ces gros binaires qui apportaient à chaque fois des tas de nouvelles fonctionnalités (ou des bugs) étaient toujours attendus avec impatience. Ca c'était sympa, surtout avec une connexion 56K!

C'était un peu Noël à chaque release. C'était beau.

Et puis toute cette tristesse pour rien puisqu'il n'y a pas de binaire de Firefox3 pour AMD64 de prêt et j'ai pas envie d'installer tous les paquets ia32-* juste pour 4 minutes de test. Vous me raconterez ?

Posted Tue 25 Dec 2007 09:13:26 AM CET Tags: