PROJET AUTOBLOG


Tiger-222

Site original : Tiger-222

⇐ retour index

Python : mémoisation

jeudi 31 octobre 2013 à 02:20
Œuvre d'Anthony Heywood
Connaissez le dicton : avoir une mémoire d'...

La mémoisation est une technique d'optimisation de code consistant à réduire le temps d'exécution d'une fonction en mémorisant ses résultats d'une fois sur l'autre, une sorte de cache quoi. Ça peut-être super pratique dans certains cas, surtout lorsqu'il y a des calculs complexes ou beaucoup de données redondantes.
Étant donné que Sam & Max ont déjà couvert le sujet, je vais seulement montrer un exemple concrêt : le cas de mon module MSS.

Le contexte


Le module MSS est, comme sont nom ne l'indique pas, un module permettant de prendre des captures d'écran sans module tiers, seulement du python pur. J'utilise intensément le module ctypes, qui permet d'appeler des fonctions C/C++ depuis python.
Sous GNU/Linux, avec un code équivalent C <=> python permettant de prendre une capture d'écran, la différence de vitesse d'exécution est quintuplée, voire sextuplée. Ça fait beaucoup. Je me suis donc plongé dans le code pour voir ce qui pouvait être revu ou amélioré. Au final, il s'avère que les routines pour récupérer les pixels et générer l'image PNG seront améliorées. Mais le gain fût minime.
Le stockage des pixels reçus par la fonction XGetPixel met un temps fou, c'est un gouffre. C'est là qu'il faut farfouiller, voilà le code fautif :
def pix(pixel):
''' Apply shifts to a pixel to get the RGB values. '''
return b((pixel ET 16711680) >> 16) + b((pixel ET 65280) >> 8) + b(pixel ET 255)

get_pix = self.XGetPixel
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]
La coloration syntaxique chie dans la colle, remplacez le ET par &.

Dans la fonction pix(), le décalage de bits n'est pas le plus gourmant, ce sont les concaténations. En effet, à chaque fois, il y a réallocation de mémoire et copie de données dont je me passerais bien.


Mémoisation


Dans la logique qui m'habite (rien de bien transcendant...), je me dis qu'il y a énormément de pixels identiques sur un écran. Il y a la dose même. Avec une telle quantitié de données, et sachant les opérations qu'il faille faire sur chacun des pixels, la mémoisation prend tout son sens :
def pix(px, _resultats={}):
# Apply shifts to a pixel to get the RGB values.
# This method uses of memoization.
if not px in _resultats:
_resultats[px] = b((px ET 16711680) >> 16) + b((px ET 65280) >> 8) + b(px ET 255)
return _resultats[px]

get_pix = self.XGetPixel
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]
J'ai modifié pixel par px afin d'éviter les barres de défilement...

Étant donné que les paramètres sont initialisés à la déclaration, le paramètre _resultats de la fonction pix() ne sera pas recréé à chaque appel. Il s'agit d'un dict qui recevra tous les pixels et le résultat attendu pour chacun d'eux. Dans ladite fonction, on vérifie si le pixel a déja été traité, si non, on effectue les opérations sur celui-ci, puis on renvoie ce que le dict a en mémoire. Un petit cache tout simple et efficace.


Résultats


Avec un écran de 1280x1024, je passe de ±4 sec à <2 sec, reduisant les pixels traités de 1 310 720 à 11 204.
Avec un écran de 1920x1280, je passe de ±6 sec à <3 sec, reduisant les pixels traités de 2 457 600 à 8 236.

♪ Un gain non négligeable ! ♪

Routeurs déchus

mercredi 30 octobre 2013 à 02:04
Linksys WRT54G v2

En ce mois d'octobre, j'ai observé une recrudescence de portes dérobées (ou backdoors) dans des routeurs grand public. Je vais tenter de regrouper des liens et donner un minimum d'explications, ça fera un petit guide de dépannage ☠

Voici la liste des routeurs recensés :
Aussi, il semblerait que certains modèle Netgear utilisent un mot de passe root codé en dur.


DLink DIR-815 UPnP Command Injection

Le 1er février 2013
Routeurs impactés : D-Link DIR-815.

The Shadow File avait 20 minutes à tuer. Et voilà que le D-Link tombe. En forgeant un packet tel que celui-ci :
M-SEARCH * HTTP/1.1
HOST:239.255.255.250:1900
ST:uuid:`reboot` <-- Ici, la commande désirée
MX:2
MAN:"ssdp:discover"
Qu'il faut envoyer en multicast à l'addresse IP 239.255.255.250 sur le port UDP (1900). Il y a même un script python qui permet d'automatiser la tâche et spécifier une commande.


Reverse Engineering a D-Link Backdoor

