Cel   : Access Lock v1.3
URL   : http://www.softheap.com/lock.html
Toolz : Si,IDA,HIEW i sysko co potrzebne ;)

Hi, ww. program sluzy do zabezpieczenia miejsca pracy w czasie
naszej nieobecnosci, tzn. po zablokowaniu stacji, zeby ponownie
moc zaczac cos robic na kompie, trzeba wpisac haslo.

Lecimy, prog bierze name, oblicza sume bajtow xoruje ja z 44 i
to jest serial a teraz pokaze wam gdzie to sie wszystko odbywa...
nie hehe, tym razem to nie ta bajka, chociaz z poczatku moze
nawet ja przypominac, ale pamietajcie pozory myla(a makijaz
jeszcze bardziej :)

Po uruchomieniu programu witani jestesmy pieknym nagscreenem
z editem umozliwiajacym wpisanie poprawnego seriala, prog
jest skomplikowany w delphi wiec wiadomo co robic, bpx hmemcpy
i sledzimy az do momentu(bpm na dane):


04775D9  lea     eax, [ebp+var_C]
04775DC  mov     edx, [ebp+var_4]      <-- wskaznik na serial
04775DF  mov     dl, [edx]             <-- 1 bajt seriala
04775E1  call    unknown_libname_12
04775E6  mov     eax, [ebp+var_C]
04775E9  call    sub_4086E0
04775EE  mov     ebx, eax              <-- ustaw ebx na wartosc int
                                           1 bajta seriala
                                           (np. '3' -> 0x03)
04775F0  lea     eax, [ebp+var_10]
04775F3  mov     edx, [ebp+var_4]
04775F6  mov     dl, [edx+1]           <-- do dl 2 bajt seriala
04775F9  call    unknown_libname_12
04775FE  mov     eax, [ebp+var_10]
0477601  call    sub_4086E0
0477606  add     ebx, eax              <-- dodaje do ebx bajt zamieniony
                                           na inta
0477608  lea     eax, [ebp+var_14]
047760B  mov     edx, [ebp+var_4]
047760E  mov     dl, [edx+2]           <-- 3 bajt seriala
0477611  call    unknown_libname_12
0477616  mov     eax, [ebp+var_14]
0477619  call    sub_4086E0
047761E  add     ebx, eax              <-- dodaj do sumy(int)
0477620  lea     eax, [ebp+var_18]
0477623  mov     edx, [ebp+var_4]
0477626  mov     dl, [edx+3]           <-- 4 bajt seriala
0477629  call    unknown_libname_12
047762E  mov     eax, [ebp+var_18]
0477631  call    sub_4086E0
0477636  add     ebx, eax              <-- dodaj do sumy jak wyzej
0477638  mov     eax, ds:off_486218    <-- wskaznik na magiczna wartosc
047763D  cmp     ebx, [eax]            <-- sprawdz
047763F  jnz     loc_477717            <-- jesli rozne skok do bad boy

0477645  lea     eax, [ebp+var_1C]
0477648  mov     edx, [ebp+var_4]
047764B  mov     dl, [edx+4]           <-- 5 bajt seriala
047764E  call    unknown_libname_12
0477653  mov     eax, [ebp+var_1C]
0477656  call    sub_4086E0
047765B  mov     ebx, eax              <-- zaladuj go do ebx jako int
047765D  lea     eax, [ebp+var_20]
0477660  mov     edx, [ebp+var_4]
0477663  mov     dl, [edx+7]           <-- 8 bajt seriala
0477666  call    unknown_libname_12
047766B  mov     eax, [ebp+var_20]
047766E  call    sub_4086E0
0477673  add     ebx, eax              <-- dodaj do ebx jako int
0477675  lea     eax, [ebp+var_24]
0477678  mov     edx, [ebp+var_4]
047767B  mov     dl, [edx+10]          <-- 11 bajt
047767E  call    unknown_libname_12
0477683  mov     eax, [ebp+var_24]
0477686  call    sub_4086E0
047768B  add     ebx, eax              <-- dodaj do ebx jako int
047768D  lea     eax, [ebp+var_28]
0477690  mov     edx, [ebp+var_4]
0477693  mov     dl, [edx+13]          <-- 14 bajt
0477696  call    unknown_libname_12
047769B  mov     eax, [ebp+var_28]
047769E  call    sub_4086E0
04776A3  add     ebx, eax              <-- jak wyzej dodaj do sumy
04776A5  mov     eax, ds:off_48624C    <-- sprawdz kolejna wartosc
04776AA  cmp     ebx, [eax]            <-- jesli rozne bad boy
04776AC  jnz     short loc_477717
04776AE  lea     eax, [ebp+var_2C]
04776B1  mov     edx, [ebp+var_4]
04776B4  mov     dl, [edx+6]           <-- nastepna seria, 7 bajt
04776B7  call    unknown_libname_12
04776BC  mov     eax, [ebp+var_2C]
04776BF  call    sub_4086E0
04776C4  mov     ebx, eax              <-- ustaw w ebx jako int
04776C6  lea     eax, [ebp+var_30]
04776C9  mov     edx, [ebp+var_4]
04776CC  mov     dl, [edx+9]           <-- 10 bajt
04776CF  call    unknown_libname_12
04776D4  mov     eax, [ebp+var_30]
04776D7  call    sub_4086E0
04776DC  add     ebx, eax              <-- suma
04776DE  lea     eax, [ebp+var_34]
04776E1  mov     edx, [ebp+var_4]
04776E4  mov     dl, [edx+0Ch]         <-- 13 bajt
04776E7  call    unknown_libname_12
04776EC  mov     eax, [ebp+var_34]
04776EF  call    sub_4086E0
04776F4  add     ebx, eax              <-- sumuj w ebx
04776F6  lea     eax, [ebp+var_38]
04776F9  mov     edx, [ebp+var_4]
04776FC  mov     dl, [edx+0Fh]         <-- 16 bajt
04776FF  call    unknown_libname_12
0477704  mov     eax, [ebp+var_38]
0477707  call    sub_4086E0
047770C  add     ebx, eax              <-- sumuj i sprawdz
047770E  mov     eax, ds:off_485FC4    <-- porownaj wynik z
0477713  cmp     ebx, [eax]            <-- magiczna wartoscia
0477715  jz      short loc_47771B

