HOW TO CRACK, by +ORC, A TUTORIAL


Lesson 6.1: Funny tricks (1)


LESSON 6 (1) - Funny tricks.  Xoring, Junking, Sliding

EXERCISE 01: [LARRY in search of the King]

     Before the next step let's resume what you have learned in

the lessons 3-5, beginning with a very simple crack exercise

(again, we'll use the protection scheme of a game, for the

reasons explained in lesson 1): SEARCH FOR THE KING (Version

1.1.). This old "Larry" protection sequence, is a "paper

protection" primitive. It's a very widespread (and therefore easy

to find) program, and one of the first programs that instead of

asking meaningful passwords (which offer us the possibility to

immediately track them down in memory) asked for a random number

that the good buyer could find on the manual, whereby the bad

cracker could not. (Here you choose -with the mouse- one number

out of 5 possible for a "gadget" choosen at random). I don't need

any more to teach you how to find the relevant section of code

(-> see lesson 3). Once you find the protection, this is what you

get:



:protection_loop

 :C922 8E0614A3       MOV     ES,[A314]

...

 :C952 50 0E          PUSH    AX & CS

 :C954 E81BFF         CALL    C872      <- call protection scheme

 :C957 5B             POP     BX twice

 :C959 8B76FA         MOV     SI,[BP-06] <- prepare store_room

 :C95C D1E6           SHL     SI,1       <- final prepare

 :C95E 8942FC         MOV     [BP+SI-04],AX  <- store AX

 :C961 837EFA00       CMP     Word Ptr [BP-06],+00  <- good_guy?

 :C965 75BB           JNZ     C922           <- loop, bad guy

 :C967 8E0614A3       MOV     ES,[A314]

 :C96B 26F606BE3501   TEST    Byte Ptr ES:[35BE],01  <- bad_guy?

 :C971 74AF           JZ C922                <- loop, bad guy

 :C973 8B46FC         MOV     AX,[BP-04]...  <- go on good guy



Let's see now the protection scheme called from :C954

 :C872 55             PUSH    BP

...

 :C8F7 90             NOP

 :C8F8 0E             PUSH    CS

 :C8F9 E87234         CALL    FD6E <- call user input

 :C8FC 5B             POP     BX

 :C8FD 5B             POP     BX

 :C8FE 8B5E06         MOV     BX,[BP+06]

 :C901 D1E3           SHL     BX,1

 :C903 39872266       CMP     [BX+6622],AX  <- right answer?

 :C907 7505           JNZ     C90E      <- no, beggar_off

 :C909 B80100         MOV     AX,0001   <- yes, AX=1

 :C90C EB02           JMP     C910

 :C90E 2BC0           SUB     AX,AX     <- beggar_off with AX=0

 :C910 8BE5           MOV     SP,BP

 :C912 5D             POP     BP

 :C913 CB             RETF              <- back to main



Here follow 5 questions, please answer all of them:

1)   Where in memory (in which locations) are stored the "right"

     passnumbers? Where in memory is the SEGMENT of this

     locations stored? How does the scheme get the OFFSET?

2)   Would setting NOPs instructions at :C965 and :C971 crack?

     Would it be a good idea?

3)   Would changing :C907 to JZ crack? Would it be a good idea?

4)   Would changing :C907 to JNZ C909 crack? Would it be a good

     idea?

5)   Write down (and try) at least 7 OTHER different patches to

     crack this scheme in spades (without using any NOP!).

Uff! By now you should be able to do the above 5 exercises in

less than 15 minutes WITHOUT USING THE DEBUGGER! Just look at the

data above and find the right answers feeling them... (you 'll

now which one are the right one checking with your debugger...

score as many points as you like for each correct answer and sip

a good Martini-Wodka... do you know that the sequence should

ALWAYS be 1) Ice cubes 2) Martini Dry 3) Wodka Moskovskaja 4)

olive 5) lemon 6) Schweppes Indian tonic?



Let's now come to the subject of this lesson:

-----> [Xoring] (Simple encryption methods)

     One easy way to encrypt data is the XOR method. XOR is a bit

manipulation instruction that can be used in order to cipher and

decipher data with the same key:

 Byte to encrypt                   key            result

     FF                  XOR       A1               5E

     5E                  XOR       A1               FF

