Blog perso d'Ozwald

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

dimanche, mai 13 2012

Culture automatisée

Ce qu'il y a de bien avec l'état d'esprit du "hack" c'est qu'on peut l'employer dans de nombreux domaines. Et ce qu'il y a de très bien c'est qu'on peut faire des combinaisons de plusieurs domaines ! Par exemple on peut faire un combo programmation/électronique/biologie et obtenir des petites expériences amusantes comme celle que je vais retranscrire ici.

Creative Common by Ozwald from ozwald.fr
L'idée de départ c'est qu'habitant en ville je ne peux planter aucun végétal "naturellement". A la rigueur je dispose de deux rebords de fenêtre pour poser des petits pots ou des jardinières mais c'est quand même super limité. Du coup comment faire pour améliorer autant que possible la pouse de jolies plantes carnivores ? La solution simple c'est d'abandonner la méthode "naturelle" (i.e. : fabriquer une tourbière de quelques mètres carrés avec écoulement d'eau permanent pour recréer des conditions marécageuses) et passer à de l'artificiel.

"Artificiel" ça peut recouper beaucoup de choses et du coup je me suis renseigné. J'ai ainsi découvert et approfondi les méthodes de cultures allant de la simple serre, à la culture aéroponique/ultraponique, en passant par l'hydroponique et l'aquaponique. Toutes ces méthodes semblent intéressantes mais il y a un point que j'ai trouvé systématiquement mal traité : l'éclairage. En effet on comprend vite que les méthodes en ultraponie, en hydroponie, ou en aquaponie, adressent principalement des problématiques d'arrosage; mais le problème de l'éclairage, lui, est souvent traité d'une façon qui m'a laissé sur ma faim. Bien souvent en effet les seuls remarques que l'on peut trouver sur l'éclairage se résument à quelque chose du genre : "une lampe au sodium super puissante, puisque c'est ce qui s'approche le plus de la vrai lumière du soleil et que ça chauffera super bien ta culture en placard où tu pourra planter plein d'herbe de provence[1]"

Ce genre de réponse ne me satisfait pas du tout puisqu'elle vise une problématique qui n'est pas la mienne. En effet ce type de réponse vise le problème de recréer des conditions naturelles dans un espace à l'abri des regards (à savoir un placard -_-); ma problématique à moi c'est de faire pousser des plantes carnivores (et des tomates cerises[2]). Ayant quelques bases en optique je me disais que les plantes n'avaient pas besoin de tout le spectre lumineux du soleil pour bien pousser, et du coup j'ai été faire un petit tour sur wikipédia pour obtenir le spectre d'absorbtion de la chlorophyle :

Spectre d'absorbtion de la chlorophyle - From Wikimedia

En regardant ça je me suis dit qu'il était probablement superflus de vouloir recréer un spectre lumineux continu, et je me suis dit qu'il était certainement énergétiquement plus intéressant de faire un éclairage par LED à des fréquences de couleur bien choisies :) ! J'ai farfouillé sur le net pour savoir si quelqu'un avait déjà fait ce genre d'expérience mais ce ne fut pas très fructueux. J'ai bien trouvé quelques personnes qui disaient qu'il fallait faire pousser sous du rouge, d'autre sous du rouge et du bleue, mais aucune référence sérieuse pour étayer le propos. Devant ce manque d'information pour me guider dans le choix (dois-je prendre des LED bleues ? Rouge ? Un mélange des deux ?) j'ai pris la décision le plus "simple" : faire un test[3].

Le protocole de test est simple : je vais réaliser en même temps 5 cultures de graines issus d'un même lot et semés dans un même terreau. L'une de ces cultures sera laissée à la lumière naturelle, l'une sera plongée dans le noir total, et les trois autres seront respectivement éclairés exclusivement par une diode rouge, bleue, et UV[4].