Magiczne wartosci:

0485E4C magic1   dd 23                 ; DATA XREF: sub_477250+80r
0485E4C                                ; DATA:00486218o
0485E50 magic2   dd 30                 ; DATA XREF: sub_477250+ECr
0485E50                                ; DATA:0048624Co
0485E54 magic3   dd 9                  ; DATA XREF: sub_477250+1C0r
0485E54                                ; DATA:00485FC4o

Ok program sumuje nastepujace bajty oczekujac wynikow:

serial[0]+serial[1]+serial[2]+serial[3]   == magic1
serial[4]+serial[7]+serial[10]+serial[13] == magic2
serial[6]+serial[9]+serial[12]+serial[15] == magic3

nalezy zwrocic uwage, ze w tym przykladzie kolejne bajty
seriala sa to inty a nie wartosci hex kolejnych bajtow jakie
wpisalismy do edita(wystarczy odjac 0x30 od liczby w formacie
ascii-dec zeby otrzymac inta), w sumie wyglada to banalnie,
aha zapomnialem dodac, ze program wymaga aby serial byl 16
znakowy, wiec potencjalna forma seriala moglaby wygladac tak:

XXXXz_Yz_Yz_Yz_Y
0123456789ABCDEF

gdzie X to bajty 1 potrzebne do wygenerowania magic1, z do
generacji magic2, Y do generacji magic3.Wszystko byloby
pieknie gdyby nie to, ze 3 bajty sa niewykorzystane, co czesto
swiadczy o tym, ze w programie jest gdzies ukryty hidden
check.Przegladajac dane w poblizu wartosci magicX, zaraz za
magic3 znajduje sie 4 bajt:

0485E58 magic_hidden  dd 10            ; DATA XREF: sub_477250+158r
0485E58                                ; sub_47BDD4+7Br

zagladajac w referencje mozna dostrzec, ze jest on wykorzystywany
w calkiem podobnej procedurze jak ta wyzej wylistowana:

0477277  mov     dl, [edx]             <-- jak procka na poczatku
0477279  call    unknown_libname_12    <-- tuta
047727E  mov     eax, [ebp+var_C]
0477281  call    sub_4086E0
0477286  mov     ebx, eax
0477288  lea     eax, [ebp+var_10]
047728B  mov     edx, [ebp+var_4]
047728E  mov     dl, [edx+1]
0477291  call    unknown_libname_12
0477296  mov     eax, [ebp+var_10]
0477299  call    sub_4086E0
047729E  add     ebx, eax
04772A0  lea     eax, [ebp+var_14]
04772A3  mov     edx, [ebp+var_4]
04772A6  mov     dl, [edx+2]
04772A9  call    unknown_libname_12
04772AE  mov     eax, [ebp+var_14]
04772B1  call    sub_4086E0
04772B6  add     ebx, eax
04772B8  lea     eax, [ebp+var_18]
04772BB  mov     edx, [ebp+var_4]
04772BE  mov     dl, [edx+3]
04772C1  call    unknown_libname_12
04772C6  mov     eax, [ebp+var_18]
04772C9  call    sub_4086E0
04772CE  add     ebx, eax
04772D0  cmp     ebx, ds:magic1        <-- sprawdz czy suma rowna
                                       <-- sie magicznej wartosci nr 1
04772D6  jnz     bad_boy

04772DC  lea     eax, [ebp+var_1C]
04772DF  mov     edx, [ebp+var_4]
04772E2  mov     dl, [edx+4]
04772E5  call    unknown_libname_12
04772EA  mov     eax, [ebp+var_1C]
04772ED  call    sub_4086E0
04772F2  mov     ebx, eax
04772F4  lea     eax, [ebp+var_20]
04772F7  mov     edx, [ebp+var_4]
04772FA  mov     dl, [edx+7]
04772FD  call    unknown_libname_12
0477302  mov     eax, [ebp+var_20]
0477305  call    sub_4086E0
047730A  add     ebx, eax
047730C  lea     eax, [ebp+var_24]
047730F  mov     edx, [ebp+var_4]
0477312  mov     dl, [edx+10]
0477315  call    unknown_libname_12
047731A  mov     eax, [ebp+var_24]
047731D  call    sub_4086E0
0477322  add     ebx, eax
0477324  lea     eax, [ebp+var_28]
0477327  mov     edx, [ebp+var_4]
047732A  mov     dl, [edx+13]
047732D  call    unknown_libname_12
0477332  mov     eax, [ebp+var_28]
0477335  call    sub_4086E0
047733A  add     ebx, eax
047733C  cmp     ebx, ds:magic2        <-- suma bajtow porownywana
                                       <-- z magic2 