As you can see XOR offers a very easy way to encrypt or to

decrypt data, for instance using the following routine:

 encrypt_decrypt:

     mov  bx, offset_where_encryption/decryption_starts

 xor_loop:

     mov  ah, [bx]            <-   get current byte

     xor  ah, encrypt_value   <-   engage/disengage xor

     mov [bx], ah             <-   back where you got it

     inc  bx                  <-   ahead one byte

     cmp  bx, offset_start_+_size  <- are we done?

     jle  xor_loop            <-   no, then next cycle

     ret                      <-   back where we came from



The encrypt_value can be always the same (fixed) or chosen at

random, for instance using INT_21, service 2Ch (get current time)

and choosing as encrypt_value the value reported in DL (but

remembering to discard the eventual value 0, coz otherwise it

would not xor anything at all!)

 random_value:

     mov  ah,2Ch

     int  21h

     cmp  dl,0

     je   random_value

     mov  encrypt_value,dl

     The problem with XORing (and with many other encryption

methods), is that the part of the code that calls the encryption

routine cannot be itself encrypted. You'll somewhere have, "in

clear" the encryption key.



     The protectionist do at times their best to hide the

decrypting routine, here are some common methods:



-----> JUNK FILLING, SLIDING KEYS AND MUTATING DECRYPTORS

  These are the more common protection method for the small

decryption part of the program code. This methods, originally

devised to fool signature virus scanners, have been pinched from

the polymorphic virus engines of our fellows viriwriters, and are

still in use for many simple decryption protection schemes. For

parts of the following many thanks go to the [Black Baron], it's

a real pity that so many potential good crackers dedicate so much

time to useless (and pretty repetitive) virus writing instead of

helping in our work. This said, virus studying is VERY important

for crackers coz the code of the viri is

*    ULTRAPROTECTED

*    TIGHT AND EFFECTIVE

*    CLOAKED AND CONCEALED.



Let's show as example of the abovementioned protection tactics

the following ultra-simple decryptor:

          MOV      SI,jumbled_data     ;Point to the jumbled data

          MOV      CX,10               ;Ten bytes to decrypt

mn_loop:  XOR      BYTE PTR [SI],44    ;XOR (un_scramble!) a byte

          INC      SI                  ;Next byte

          LOOP     mn_loop             ;Loop the 9 other bytes



This small program will XOR the ten bytes at the location pointed

to by SI with the value 44.  Providing the ten bytes were XORed

with 44 prior to running this decryptor the ten bytes will be

restored to their original state.

In this very simple case the "key" is the value 44. But there are

several tricks involving keys, the simplest one being the use of

a "sliding" key: a key that will be increased, or decreased, or

multiplied, or bit-shifted, or whatever, at every pass of the

loop.



A possible protection can also create a true "Polymorph"

decryptor, a whole decryptor ROUTINE that looks completely

different on each generation. The trick is to pepper totally

random amounts of totally random instructions, including JUMPS

and CALLS, that DO NOT AFFECT the registers that are used for the

decryption. Also this kind of protection oft uses a different

main decryptor (possibly from a selection of pre-coded ones) and

oft alters on each generation also all the registers that the

decryptor uses, invariably making sure that the JUNK code that

it generates doesn't destroy any of the registers used by the

real decryptor!  So, with these rules in mind, here is our simple

decryptor again:



         MOV      DX,10              ;Real part of the decryptor!

         MOV      SI,1234            ;junk

         AND      AX,[SI+1234]       ;junk

         CLD                         ;junk

         MOV      DI,jumbled_data    ;Real part of the decryptor!

         TEST     [SI+1234],BL       ;junk

         OR       AL,CL              ;junk

mn_loop: ADD      SI,SI              ;junk instr, but real loop!

         XOR      AX,1234            ;junk

         XOR      BYTE PTR [DI],44   ;Real part of the decryptor!

         SUB      SI,123             ;junk

         INC      DI                 ;Real part of the decryptor!

         TEST     DX,1234            ;junk

         AND      AL,[BP+1234]       ;junk

         DEC      DX                 ;Real part of the decryptor!

         NOP                         ;junk

         XOR      AX,DX              ;junk

         SBB      AX,[SI+1234]       ;junk

         AND      DX,DX              ;Real part of the decryptor!

         JNZ      mn_loop            ;Real part of the decryptor!



