==================== (trying to!!)Keygenning PowerMarks 3.5 =====================


                a tutorial by j!m Published by +Tsehp October 2001



Date  : 2001-10-11

Target: Power Marks 3.5 build 297 from Kaylon Technologies.

Where : www.kaylon.com/

tools : softice,

        Windasm (for dead listing work),

        borland C++ (for the keygen),

        Hedit (to patch),

        Icedump (for dumps!!).


A word about this tool:


Do you, as i do, use more than one browser? (IE, Opera, Netscape...), if you answered yes, then you should have had

the problem of the bookmarks management.

This tool solves this problem for good!, it is able to import all the different bookmarks formats from the different

browsers and puts them into a single HTML page so you can save them easily.

It is able to catch/send addresses from browsers windows.

You can associate keywords with your bookmarks addresses so you don't

have to think about putting them in complicated

directories and sub-directories that never match your needs...

Try it!!!


A word about the protection:


This time we will talk about the Secure Hash Algorithm (160 bits) used in the keygen scheme,

SHA is an algorithm that takes some bytes in entry and computes a 160 bits digest of these bytes.

It is very very very difficult to find the original message from the digest, that's why these kind of functions

are called 'one way functions'.

For more informations about the SHA algo i recommend you the FIPS Homepage at http://www.itl.nist.gov/fipspubs/index.htm.


The only attack i know against the SHA algorithm is the brute force attack. But with

the keys used here(16 digits, that means a 10^16 key space),

this attack is not practical, nevertheless we will implement this attack in a conceptual

bruteforcer (waiting for powerfull computers...)


But we will not surrender and you will see that with a litlle patch we are going

to defeat a protection

that was theorically unbreakable!!



ok let's go!


launch PowerMark 3.5, choose the Help/Enter Licence menu and Ctrl+D to call softice.

I will not give you a lot of details here, because the way to reach the decision function is quite easy.

just try to bpx the GetWindowTextA, press Ctrl+D to go back to Powermarks and press the OK button into

the dialog box.

Now play with F8 & F10 to trace into, until you reach these lines:


:00435A95 8B5608                  mov edx, dword ptr [esi+08]     ;@serial

:00435A98 8B4F08                  mov ecx, dword ptr [edi+08]     ;@name     

:00435A9B E8058CFFFF              call 0042E6A5             ;call decision


:00435AA0 85C0                    test eax, eax      

:00435AA2 7409                    je 00435AAD


ok, we have found the simple test/je combination, but it's not our time, go on tracing with F8...

Here comes the little t

hings we will patch later,


:0042E6B7 E8A4D70000              call 0043BE60             ;interesting us


:0042E6BC 3D6965C632              cmp eax, 32C66569

:0042E6C1 0F8488000000            je 0042E74F               ;bad serial format

:0042E6C7 3D74788689              cmp eax, 89867874

:0042E6CC 745C                    je 0042E72A               ;bad name format

:0042E6CE 3D01DC1498              cmp eax, 9814DC01

:0042E6D3 740C                    je 0042E6E1               ;yeahhh good !!

:0042E6D5 3DBF61A7D9              cmp eax, D9A761BF

:0042E6DA 7473                    je 0042E74F               ;wrong licence

:0042E6DC E99B000000              jmp 0042E77C


go on tracing...


:0043BE60 55                      push ebp


:0043BE61 8BEC                    mov ebp, esp

:0043BE63 81ECAC020000            sub esp, 000002AC

:0043BE69 56                      push esi

:0043BE6A 8BF2                    mov esi, edx

:0043BE6C 33D2                    xor edx, edx              ;testing the name format


 8A01                    mov al, byte ptr [ecx] ;ecx = @name

:0043BE70 84C0                    test al, al

:0043BE72 7418                    je 0043BE8C

:0043BE74 3C20                    cmp al, 20

:0043BE76 7411                    je 0043BE89

:0043BE78 0FB6C0                  movzx eax, al

:0043BE7B 42                      inc edx

:0043BE7C 8A8040AC4700            mov al, byte ptr [eax+0047AC40] ;convert the name

:0043BE82 88841553FDFFFF          mov byte ptr [ebp+edx-000002AD], al

:0043BE89 41                      inc ecx

:0043BE8A EBE2                    jmp 0043BE6E