Pour cette expérience je vais donc utiliser 4 pots en plastique noir. L'un sera directement retourné sur la culture qui ne doit pas avoir de lumière, et les trois autres seront préparés pour éclairer au mieux d'une unique couleur les cultures qu'ils recouvreront. La préparation est simple : j'ai recouvert les bords intérieurs de papier aluminium afin que le maximum de lumière atteigne les plants, j'ai planté une diode sur le fond du pot pour que ses connections soient accessible de "l'extérieur", et j'ai calibré une résistance série pour que chaque diode consomme autant de puissance électrique malgré la différence de chute de tension à leur bornes : Pot opaque vu du dessus. Intérieur d'un pot pour éclairage mono-couleur.

Pour garder les diodes allumées 12h par jour, et éteintes 12h par jour j'avais deux solutions : les allumer moi-même à heure fixe tout les matins et les éteindre tout les soirs; ou opter pour une méthode de feignasse et utiliser un microcontrolleur pour qu'il fasse ça à ma place. Bien évidemment j'ai opté pour la solution micro-controlleur (ce qui m'a permit de m'entrainer à la gestion des timers et des interruptions, ainsi que de constater que si je veux faire une "vrai" horloge un jour il faudra que j'utilise un chip RTC pour compenser la dérive de l'oscillateur interne du micro-controlleur[5]). Si vous êtes curieux vous pouvez aller jeter un oeil au code que j'ai mis en pièce jointe de ce billet, m'enfin il n'est pas très intéressant puisque 70% du code porte sur l'affichage et le réglage de l'heure (affichage réalisé par un afficheur 7 segment, et réglé par un unique bouton permettant d'avancer le temps).

Il ne reste donc plus qu'à mettre le terreau dans un grand bac en plastique, à y semer des lentilles vertes (parce que, de mémoire de classe de CP, ça pousse super facilement et rapidement ces trucs là) et à lancer l'expérience. Voilà donc à quoi ressemble le montage expérimental : Expérience en place.

Après une dizaine de jours les résultats sont surprenants :) !

Pendant la germination nous avons deux cultures qui ont nettement pris la tête : la culture obscure (!!), et la culture rouge. Ces deux cultures étant suivi de prêt par les cultures bleue et UV, elles-même tallonnées par la culture au soleil.