As you should be able to see, quite a mess! But still executable

code. It is essential that any junk code generated by the

Polymorph protection is executable, as it is going to be peppered

throughout the decryptor. Note, in this example, that some of the



junk instructions use registers that are actually used in the

decryptor! This is fine, providing the values in these

registers aren't destroyed. Also note, that now we have random

registers and random instructions on each generation. So, a

Polymorph protection Engine can be summed up into three major

parts:

  1 .. The random number generator.

  2 .. The junk code generator.

  3 .. The decryptor generator.

There are other discrete parts but these three are the ones where

most of the work goes on!



How does it all work?  Well a good protection would

*    choose a random selection of registers to use for the

decryptor and leave the remaining registers as "junk" registers

for the junk code generator.

*    choose one of the compressed pre-coded decryptors.

*    go into a loop generating the real decryptor, peppered with

junk code.

From the protectionist's point of view, the advantages of this

kind of method are mainly:

*    the casual cracker will have to sweat to find the decryptor.

*    the casual cracker will not be able to prepare a "patch" for

the lamers, unless he locates and patches the generators, (that

may be compressed) coz otherwise the decryptor will vary every

time.



To defeat this kind of protection you need a little "zen" feeling

and a moderate knowledge of assembler language... some of the

junk instructions "feel" quite singular when you look at them

(->see lesson B). Besides, you (now) know what may be going on

and memory breakpoints will immediately trigger on decryption...

the road is open and the rest is easy (->see lessons 3-5).



-----> Starting point number magic

For example, say the encrypted code started at address 10h, the

following could be used to index this address:

 MOV   SI,10h         ;Start address

 MOV   AL,[SI]        ;Index from initial address

But sometimes you'll instead find something like the following,

again based on the encrypted code starting at address 10h:



 MOV   DI,0BFAAh      ;Indirect start address

 MOV   AL,[DI+4066h)  ;4066h + 0BFAAh = 10010h (and FFFF = 10h)!!

The possible combinations are obviously infinite.





[BIG KEYS] (Complicated encryption methods)

     Prime number factoring is the encryption used to protect

sensible data and very expensive applications. Obviously for few

digit keys the decoding is much easier than for, say, 129 or 250

digit keys. Nevertheless you can crack those huge encryption too,

using distributed processing of quadratic sieve equations (which

is far superior for cracking purpose to the sequential processing

methods) in order to break the key into prime numbers. To teach

you how to do this sort of "high" cracking is a little outside

the scope of my tutorial: you'll have to write a specific short

dedicated program, linking together more or less half a thousand

PC for a couple of hours, for a 250 bit key, this kind of things

have been done quite often on Internet, were you can also find

many sites that do untangle the mysteries (and vagaries) of such

techniques.

  As References I would advocate the works of Lai Xueejia, those

swiss guys can crack *everything*. Begin with the following:

Xuejia Lai, James Massey, Sean Murphy, "Markov Ciphers and

     Differential Cryptanalysis", Advances in Cryptology,

     Eurocrypt 1991.

Xuejia Lai, "On the Design and Security of Block Ciphers",

     Institute for Signal and Information Processing,

     ETH-Zentrum, Zurich, Switzerland, 1992

Factoring and primality testing is obviously very important for

this kind of crack. The most comprehensive work I know of is:

(300 pages with lengthy bibliography!)

    W. Bosma & M. van der Hulst

    Primality Testing with Cyclotomy

    Thesis, University of Amsterdam Press.

A very good old book you can incorporate in your probes to build

very effective crack programs (not only for BBS accesses :=) is

*the* "pomerance" catalog:

Pomerance, Selfridge, & Wagstaff Jr.

    The pseudoprimes to 25*10^9

    Math. Comp. Vol 35 1980 pp. 1003-1026



Anyway... make a good search with Lykos, and visit the relevant

sites... if encryption really interests you, you'll be back in

two or three (or thirty) years and you'll resume cracking with

deeper erudite knowledge.

[PATENTED PROTECTION SYSTEMS]

  The study of the patented enciphering methods is also *quite*

