lundi 9 avril 2012

Juste des hashs

kevin@slackware:~$ vi doc.txt
reading doc.txt

wrote doc.txt, 190 lines, 8175 chars
kevin@slackware:~$ md5sum doc.txt
7c57b61f9f99c541ea8c17f1f4b8ded4  doc.txt
kevin@slackware:~$ sha1sum doc.txt
2035d6d4e944f8716e85d688057dde5e7cc7c32f  doc.txt
kevin@slackware:~$

mardi 3 avril 2012

Browserquest de mozilla, c'est quand meme plus simple que le SSTIC


Afin de promouvoir la norme HTML5, mozilla a publié un jeu n'utilisant que cette technologie : browserquest.
Le jeu ressemble à Zelda, et plusieurs références très geeks émaillent le jeu (Nyan cat, Portal, Star wars, Le seigneur des anneaux, Mario bros, Rickroll, etc..).

Le principe du jeu est simple, vous démarrez simple joueur avec une petite épée et au fur et à mesure de la progression, des armes plus puissantes peuvent être utilisées. Un mécanisme d'"achievement" est présent, vous récompensant de différentes réussites (se faire rickroller, tuer 50 ennemis, etc..). Je n'ai pas joué fort longtemps, mais la carte à l'air assez grande. Le problème dans ce genre de jeu, c'est que l'on commence assez faible et que le moindre ennemi vous achève en un tour de jeu ce qui est vite assez frustrant.

Dans le temps, les joueurs tentaient souvent de modifier les sauvegardes pour s'arroger des vies supplémentaires. Nous avons lu que le jeu autosauve les caractéristiques du joueur (HTML5 et Localstorage).
Créons un joueur appelé Palladin (oui, je fais original):


Fermons l'onglet du navigateur. Si je rouvre le navigateur on me propose bien de nouveau ce personnage:


Il est donc enregistré quelque part.

$ grep -rl Palladin .mozilla/firefox/
.mozilla/firefox/70willuz.default/webappsstore.sqlite

Les données semblent être enregistrées dans cette base sqlite3.
$ sqlite3 webappsstore.sqlite
SQLite version 3.7.5
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .table
webappsstore2
sqlite> .schema webappsstore2
CREATE TABLE webappsstore2 (scope TEXT, key TEXT, value TEXT, secure INTEGER, owner TEXT);
CREATE UNIQUE INDEX scope_key_index ON webappsstore2(scope, key);
sqlite> select scope from webappsstore2;
 (...)
gro.allizom.tseuqresworb.:http:80
sqlite> 
L'utilisateur averti comprend vite que le domaine se lit à l'envers, on lit bien browserquest.mozilla.org

sqlite> select value from webappsstore2 where scope='gro.allizom.tseuqresworb.:http:80';
{"hasAlreadyPlayed":true,"player":{"name":"Palladin","weapon":"sword1","armor":"clotharmor","image":"data:image/png;base64,iVBO (...) gg=="},"achievements":{"unlocked":[4],"ratCount":1,"skeletonCount":0,"totalKills":1,"totalDmg":24,"totalRevives":0}}
Rien n'est obfusqué (j'ai juste réduite le base64 de l'image png), il est donc temps d'aller chercher le code source du jeu pour connaitre la liste des armes disponibles. On se doute bien que weapon et armor sont à modifier, et que le "unlocked" d'achievements est une simple liste.

Le fichier shared/js/gametype.js donne toutes les infos nécessaires.
Types.rankedWeapons = [
    Types.Entities.SWORD1,
    Types.Entities.SWORD2,
    Types.Entities.AXE,
    Types.Entities.MORNINGSTAR,
    Types.Entities.BLUESWORD,
    Types.Entities.REDSWORD,
    Types.Entities.GOLDENSWORD
];

Types.rankedArmors = [
    Types.Entities.CLOTHARMOR,
    Types.Entities.LEATHERARMOR,
    Types.Entities.MAILARMOR,
    Types.Entities.PLATEARMOR,
    Types.Entities.REDARMOR,
    Types.Entities.GOLDENARMOR
];
Donc goldensword et goldenarmor semblent être des options intéressantes :-)

La deuxième variable concerne les achievments, et l'on va tous se les arroger. Une requête sqlite unique permet de modifier tout cela:

$ sqlite3 webappsstore.sqlite
sqlite> update webappsstore2 set value='{"hasAlreadyPlayed":true,"player":{"name":"Palladin","weapon":"goldensword","armor":"goldenarmor","image":"data:image/png;base64,iVB (...) gg=="},"achievements":{"unlocked":[4,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],"ratCount":0,"skeletonCount":0,"totalKills":0,"totalDmg":0,"totalRevives":0}}' where scope='gro.allizom.tseuqresworb.:http:80';
Et on relance le jeu. Le palladin a changé d'apparence et de puissance:
Tout de suite, ça fait sérieux.

Et pour les achievements:

Win \o/ 

Vous pouvez courir plein nord pour aller défaire le boss.

C'est d'une simplicité désarmante au contraire du SSTIC où je semble être coincé sur une webcam USB qui ne veut rien me dire :-/

EDIT (06avril) : Sous Google Chrome, le fichier sqlite est enregistré sous:
~/.config/google-chrome/Default/Local Storage. Le fichier n'est pas suffixé en sqlite, et se nomme http_browserquest.mozilla.org_0.localstorage.
La table ne contient qu'une seule ligne et vous pouvez l'updater de la même manière:
update ItemTable set value='{"hasAlreadyPlayed (...) ' where value like 'has';