0477342  jnz     bad_boy

0477348  lea     eax, [ebp+var_2C]     <-- tu sie zaczyna niespodzianka
047734B  mov     edx, [ebp+var_4]      <-- pobierane sa bajty, ktore nie
047734E  mov     dl, [edx+5]           <-- byly wczesniej sprawdzane po
0477351  call    unknown_libname_12    <-- wpisaniu seriala i kliknieciu
                                       <-- register
0477356  mov     eax, [ebp+var_2C]
0477359  call    sub_4086E0
047735E  mov     ebx, eax              <-- jako int zapisz 6 bajt do ebx
0477360  lea     eax, [ebp+var_30]
0477363  mov     edx, [ebp+var_4]
0477366  mov     dl, [edx+8]           <-- 9 bajt
0477369  call    unknown_libname_12
047736E  mov     eax, [ebp+var_30]
0477371  call    sub_4086E0
0477376  add     ebx, eax              <-- dodaj do ebx jako int
0477378  lea     eax, [ebp+var_34]
047737B  mov     edx, [ebp+var_4]
047737E  mov     dl, [edx+10]          <-- 11 bajt seriala
0477381  call    unknown_libname_12
0477386  mov     eax, [ebp+var_34]
0477389  call    sub_4086E0
047738E  add     ebx, eax              <-- dodaj do sumy
0477390  lea     eax, [ebp+var_38]
0477393  mov     edx, [ebp+var_4]
0477396  mov     dl, [edx+14]          <-- 15 bajt seriala
0477399  call    unknown_libname_12
047739E  mov     eax, [ebp+var_38]
04773A1  call    sub_4086E0
04773A6  sub     ebx, eax              <-- odejmij od sumy
04773A8  cmp     ebx, ds:magic_hidden  <-- sprawdz czy wynik
                                       <-- rowny bajtowi magic_hidden
04773AE  jnz     short bad_boy         <-- jesli nie wyjscie

...
04773FE  mov     dl, [edx+15]
0477401  call    unknown_libname_12
0477406  mov     eax, [ebp+var_48]
0477409  call    sub_4086E0
047740E  add     ebx, eax              <-- sprawdzanie magic 3
0477410  cmp     ebx, ds:magic3        <-- ale wykorzystane bajty sa
0477416  jz      short loc_47741C      <-- takie same jak w 1 procedurze

Zagladajac na poczatek tej procki mozemy zobaczyc z jakiego
miejsca jest ona wywolywana, stawiajac bpx-a na jej wejsciu
softice zatrzymuje program po wpisaniu hasla jakie jest
potrzebne do konfiguracji Access Locka, w sumie wystrczy troche
poexperymentowac zeby znalezc taki punkt zapalny.Patrzac
trzezwo, potencjalny serial musi teraz wygladac tak:

XXXXzwYzwYz_YzwY
0123456789ABCDEF

gdzie:

serial[0]+serial[1]+serial[2]+serial[3]   == magic1
serial[4]+serial[7]+serial[10]+serial[13] == magic2
serial[6]+serial[9]+serial[12]+serial[15] == magic3

serial[5]+serial[8]+serial[10]-serial[14] == magic_hidden

no to juz lepiej, bo im mniej jest bajtow, ktore nie sa
wykorzystywane tym mniejsze prawpopodobienstwo, ze moga
byc uzyte w jakichs hidden checkach, heh ale zostal ten
cholerny bajt o indexie 11 w serialu, mozna olac sprawe i
napisac keygena, ktory bedzie generowal "poprawne" seriale,
tak jak ja to zrobilem, tylko, ze ten 12 bajt seriala
nie dal mi spac i nastepnego dnia zaczalem szukac innych
checkow, przestawilem date do przodu na 3 miechy,
uruchamiam proga i nic, w about nadal "Thank U Very Much bleble"
przypadkowo przegladajac dane w poblizu wartosci magicX
natknalem sie na tablice wskaznikow do dziwnych stringow,
pod latarnia najciemniej jak mawia znajoma dziwka ;), no
ciemno bo referencje doprowadzily do procki, ktora nie jest
bezposrednio wywolywana z kodu, tylko jej adres znajdowal sie
w jakiejs tablicy bez zadnych referencji(kocham delphi i kfiatki),
no ok mowie sobie, juz chcialem odpuscic, az nagle po
kilkudziesieciu page up(jakze profesjonalne podejscie do
tematu ;) znalazlem calkiem ciekawy fragment:

047C430 sub_47C430      proc near      ; CODE XREF: sub_481610+2Bp
047C430 
047C430 var_C           = qword ptr -0Ch
047C430 var_4           = dword ptr -4
047C430 
047C430  push    ebp
047C431  mov     ebp, esp
047C433  add     esp, 0FFFFFFF4h
047C436  push    ebx
047C437  xor     eax, eax
047C439  mov     [ebp+var_4], eax
047C43C  xor     eax, eax
047C43E  push    ebp
047C43F  push    offset loc_47C4E3
047C444  push    dword ptr fs:[eax]
047C447  mov     fs:[eax], esp
047C44A  mov     eax, 14h
047C44F  call    sub_402B60            <-- random % 14h
047C454  cmp     eax, 7                <-- sprawdz czy wynik
047C457  jnz     short loc_47C4CD      <-- rowny 7, jesli nie wyjscie