Une fois la germination effectuée et les premières feuilles sorties on assiste à un équilibrage des 5 cultures en termes de longueur de pousse (y compris de l'obscure donc !). La seule culture qui se détache nettement des 4 autres reste néanmoins l'obscure puisqu'au lieu d'avoir de jolis plants verts elle a des plants blanchatre qui ont un peu de mal à tenir vertical.

Si vous voulez plus de détails sur le déroulement précis de la pousse de chaque échantillon vous pouvez télécharger le fichier ZIP joint à cet article, il contient quasiment une photo pour chaque jour d'expérience.

A partir de cette expérience super simpliste les questions ouvertes sont pourtant nombreuses :

  • Pourquoi le pot obscur germe-t-il aussi vite ? Est-ce grace à l'effet "serre" du pot opaque qui augmente l'humidité ?
  • J'ai visé du bleue, du rouge, et de l'UV, qui sont tout les trois normalement assez bien exploités par la chlorophyle; cependant le relatif "match nul" au bout de l'expérience me fait penser que j'aurai pu tenter une culture sous lumière verte pour vérifier si, comme la théorie l'indique, j'aurai obtenu les même résultats que dans l'obscurité (ou pas ?!)
  • Mes cultures sous lumière artificielle ont poussé quasiment à la même vitesse que celle exposée à la lumière du jour; que se passe-t-il si je double la puissance lumineuse artificielle ? Et si je la divise par deux ?
  • J'ai imposé des cycles jours/nuit de 12h/12h à mes cultures sous lumière artificielle. Que se passe-t-il si j'accélère ou si je ralenti ce cycle ?
  • Enfin une question évidente : que se passe-t-il sur une durée de vie plus longue de la plante (là j'ai abandonné l'expérience avant la maturation complète des lentilles faute de parvenir à bricoler des serres opaques assez grandes) ? De même que se passe-t-il sur d'autres plantes (par exemple sur les tomates cerises et les drosera/nepenthes que je vise) ?

Enfin, en guise de conclusion, je constaterait la chose suivante : Chaque LED utilisait environ 54mW de puissance électrique (51.5mW pour le rouge, 54.4mW pour le bleue, et 57.8mW pour l'UV), les pots faisant 7x7cm à la base (mesure intérieure) on est donc sur une consommation de 11W/m² pour l'éclairage, c'est à dire une énergie consommée de 48kWh pour un an d'éclairage. Si on recoupe avec les infos de Wikipédia sur les panneaux solaires (à savoir qu'un m² de panneau solaire a une puissance d'environ 150Watt Crete et qu'en Europe 1Watt Crete permet de produire environ 1kWh/an[6]) on obtient qu'un panneau solaire de 1m² pourrait, sur une année, fournir assez de puissance (150kWh) pour éclairer environ 3m² de culture :) Intéressant, non ?

Notes

[1] J'ai mis "herbe de provence" mais en réalité internet est submergé de conseils pour faire pousser un tout autre type de plante (dont, perso, la méthode de pousse m'intéresse encore moins que celle des herbes de provence).

[2] j'ai été obligé par ma copine

[3] On peut également dire "expérience" pour faire plus scientifique.

[4] Référez-vous à la courbe d'absorbtion de la chlorophyle, vos verrez que le rouge vise un pic important sur la chlorophyle A, la bleue vise un pic important de chlorophyle B, et l'UV tape un plateau correcte pour la A et un peu la B

[5] Sur la durée de l'expérience, à savoir un peu plus de 10 jours, l'horloge de l'Atmega8 avait pris un peu plus d'une heure de décalage.

[6] Avec une forte variance, en gros entre 0.5 et 1.4

samedi, mai 5 2012

De l'incompétence à Pole Emploi

Ca fait plus d'un mois que je suis sans emploi et que je tente de m'inscrire à Pole Emploi. Le problème c'est que je me heurte à un mur inébranlable d'incompétence crasse...De lassitude je rend publique le dernier courrier que je leur ai envoyé, la réponse sera également rendue publique (si tant est que j'en ai une un jour). D'une part ça soulage, et d'autre part peut-être qu'un miracle pourra se produire et que quelqu'un de compétent à Pole Emploi lira ce message et débloquera la situation :

Bonjour,

Lors de mon rendez-vous d'inscription on m'a demandé des documents qui n'avaient pas été précisés dans les convocations, en particulier une fiche "relative au portage salarial", mais le problème c'est que je n'ai JAMAIS été en portage salarial. J'ai eu beau m'expliquer de toute les façons possible à la dame qui me recevait elle n'a rien voulue entendre et j'ai donc du repartir chez moi avec mon dossier de demande d'allocations sous le bras. J'ai réalisé les photocopie du contrat de travail qui m'avait également été demandé et j'ai retourné tout le dossier en ajoutant une phrase qui expliquait que, n'ayant jamais été en portage salarial (ce que vous pouvez vérifier en lisant le contrat de travail joint) il m'était impossible de faire remplir l'attestation "A remplir exclusivement par l'employeur en cas de rupture du contrat de portage salarial" (je cite le titre de la fameuse fiche que vous me réclamez...).

Je viens de recevoir par la Poste l'ensemble du dossier de demande d'allocation que vos services m'ont retournés, sous prétexte que l'attestation "à remplir exclusivement par l'employeur en cas de rupture du contrat de portage salarial" (je cite toujours le titre du fameux formulaire) n'avait pas été remplie par mon ancien employeur.

JE DEMANDE DONC A AVOIR RENDEZ-VOUS AVEC QUELQU'UN DE COMPETENT OU DE RESPONSABLE. De compétent parce qu'il pourra comprendre qu'il est complètement con de s'acharner à me demander un formulaire que je ne PEUX PAS faire remplir (je veux bien lui faire lecture à haute voix de mon ancien contrat de travail puis de la définition légale du portage salarial autant de fois qu'il sera nécessaire à ce qu'il comprenne); ou de responsable pour qu'il puisse me signer une attestation de refus d'indemnisation sous l'unique prétexte que je ne fourni pas cette fiche, ainsi je pourrai aller porter plainte et, peut-être, vous obliger à appliquer la Loi.

Je reste dans l'attente d'un retour RAPIDE de votre part.

---

Edit du Vendredi 11 Mai 2012,11h30 : en réponse à mon courrier j'ai reçu un accusé de réception automatique stipulant "Nous vous répondrons sous 48 heures (2 jours ouvrés), soit le Jeudi 10 Mai 2012 au plus tard ou 7 jours calendaires s'il s'agit d'une réclamation.". Sauf que nous sommes déjà à 6 jours calendaires et que je n'ai toujours eu aucune réponse...le suspens est presque palpable : vont-ils, encore une fois, mal faire leur boulot en ne répondant pas dans les temps :-D ? Ca semble plausible sachant que la dernière fois que j'ai essayé d'avoir un conseiller au téléphone j'ai appris qu'ils ne répondaient pas le vendredi après-midi (horaires officiels...).

Edit du Dimanche 13 Mai 2012, 15h12 : Bon bah toujours aucune réponse de la part de Paul en Bois. Ca aurait été surprenant aussi qu'ils respectent une échéance quelconque (qu'ils se sont pourtant eux même fixés)... Allez, disons que je vais quand même attendre jusqu'à lundi ou mardi soir avant de les relancer.

Edit du vendredi 18 Mai 2012, 00h32 : Toujours aucune réponse.

vendredi, avril 13 2012

L'arduino c'est contagieux

Le 9 mars 2011 dernier (merci Twitter pour la date exacte) j'ai acheté un arduino. Depuis j'ai pas mal joué avec et j'en arrive aujourd'hui à vouloir utiliser au jour le jour certains de mes bricolages. Le problème c'est que si je dois acheter un arduino pour chaque bricolage que je veux garder et utiliser quotidiennement ça risque de taper sérieusement dans mon budget. Heureusement il y a pleins de solutions à ce problème.
Arduino UNO - Creative Common by "Beraldo Leal" on Flickr

La première solution c'est de ne tout simplement jamais utiliser d'arduino et d'oublier carrément les micro-controlleurs Atmega. L'un de mes amis, qui fait de l'électronique depuis des années, a ainsi toujours utilisé des PIC. L'avantage des PIC, par rapport aux Arduino, c'est leur prix ridicule (comptez quelques dizaines de centimes d'euros pour les plus petits alors qu'un arduino coutera minimum une quinzaine d'euros). Mais l'inconvénient majeur des PIC c'est qu'il vous faudra un programmeur matériel dédié pour uploader vos programmes dessus, et que ce programmeur dédié coute cher (comptez une trentaine ou une cinquantaine d'euros).