Le 12 octobre 2013
Routeurs impactés : D-Link DI-524UP, D-Link DI-604S, D-Link DI-604UP, D-Link DI-604+, D-Link DI-624, D-Link DIR-100, D-Link DIR-120, D-Link TM-G5240, Planex BRL-04R, Planex BRL-04UR et Planex BRL-04CW.

Un chercheur en sécurité de chez /dev/ttyS0 à découvert qu'un certain Joel à implémenté une porte dérobée dans les routeurs utilisant le firmware v1.13. L'exploit est on ne peut plus simple : il suffit de modifier l'User-Agent tel que :
xmlset_roodkcableoj28840ybtide
Pour le côté fun, si on lit à l'envers, ça donne « Edit by 04882 Joel Backdoor ». Merci Joel.


From China, With Love

Le 17 octobre 2013
Routeurs impactés : Tenda W302R, Tenda W330R ou encore Medialink MWN-WAPR150N.

Toujours un chercheur en sécurité de chez /dev/ttyS0, tout se passe au niveau de la forge du packet :
echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 IP_routeur 7329
Notez le "/bin/ls" dans le "echo", c'est la commande qui sera exécutée en root...


Complete, Persistent Compromise of Netgear Wireless Routers

Le 22 octobre 2013
Routeurs impactés : Netgear WNDR3700v4, Netgear WNDR3800 et Netgear WNDR4700.

The Shadow File a mis à mal les routeurs Netgear, bien comme il faut...
Il suffit de se rendre à l'adresse suivante pour désactiver totalement le contrôle d'accès :
http://IP_routeur/BRS_02_genieHelp.html

Pour voir les mots de passe Wi-Fi en clair :
http://IP_routeur/BRS_success.html

Et puis on peut aussi passer des commandes shell, sinon c'est pas rigolo. J'en garde une copie, juste au cas où.


Bref !


