dimanche, 25 novembre 2007

Fonction url_get_contents en PHP

Plutôt que d'utiliser un bien moche file_get_contents($url)$url est une url, je vous propose une petite fonction url_get_contents($url) utilisant l'extension curl de PHP qui permet aussi bien de télécharger le contenu d'une url via GET que POST :

function url_get_contents($url, $post = null) {
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt ($curl, CURLOPT_HEADER, 0);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);
//curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1); // if no safe_mode neither open_basedir

if (is_array($post)) {
curl_setopt ($curl, CURLOPT_POST, 1);
curl_setopt ($curl, CURLOPT_POSTFIELDS, $post);
}

$html = curl_exec ($curl);
curl_close ($curl);
return $html;
}

L'utilisation est réellement simple :

$content = url_get_contents('http://www.noisette.ch');

Reverse MD5 databases aggregator

J'écrivais il y a à peu près une année un message à propos des reverses MD5 et de la problématique que ces bases de données posent.
Suite à un message au sujet de l'utilisation de Google comme base de données de hash (en anglais), j'ai remis à jour mon aggrégateur de revse MD5.

Il questionne maintenant pas moins de 8 bases de données en plus de sa base de données propre, et permet maintenant de recevoir un mail quand le hash est trouvé après-coup.

Une petite API est disponible pour intégrer le service dans vos propres applications, notemment pour déterminer si un mot de passe sera crackable en O(1).

Happy md5 cracking sur md5.noisette.ch.

mardi, 9 octobre 2007

Contourner le blocage du port SMTP

Votre provider bloque le port tcp/25 (SMTP) et donc vous ne pouvez pas envoyer de mails via votre serveur mail préféré ?

Une solution toute simple mais qui nécessite d'avoir un compte shell sur un serveur quelconque (qui peut être votre ordinateur local), qu'on va nommer srv_shell dans cet exemple, est de faire un tunnel entre votre ordinateur local, le srv_shell et votre serveur de mail préféré, appelé srv_mail ici.

La commande à exécuter sur votre ordinateur local est la suivante :

ssh -NL 2525:srv_mail:25 user@srv_shell
L'utilisation d'un clé ssh est encouragée.

Ensuite dans votre logiciel d'envoi de mail préféré il suffit de spécifier comme serveur sortant localhost sur le port 2525.

Et hop la sécurité le côté ennuyeux à ce type de sécurité mis en place par l'administrateur est bypassé. J'y reviendrai d'ailleurs dans un autre article, car il m'est arrivé récemment ce genre de mésaventure : ip fixe avec serveur Exchange + Storm Worm = blacklistage de l'ip...

Une deuxième solution pourrait venir à l'esprit si on possède son propre serveur dédié, mais je vais expliquer pourquoi cette solution est à bannir au plus vite.

La deuxième idée est d'utiliser un logiciel comme rinetd ou redir, qui ont pour but de rediriger le traffic adressé à un port vers un autre. Donc tout ce qui arriverait sur le port 2525 de srv_shell serait redirigé vers le port 25 du srv_mail. Le problème de cette solution est quand les deux serveurs srv_shell et srv_mail sont les mêmes, la connexion sur le port 25 est redirigé par la même machine, le service mail va donc recevoir une connexion depuis localhost. Et comme la très grande majorité des services mails sont configurés pour que localhost puisse envoyer sans restrictions des mails, cette configuration ouvre un open-relay. Quiconque trouve ce port 2525 sur votre serveur pourra l'utilisé pour spammer le monde entier -> la redirection de port sur un serveur mail est donc à bannir.

lundi, 8 octobre 2007

Création manuelle d'un botnet "localisé"

Une méchante idée m'est venue en lisant un article de Slashdot : Cracked Linux Boxes Used to Wield Windows Botnets.

Afin de se composer un réseau de botnets, il serait extrêmement simple à une personne malveillante de vendre des routers ADSL modifiés (rootkités) sur des sites comme Ebay ou Ricardo en Suisse. L'utilisation pour l'acheteur pourrait être strictement similaire, au point qu'il ne se douterait pas que quelqu'un d'autre à la main sur son nouveau routeur.