La seconde solution c'est d'utiliser des Atmega nu. Les Atmega c'est la famille des micro-controlleurs qui sont au coeur des Arduino. En fait un Arduino c'est un atmega avec un peu d'électronique autour pour uploader les instructions sans programmeur externe, et pas mal de logiciel pour rendre ultra simple le codage, la compilation, et l'upload sur l'Atmega. Donc quand on utilise un Arduino en fait on utilise un Atmega :) L'avantage des Atmega (et leur petits frêres les Attiny) c'est le prix du programmeur externe, en effet vous pouvez utiliser votre Arduino comme programmeur pour Atmega (via le sketch ArduinoISP, donc aucun investissement supplémentaire si vous arrivez à le faire marcher) ou bien en acheter un tout fait et dédié à cet usage (ce qui est beaucoup plus simple à mon gout) pour la modique somme de 3€ sur eBay. L'inconvénient c'est que les Atmega (et les Attiny) sont plus chers que les PIC (et qu'il existe également moins de modèles différents); mais ne vous affolez pas ça reste quand même largement moins cher qu'un arduino complet et vous n'aurez donc aucun scrupule à "investir" 1 ou 2 euros dans un Atmega destiné à rester à perpétuité dans votre bricolage numéro 3454464béta :D

Dans l'idée de fabriquer des bricolages "définitifs" je me suis donc orienté vers la seconde option : programmeur matériel dédié à acheter une fois et atmega (ou attiny) indépendant à acheter pour chaque montage "définitif". Le prix de cette migration a donc été pour mon cas de :

  • 3€ pour un programmeur dédié USBASP (acheté sur eBay)
  • 1,30€ pièce pour des Atmega8 (également achetés sur eBay)
  • ou 3,5€ pièce pour des ATtiny85 (encore et toujours achetés sur eBay) à la place des Atmega8 si je veux un tout petit montage.

