Skip navigation.

devloop :: blog

Blog sur la sécurité informatique, la programmation, Linux et le Web

February 2009

( Monthly archive )

Killed by a mumak, while reading a book

,

Et voilà où ça mène d'être trop studieux :lol:

Hier, explosion de mon meilleur score à Nethack avec une Valkyrie :knight:
La partie s'est faite tranquillement et sans rencontrer de grandes difficultées. Je suis plutôt parti du bon pied et ait trouvé différentes armures qui m'ont suivi jusqu'à la mort :
  • +3 small shield (de base)
  • +2 pair of speed boots
  • +0 dwarvish cloak
  • +1 orcish helm

J'ai même récupéré une armure "elven mithril-coat" que j'ai pû enchanter, ramenant mon AC à -5 :smile:
Cette dernière ne fera malheureusement pas long feu puisque disparue sans que j'y prette attention (parchemin de destruction d'armure ?). J'ai tout de même conservé un AC de -4 pendant un bon moment puis -3 à la fin.

J'ai eu chaud à un moment, me retrouvant tout d'un coup autour d'un tas de monstres surgis de nulle part, peut-être "appelés" par un leprechaun. Heureusement j'étais proche des escaliers, ce qui m'a permis de prendre la fuite, récupérer mon souffle et revenir leur casser la gueule :devil:

J'ai récupéré pas mal de baguettes magiques dans des combats : cold, striking, lighting, sleep et speed. De même la récupération d'Excalibur, quoiqu'un peu tardive, n'a pas posé de problèmes.
La visite des mines était presque une visite de courtoisie, les gnomes étant pacifiques avec moi.

Je me suis presque exclusivement servi de mon épée et de dagues (ainsi que la pioche pour creuser des tunnels p: )

A ajouter à mon attirail, une amulette de réflection qui s'est montrée très efficace.