Dans cet ordre d'idée, on voit de plus en plus de router ADSL se faire rootkiter à la suite d'un piratage d'un ordinateur. La raison principale : un mot de passe par défaut... Idem pour les connexions wireless : on la casse (l'histoire d'une journée pour du WEP avec du matériel correct) avant de s'attaquer au router !

En résumé, il serait presque rentable de se monter un botnet "localisé" et persistant, car placé dans des endroits stratégiques.

Deux petites recommandations pour éviter toutes mauvaises surprises : TOUJOURS modifier le mot de passe de vos routeurs (quitte à le noter dessous, le pirates devant hacker votre webcam et le robot téléguidé du petit frère pour réussir à placer le mot de passe dans le champs de vision de la webcam), et abandonner les connexions wireless...

vendredi, 28 septembre 2007

La surjection, nouvelle maladie ?

La prochaine fois que vous allez chez le médecin, dites-lui que vous souffrez d'une surjection et que je avez besoin d'un injection pour retrouver un état stable de bijection...

lundi, 24 septembre 2007

Implémentation paresseuse du "Visitor pattern" en PHP

Sans m'étendre sur les bienfaits du Visitor pattern, dont le but est de séparer un algorithme de sa structure de données, je souhaite proposer ici une implémentation paresseuse mais possible en PHP.

En théorie ce pattern repose sur 2 interfaces qui permettent de faire un double dispatch (appeler depuis un objets visitable la fonction lui correspondant dans le visiteur) :

  • Visitable qui contient une fonction apply(Visitor $v)
  • Visitor qui contient une fonction visit(Visitable $v)
Puisqu'en PHP il n'est pas possible de faire de la surcharge de paramètres de fonction (polymorphisme), il faut donc appeler les fonctions différemment selon les types de structure de données.

En Java :
interface Visitor {
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
abstract class Visitable {
void apply(Visitor visitor) {
visitor.apply(this);
}
}

En PHP :
interface Visitor {
public function visitWheel($wheel);
public function visitEngine($engine);
public function visitBody($body);
public function visitCar($car);
}
interface Visitable {
public function apply(Visitor $visitor);
}

On remarque donc qu'en PHP on devra réécrire toutes les fonctions apply pour qu'elles appellent la fonction visit___ correspondant à leur type.
Mais paresseux comme je suis, la redéfinition de la fonction apply pour chaque visitable me parait un tâche trop répétitive et ennuyeuse. L'idée sous-jacente est de faire un dispatch dynamique en fonction du type du visitable, de la façon suivante :
abstract class Visitable {
public function visit(Visitable $visitable)
{
$func = array(&$this, 'visit' . get_class($visitable));
if (!is_callable($func)) {
trigger_error('[' . get_class($this) . '] Class ' . get_class($this) . ' has no visit' . get_class($visitable) . ' function', E_USER_ERROR);
}
call_user_func($func, $visitable);
}
}

Ainsi le visiteur devrait implémenter les fonctions standards visitWheel, visitEngine, ... mais leur dispatching devient automatique !

Mis à part la lourdeur de la fonction call_user_func, le reste de cette implémentation dynamique reste intéressante.

Références :
http://en.wikipedia.org/wiki/Visitor_pattern
http://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_is_more_than_function_overloading

Plus d'information pour les intéressés :
http://www.polyglotinc.com/reflection.html
http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

mardi, 18 septembre 2007

Offre d'emploi : customer care

Ma petite startup, leader en suisse romande sur le marché des logiciels immobiliers, recherche un nouveau collaborateur afin d'assurer le support technique et la formation de ses nombreux clients.

Plus concrètement, le poste consisterait à répondre par téléphone/email aux questions techniques et d'assurer la formation des nouveaux clients sur les logiciels.

Le profile recherché est le suivant :