Par contre en basculant sur du micro-controlleur indépendant on perd un avantage énorme de l'arduino : l'IDE et ses bibliothèques simplifiant monstrueusement la tache du codeur. A titre d'exemple voilà le code Arduino qui fait clignoter une LED (l'équivaleur électronique de "Hello World") :

void setup() {                
  // initialize the digital pin 13 as an output.
  pinMode(13, OUTPUT);     
}

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

Et, pour comparer, le même code pour ATtiny85 sans utiliser les librairies Arduino :

#include<avr/io.h>
#include<util/delay.h>
void sleep(int millisec) {
	while(millisec)
	{
		_delay_ms(1);/* 1 ms delay */
		millisec--;
	}
}

main() {
	DDRB |= 1<<PB3; /*PB3 is now an output*/
	while(1) {
		PORTB &= ~(1<<PB3); /* PB3 low */
		sleep(1500); /* 1.5s delay */
		
		PORTB |= (1<<PB3); /* PB3 high */
		sleep(3000); /* 3s delay */
	}
}

Tout de suite c'est quand même moins user-friendly. Et encore, là on fait juste clignoter une LED. Soyez assurés que quand on joue avec les interruptions c'est encore plus moche. M'enfin bon, ça reste quand même compréhensible, donc poursuivons. Quand on utilise l'IDE Arduino on branche son arduino en USB, on écrit son code, puis on clique sur le bouton "compile and upload" et c'est fini, l'Arduino se comporte comme on l'a programmé. Quand on utilise un micro-controlleur indépendant c'est "un poil" plus compliqué.

D'abord il faut brancher l'USBASP (notre programmeur matériel dédié) : Coté USB c'est trivial, coté Micro-controlleur il faut ressortir la doc des branchements. Une fois la doc sous les yeux le branchement est simple puisqu'il suffit de se débrouiller pour que les fils MOSI/MISO/SCK/RST du programmeur correspondent aux pates MOSI/MISO/SCK/RST du micro-controlleur. Ca n'a rien de sorcier mais on est obligé de ressortir le schéma à chaque fois (parce que, franchement, l'apprendre par coeur...). Branchement coté programmeur :
USBASP programmer
Et branchement coté micro-controlleur (ci-dessous pour les attiny) :
pinout attiny 25/45/85

Une fois correctement branché il faut coder (pour ça on peut être certain que VIM ne nous laissera pas tomber :)). Ensuite on compile avec avr-gcc en faisant attention de bien choisir la plateforme cible :
avr-gcc -mmcu=attiny85 ledblink.c -Os -o ledblink_tiny85.o
Une fois compilé on extrait le code intéressant au format ihex :
avr-objcopy -j .text -j .data -O ihex ledblink_tiny85.o ledblink_tiny85.hex
Il ne reste plus qu'à uploader le code sur notre micro-controlleur à 3€ :
avrdude -p /dev/ttyS3 -c usbasp -p t85 -v -U flash:w:ledblink_tiny85.hex

Et "voilà" la LED qu'on a branché sur la pate PB3 de l'attiny (via une résistance de plus de 300 ohms pour ne pas la cramer) clignote gentiment. Maintenant plus rien ne s'oppose à la réalisation de montages permanents coutant moins de 10€ :) !

EDIT 14/04/2012 : chez moi par défaut avr-gcc ne trouve par le fichier "crtm8.o" et du coup il ne parvient pas à linker correctement quand je lui spécifie une cible "atmega8" à la place de "attiny85". Pour régler le problème il suffit de lui rappeler où trouver "crtm8.o" avec son option -B:
avr-gcc -mmcu=atmega8 ledblink.c -Os -o ledblink_atmega8.o -B /usr/avr/lib/avr4/
La suite reste similaire à l'exemple donné pour l'attiny85:
avr-objcopy -j .text -j .data -O ihex ledblink_atmega8.o ledblink_atmega8.hex
Et pour l'upload on change juste l'option "-p" en mettant "m8" (= atmega8) à la place de "t85" (=attiny85) :
avrdude -p /dev/ttyS1 -c usbasp -p m8 -v -U flash:w:ledblink_atmega8.hex