047C459  call    @Date                 <-- aktualna data
047C45E  fstp    [ebp+var_C]
047C461  wait
047C462  call    sub_47C0C0
047C467  fsubr   [ebp+var_C]
047C46A  mov     eax, ds:off_48624C
047C46F  fild    dword ptr [eax]
047C471  fcompp  st(1), st             <-- ilosc dni dzialania proga
                                       <-- do 30
047C473  fnstsw  ax                    <-- stan flag kooprocesora do ax
047C475  sahf                          <-- z ah do rejestru flag procka
047C476  jnb     short loc_47C4CD      <-- jesli prog chodzi mniej
                                       <-- niz 30 dni wyjdz z procki
047C478  lea     eax, [ebp+var_4]
047C47B  call    sub_47C2CC
047C480  mov     eax, [ebp+var_4]      <-- niespodzianka(ktora to juz?)
047C483  call    get_strlen            <-- dlugosc seriala
047C488  test    eax, eax
047C48A  jle     short loc_47C4CD
047C48C  mov     eax, [ebp+var_4]      <-- serial
047C48F  call    sub_47BDD4            <-- eureka!!!
047C494  test    al, al                <-- jesli ta procka zwroci 1
047C496  jnz     short loc_47C4CD      <-- tzn, ze serial jest ok
047C498  mov     eax, [ebp+var_4]      <-- jesli 0 to dzieja sie
047C49B  call    get_strlen            <-- ciekawe rzeczy
047C4A0  call    sub_402B60
047C4A5  mov     ebx, eax
047C4A7  inc     ebx
047C4A8  lea     eax, [ebp+var_4]
047C4AB  call    sub_403FB0
047C4B0  lea     eax, [eax+ebx-1]
047C4B4  push    eax
047C4B5  mov     eax, 5Ah
047C4BA  call    sub_402B60            <-- random
047C4BF  add     eax, 31h
047C4C2  pop     edx
047C4C3  mov     [edx], al             <-- uszkodzenie seriala
047C4C5  mov     eax, [ebp+var_4]      <-- zapisanie do go pliku
047C4C8  call    sub_47C21C            <-- konfiguracyjnego

Zapuscilem sobie proga spod si loadera zakladajac jednoczesnie
breakpointa na wejscie tej procki i nic, mysle dupa, wzialem
zamknalem okno glowne Access Locka i wow jestem w si na poczatku
procki, o co teraz w tym wszystkim biega, ano program generuje
sobie losowa liczbe od 0 do 14h-1 i sprawdza czy jest to 7ka, jesli
nie jest, nic sie nie dzieje, mamy nadal zarejestrowany program,
jesli jest to 7ka i dodatkowo minelo juz 30 dni odkad nasz pieknie
"zarejestrowany" prog smiga, wywolywana jest jeszcze jedna ukryta
procka i jesli ta tajemnicza pani zwroci 1 to ok, program jest
nadal zarejestrowany, ale jesli zwroci 0 to oryginalny serial,
wprowadzony i przyjety po pierwszych checkach, zostaje uszkodzony
i ponownie zapisany do pliku konfiguracyjnego(dodatkowo zaszyfrowany),
ale uszkodzenie jest tak wrednie zrobione zeby po ponownym
uruchomieniu proga, serial nie przeszedl pierwszych checkow co
jednoczesnie powoduje, ze znowu ukazuje sie nag-screen.Warto wiec
zajrzec do tej procki, ktora widac, odgrywa decydujaca role w
sprawdzaniu poprawnosci seriala, a wiec g 47BDD4 i podroz:

047BDFE  mov     [ebp+var_5], 0
047BE02  lea     edx, [ebp+var_10]
047BE05  mov     eax, offset modulus_n ; "16300E3FD1D20B...
047BE0A  call    convert_base          <-- zamienia na hex bajty
                                           stringa("CD"-> 0xCD)
047BE0F  mov     eax, [ebp+var_10]
047BE12  push    eax
047BE13  lea     edx, [ebp+var_14]
047BE16  mov     eax, offset exponent ; "010001"
047BE1B  call    convert_base
047BE20  mov     edx, [ebp+var_14]
047BE23  lea     eax, [ebp+var_4]
047BE26  pop     ecx
047BE27  call    sub_47AFB4
047BE2C  lea     edx, [ebp+var_18]
047BE2F  mov     eax, [ebp+var_4]
047BE32  call    sub_4550AC
047BE37  mov     edx, [ebp+var_18]
047BE3A  lea     eax, [ebp+var_4]
047BE3D  call    sub_403BF8
047BE42  mov     [ebp+var_C], 1
047BE49 
047BE49 loc_47BE49:                    ; CODE XREF: sub_47BDD4+96j
047BE49  mov     eax, [ebp+var_4]      <-- nasz zaszyfrowany serial
047BE4C  mov     edx, [ebp+var_C]      <-- kolejne zaszyfrowane,
                                           poprawne seriale

047BE4F  mov     edx, ds:magic_hidden[edx*4]
047BE56  call    sub_403EF0            <-- string compare
047BE5B  jnz     short loc_47BE63
047BE5D  mov     [ebp+var_5], 1
047BE61  jmp     short loc_47BE6C
047BE63 
047BE63 loc_47BE63:                    ; CODE XREF: sub_47BDD4+87j
047BE63  inc     [ebp+var_C]
047BE66  cmp     [ebp+var_C], 24h
047BE6A  jnz     short loc_47BE49

