CDEdit 1.12 |
|
|
30/07/2000 |
by "GuZuRa" |
|
Published by Quequero |
||
| Di fronte alle delusioni lo stolto cerca comprensione... | Inserisco anche questa soluzione perchè contiene un approccio interessante alla protezione del programma, bravo guzu. |
Il saggio cerca un'altra donna... |
| UIC's form |
|
UIC's form |
Difficoltà |
(X)NewBies ( )Intermedio ( )Avanzato ( )Master |
Ho scritto questo tutorial perchè il programma si offre a più tecniche di approccio (oltre alla pesca del seriale) e mi permette di parlare di una caratteristica di IDA che sicuramente tutti i più esperti conoscono ma che non ho mai trovato menzionata in alcun tutorial che non fosse dedicato esclusivamente ad IDA, altra cosa voglio mostrare come si possa affrontare un algoritmo di protezione sotto un'altra ottica
Introduzione |
Tools usati |
Sice,IDA,una tabella ASCII e il GetType tutti reperibili alla UIC
URL o FTP del programma |
UIC :))))))
Notizie sul programma |
Non ho la più pallida idea di cosa fa stò programma
Essay |
Spero sappaiate usare un pò IDA altrimenti leggetevi il chiarissimo tutorial di Quequero alla UIC(non credo ci sia bisogno di commenti... ;))
Voglio incominciare a parlare di quella caratteristica di IDA che va sotto il nome di
"Tecnologia Flirt" (come è chiamata nell'help in linea):
Traduco dall'help in linea
Load FLIRT signature file (questo è il comando)
Questo comando permette di applicare un'ulteriore "signature file" al programma.
Un "signature file" contiene i patterns di alcune standard runtime functions.
Con questo aiuto, IDA è capace di riconoscere le standard functions e i nomi associati ad
esse (e sostituirli nel listato come fa il WDasm con le API).
IDA cerca di riconoscere automaticamente i "signature files" usati dal programma
(lo fa nell'analisi iniziale). Sfortunatamente, questo non è sempre possibile. Questo
comando permette di forzare IDA ad utilizzare dei "signature file" specificati
da noi.
Prendiamo ora il CDEdit e decompiliamolo con IDA, aspettiamo che finisca e andiamo a
vedere che signature ha utilizzato; e vediamo che non ha riconosciuto niente, nemmeno il
compilatore utilizzato, ergo se affrontiamo il programma a parte le API dovremmo sorbirci
un bel po di call innominate da riconoscere.
Prima di andare avanti troviamo la routine che dal nick genera il seriale: aprite CDEdit,
andate nel form di registrazione e digitate i dati che volete (Nick e Serial), CTRL-D e un
BPX HMEMCPY in Sice possono bastare, uscite da Sice e clikkate Register e Sice si stoppa,
F11 e poi fate F12 fino a che non rientrate nel codice del programma steppate tutte le POP
e le RET che ci sono fino a che non rientrate nella routine madre (non
è detto che sia il MAIN ma intendo la routine dominante in
questa parte di codice; dovreste saperla riconoscere se avete fatto le lezioni
precedenti) ,ora steppate senza entrare nelle call e vedrete che brekkerete su altri
HMEMCPY e ogni volta vi troverete a risteppare nelle POP di prima, ogni tanto quando
uscite dalle call prima di entrare in altre call date un'occhiata ai registri e ai
parametri passati e prima o poi finirete qui (per una trattazione più chiara di questo
punto c'è il tut di AndreGeddon):
004758B3 mov eax,
[ebp+var_4] ;in eax finisce il Nick
004758B6 lea edx, [ebp+var_C]
004758B9 call sub_473B40 ;questa elabora il Seriale
In uscita avete il Serial elaborato e a questo punto avreste già finito...
Ora andiamo a vedere cosa contiene questa routine con IDA (non abbiamo ancora applicato
alcun signature)
Questo è solo un pezzo della routine che serve da esempio, di fianco alle call vi metto
(in verde) quello che sostituisce IDA quando usa le signature :
00473B40 sub_473B40 proc near ; CODE XREF:
sub_473CF4+B5p
00473B40 ; sub_4757D4+E5p
00473B40
00473B40 var_220 = dword ptr -220h
00473B40 var_21C = byte ptr -21Ch
00473B40 var_11C = byte ptr -11Ch
00473B40 var_1C = dword ptr -1Ch
00473B40 var_18 = dword ptr -18h
00473B40 var_14 = dword ptr -14h
00473B40 var_10 = dword ptr -10h
00473B40 var_C = dword ptr -0Ch
00473B40 var_8 = dword ptr -8
00473B40 var_4 = dword ptr -4
00473B40
00473B40 push ebp
00473B41 mov ebp, esp
00473B43 add esp, 0FFFFFDE0h
00473B49 push ebx
00473B4A push esi
00473B4B push edi
00473B4C xor ecx, ecx
00473B4E mov [ebp+var_220], ecx
00473B54 mov [ebp+var_10], ecx
00473B57 mov [ebp+var_14], ecx
00473B5A mov [ebp+var_8], edx
00473B5D mov [ebp+var_4], eax
00473B60 mov eax, [ebp+var_4]
00473B63 call sub_403CDC ; call @System@@LStrAddRef$qqrv ; System __linkproc__ LStrAddRef(void)
00473B68 xor eax, eax
00473B6A push ebp
00473B6B push offset loc_473CE6
00473B70 push dword ptr fs:[eax]
00473B73 mov fs:[eax], esp
00473B76 lea eax, [ebp+var_10]
00473B79 call sub_4038AC ; call @System@@LStrClr$qqrr17System@AnsiString ;
System __linkproc__
00473B7E jmp short loc_473B8B
LStrClr(System::AnsiString &)
00473B80 ; ---------------------------------------------------------------------------
00473B80
00473B80 loc_473B80: ; CODE XREF: sub_473B40+62j
00473B80 lea eax, [ebp+var_4]
00473B83 mov edx, [ebp+var_4]
00473B86 call sub_403B30 ; call @System@@LStrCat$qqrv ; System __linkproc__ LStrCat(void);
00473B8B
00473B8B loc_473B8B: ; CODE XREF: sub_473B40+3Ej
00473B8B mov eax, [ebp+var_4]
00473B8E call sub_403B28 ; questa la riconosce, è una lstrlen, ma non sostituisce il nome (???)
; comunque lstrlen è la prima
informazione che trovate quando ci entrate
; quindi sostituitevi voi il nome
00473B93 test eax, eax
00473B95 jle short loc_473BA4
00473B97 mov eax, [ebp+var_4]
00473B9A call sub_403B28 ;come due righe sopra
00473B9F cmp eax, 9
00473BA2 jl short loc_473B80
Morale della favola se prima avevate quattro routine da riconoscere ora le conoscete tutte
e quattro.
Bhe sembra assurdo ma dopo aver usato le signature delle venti circa routine
chiamate (senza le signature avreste dovuto guardare le sottoroutine e le sottoroutine
delle sottoroutine...!!!) 19 diventano esplicite e l'unica rimasta non riconosciuta se ci
entrate chiama un'unica sottoroutine riconosciuta e a questo punto mi è venuto da
ridere...Capirete vedendo il listato di tutta la routine di protezione esplicitata
E' giunto il momento di raccontarvi come si ottiene questo risultato. Io sono
partito dal fatto che IDA non avesse riconosciuto il compilatore del programma e ho
pensato di aiutarla utilizzando e il GetType per farmi un'idea di quale potesse essere.
L'utilizzo del GetType è banale e spero che lo conosciate (altrimenti è ora che
impariate a usare i tool a disposizione e leggervi i manuali); il GetType
si usa di solito per capire quale packer è stato usato su un programma ma vi dice tra le
altre cose quale compilatore è stato usato per compilare il programma stesso; vi riporto
la schermata del GetType (solo le righe interessanti ai nostri fini):
[C:\PROGRAMMI\CDEDIT\CDEdit.exe] -----
DOS executable file - 951808 bytes
Portable executable (starting at 256 for 951552 bytes)
Compiler: Borland Delphi 3/4 (heuristic)
;
mica male sta cosa!!!
Ora conosciamo il compilatore, andiamo ad applicare le signature relative ai compiltori di
tipo Delphi: dopo che IDA ha finito la sua analisi si scieglie dal menu File il Load file
e poi Flirt signature file che vi apre un menu dove potete sciegliere le signature che
volete applicare; in questo caso tutte quelle del Delphi che sono (vi riporto i codici
come sono nell'ultima versione di IDA):
BP32_2; C4VCL; D3VCL; D4VCL ;DELPHI;
Dopo che IDA ha filtarato il file attraverso queste signature (osservate mentre elabora
quante volte dice "delete unknown_libname_xxx" cioè sta riconoscendo e
sostituwendo le funzioni e le librerie) e andiamo a riprendere la routine di protezione
per intero per incominciare il nostro vero lavoro.
Vi riporto il codice commentato:
Si incomincia
0473B40 ; Attributes: library function bp-based frame
00473B40
00473B40 sub_473B40 proc near ; CODE XREF: sub_473CF4+B5p
00473B40 ; _TfrmRegister_btnRegistraClick+E5p <--- !!! NOTATE ANCHE QUESTA !!!
...
00473B40 push ebp
00473B41 mov ebp, esp
00473B43 add esp, 0FFFFFDE0h
00473B49 push ebx
00473B4A push esi
00473B4B push edi
00473B4C xor ecx, ecx
00473B4E mov [ebp+var_220], ecx
00473B54 mov [ebp+var_10], ecx
00473B57 mov [ebp+var_14], ecx
00473B5A mov [ebp+var_8], edx
00473B5D mov [ebp+var_4], eax
00473B60 mov eax, [ebp+var_4]
00473B63 call @System@@LStrAddRef$qqrv ; System __linkproc__ LStrAddRef(void)
00473B68 xor eax, eax
00473B6A push ebp
00473B6B push offset loc_473CE6
00473B70 push dword ptr fs:[eax]
00473B73 mov fs:[eax], esp
00473B76 lea eax, [ebp+var_10]
00473B79 call @System@@LStrClr$qqrr17System@AnsiString ; System __linkproc__
LStrClr(System::AnsiString &)
00473B7E jmp short loc_473B8B
; dovreste metterci poco a capire che si parte da questo salto
00473B80 ; ---------------------------------------------------------------------------
loc_473B80: ; CODE XREF: sub_473B40+62j
00473B80 lea eax, [ebp+var_4]
00473B83 mov edx, [ebp+var_4]
; la call successiva fa si che ebp-4 diventi nicknick
00473B86 call @System@@LStrCat$qqrv ; System __linkproc__ LStrCat(void) ;concatena due stringhe
loc_473B8B: ; CODE XREF: sub_473B40+3Ej
00473B8B mov eax, [ebp+var_4]
; mette in eax il nick
00473B8E call Lunghezza_stringa_in_eax ; il nome
l'ho messo io è la lstrlen
00473B93 test eax, eax
00473B95 jle short loc_473BA4
; salto se la stringa è nulla
00473B97 mov eax, [ebp+var_4]
; rimetto in eax il nick
00473B9A call Lunghezza_stringa_in_eax
00473B9F cmp eax, 9
; confronto la lunghezza del nick con nove
00473BA2 jl short loc_473B80
; salto se il nick è più corto di nove
loc_473BA4: ; CODE XREF: sub_473B40+55j
00473BA4 lea eax, [ebp+var_11C]
00473BAA mov edx, [ebp+var_4]
00473BAD call @StrPCopy
; ebp-11c conterrà il nick
00473BB2 mov eax, [ebp+var_4]
00473BB5 call Lunghezza_stringa_in_eax
00473BBA dec eax ; decresce la lunghezza di uno
00473BBB test eax, eax
00473BBD jl loc_473CAD ; salto quando a forza di togliere dalla stringa arriverò al terminatore
00473BC3 inc eax ; rimetto a posto
00473BC4 mov [ebp+var_18], eax
;
ebp-18 ha la lunghezza della stringa
00473BC7 mov [ebp+var_C], 0
; azzero ebp-c
00473BCE lea eax, [ebp+var_11C]
;
carico in eax il nuovo nick
00473BD4 mov [ebp+var_1C], eax
;
e lo metto in ebp-1c
loc_473BD7: ; CODE XREF: sub_473B40+167j
00473BD7 mov eax, [ebp+var_1C]
00473BDA xor ebx, ebx
; azzero ebx
00473BDC mov bl, [eax]
; metto in bl l'equivalente ASCII del char in esame
00473BDE mov eax, [ebp+var_4]
; metto in eax il nick
00473BE1 call Lunghezza_stringa_in_eax
00473BE6 sub eax, [ebp+var_C] ; sottraggo alla lunghezza del nick il
valore di ebp-c che al primo ciclo è zero
00473BE9 lea eax, [eax+eax*8]
; faccio questo conto eax diventa eax+8*eax
00473BEC mov ecx, 3
; metto in ecx 3
00473BF1 cdq ; trasformo
eax in edx : eax cioè se eax=xxxxxxxx diventa edx=00000000 : eax=xxxxxxxx
00473BF2 idiv ecx
; divido eax per ecx con quoziente in eax e resto in edx
00473BF4 add ebx, eax
; aggiungo il quoziente al valore ASCII del char in esame
00473BF6 cmp ebx, 9
00473BF9 jle loc_473C82
; salto se il valore è minore di nove
00473BFF lea edx, [ebp+var_14]
00473C02 mov eax, ebx
00473C04 call @IntToStr
; il valore di eax "come intero" finisce in ebp-14
00473C09 jmp short loc_473C82
; muovo in eax la locazione dove ho messo il valore intero
00473C0B ; ---------------------------------------------------------------------------
loc_473C0B: ; CODE XREF: sub_473B40+14Dj
00473C0B xor edi, edi
; inizializzo edi
00473C0D lea eax, [ebp+var_21C]
00473C13 mov edx, [ebp+var_14]
00473C16 call @StrPCopy
; copio la stringa numerica in ebp-21c
00473C1B xor edx, edx
00473C1D push ebp
00473C1E push offset loc_473C71
00473C23 push dword ptr fs:[edx]
00473C26 mov fs:[edx], esp
00473C29 mov eax, [ebp+var_14]
00473C2C call Lunghezza_stringa_in_eax ; calcola
la lunghezza dellla stringa numerica
00473C31 mov esi, eax
; mette la lunghezza in eax
00473C33 dec esi
00473C34 test esi, esi
00473C36 jl short loc_473C5D
; non salto quando ho finito di lavorare sulla stringa
00473C38 inc esi
00473C39 lea ebx, [ebp+var_21C]
;
carico in ebx la stringa
loc_473C3F: ; CODE XREF: sub_473B40+11Bj
00473C3F lea eax, [ebp+var_220]
00473C45 mov dl, [ebx]
; in dl finisce l'equivalente ASCII del primo numero in esame
00473C47 call Ci_interessa_ebp_220
00473C4C mov eax, [ebp+var_220]
; il
primo byte puntato da eax è l'ASCII del numero in esame
00473C52 call @StrToInt
; se in eax avevo 31 come primo byte ora ho 1 se 32 ora 2
00473C57 add edi, eax
; aggiungo ad eax
00473C59 inc ebx
; incremento ebx
00473C5A dec esi ; decresco esi
00473C5B jnz short loc_473C3F ; ricomincio la trafila col successivo numero della stringa numerica
; alla fine in edi mi ritrovo la somma dei valori che componevano la
stringa originale
; cioè se avevo 123 come originale ora ho in edi 1+2+3=6
loc_473C5D: ; CODE XREF: sub_473B40+F6j
00473C5D lea edx, [ebp+var_14]
00473C60 mov eax, edi
00473C62 call @IntToStr
; in ebp-14 finisce il valore elaborato
00473C67 xor eax, eax
00473C69 pop edx
00473C6A pop ecx
00473C6B pop ecx
00473C6C mov fs:[eax], edx
00473C6F jmp short loc_473C82
; muovo in eax la locazione dove ho messo il valore intero
00473C71 ; ---------------------------------------------------------------------------
loc_473C71: ; DATA XREF: sub_473B40+DEo
00473C71 jmp @@HandleAnyException ; __linkproc__ HandleAnyException
00473C76 ; ---------------------------------------------------------------------------
00473C76 call @@DoneExcept ; @System@@DoneExcept$qqrv
00473C7B jmp short loc_473CB8
00473C7D ; ---------------------------------------------------------------------------
00473C7D call @@DoneExcept ; @System@@DoneExcept$qqrv
loc_473C82: ; CODE XREF: sub_473B40+B9j
00473C82 ; sub_473B40+C9j ...
00473C82 mov eax, [ebp+var_14]
;
muovo in eax la locazione dove ho messo il valore intero
00473C85 call @StrToInt
; la stringa che contiene i numeri è trasformata in un intero
00473C8A cmp eax, 9
00473C8D jg loc_473C0B
; salto se il numero ottenuto è maggiore di nove
00473C93 lea eax, [ebp+var_10]
00473C96 mov edx, [ebp+var_14]
;
mi preparo ad appendere i numeri del seriale in ebp-10
00473C99 call @System@@LStrCat$qqrv ; System __linkproc__ LStrCat(void)
00473C9E inc [ebp+var_C]
; incremento ebp-c
00473CA1 inc [ebp+var_1C]
; incremento ebp-1c
00473CA4 dec [ebp+var_18]
; decresco ebp-18 diminuisco il valore della lunghezza del nick
; mi preparo a ricominciare col carattere del nick successivo
00473CA7 jnz loc_473BD7
IL RESTO DELLA ROUTINE SERVE SOLO A METTERE A POSTO IL CASINO FATTO
MA NON FA ULTERIORI ELABORAZIONI
loc_473CAD: ; CODE XREF: sub_473B40+7Dj
00473CAD mov eax, [ebp+var_8]
00473CB0 mov edx, [ebp+var_10]
00473CB3 call @System@@LStrLAsg$qqrv ; System __linkproc__ LStrLAsg(void)
loc_473CB8: ; CODE XREF: sub_473B40+13Bj
00473CB8 xor eax, eax
00473CBA pop edx
00473CBB pop ecx
00473CBC pop ecx
00473CBD mov fs:[eax], edx
00473CC0 push offset loc_473CED
loc_473CC5: ; CODE XREF: CODE:00473CEBj
00473CC5 lea eax, [ebp+var_220]
00473CCB call @System@@LStrClr$qqrr17System@AnsiString ; System __linkproc__
LStrClr(System::AnsiString &)
00473CD0 lea eax, [ebp+var_14]
00473CD3 mov edx, 2
00473CD8 call @System@@LStrArrayClr$qqrv ; System __linkproc__ LStrArrayClr(void)
00473CDD lea eax, [ebp+var_4]
00473CE0 call @System@@LStrClr$qqrr17System@AnsiString ; System __linkproc__
LStrClr(System::AnsiString &)
00473CE5 retn
00473CE5 sub_473B40 endp ; sp = -234h
Il codice è tutto svelato e non dobbiamo nemmeno steppare dentro le routine ma vale la
pena di far un riassuntino sullo schema di protezione:
il programma calcola la lunghezza del nick e se è più piccola di nove la trasforma in
una del tipo nicknick, per chiarire vediamo tre esempi:
GuZuRa diventa GuZuRaGuZuRa
AndreaGeddon resta uguale (scusa Andre se prendo in prestito il tuo nome ;)))))
Figa diventa FigaFigaFiga (ripeto finchè non raggiungo 9 o più char)
Il secondo passo è quello di prendere la lunchezza del nick, sottrarre un valore che al
primo ciclo è zero e poi viene incrementato di uno ,carattere per carattere, poi si
prende la lunghezza (meno il valore sottratto) e la si moltiplica per 9 , si divide il
risultato per 3 e il quoziente si aggiunge all'equivalente ASCCI del char in esame, questo
valor è convertito in intero supponiamo diventi 85 allo si fà 8+5=13 na 13 è maggiore
di 9 quindi si fà ancora 1+3=4 che sarà uno dei numeri che compone il seriale.
Per spiegarmi meglio vi faccio vedere come viene elaborato il mio nick
GuZuRa (è meno di 9 caratteri) diventa GuZuRaGuZuRa, e la lunghezza è 12
Al primo ciclo lunghezza-0 quindi 12-0=0 poi si fà 12*9=108 ora divido per 3 e ottengo 36
che va sommato al valore del char "G" che è 71 quindi in totale 71+36= 107 ora
faccio 1+0+7=8 che sarà il primo numero del seriale
Al secondo ciclo ho lunghezza-1 quindi 12-1=11 poi 11*9=99 diviso 3 e ottengo 33 a cui
sommo 117 per la "u" e ottengo 150 da cui il secondo numero del seriale che è 6
Al terzo ciclo partirò da lunghezza-3 e così via per tutti i caratteri i conti
sono fatti in decimale ma ovviamente in fase di debug troverete i relativi hex)
Questo dovrebbe aver chiarito la generazione del seriale quindi vi propongo il mio Keygen
che ho scritto in C e ASM mischiando il codice
Il keygen va bene solo per i nick lunghi da 5 a 20 char (non è perfetto ma ho avuto poco
tempo) ed è compilato con il compilatore del Visual C++ ma penso che sia facilmente
adattabile, in azzuro c'è la parte scritta in ASM dategli un'occhiata perchè è
carino...
#include<stdio.h>
#include<ctype.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
//********************
int calcola(char Nickchar,int lunghezza)
{
static int c=0;int i;
__asm
{
xor ebx,ebx;
mov bl,Nickchar;
mov eax,lunghezza;
sub eax,c;
lea eax,[eax+eax*8];
mov ecx,3;
cdq;
idiv ecx;
add ebx,eax;
mov i,ebx;
};
c++;
return i;
};
//********************
int calcolaTOT(int var)
{
int val;
div_t unico;
unico=div(var,10);
val=unico.rem;
var=var-unico.rem;
var=var/10;
if (var==0) return val;
else
{
val=val+calcolaTOT(var);
return val;
}
};
//*********************
main()
{
unsigned int lunghezza,c=0,var,val,i;
char *Nick,*NickNick;
Nick=malloc(21*sizeof(char));
NickNick=malloc(21*sizeof(char));
printf("KEYGEN\n");
printf("Vale per nick lunghi da 5 a 20 char\n");
printf("Dammi il nick :");
gets(Nick);
strcpy(NickNick,Nick);
printf("\n");
lunghezza=strlen(Nick);
if (lunghezza<9)
{
strcat(NickNick,Nick);
lunghezza=strlen(NickNick);
}
printf("Password :");
for (i=0;i<=lunghezza-1;i++)
{
var=calcola(NickNick[i],lunghezza);
val=calcolaTOT(var);
while (val>9) val=calcolaTOT(val);
printf("%u",val);
}
printf("\n");
printf("Premi un tasto per finire");
while (!_kbhit());
}
//*********************
Non abbiamo ancora finito perchè vi voglio far vedere un'altro metodo di attacco
dell'algoritmo che vi farà capire che la strada più ovvia a volte non è la più breve
Iniziamo a notare alcune cose dell'algorimo: primo e più importe è il fatto che il
seriale non è rielaborato nel suo complesso alla fine ma ogni numero generato è a se
stante ed e ricostruibile; il valore dei char del nick vengono utilizzati solo una volta
in una somma, e soprattutto il seriale si costruisce per il 90%
lavorando sulla lunghezza del nick e non sul nick stesso ma
l'importanza di questo la capirermo tra breve
Dimentichiamoci del nick e consideriamo una password lunga dieci o più valori (per aver
le cose facilitate... stiamo cercando la strada più breve) e freghiamocene anche del
valore della password
Supponiamo sia lunga dieci; il primo valore come è generato?? Chiamiamolo X per comodità
(che fantasia...) avremo:
Primo ciclo lunghezza=10 tolgo 0 moltiplico per 9 ottengo 90 divido per 3 ottengo 30 a
questo sommo l'equivalente di un ASCII e ottengo un intero di cui sommo le cifre e ottengo
X
Tutto sta a prendere un carattere a piacere,quello che volete, sommargli 30 calcolare la somma dei numeri che lo compongono e avete X
Secondo ciclo lunghezza=10 tolgo 1 moltiplicoper 9 divido per 3 e ottengo 27 e poi la solita trafila...
Terzo ciclo lunghezza=10 tolgo 2 poi per 9 diviso 3 e ho 24
sommo il valore del carattere e come prima...
Capito il giochetto...
Questo è lo schema per una password lunga 10
1° 2° 3°
4° 5° 6° 7°
8° 9° 10°
NUMERI
30 27 24 21
18 15 12 9
6 3
Valore da sommare al char
C H E
C A Z
Z A T
A
Ho scelto il seguente
nick
67 72 69 67
65 90 90 65
84 65
Equivalenti decimali dei char del
nick
97 99 93 88
83 105 102 74
90 68
Somma equivalenti più elaborazione
lunghezza
9+7 9+9 9+3 8+8
8+3 1+0+5 1+0+1 7+4 9+0 6+8
9+7=16 poi 1+6=7 valore finale
7 9 3
7 2 6
3 2 9
5
Password
Una cosa per concludere: potreste definire la password numerica e poi risalire al nick
facilmente per esempio volete che la password sia 9999999999 cioè dieci 9 allora vi serve
per il primo numero un char che sommato a 30 dia per esempio 117 0 108 (dato che
8+1=9) quindi andiamo a cercare nella tabella ASCII il char che ha equivalente
"decimale" 87 che è la W (se avessimo voluto utilizzare il 108 avremmo scelto
la N maiuscola che ha equivalente "decimale" 78), se avete capito per il secondo
carattere cerchiamo per esempio il char che corrisponde a 63 (63+27=90 ovvio) che è il
punto di domanda oppure il 81 (81+27=108) che è la Q, poi per il terzo sara 63+3=66 che
è la B maiuscola, per il quarto il 69 che è la E maiuscola e così via
Per la password 9999999999 useremo il nick W?BEHKNQTW oppure il nick NQBEHKNQTW ed è qui
che si vede ancora la debolezza dell'algoritmo perchè per una password possono andare
bene più nick (va bene anche <?BEHKNQTW dato che il < ha equivalente 60 e quindi
60+30=90) ...
Ultimissima se la password è lunga 11 con il primo carattere partirete da 33 col secondo
da 30...(PENSATECI)
Con questo vi saluto
Ciauz GuZuRa
|
Una riga per salutare Quequero per tutto quello che fà per insegnarci qualcosa e perchè ha introdotta una pagina XXX di cui non posso più fare a meno.
Saluto tutti quelli con cui ho avuto il piacere di parlare su #crack-it e in ML così spero di non scordare nessuno, sto imparando tantissimo da voi grazie.
Disclaimer |
| UIC's page of reverse engineering, scegli dove andare: |
| Home Anonimato Assembly ContactMe CrackMe Forum Iscrizione |
| Lezioni Links Linux NewBies News Playstation |
| Search Tools Tutorial UIC Faq XXX Page |
| UIC |