interesting for our aims :=) Here are some interesting patents,

if you want to walk these paths get the complete texts:

     [BEST]    USPat 4168396 to Best discloses a microprocessor

for executing enciphered programs. Computer programs which have

been enciphered during manufacture to deter the execution of the

programs in unauthorized computers, must be decrypted before

execution. The disclosed microprocessor deciphers and executes

an enciphered program one instruction at a time, instead of on

a continuous basis, through a combination of substitutions,

transpositions, and exclusive OR additions, in which the address

of each instruction is combined with the instruction. Each unit

may use a unique set of substitutions so that a program which can

be executed on one microprocessor cannot be run on any other

microprocessor. Further, Best cannot accommodate a mixture of

encrypted and plain text programs.

     [JOHNSTONE]    USPat 4120030 to Johnstone describes a

computer in which the data portion of instructions are scrambled

and in which the data is of necessity stored in a separate

memory. There is no disclosure of operating with instructions

which are completely encrypted with both the operation code and

the data address portion being unreadable without a corresponding

key kernel.

     [TWINPROGS]    USPat 4183085 describes a technique for

protecting software by providing two separate program storages.

The first program storage is a secure storage and the second

program storage is a free storage. Security logic is provided to

check whether an output instruction has originated in the secure

store and to prevent operation of an output unit which receives

output instructions from the free storage. This makes it

difficult to produce information by loading a program into free

storage.

     [AUTHENTICATOR]     USPat 3996449 entitled "Operating System

Authenticator," discloses a technique for authenticating the

validity of a plain text program read into a computer, by

exclusive OR'ing the plain text of the program with a key to

generate a code word which must be a standard recognizable code

word which is successfully compared with a standard corresponding

code word stored in the computer. If there is a successful

compare, then the plain text program is considered to be

authenticated and is allowed to run, otherwise the program

is not allowed to run.



ELEMENTS OF [PGP] CRACKING

In order to try to crack PGP, you need to understand how these

public/private keys systems work. Cracking PGP seems extremely

difficult, though... I have a special dedicated "attack" computer

that runs 24 hours on 24 only to this aim and yet have only begun

to see the light at the famous other end of the tunnel. It's hard, but 

good crackers never resign! 

  We'll see... I publish here the following only in the hope that 

somebody else will one day be able to help...

 

  In the public key cryptosystems, like PGP, each user has an 

associated 

  encryption key E=(e,n) and decryption key D=(d,n), wherein the 

encryption 

  keys for all users are available in a public file, while the 

decryption 

  keys for the users are only known to the respective users. In order 

to 

  maintain a high level of security a user's decoding key is not 

determinable

  in a practical manner from that user's encoding (public) key. 

Normally in 

  such systems, since e.multidot.d.ident.1 (mod(1 cm((p-1),(q-1)))), 

(where 

  "1 cm((p-1),(q-1))" is the least common multiple of the numbers p-1 

and 

  q-1) d can be determined from e provided p and q are also known. 

  Accordingly, the security of the system is dependent upon the 

ability to 

  determine p and q which are the prime factors of n. By selecting p 

and q to

  be large primes, the resultant composite number n is also large, and 

 

  correspondingly difficult to factor.

  For example, using known computer-implemented factorization methods, 

on the

  order of 10.sup.9 years is required to factor a 200 digit long 

number. 

  Thus, as a practical matter, although a user's encryption key 

E=(e,n) is 

  public, the prime factors p and q of n are effectively hidden from 

anyone 

  due to the enormous difficulty in factoring n. These aspects are 

described 

  more fully in the abundant publications on digital signatures and 

  Public-Key Cryptosystems. Most public/private systems relies on a 

message-

  digest algorithm.

  A message-digest algorithm maps a message of arbitrary length to a 

"digest"

  of fixed length, and has three properties:

  Computing the digest is easy, finding a message with a given digest 

  "inversion" is hard, and finding two messages with the same digest 

  "collision" is also hard. Message-digest algorithms have many 

applications,

  not only digital signatures and message authentication. RSA Data 

Security's

  MD5 message-digest algorithm, developed by Ron Rivest, maps a 

message to a 

  128-bit message digest. Computing the digest of a one-megabyte 

message 

  takes as little as a second.  While no message-digest algorithm can 