Ok juz nieco pozmienialem nazwy procek, wiec tak, widac,
ze procka cos miesza z tym dupnym stringiem i jakas dziwna
wartoscia '10001', wow potem widac, ze brany jest nasz serial
cos sie z nim dzieje(troche dlugo) i w petli jakies dlugawe
stringi sa porownywane z innymi(akurat to te, o ktorych
wspominalem, ze tablica z ich wskaznikami znajduje sie pod
bajtem hidden_check), ale to zamotasuplane, ale moment ta
liczba 010001 skad ja to znam, chwila medytacji i mantrowania
...mmmm...tak pamietam(ave ci dalej-lama), bylo o tym
pisane na http://zencrack2.cjb.net w tutorialach o szyfrowaniu
RSA, czyzby wiec spotkal mnie ten zaszczyt ;), szyfrowanie
RSA wykorzystuje bardzo duze liczby wiec wszystko by sie
zgadzalo, po przeczytaniu paru tutkow mozna przypuszczac ;),
ze te "10001" to publiczny exponent a ta dupna liczba:

CODE:0047BEA8 modulus_n db '16300E3FD1D20B5D1AA942875657D514FB061437F8ECCF66C123CB20FF31'
                        db 'E642FBC6F9',0

to publiczny modul N, iloczyn liczb pierwszych P i Q.
Dobra troche teori bo sie za bardzo zagalopowalem,
szyfrowanie RSA wykorzystuje system kluczy publicznych
tzn., ze mozna cos zaszyfrowac kluczem, ktory moze byc
opublikowany(publiczny), ale odszyfrowac dane zaszyfrowane
kluczem publicznym, mozemy tylko, uzywajac klucza prywatnego.
Generacja klucza publicznego nazywanego N odbywa sie
poprzez przemnozenie 2 liczb pierwszych P i Q:

N = P * Q

nalezy tutaj powiedziec, ze P i Q nie moga sie miedzy soba
bardzo roznic jesli chodzi o rozmiar, do szyfrowania
oprocz klucza publicznego, ktorym jest N, potrzebny jest
takze exponent E, ktory musi spelniac warunek:

GCD(E, (P-1)*(Q-1))==1)

gdzie GCD to najwiekszy wspolny dzielnik, ok majac te
2 liczby mozna przystapic do szyfrowania, ktore odbywa
sie wg. wzoru:

C = M^E mod N   

^   - oznacza podniesienie do potegi a NIE xor
mod - reszta z dzielenia 

gdzie C to szyfrogram, M wiadomosc, ktora szyfrujemy, E publiczny
exponent i N publiczny kluczyk.Dlugosc M nie moze byc wieksza
od dlugosci N, inaczej nalezy M rozbic na mniejsze bloki i
osobno szyfrowac.Dobra czyli wiemy(no warto poczytac jeszcze
inne texty o RSA) mniej wiecej jak odbywa sie szyfrowanie,
a jak odbywa sie deszyfrowanie spytacie?Do deszyfrowania potrzebny
jest juz prywatny exponent zwany D:

D = E^(-1) mod ((P-1)*(Q-1))

i deszyfrowanie przebiega wg. wzoru:

M = C^D mod N

gdzie M to odszyfrowane dane, C szyfrogram, D prywatny
exponent/klucz, N publiczny modul, zeby nie pozostac
goloslownym wykonamy male cwiczenie.

Mamy np. bajt 0x04 i chcemy go zaszyfrowac, najpierw
nalezy wybrac sobie liczby pierwsze P i Q:

P = 5
Q = 11

teraz nalezy obliczyc N, czyli P*Q:

N = P * Q = 5 * 11 = 55

zostalo nam tylko wybranie publicznego exponentu E, zeby
nie motac za bardzo zalozmy, ze to bedzie 3:

C = M^E mod N = 4^3 mod 55 = 64 mod 55 = 9

Ok, teraz na odwyrtke, czyli deszyfrowanie, nalezy sobie
obliczyc prywatny exponent D, do ktorego obliczenia przyda
sie prog o nazwie RSATool albo jakis porzadny kalkulator:

D = E^(-1) mod ((P-1)*(Q-1)) = 3^-1 mod 4*10 = 27

korzystajac z kalkulatora, z ktorego ja korzystalem(link na
koncu tuta), wystarczy spod linii komend wpisac inv(3,40) i
zalatwione :)

Deszyfrowanie, tutaj juz przyda sie ten ww. "kalkulatorek":

M = C^D mod N = 9^27 mod 55 = 4

No w sumie to calkiem proste, ale sila RSA tkwi w dlugosci
zastosowanych kluczy, im dluzszy publiczny modul N tym wiecej
trzeba poswiecic czasu procesora na rozbicie go na liczby P i Q.
Okej wlasnie przyszedl czas na powrot do tematu arta.Sprawa
wydaje sie prosta(ja to mam poczucie humoru?), nasz prog bierze
sobie serial w oryginalnej postaci, szyfruje go wg. publicznego
klucza:

047BEA8 modulus_n db '16300E3FD1D20B5D1AA942875657D514FB061437F8ECCF66C123CB20FF31'
                  db 'E642FBC6F9',0

i zaszyfrowany string porownywany jest z zapisanymi w exeku
patternami:

047B178 sz0bc1b3f8386cc db '0BC1B3F8386CCF08F72A08D47BD90FDD0A7A05F432B4346668E36747028D'
047B178                                         ; DATA XREF: DATA:00485E5Co
047B178                 db '76ECDF4C11',0
047B1BF                 align 4
047B1C0                 dd 0FFFFFFFFh, 'F'
047B1C8 sz08d1be15aa76b db '08D1BE15AA76BB9442CB76FEE8436E61A8A3F5A5B19D642BD956126E80AF'
047B1C8                                         ; DATA XREF: DATA:00485E60o
047B1C8                 db '51496CF618',0
047B20F                 align 4
047B210                 dd 0FFFFFFFFh, 46h
047B218 sz01d092259ced6 db '01D092259CED60F3053EB8A3DE1C2166621324A2C0990AE9DA1A598D8EA7'

...no jest tego troche wiec nie bede wszystkiego wklejal

Przegladajac kod widzielismy liczbe 10001 a prawie, we
wszystkich dokumentacjach bylo napisane, ze wlasnie ta
liczba jest najczesciej stosowana jako publiczny exponent,
wiec wszystko staje sie jasne.Teraz wystarczy zdeszyfrowac
dowolny serial znajdujacy sie na liscie kluczy i ponownie
zarejestrowac program korzystajac wlasnie z tego sn.Tutaj
zaczyna sie zabawa, do deszyfrowania potrzebny jest prywatny
klucz D ktorego nie ma w exeku(bez sera by to bylo), ale
nie jestesmy jedynymi ludzmi na tej planecie, ktorym potrzebne
bylo rozwiazanie, skutkiem czego powstalo wiele programow
wspomagajacych lamanie RSA, jednym z nich jest wyzej wspominany
RSATool, ktory pozwoli rozbic liczbe N na P i Q a majac E mozna
z latwoscia obliczyc prywatny klucz D.Uruchamiamy RSATool w
miejsce Modulus(N) wpisujemy:

16300E3FD1D20B5D1AA942875657D514FB061437F8ECCF66C123CB20FF31E642FBC6F9

W miejsce Public Exp. wpisujemy 65537(10001h), klikamy Factor
N i idzemy na kawke jak mamy szybki procesor albo na kolejny
odcinek Nikity, tak jak w moim przypadku ;), w sumie zajelo to
troche ponad pol godziny i tak oto:

P = 7373642F323330F4FC59
Q = 3132EE732C632CF7F2F42D4A7364647363366B2C732F734BA1

teraz klikamy Calc D:

D = BC6B5C969B3F214187263A0490434052B3894AF470585903B249F24359F69E8F8201

no i nawet sie nie musimy meczyc przy deszyfrowaniu kluczy,
bo RSATool posiada takze opcje Test dzieki, ktorej mozna
z poziomu tego proga deszyfrowac jakies dane, najpierw w
pole "Message to encrypt" wpiszmy jakies byle jakie dane i
dajemy Encrypt, teraz wystarczy w edita Result wkleic dowolny
string, ktory znajdowal sie na liscie zaszyfrowanych kluczy
np.:

0BC1B3F8386CCF08F72A08D47BD90FDD0A7A05F432B4346668E36747028D76ECDF4C11

jedno klikniecie w Decrypt i w polu "Message to encrypt" ukazuje sie
oto taki numerek:

6368455822991961

teraz warto by bylo sprawdzic czy program przyjmuje taki numer,
jak mamy zalozone bpx-y w krytycznym momencie piszemy r fl z, tak
zeby program myslal, ze nie jest zarejestrowany, pokaze sie nag
screen, wpisujemy ten serial no i "Thanks...", uruchamiamy Acccess
Locka jeszcze raz, zamykamy jego okno(po Activate) i teraz tak
manipulujemy flagami Z i C zeby dojsc do procki ostatecznej ;)

047C44A  mov     eax, 14h
047C44F  call    sub_402B60            <-- random % 14h
047C454  cmp     eax, 7                <-- 
047C457  jnz     short loc_47C4CD      <-- r fl z

047C471  fcompp  st(1), st             <-- ilosc dni dzialania proga
                                       <-- do 30
047C473  fnstsw  ax
047C475  sahf
047C476  jnb     short loc_47C4CD      <-- r fl c
...
047C48F  call    sub_47BDD4            <-- eureka!!!
047C494  test    al, al                <-- jesli ta procka zwroci 1
047C496  jnz     short loc_47C4CD      <-- tzn, ze serial jest ok
047C498  mov     eax, [ebp+var_4]      <-- jesli 0 to dzieja sie
047C49B  call    get_strlen            <-- ciekawe rzeczy

procka zwraca 1, czyli sukces, teraz pozostaje jeszcze
odkodowanie pozostalych zaszyfrowanych seriali i sprawdzenie
ich pod wzgledem pierwszych checkow, bo w sumie moglaby sie
zdarzyc taka sytuacja, ze odszyfrowany serial przechodzi przez
sprawdzanie bajtow i zgadzaja sie wartosci magic1,magic2 i 3, 
ale np. sprawdzanie magic_hidden da negatywne wyniki, heh to
by dopiero bylo zabezpieczenie ;), no, ale po malych testach
moge powiedziec, ze wszystkie zaszyfrowane seriale sa rowniez
poprawne jesli chodzi o wartosci magic.

Podsumowanko, no bardzo sie ciesze, ze wreszcie natrafilem
na takie zabezpieczenie, ale jednoczesnie wiem, ze gdyby autor
zamiast 280bitowego klucza N zastosowal np. 1024bitowy, ten
tut by chyba nigdy nie powstal, ale mimo wszystko zabezpiecznie
bylo ciekawe(nie ma jak milionowy raz progi licza sume bajtow
z name i to jest numer seryjny ;), te hidden checki mogly zwiesc
niejednego zaprawionego w boju, jak nie wierzycie to poszukajcie
sobie na astalaviscie produkcji do Access Lock 1.3, ja znalazlem
pare i seriale przechodzily tylko 1 checki.Swiat jest wielki...
ale to juz znacie ;)