  • Langue maternelle française, bon niveau en allemand un plus
  • Excellentes capacités en communication, autant orales qu'écrites
  • Bonne capacité à comprendre et résoudre les problèmes
  • Capacité de travailler sur plusieurs tâches en parallèle
  • Bonne compréhension de l'architecture client-serveur
Les postulations peuvent être directement adressées à info _A_T_ migtechnology _P_O_I_N_T_ ch.

dimanche, 16 septembre 2007

Algue? piézo-phosphorescente

Mercredi 12 septembre 2007, tard le soir, plage de Vieux-boucaux dans les Landes française.

Nous étions alors en vacances entre amis. Une soirée des plus tranquilles, avec comme il se doit un passage sur la plage pour boire quelque breuvage local. Cadre peu crédible pour la suite de l'histoire si nous n'avions pas été 9 à être témoin du phénomène que nous avons découvert ce soir-là.

C'est en s'approchant de l'océan qu'on aperçut des points lumineux autour de nos pas. Des points d'une légère lumière bleutée s'illuminaient à chaque pression de nos pieds sur le sol dans un rayon d'une vingtaine de centimètres, avant de disparaitre 3 secondes plus tard.
Phénomène qui nous a émerveillé une bonne partie de la soirée, mais qui reste un mystère pour nos esprits curieux...

Une hypothèse d'une algue ou d'un organisme piézo-phosphorescent est de mise, car les points de couleurs apparaissaient dans une zone semblable à la zone de compression imposée par nos pas...

Mais les hypothèses les plus folles ont été imaginées sous cette nuit claire et chargée d'étoiles filantes.

lundi, 20 août 2007

Générateur automatique de visualisation de site

Un nom qui ne donne pas très bien en français, mais j'ai développé avec une petite équipe un générateur automatique de visualisation de site.

Le principe est simple : on donne une url au générateur qui nous retourne une image qui est une copie d'écran du site qu'on aurait eu dans notre navigateur. Le coeur du générateur utilise le moteur Gecko pour le rendu de la page web.

Une démo du service de génération de visualisation de site est disponible en ligne, et l'idée est de développer une puissant API pour interfacer le service. L'idée principale de l'API est d'utiliser une url de callback qui permettra au service directement de retourner l'image une fois générée afin d'éviter au client de devoir poller pour controler si l'image est créée ou pas.

Les possibilités du service sont les suivantes :

  • Taille des images paramétrables (120x90, 160x120, 320x240, 640x480, 1024x768)
  • Format d'image JPEG ou PNG
  • Ajout de délai avant la capture (pour les sites en flash par exemple)
  • Mise-à-jour hebdomadaire, mensuelle ou annuelle des captures
Les feedbacks sont bien évidemment encouragés, et d'autres news sur l'API & CO suivront.

jeudi, 16 août 2007

Uniqid ou la contre-intuitivité des arguments

D'après le manuel PHP, le prototype de la fonction uniqid est le suivant :

string uniqid ( [string prefix [, bool more_entropy]] )
Le deuxième paramètre à l'air réellement intéressant, dans la mesure où il assure une meilleure unicité de la chaine produite. Une propriété qui de toute évidence nous intéresse si on utilise cette fonction uniqid.

Sans s'étendre sur la probabilité de collision entre les 2 appels (ce que j'étendrai plus longuement dans un autre article), je voulais juste montrer la différence de vitesse d'exécution qu'induisait ce paramètre more_entropy. Un petit script faisant 100 appels à uniqid avec une valeur possible du paramètre, nous donne le résultat suivant (!) :

100 * uniquid(mt_rand()) en 0.799283981323 seconde

100 * uniquid(mt_rand(), true) en 0.00346183776855 seconde

Chose extrêmement intéressante, le temps d'exécution de la fonction est 3 ordres de grandeurs en dessous si on demande une meilleures unicité du résultat.

La question obligée est donc : pourquoi est-ce que cette fonctionne ne prend pas par défaut cette option, puisqu'elle a tous les avantages (meilleures résultats, plus rapide) ?