EDIT2 14/04/2012 : Rajout en fichier joint d'un exemple de code réalisant deux Fast PWM sur atmega8 (typiquement pour diriger un robot)

dimanche, janvier 22 2012

Du capitalisme

L’Académie française propose une définition simple du capitalisme : le capitalisme est un « régime économique dans lequel les moyens de production sont propriété privée ». Dans la pratique, il est patent que le terme est loin d'être doté d'une acception consensuelle. D'où l'existence de nombreuses significations différentes, dont une se basant sur la mécanique d'accumulation du capital comme facteur de production.[1]

Billets de monopoly - Creative Common by graciepoo on Flickr
Dans l'acceptation du "capitalisme" telle qu'ébauchée en introdution de ce billet "l'accumulation du capital comme facteur de production" est l'un des fondamentaux, et en ce sens je suis un capitaliste de l'informatique. Cette réflexion m'est venu il y a déjà pas mal de temps en lisant une présentation (dont j'ai malheureusement oublié les références :( ) sur la façon de faire efficacement du fuzzing. Dans cette présentation il y avait un slide expliquant qu'écrire un fuzzer évolué n'était pas une bonne façon de faire du fuzzing, mais que la bonne façon de faire du fuzzing c'était d'écrire un fuzzer évolué pendant qu'un fuzzer écrit en 30s tournait. Ainsi, lorsque je me suis finalement mis à jouer un peu sérieusement avec de l'audit de code statique (environ un an après mes premiers tests dans le domaine) j'ai appliqué cette stratégie. Ce sont les premiers résultats de ces recherches que je vais relater dans ce billet.

Les outils