-----------------------------------------------------------

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#include "miracl.h"     // v4.5

#define KEYS 35

char    *buff;
int     i,j,t;

big     m,n,e,d,c;


static char public_n[]="16300E3FD1D20B5D1AA942875657D514FB061437F8ECCF66C123CB20FF31E642FBC6F9";
static char private_d[]="BC6B5C969B3F214187263A0490434052B3894AF470585903B249F24359F69E8F8201";
static char public_exp[]="10001";

static char *keys[] ={
"0BC1B3F8386CCF08F72A08D47BD90FDD0A7A05F432B4346668E36747028D76ECDF4C11",
"08D1BE15AA76BB9442CB76FEE8436E61A8A3F5A5B19D642BD956126E80AF51496CF618",
"01D092259CED60F3053EB8A3DE1C2166621324A2C0990AE9DA1A598D8EA731F3722922",
"095F0C4D70511933571F275319C21CB395E2E3C5572FDCD4B375C9E8EB0BC7CBAEC700",
"0D8DA9451E00F7E528CCD534DE20559C8144CF7E3B4B882D24DC38EF3F916A7374FC51",
"0A09B3D7A3EB67B9CCB8B98C15B92CC5E4F5827EB464857BB2F9F8C69AD96CCECEFC63",
"07A7B58ECE60B7597F63AEC8030ED135A1F4AEEF24DB3DC62BE68668555E079A3E27EE",
"12A8E196EDAB588551374C11F3068D95683D3A17016C632EC1322EDA1C37BBDE17B2BA",
"04D3A1BD51DD8A0CAF58EBA8D7921E296E35C1A39D57E76F9D7F10F009E4719BD667E4",
"0D3CACAD81BDF2088D4C12222693612761F5D4CEE3408C166819B173CAF3775F3F5BC7",
"FF0FBA81427B60D38CC13250E9B9574569FA01B62A09B2D4AC026DCDC17050ED5603",
"05C4ACB86CF77CF058445FA34B05C2DE7823AA36AF5A0471AD0A0972DAF932687EA83A",
"1318412614C0B4ABF88F52247BC4F26574031EA5EB408A86259EA96F2BE6CAFD4E2747",
"0244B7068C7B2484595E35430A648EF230092924AD25EFEE640CD1B22F24D76F1E2B01",
"077FF4292855CAC00BF16B401BFF93423BA7B72611538565C32EFF366818C2A66BD0E4",
"0FA0F079D4B8B65D0DDAF11CB715570AFFB079A8A0BC9383A55B0F412FCA4A5CAA6560",
"1504A02E388920F60895E0CA74648034590ABBD6FBD35028C58B335AAF28271F5AB824",
"078ED056DB746BE027F2E58883CD3231CEC9847DA89590C68F3015203936445082C253",
"0F76394A95C11CDBEB8295CDAB55581D72BAB9D38031E7517C1E00DA6A091BA14D7B43",
"1194B5CC8F92B90B6D42E9F0C7D6605577D3AC6FBBD70C84AA18754866B1778111E987",
"06FECF48A12AC24CD3682929FA10AE56003FC1ED8F732E0C359E1F237D8B0BBDA1FA67",
"119E08A5A6B1E9AE7A88C66C7274C3C0EF60C1C2D32DA2E5C28302F23482E3E56BB3BD",
"03E67F7974FBB03C46DC015DA15E8DD9E1DB32FE8593421F3D281FADBE114088DADC79",
"0744A31132FD22834FABB0489F02F84A182EC2BECF85E9A863657B68182467A8486F60",
"0E789FD78A02D84CC69F04AF54A12E3482303C6DF3EA59B0C86D8423005D9224B78650",
"0D26C75C94558A517E431A00EEFD94B52A2D3922839B091A8E7CE9AF3A47FECB1ED2D1",
"0D2F904FD2A6A94A991ABE52A014A3683D4A67BC3C89E2ACFCD8E3D3A6D0382A01892A",
"146701F5E33A77EABF8F44ADF08C2E56FA104DB8E292E26315C042A44ABD285ED8C763",
"06C50CA7AF4FE2B4FAC5B0196FEFEF342531E5D84691A3B059516D8981CAE7940ED9E8",
"11AA727158D72609E13FB8EC47CD7E4DC5B275350F4ABC5488C237E636D3851C4513E2",
"0E98A1DABA1BDAA6E64A800AA1901054DE11961B7278889F4A2F473CBDF21BD05A860F",
"15727598D96926D979C9E843EC4C302B3777A2552B35C20250AE49D9CAC977D0668C50",
"161D61DD95872D068B81BB9725CC9D28EF82ED89B64108D8E8D7768B34CBF51410EB4A",
"083817044C1E8F80DA93842B29E92E3A3B39A8C147B55A1849B68B4F6D7955E7B7086F",
"079A1421E4CCF8A14B769C8BFFE0EFD69352BEACFE5498D3B97129B8DF346160DCCE95"
};



////////////////////////////////////////////////////////////
//
// taki dodatkowy check, ktorego nie chcialo mi sie omawiac,
// prog sprawdza czy w serialu nie powtarzaja sie za czesto
// okreslone bajty
//
////////////////////////////////////////////////////////////