:0043BE8C 80A41554FDFFFF00        and byte ptr [ebp+edx-000002AC], 00


now we have computed N = g(n) where n is the name you entered


:0043BE94 83FA03                  cmp edx, 00000003         ;3 cars at least

:0043BE97 730A                    jnb 0043BEA3

:0043BE99 B874788689              mov eax, 89867874         ;bad name, too short, do you remember?

:0043BE9E E9E1000000              jmp 0043BF84              ;end


:0043BEA3 8D8D54FDFFFF      

     lea ecx, dword ptr [ebp+FFFFFD54]    ;@N

:0043BEA9 E804010000              call 0043BFB2             ;test if your name is in the black list!


If the name you entered is in the black list then eax = 1 after the call above.

enter 'angie wetzel' or 'farid nagi' as name for example, and after the call eax = 1,

there are 6 refused names, try to find them!! (it's not difficult at all!!)


:0043BEAE 85C0                    test eax, eax

:0043BEB0 740A                    je 0043BEBC               ;eax = 0 ?

:0043BEB2 B8BF61A7D9              mov eax, D9A761BF         ;invalid licence

:0043BEB7 E9C8000000              jmp 0043BF84


:0043BEBC 8A06                    mov al, byte ptr [esi]    ;here start the serial format tests

:0043BEBE 33C9                    xor ecx, ecx

:0043BEC0 84C0                    test al, al

:0043BEC2 7429                    je 0043BEED

:0043BEC4 3C30                    cmp al, 30                ;'0'

:0043BEC6 7210                    jb 0043BED8

:0043BEC8 3C39                    cmp al, 39                ;'9'

:0043BECA 770C     

              ja 0043BED8

:0043BECC 83F910                  cmp ecx, 00000010

:0043BECF 741C                    je 0043BEED

:0043BED1 88440DEC                mov byte ptr [ebp+ecx-14], al

:0043BED5 41                      inc ecx

:0043BED6 EB08                    jmp 0043BEE0

:0043BED8 3C20                    cmp al, 20

:0043BEDA 7404                    je 0043BEE0

:0043BEDC 3C2D                    cmp al, 2D

:0043BEDE 750D                    jne 0043BEED

:0043BEE0 8A4601                  mov al, byte ptr [esi+01]

:0043BEE3 46                      inc esi

:0043BEE4 84C0                    test al, al

:0043BEE6 75DC                    jne 0043BEC4

:0043BEE8 83F910                  cmp ecx, 00000010         ;must be 16 digits

:0043BEEB 740A                    je 0043BEF7

:0043BEED B86965C632              mov eax, 32C66569         ;bad serial

:0043BEF2 E98D000000              jmp 0043BF84

:0043BEF7 8065FC00                and byte ptr [ebp-04], 00


*********************** Here comes the crypto part *******



:0043BEFB 8D8D58FFFFFF            lea ecx, dword ptr [ebp+FFFFFF58]

:0043BF01 E8F3CCFFFF              call 00438BF9


under softice, type d ecx, you see the following 20 bytes:

01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 F0 E1 D2 C3

These are the five 32 bits values used to initialize the SHA Algorithm

let's go on...


:0043BF06 8D8554FDFFFF            lea eax, dword ptr [ebp+FFFFFD54]     ;@N

:0043BF0C 50                      push eax

:0043BF0D E89EF30100              call 0045B2B0                   ;get length

:0043BF12 59                      pop ecx

:0043BF13 8D9554FDFFFF            lea edx, dword ptr [ebp+FFFFFD54]

:0043BF19 50                      push eax

:0043BF1A 8D8D58FFFFFF            lea ecx, dword ptr [ebp+FFFFFF58]    

:0043BF20 E8FFCCFFFF              call 00438C24                   ;sha prepare     


:0043BF25 8D9558FFFFFF            lea edx, dword ptr [ebp+FFFFFF58]

:0043BF2B 8D4DD8                  lea ecx, dword ptr [ebp-28]

:0043BF2E E8A6CDFFFF              call 00438CD9      

            ;sha compute SHA(N)

:0043BF33 8D45C8                  lea eax, dword ptr [ebp-38]

:0043BF36 8D55D8                  lea edx, dword ptr [ebp-28]


d edx to see the 20 bytes (160 bits) hash of your name!!

I used Damn hash calculator (http://www.damn.to/main.html) to be sure that it was really a SHA digest

for example, if i type 'jim' as the name in powermarks registration box, my SHA digest is:


Calculating hash of 3 bytes string `JIM`...(remember the conversion jim-->JIM)


SHA-160     : 82D7966F4CD1B0EC3DE22B534378269E5AA15746


ok continue...


:0043BF39 50                      push eax

:0043BF3A 8D4DEC                  lea ecx, dword ptr [ebp-14]

:0043BF3D E8DDFEFFFF              call 0043BE1F                   ;derivate serial with name...


The fonction computes S = f(s,N) , where s is the serial you entered and N the converted name


s is the serial given to you by Kaylon technologies when you register, S is the real key that will be hashed.

why ??

just because there are only 128 valid keys as you will see later (the hash codes of these keys are included in the program).

When you register this program, Kaylon technologies choose a key among the 128 according to the first byte of your SHA(N).

After that, this key is derived with the 16 first bytes of your SHA(N) and then sent to you, so even if two people that register

have the same first byte in their respectives SHA(N), the real key given to them will be the same but the digits they have to enter will be different...


:0043BF42 8D8D58FFFFFF            lea ecx, dword ptr [ebp+FFFFFF58]     ;sha init

:0043BF48 E8ACCCFFFF              call 00438BF9

:0043BF4D 8D55C8                  lea edx, dword ptr [ebp-38]

:0043BF50 8D8D58FFFFFF            lea ecx, dword ptr [ebp+FFFFFF58]

:0043BF56 6A10                    push 00000010                   ;fixed length for the serial

:0043BF58 E8C7CCFF

FF              call 00438C24                   ;sha prepare

:0043BF5D 8D9558FFFFFF            lea edx, dword ptr [ebp+FFFFFF58]

:0043BF63 8D4DB4                  lea ecx, dword ptr [ebp-4C]

:0043BF66 E86ECDFFFF              call 00438CD9                   ;sha compute SHA(S)


:0043BF6B 8D55B4                  lea edx, dword ptr [ebp-4C]           ;@SHA(S)

:0043BF6E 8D4DD8                  lea ecx, dword ptr [ebp-28]           ;@SHA(N)


:0043BF71 E811000000              call 0043BF87                   ;decides!!!


This function takes the first byte of SHA(N), call it B, computes B % 128 (modulus), this give us a value V between 0 and 127,

this value V is the index of the valid key.

But the programs doesn't handle the Keys, it just carries a table of the 128 digests of the good keys.

It then computes V*20 (each digest is 20 bytes long) and add this value to the table's offset to point to the digest of the correct key.

After that, the program tests if each byte of SHA(S) match with the pointed digest.


:0043BF76 F7D8                    neg eax                   ;eax = 0(b

ad) or 1(good)

:0043BF78 1BC0                    sbb eax, eax

:0043BF7A 25427A6DBE              and eax, BE6D7A42

:0043BF7F 05BF61A7D9              add eax, D9A761BF

:0043BF84 5E                      pop esi

:0043BF85 C9                      leave

:0043BF86 C3                      ret


So, How to register??


I Have ripped the digest table and written a simple C bruteforcer (it is easy to find C implementation of SHA, you can

even rip the asm code of the SHA function included in powermarks...), trying to find a key with a valid digest.

But as you could have read, the key is a 16 digit number, so the keyspace is 10^16, nearly 2^53,

if your name is NSA, may be you can affoard a computer that will be able to do this kind of attack,

but in my case it is far beyond the scope of my Athlon 800!!!!


So, What can we do?


Hacking Kaylon's network to rip the keys file is a great idea!! but there is another way : patching.

we will modify the sequence:


 F7D8                    neg eax                      ;eax = 0(bad) or 1(good)

:0043BF78 1BC0                    sbb eax, eax


        F7D0              not eax

          90                      nop

        90                  nop


you can do it inline with softice, a 43bf76, or with your favorite hex editor (search for F7D81BC02542 and replace F7D81BC0 by F7D09090).

After that, to register, all you have to do is type in your name and a 16 digits number and press OK!!


Final Word


As you can see, a little patch breaks the beautifull mathematical theory into pieces...That man can do, man can undo...

Keep it in mind!


I'm waiting for your comments, your ideas (a distributed attack implementation...?), another solution....