Adhérant totalement à la philosophie du "je travaille sur un bon outil pendant qu'un outil pourri que j'ai écrit en 10mn est déjà en train de tourner" j'ai donc commancé à analyser du code source PHP avec une dizaine de lignes de python qui se contentaient de :

  • Télécharger un projet PHP sur sourceforge/drupal/wordpress
  • Décompresser l'archive du projet
  • Faire l'équivalent d'un "grep" sur l'ensemble des fichiers PHP contenus dans l'archive
  • Effacer le repertoire temporaire dans lequel j'avais téléchargé et décompressé l'archive (ça a l'air con mais vu la simplicité du projet une fonctionnalité, même aussi triviale, compte).

Voilà quelques exemples des expressions régulières que ce mini script cherche:

  • (XSS) .*echo .*\$_GET.*
  • (XSS) .*echo .*\$_POST.*
  • (XSS) .*echo .*\$_REQUEST.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_GET.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_POST.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_REQUEST.*
  • ([LR]FI) .*require\(\$_GET.*
  • ...

Bref cette première version était vraiment très rustique et pourrait être re-codé 100% en bash à coup de wget, unzip, et grep.

Pendant que cette première version tournait je me suis penché sur l'utilisation de PHC. L'idée est de réaliser ce dont je parlais dans mon vieux billet, à savoir d'utiliser PHC pour convertir le code source PHP en une représentation plus simple, et de réaliser une analyse par propagation de teinte sur cette représentation simplifiée. PHC propose 3 représentations intermédiaires, la plus simple d'entre elle étant la "MIR" c'est celle-ci que j'ai choisi (au format texte brute plutôt qu'XML) : phc --dump=mir mon_fichier.php.

Une fois mes fichiers PHP convertit en représentations "MIR" je parse le texte résultant pour en extraire des blocs de codes, chacun portant une étiquette utilisée par la représentation MIR pour d'éventuels GOTO, puis je débute ma simulation de propagation de teinte par la première ligne du premier bloc. A chaque assignation de variable rencontrée :

  • j'enregistre son nom dans un dictionnaire
  • je lui associe une valeur de teinte (si la variable se voit attribuée une constante la teinte est nulle, si elle se voit attribuée une variable de type $_GET[...] elle obtient une valeur de 1, si elle se voit attribuée la concaténation de deux autres variables sa teinte est la somme des teintes des variables concaténées, etc.)
  • je lui attribue une représentation (si son assignation est une constante je la reprend comme représentation, si son assignation est une variable sensible type "$_GET[...]" j'utilise ça, si on lui assigne la concaténation de variables je lui attribue la concaténation des représentation des variables concaténées, etc.)

Lorsqu'une fonction est appelée je regarde si son nom apparait dans l'une des listes de "fonctions sensibles" que j'ai hardcodé[2] et si tel est le cas je vérifie la teinte de la variable utilisée en argument. Si la teinte n'est pas nulle je lève une alerte en spécifiant la valeur de teinte utilisée, la représentation de la variable incriminée, et la famille de la fonction sensible (XSS, SQLi, [RL]Fi, PHPi).

Ce deuxième outil, bien qu'encore extrèmement rustique (246 lignes de python (199 sans les commentaires)), est sensiblement plus efficace que mon grossier "grep-like", comme nous allons voir tout de suite.

Les résultats

Ecrire un outil d'analyse de code c'est bien, mais encore faut-il avoir du code à analyser (et taper aléatoirement dans sourceforge c'est amusant deux secondes mais ça lasse vite) ! C'est donc en me demandant ce que j'allais bien pouvoir analyser que je me suis souvenu de cette liste de "bounty programs", et en particulier du dernier programme listé : celui de White Fir Design. Cette entreprise américaine, que je vous invite à découvrir, propose plusieurs bounty programs sur des logiciels open source dont un sur Wordpress et ses plugins téléchargés à plus d'un million d'exemplaires. C'est donc sur cette cible que j'ai testé mes deux outils d'analyse de code.

Pendant que j'écrivais mon outil de propagation de teinte basé sur PHC le premier script (grep-like) a relevé un nombre important d'alertes. C'est là que l'un des gros défaut de cette approche se fait sentir : il y a énormément de faux positifs. Par exemple la ligne suivante, bien que n'étant absolument pas vulnérable à quoi que ce soit, remonte à chaque itération de mon script comme un XSS potentiel :

echo (isset($_GET['session']) ) ? '?session=1' : '';

Malgré ces faux positifs j'ai tout de même réussi à confirmer quelques vulnérabilités de type XSS dans des pages d'admins de plugins téléchargés à plus d'un million d'exemplaire, et j'ai donc eu la double joie de toucher un petit bounty[3] tout en ayant le sentiment d'avoir rendu internet un peu plus sûr (tout ça avec "grep"...).

Une fois mon script d'analyse par propagation de teinte terminé je l'ai relancé sur le même périmètre et, après quelques réglages, j'ai eu le plaisir de voir qu'il parvenait à identifier l'ensemble des XSS que mon grep-like avait trouvé et que j'avais confirmé. Non seulement il obtient donc d'aussi bon résultats, mais en plus le nombre de faux positif est nettement plus faible (la majorité de ceux qui restent sont dus à la non-prise en charge des fonctions de "sanitize-check" type "preg_match"...il faudra que je rajoute le support de ces vérifications à l'occasion). Enfin, cerise sur le gateau, la version par propagation de teinte a réussi à lever un lièvre que le "grep-like" n'aurai pas pu avoir (parce que plusieurs lignes de code étaient impliquées) : une jolie time-based-blind-SQLi.

En guise de conclusion sauvage qu'est-ce-qu'il y a à retirer de tout ça ?

  • que l'analyse statique de code, même dans ses versions les plus rustiques (grep) peut encore être utile de nos jours.
  • que l'approche consistant à faire tourner un outil pourri pendant que l'on travaille à la fabrication d'outils plus évolué est une bonne approche (en tout cas moi je l'aime bien, elle me donne l'impression que mon temps CPU est utile et, en remontant des résultats de temps en temps, elle me garde motivée sur le codage des outils performants et prépare les cas de tests sur lesquels on pourra tester les outils performants :) ).
  • que l'équipe de White Fir Design est impressionante (ces gars donnent de l'argent pour aider à sécuriser des logiciels dont ils ne retirent qu'indirectement profit, moi je trouve ça fort !)
  • que les développeurs de plugins Wordpress sont généralement très sympa (j'ai eu à chaque fois des retours très cools de leur part)
  • <troll>que le code de Drupal est plus sécurisé que celui de Wordpress</troll> (ou que mes outils lui sont moins adaptés et/ou que j'ai eu moins de chance avec Drupal qu'avec Wordpress).

Notes

[1] Toute l'intro est largement pompée de : http://fr.wikipedia.org/wiki/Capitalisme

[2] print,->get_var,->get_results, ->query, mysql_query, require, require_once, include, eval

[3] Bounty immédiatement dépensé sur eBay en composants électroniques divers et variés pour mon arduino

samedi, octobre 22 2011

Brèves du jour

Un mini billet pour deux petites brèves : une astuce python (déjà bien connue, mais plus on réplique ce genre d'info moins on a de mal à la retrouver quand on l'a oublié), et un pointeur sur un jouet sympa.

Tools - Creative Common by mtneer_man on Flickr
Tout d'abord l'astuce python : comment changer son user-agent quand on utilise la librairie urllib. C'est un problème ultra-classique puisque pas mal de sites font du filtrage sur ce user-agent et refusent de répondre quand ils repèrent un script python[1]. En fouillant sur le net on trouve pleins de méthodes plus ou moins bidons (certaines se contentent carrément de rajouter un second header "user-agent", ce qui n'est évidemment pas ce que l'on cherche à faire), et après en avoir testé au moins une demi-douzaine voici celle que j'utilise à présent (et qui marche :D) :

import urllib
# ============ USER AGENT MAGIC ===========
class UAOpener(urllib.FancyURLopener):
        version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'
urllib._urlopener = UAOpener()
# =========================================

Et voilà :) Comme pour le passage via TOR c'est tout ce qu'il y a à faire. Accessoirement j'ai réalisé récemment que le dernier paramètre de "setdefaultproxy" que j'utilise pour passer par TOR souffre un bug ennuyeux : il est ignoré :-D Donc que vous mettiez à "True" ou à "False" les résolutions DNS ne passeront JAMAIS par votre proxy socks (et donc par TOR)...ennuyeux n'est-ce-pas ? En tout cas maintenant vous êtes prévenus :)

Le petit jouet maintenant : ça n'a rien de nouveau non plus, mais c'est tout de même un jouet rigolo. Il s'agit du WOrdnet Libre du Français[2]. Pour ceux qui connaissent Wordnet : c'est Wordnet pour le Français ;) Pour ceux qui ignorent ce qu'est Wordnet c'est une base de donnée concernant le sens des mots et leurs relations les uns avec les autres. Un usage immédiat de Wordnet c'est de trouver des synonymes (dans la langue française avec WOLF, dans la langue anglaise avec le Wordnet original), un autre usage consiste à mesurer la proximité de sens entre deux mots par exemple. Les possibilités sont vraiment nombreuses, notamment en data-mining. Bref vous pouvez le télécharger ici au format XML, et ces trois mini remarques pourraient vous êtes utiles si vous voulez travailler avec :

  • Le document ne contient pas de balise racine, ajoutez donc en une si vous voulez que xmllint --format ou xml.dom.minidom.Parse ne vous insulte pas. Par exemple un petit <wolf> en début de document et un petit </wolf> en fin de document feront parfaitement l'affaire.
  • Les '&' ont tendance à faire crier le module python xml.dom.minidom. Pour ma part je les ai donc purement et simplement supprimés grâce à un petit sed.
  • Le XML pèse 38Mo sur disque, une fois parsé par xml.dom.minidom mon interpréteur Python prend plus de 1Go ;-) Veillez donc à avoir de la RAM disponible.

Notes

[1] Par exemple wikipedia.

[2] WOLF

- page 1 de 8