Comme disait Pépin.
J'ai bien peur que d'autres soient à venir... En attendant, quelques lecture intéressantes :
Et sinon, vive le libre, vive le Linksys WRT54G (photo de l'article) et son firmware open-source DD-WRT !

Routeurs déchus

mercredi 30 octobre 2013 à 01:04
Linksys WRT54G v2

En ce mois d'octobre, j'ai observé une recrudescence de portes dérobées (ou backdoors) dans des routeurs grand public. Je vais tenter de regrouper des liens et donner un minimum d'explications, ça fera un petit guide de dépannage ☠

Voici la liste des routeurs recensés :
Voir la partie des lectures intéressantes, il y a d'autres routeurs concernés.
Aussi, il semblerait que certains modèle Netgear utilisent un mot de passe root codé en dur.


DLink DIR-815 UPnP Command Injection

Le 1er février 2013
Routeurs impactés : D-Link DIR-815.

The Shadow File avait 20 minutes à tuer. Et voilà que le D-Link tombe. En forgeant un packet tel que celui-ci :
M-SEARCH * HTTP/1.1
HOST:239.255.255.250:1900
ST:uuid:`reboot` <-- Ici, la commande désirée
MX:2
MAN:"ssdp:discover"
Qu'il faut envoyer en multicast à l'addresse IP 239.255.255.250 sur le port UDP (1900). Il y a même un script python qui permet d'automatiser la tâche et spécifier une commande.


Reverse Engineering a D-Link Backdoor

Le 12 octobre 2013
Routeurs impactés : D-Link DI-524UP, D-Link DI-604S, D-Link DI-604UP, D-Link DI-604+, D-Link DI-624, D-Link DIR-100, D-Link DIR-120, D-Link TM-G5240, Planex BRL-04R, Planex BRL-04UR et Planex BRL-04CW.

Un chercheur en sécurité de chez /dev/ttyS0 à découvert qu'un certain Joel à implémenté une porte dérobée dans les routeurs utilisant le firmware v1.13. L'exploit est on ne peut plus simple : il suffit de modifier l'User-Agent tel que :
xmlset_roodkcableoj28840ybtide
Pour le côté fun, si on lit à l'envers, ça donne « Edit by 04882 Joel Backdoor ». Merci Joel.


From China, With Love

Le 17 octobre 2013
Routeurs impactés : Tenda W302R, Tenda W330R ou encore Medialink MWN-WAPR150N.

Toujours un chercheur en sécurité de chez /dev/ttyS0, tout se passe au niveau de la forge du packet :
echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 IP_routeur 7329
Notez le "/bin/ls" dans le "echo", c'est la commande qui sera exécutée en root...


Complete, Persistent Compromise of Netgear Wireless Routers

Le 22 octobre 2013
Routeurs impactés : Netgear WNDR3700v4, Netgear WNDR3800 et Netgear WNDR4700.

The Shadow File a mis à mal les routeurs Netgear, bien comme il faut...
Il suffit de se rendre à l'adresse suivante pour désactiver totalement le contrôle d'accès :
http://IP_routeur/BRS_02_genieHelp.html

Pour voir les mots de passe Wi-Fi en clair :
http://IP_routeur/BRS_success.html

Et puis on peut aussi passer des commandes shell, sinon c'est pas rigolo. J'en garde une copie, juste au cas où.


Bref !


Comme disait Pépin. J'ai bien peur que d'autres soient à venir...

En attendant, quelques lecture intéressantes :
Et sinon, vive le libre, vive le Linksys WRT54G (photo de l'article) et son firmware open-source DD-WRT !

Git : revoir ses branches

mardi 29 octobre 2013 à 13:57
Suite à la lecture de l'article My Git Branching Model -- William DURAND, je me suis rendu compte que c'était une peu brouillon de mon côté. Je trouve son modèle pratique.

Le cas de Pombo


J'ai donc voulu revoir le modèle de Pombo, entre autres. L'ancien modèle était le suivant : une seule branche master, avec tout dedans à la rache.
La dernière version stable de Pombo est la 0.0.10, soit le commit n°31. La version en cours de développement en est au commit n°112. Vous voyez le bousin arriver ?

Coment faire ? La réponse est simple, la méthode aussi (enfin après quelques recherches) :
En pratique, ça se fera tel que :
# créer la branche temporaire master-tmp à partir du commit n°31
git checkout 35d7690 -b master

# renommer la branche master en develop
git branch -m master develop

# renommer la branche master-tmp en master
git branch -m master-tmp master

# pousser la branche develop
git push origin develop
# git config --global push.default simple

# synchroniser la branche develop avec celle sur le serveur distant
git checkout develop
git push --set-upstream origin develop

# supprimer la branche master distante, devenue obsolète
# si vous utilisez GitHub, pensez à déclarer la branche develop comme celle par défaut
git push origin :master

# pousser la branche master nouvellement recréée
git push origin master
# si vous utilisez GitHub, pensez à remettre la branche master comme celle par défaut

# synchroniser la branche master avec celle sur le serveur distant
git checkout master
git push --set-upstream origin master
Dans tout ça, la nouvelle commande pour moi est git checkout <id> -b <nom>.


Nouvelle fonctionnalité


Dorénavant, lors de l'ajout d'une fonctionnalité, j'ajouterai une nouvelle branche feat-<nom> depuis develop :
git checkout -b feat-<nom> develop

Mémo pour pousser une fonctionnalité dans la branche develop :
git checkout develop
git pull --ff-only origin develop
git checkout feat-<nom> git merge feat-<nom>
git rebase develop
git merge --no-ff feat-<nom>
git push origin develop


Comme je compte appliquer ce modèle de branches à mes autres projets, voyez-vous une meilleure solution ?

Git : revoir ses branches

mardi 29 octobre 2013 à 12:57
Suite à la lecture de l'article My Git Branching Model -- William DURAND, je me suis rendu compte que c'était une peu brouillon de mon côté. Je trouve son modèle pratique.

Le cas de Pombo


J'ai donc voulu revoir le modèle de Pombo, entre autres. L'ancien modèle était le suivant : une seule branche master, avec tout dedans à la rache.
La dernière version stable de Pombo est la 0.0.10, soit le commit n°31. La version en cours de développement en est au commit n°112. Vous voyez le bousin arriver ?

Coment faire ? La réponse est simple, la méthode aussi (enfin après quelques recherches) :
En pratique, ça se fera tel que :
# créer la branche temporaire master-tmp à partir du commit n°31
git checkout 35d7690 -b master-tmp

# renommer la branche master en develop
git branch -m master develop

# renommer la branche master-tmp en master
git branch -m master-tmp master

# pousser la branche develop
git push origin develop
# git config --global push.default simple

# synchroniser la branche develop avec celle sur le serveur distant
git checkout develop
git push --set-upstream origin develop

# supprimer la branche master distante, devenue obsolète
# si vous utilisez GitHub, pensez à déclarer la branche develop comme celle par défaut
git push origin :master

# pousser la branche master nouvellement recréée
git push origin master
# si vous utilisez GitHub, pensez à remettre la branche master comme celle par défaut

# synchroniser la branche master avec celle sur le serveur distant
git checkout master
git push --set-upstream origin master
Dans tout ça, la nouvelle commande pour moi est git checkout <id> -b <nom>.


Nouvelle fonctionnalité


Dorénavant, lors de l'ajout d'une fonctionnalité, j'ajouterai une nouvelle branche feat-<nom> depuis develop :
git checkout -b feat-<nom> develop

Mémo pour pousser une fonctionnalité dans la branche develop :
git checkout develop
git pull --ff-only origin develop
git checkout feat-<nom> git merge feat-<nom>
git rebase develop
git merge --no-ff feat-<nom>
git push origin develop


Comme je compte appliquer ce modèle de branches à mes autres projets, voyez-vous une meilleure solution ?