yet be 

  secure, MD5 is believed to be at least as good as any other that 

maps to a 

  128-bit digest. As a final gift, I'll tell you that PGP relies on 

MD5 for a

  secure one-way hash function. For PGP this is troublesome, to say 

the 

  least, coz an approximate relation exists between any four 

consecutive 

  additive constants. This means that one of the design principles 

behind MD4

  (and MD5), namely to design a collision resistant function, is not 

  satisfied. You can construct two chaining variables (that only 

differ in 

  the most significant bit of every word) and a single message block 

that 

  yield the same hashcode. The attack takes a few minutes on a PC. 

From here 

  you should start, as I did.

 

  [DOS 4GW] cracking - This is only a very provisory part of this 

tutorial. 

  DOS 4GW cracking will be much better described as soon as [Lost 

soul] sends

  his stuff, if he ever does. For (parts of) the following I thank 

[The 

  Interrupt].

  Most applications of every OS, and also of DOS 4GW, are written in C 

 

  language, coz as you'll have already learned or, either, you'll 

learn, only

  C allows you to get the "guts" of a program, almost approaching the 

  effectiveness of assembler language. C is therefore the LANGUAGE OF 

CHOICE 

  for crackers, when you prepare your tools and do not directly use 

assembler

  routines.

  Besides... you'll be able to find VERY GOOD books about C for next 

to  

  nothing in the second hand bookshops. All the lusers are throwing 

money 

  away in spades buying huge, coloured and absolutely useless books on 

 

  unproductive "bloated" languages like Visual basic, C++ and Delphy. 

Good C 

  new books are now rare (books on assembler language have always 

been) and 

  can be found almost exclusively on the second hand market. Find 

them, buy

  them, read them, use them for your/our aims. You can find a lot of C 

 

  tutorials and of C material on the Web, by all means DO IT!

  Be a conscientious cracker... learn C! It's cheap, lean, mean and 

very 

  productive (and creative) :=)     

  Back to the point: most stuff is written in C and therefore you need 

to 

  find the "main" sub-routine inside the asm. With DOS/4GW programs, 

search 

  the exe file for "90 90 90 90", almost always it'll be at the start 

of the 

  compiled code. Now search for an INT_21 executed with 4C in AH, the 

exec to 

  dos code (if you cannot "BPINT 21 AH=4C" with your tool, then search 

for 

  the sequence "b4 4c cd 21". This is the equivalent to [mov AH,4C & 

int 21]:

  it's the most direct call, but as you'll have already learned, there 

are 

  half a dozen ways to put 4C in AX, try them all in the order of 

their 

  frequency).

  A few bytes above the INT_21 service 4C, you'll find the call to the 

"main"

  subroutine: "E8 xx xx". Now place a "CC" byte a few bytes above the 

call in

  the exe and run the exe under a debugger. When the computer tries to 

 

  execute the instruction you'll be throw back in the debugger coz the 

"CC" 

  byte acts as INT_01 instruction. Then proceed as usual.

 

  [THE "STEGONATED" PASSWORD HIDEOUT]

  A last, very nice trick should be explained to every wannabe 

cracker, coz 

  it would be embarrassing to search for passwords or protection 

routines 

  that (apparently) are not there. They may be hidden INSIDE a picture 

(or a 

  *.waw file for that matter). This is steganography, a method of 

disguising 

  messages within other media.

 

  Depending on how many shades of grey or hues of colour you want to 

have, a 

  pixel can be expressed using 8. 16, 32 or even more bits. If the 

least 

  significant bit is changed. the shade of the pixel is altered only 

  one-256th, one-65,OOOth or even less. No human eye could tell the 

  difference.

  What the protectionist does, is hijack the least significant bit in 

each 

  pixel of a picture. It uses that bit to store one bit of a 

protection, or 

  of a password (or of a file, or of a secret message). Because 

digitized 

  pictures have lots of pixels, it's possible to store lots of data in 

a 

  single picture. A simple algorithm will transfer them to the 

relevant parts

  of the program when it needs be, and there we'll intercept them. 

You'll 

  need to learn very well the zen-cracking techniques to smell this 

kind of 

  stuff though (-> see lesson B). Well, that's it for this lesson, 

reader.