BOOL checkchars(unsigned char *key)
{
unsigned int i,j,k;

        for (i = 0;i < 9;i++)           // sprawdz liczby dec od 0-9
        {
        k = 0;                          // inicjalizuj k na 0

                for (j = 0;j < 16;j++ ) // sprawdz calego seriala
                {                       // pod wzgledem wystepowania okreslonych bajtow
                k = ( key[j] == i ) ? k+1:k;
                }
                                        // jesli jakis bajt w serialu sie powtarza
                                        // wiecej jak 3 razy(w hiddenie jest 3) serial jest niepoprawny
                if ( k > 3) return FALSE;

        }

        return TRUE;                    // serial jest ok

}

////////////////////////////////////////////////////////////
//
// procka sprawdza czy okreslony klucz spelnia wymagania
// pierwszych checkow jakie sa wykonywane w programie
//
////////////////////////////////////////////////////////////

BOOL checkkey(unsigned char *key)
{
        unsigned int w,z,y,x;

        if (checkchars(key) == FALSE) return FALSE;

        w = key[0];x = key[1];y = key[2];z = key[3];
        if ( (w + x + y + z - (4*0x30) ) != 0x17 ) return FALSE;

        w = key[4];x = key[7];y = key[10];z = key[13];
        if ( (w + x + y + z - (4*0x30) ) != 0x1E ) return FALSE;

        /* hidden check */

        w = key[5];x = key[8];z = key[14];
        if ( (w + x + y - z - (3*0x30)+0x30 ) != 0x0A ) return FALSE;

        w = key[6];x = key[9];y = key[12];z = key[15];

        if ( (w + x + y + z - (4*0x30) ) != 0x09 ) return FALSE;

        return TRUE;
}


int main()
{
        /* zainicjalizuj system miracl */
        miracl *mip = mirsys(400,0);

        /* zainicjalizuj zmienne, wazne bo inaczej jest gpf */
        m = mirvar(0);n = mirvar(0);d = mirvar(0);
        e = mirvar(0);c = mirvar(0);

        /* ustaw baze liczbowa = 16 */
        mip->IOBASE = 16;

        /* zamien na format big */
        cinstr(d,private_d);
        cinstr(e,public_exp);
        cinstr(n,public_n);


        /* alokuj pamiec */
        buff = malloc(256);

        printf( "--   \n"
                "Ŀ\n"
                "                     2oo1 \n"
                "\n"
                "--    \n"
                "Access Lock v1.3 key checker by bart\n"
                "--    \n"
                "Valid keys :\n\n");


        j = 0;

        for (i = 0;i < KEYS ; i++ )
        {

        /* zamien kolejne stringi na format big */
        cinstr(c, keys[i]);
        
        /* deszyfrowanie m=c^d mod n */
        powmod(c,d,n,m);

        /* zamien na bajty zdeszyfrowany ciag */

        big_to_bytes(256,m,buff);

                /* sprawdz czy klucz przechodzi przez pierwsze checki */
                if (checkkey(buff+1) == TRUE)
                {

                /* wyswietl klucz */
                printf("%s ",buff+1);

                j++;
                if (j % 4 == 0) printf("\n");

                }
        }

        if ( i == KEYS ) printf("\n\nAll keys are valid.\n");

        printf( "--    \n"
                "\nPress any key . . .\n");

        
        /* deinicjalizuj zmienne typu big */
        mirkill(m);mirkill(n);mirkill(e);mirkill(d);mirkill(c);

        /* zwolnij pamiec */
        free(buff);

return getch();
}

----------------------------------------------------------

kompilacja:

lcc -O check.c
lcclnk -s -subsystem console check.obj miracl.lib

----------------------------------------------------------

Stuff, ktory moze sie przydac:

Oficjalna strona RSA
http://www.rsasecurity.com/


Implementacja RSA uzyta w progu
http://ace.ulyssis.student.kuleuven.ac.be/~triade/
autor Walied Othman


Program RSATool
http://egoiste.cjb.net


Bardzo przydatny kalkulator, ktory moze zastapic RSATool gdy przyjedzie
obliczac D, a exponent bedzie liczba formatu big, ogolnie dobra rzecz
http://www.maths.uq.edu.au/~krm/krm_calc.html


Tutoriale na temat RSA
http://zencrack2.cjb.net
http://www.woodmann.com/crackz/
http://mesa-sys.com/mercution/hf/tutorials/projectcryptology/essay_02.html


Zawsze najnowsza wersja biblioteki MIRACL wspomagajacej oblicznia
na duzych liczbach(przyklady lamania RSA) + zrodla w C
ftp://ftp.compapp.dcu.ie/pub/crypto/miracl.zip


Miracl homepage
http://indigo.ie/~mscott/


Biblioteka RSA i RSA Euro + zrodla w C
ftp://task.gda.pl/pub/security/crypto/LIBS/


Greetz2(2 czesci):

5C05B0F2AE09EF391E5EB4C413FEDB4786D45F0CA08D3712F770AD6D24610020
6FAE4B7E2A7DD7F3C496B8E3806F009A19D2B9B29C5C1ED8D09139ADB7E2BE69

N = 8E29C91B49AD624F4D284733BC16BECFBD3EADC81C87520039DD7CC6E96F0951
E = 10001


bart^CrackPl
cryogen@poland.com | cryogen@box43.pl | http://www.ctrl-d.prv.pl