Enfin, chose qui arrive assez rare pour être signalé : mon chat de combat aura vécu plus longtemps que moi (mon chat c'est un thug, il porte un bandana autour du coup).

L'apprentissage réussi d'un livre de sort d'identification ne m'aura pas été de grande utilité car les Valkyries sont de piètres jeteuses de sorts et que mes 21 points d'énergie n'étaient pas suffisant.

J'ai beaucoup exploré le dongeon, descendant jusqu'au niveau 16 (je n'étais pas allé aussi loin, que ce soit NAO ou unfoog.de).

J'ai découvert un niveau pour le moins étrange qui s'est avéré être le Rogue level ainsi que le premier niveau de la quête des Valkyries où mon maître m'a dis que je n'étais pas encore prêt pour le grand combat p:

C'est finalement la lecture d'un livre de résurrection qui m'a rendu inconscient durant un moment. Laps de temps suffisant pour me faire attaquer par un Mumak qui provoqua ma fin rip
Comme quoi il faut toujours lire dans un endroit où l'on ne peut pas être dérangé p:

Capture de l'écran de fin

Et enfin je profite de ce billet pour vous faire part de l'apparition d'une implémentation AJAX de Nethack, baptisée Nethax :yikes:

PNG Noise : convertir un fichier en une image

, , ,

Voici deux petits programmes que j'ai fait en me servant de la librairie d'écriture/lecture d'images PNG PNGwriter.
Cette librairie est très simple et permet de générer des images très basiques particulièrement adaptés aux graphes et autres représentations mathématiques (voir les exemples sur le site). Des fonctions très pratiques sont disponibles comme placer un simple pixel, un trait, une forme géométrique, du texte...

Mon objectif premier en utilisant cette librairie était de faire un programme capable de prendre des données brutes dun fichier quelconque et d'en faire une image PNG valide (affichable sans erreur dans différents logiciels). Le résultat n'est forcément pas très beau (c'est du "bruit") mais on peut procèder en sens inverse et extraire les données présentes dans l'image pour recréer le fichier original.

L'utilité du programme est questionnable. Une des applications pourrait être de passer certains filtres sur les formats de fichiers comme ceux présents sur les service de stockage d'image en ligne. On pourrait alors y stocker tout type de données.
Du point de vue stéganographique le programme offre un excellent ratio mais un oeil humain se douterait que l'image renferme un secret ;-)
Enfin l'idée m'est entrée dans la tête donc il fallait que je le fasse :D Je vous laisse à votre imagination pour d'autres applications

Le principe est le suivant :
  • PNG est un format d'image matricielle, c'est à dire que les images sont définies par un ensemble de pixel
  • Chaque pixel de l'image est définit par une couleur codée sur 3 valeurs : R, V, B (rouge, vert et bleu)
  • Chacune de ces couleurs primaires est codée de 0 à 65535, correspondant à autant de nuances différentes

Une nuance de couleur (0 à 65535) tient sur 2 octets. On a donc 6 octets (car 3 couleurs primaires) par pixel. Il suffit alors de lire le fichier à "transformer" par morceaux de 6 bits et de les intégrer comme pixel dans une image.
Le programme s'arrange pour que les dimensions de l'image finale soient le plus proche possible du carré. Les derniers pixels sont donc des pixels de bourrage.

Le tout premier pixel de l'image sert à stocker la taille du fichier d'origine pour déterminer le nombre d'octets effectifs lors de l'opération inverse.

En utilisant le programme transform sur ce fichier pdf vous expliquant comment implémenter la suite de Fibonacci en kernel-land (hmmm), on obtient l'image suivante :

Le programme extract sera capable de retrouver le fichier original à partir de cette image.

C'est aussi intéressant car ça permet de voir tout de suite les répétitions présentes dans un fichier : les zones unies de l'image représentent les zones du fichier qui gagneraient à être compressées :smile:
Ainsi si on regénère une image à partir du fichier PDF une fois compressé avec bzip2 on obtient :

Vous trouverez les sources dans l'archive png_noise.zip
La librairie PNGwriter n'est pas incluse. Les commandes pour la compilation sont indiquées dans la source.

Imeem.com Python Crypto API

, , ,

C'est après un brin d'analyse, un peu d'aide :smile: et une bonne quantité de neuronnes explosés sur le développement que je suis parvenu au même résultat que pour Anywhere.FM, c'est à dire pouvoir accèder directement aux flux audios sans avoir à passer par l'interface web "flash powered" du site.

Contrairement à Anywhere.FM où la difficultée se trouvait dans l'utilisation du protocole AMF et l'absence d'API, pour Imeem il fallait se concentrer sur l'analyse du lecteur audio en Flash présent sur le site.

Après avoir testé sans succès différents décompileurs (limitations génantes et/ou bugs divers) on m'a finalement donné un code satisfaisant décompilé à l'aide d'un logiciel de Eltima en version d'évaluation.
Dans les sources obtenues ont pouvait lire les fonctions cryptographiques utilisées par le site ainsi que la clé de chiffrement.

En effet, même si le fonctionnement du site ne semble pas correspondre à ce que l'on appelle un DRM, il y a toutefois des protections diverses pour empêcher le téléchargement en masse des titres proposés sur la plateforme.
Tout se concentre sur l'utilisation d'urls à usage unique qui sont générées par les fonctions cryptographiques du Flash ainsi que les variables de chiffrement fournies par la fonction non documentée "mediaGetStreamInfo" de l'API.

Les conversions de données
A l'aide des variables obtenues par la fonction mediaGetStreamInfo, on génère une chaine de caractère représentant un objet JSON que l'on passe à la moulinette à la fonction encrypt avec la clé secrète trouvée par décompilation.
Bizarrement, cette clé n'est pas la même dans deux fichiers SWF analysés sur le site. Sur l'un la clé est "Your mom is a whore.", sur l'autre il s'agit de "I:NTnd7;+)WK?[:@S2ov". Ma première tentative réussie s'étant fait avec cette seconde clé, je l'ai ensuite conservé pour le reste des opérations.

L'API cryptographique considère 3 types de données qui sont autant d'étapes à un chiffrement/déchiffrement :
  • str : il s'agit d'une chaine de caractères simple. C'est l'état du JSON passé à encrypt
  • bytes : il s'agit d'un tableau d'octets, représentation d'une chaine de caractères (utilisation de la fonction ord())
  • blocks ou binary : un tableau d'entiers de 4 octets qui sont juste une représentation des tableaux d'octets précédents.
  • ascii : une chaine de caractères générée à partir des blocks précédents

Le passage de Blocks à Ascii ce fait de la façon suivante :
  1. On prend 3 blocks : 3x4 octets soit 24 bits
  2. On les accole et on découpe le résultat en morceaux de 6 bits, soit 4 morceaux de 6 bits
  3. Chacun des quatres morceaux représente un chiffre (de 0 à 63) qui est utilisé comme index dans une chaine de caractères prédéfinie composée de lettres minuscules et majuscules, des numéros, du tiret et de l'underscore

Le chiffrement
Le chiffrement consiste d'abord à convertir le JSON et la clé en blocks qui sont alors chiffrés par l'algorithme XTEA qui est une amélioration du TEA
Le tableau de blocks obtenu est finalement converti en représentation Ascii en suivant l'opération décrite précédemment.
Cette chaine de caractère est une partie de l'URL où on pourra accèder à la ressource (précédée du nom du serveur et du path indiqués dans le JSON et terminée par l'extension .flv)

L'implémentation
L'implémentation m'a posé différents problèmes dus en partie au typage des données en Python. Ce dernier intégre la notion de débordement des entiers, ainsi un chiffre sera passé de int à long de façon invisble au développeur si la donnée dépasse ses limites.
Un exemple concret est le décalage de bits sur la gauche. Si on considère l'entier sur 32 bits 0xFF0000F0, un décalage de 8 bits vers la gauche générerait en C le chiffre 0xF0000F00 : le F du début est supprimé.
Un Python le déclage se produit mais la donnée est passée sur 64 bits et le F est donc conservé :frown:
J'ai du alors implémenter une fonction "SHL" ainsi qu'une fonction "USHR" (unsigned right shift) que le langage Python ne fournit pas :
  def USHR(self,n,d):
    if n>=0:
      return n>>d
    else:
      return (n>>d)&(0xffffffff>>d)

  def SHL(self,n,d):
    mask=n&(0xffffffff>>d)
    return mask<<d

Pour éviter les débordements sur les opérations arithmétiques, j'ai eu recours à la librairie NumPy (présente dans les dépôts Packman sous openSUSE) qui permet d'utiliser des "uint32".

Dans l'archive imeem_crypto.zip vous trouverez :

Notez qu'une personne non-enregistrée sur le site n'accède qu'à des URLs qui correspondent aux extraits musicaux et non aux morceaux complets.
Mon implémentation cryptographique en Python est aussi visible ici avec coloration syntaxique :smile:
Il ne me reste plus qu'à me recoder un lecteur audio pour profiter de ma musique présente sur le site.