|
|
Undocumented HASP
(no more security through obscurity)
|
Advanced
|
27 May 1998
|
by
Bajunny
|
|
|
Courtesy of Fravia's page of
reverse engineering
|
slightly edited
by fravia+ |
fra_00xx 980527 Bajunny 0010 AD DG
|
...maybe the HASP designers never took this into account and
concentrated rather on production costs... and cut costs on
good encryption... they must have thought that neither the
(gullible) programmers nor the (incompetent) testers would
ever have found out the terrible intrinsic weakness of this
HASP scheme...
... luckily there are some good reversers around, like
Bajunny, that with this last part of his now famous Undocumented Hasp
essay, eliminates once for all Aladdin's protection scheme, which
proves to be rather trivial (russian dudes have even created
automated 'dehaspers'). Software programmers, take note: NEVER
trust commercial protectors: see, FOR MONEY you'll always be able to
get only "poor concocted" protections , you'll find
FAR better protections FOR FREE (on this very site
as well). As usual, on this web of ours.
|
Dongles |
|
There is a crack, a crack in everything
That's how the light gets in
| |
Rating
|
( )Beginner ( )Intermediate (x)Advanced ( )Expert
|
|
Some necessary final words for my Undocumented HASP project..
Undocumented HASP
Closing Part
Written by
Bajunny
--------------------------------------------------------------
Undocumented HASP, by -bajunny
Part III
(hopefully the last one)
7. C'est la mort du petit cheval.
---------------------------------
Brushing up my materials on HASP reversing while writing
these words I suddenly realized there was nothing more to add!
You have been shown how HASP produce its answer to given seed,
and now you are able to bruteforce HASP password in case you have
a solitary dongle and no corresponding software... boy, you can
even read/write ALL hasp memory!
Of course, there were some dark spots in my narration - bound
to be, coz I never tried to contact the manufacturer and
had no information whatsoever on internals (hhe, I will hardly
receive anything but useless advertisement brochures)..
I also didn't describe the necessary electrical wiring here:
it's rather trivial, just imagine famous HASP ASIC and
93C46X EEPROM and a bunch of diodes...
Such EEPROM is not protected and can be soldered away and
analyzed - well, it's not necessary: it can be read/written in
place much more easily..
Soon after publishing part II I was told that memory is
accessed through MicroWire(tm) protocol - and so opcodes
0100100000 and 0100010000 stand for "bulk erase" and
"bulk write" respectively (do not forget to save your HASP
memory content before you decide to play with them:) - many
thanks to Highway SÅar for that info!
Very interesting things came from the "secret table". Let's look
again at this neat 64-bit-to-one boolean function, that I prefer
to arrange as 8x8 table. Here is the snapshot for one of my HASPs:
0 1 0 1 1 0 0 1 please note, number of 1s and 0s are equal and
1 1 0 1 1 0 0 0 all columns exhibit some very clear symmetrical
0 1 0 0 0 0 0 1 patterns. I have observed about 10 such tables
1 1 0 0 0 0 0 0 (not a big number for solid statistics, BTW)
0 1 1 1 1 0 1 1 and everywhere I saw only vectors from the set
1 1 1 1 1 0 1 0 { 00000000, 11111111, 10101010, 01010101,
0 1 1 0 0 0 1 1 11001100, 00110011, 11110000, 00001111 }
1 1 1 0 0 0 1 0 (how close to the truth was I!! -- see appendix)
This observation moved me to the following explanation of the
boolean's output: input actually consists of two triads, one to
select a certain bit from the other, invert or not invert it and
so generate a vector from the set above..
*** ***
| | For each boolean we have thus a complexity of
| selector 8 triads (or 24bits..) - so Aladdine could not
| make more than 16M unique HASPs :)
bits to be selected, add an imaginary 4th wire for a constant
input - totals in 4 + inverted ==> 8 vectors!
All HASPs I've tested had symmetrical booleans - I strongly
believe it is this that made some independent testers trust
in HASP API#2 good security... The reason is that linear
congruential RNG, though very weak, provide "linear", i.e.
uniform performance on bin test - and if boolean is also
symmetrical (in a crypto sense, i.e. it has equal number
of 0s and 1s) the output would be rather "random-looking"
and non-biased for simple statistical tests if only boolean
isn't degenerately symmetrical (in usual sense). But it's all
my fabrications, maybe the HASP designers never took this into
account, concentrated rather on production costs... and cut
costs on good encryption... they must have thought that neither
the (gullible) programmers nor the (incompetent) testers would
ever have found out the intrinsic weakness of this scheme...
Observation of that symmetry really helps when reconstructing
secret tables by some known HASP answers but I never expected that
the key to HASP secret table structure had been in my hands
all the time! But listen to the real story!...
At the beginning of May two russian crackers (MeteO and Fixit)
have found by trial&error and pure Zen pondering the strongest
correlation between the secret table boolean and the HASP password!!!
As MeteO said: "now HASP is really DEAD", there's nothing left except
EEPROM.. Automatically all the problems with ambiguous password
detection vanished, coz now one can draw a secret table from the
password and the contrary as well! YOU CAN DERIVE the valid password
from the secret table (which is observable after a quick session of
password bruteforcing)!
The relevant code is presented in appendix. Now I would like to
give some finalizing comments for my "Undocumented HASP" essay...
I hope you survived boredom reading through this...
Well, I hope this text was useful. Its main purpose was not
to show you what's inside HASP, which proved fairly easy, but to show
you all the IMPORTANCE to dig deeper in order
to UNDERSTAND things.
As far as I remember the black magic of cybernetics, Ashby law states
that the required variety of regulator must exceed those of the system
being regulated.
So whenever someone tries purposely to lower the amount of relevant
information available to you (Micro$oft, anti-reverser regulators,
obfuscating programmers...) he actually lowers your required variety
- and you become therefore much more controllable! (Sorry, I should stop
this rambling here, it certainly needs more preparation - but I guess
that now you yourself have athered a different vision than before,
haven't you? :)
Another note: remember that "shoulders principle"? When I bumped into
MeteO's results I was at first dumbfounded, but he reassured me - "After
all, without your findings we wouldn't have gone any further.." And I
believe that the open +HCU university is playing indeed a great role
"to make bridges, not walls"!
Yours faithfully, --Bajunny
Thanks to:
MeteO and Fixit,
Highway SÅar,
Shaman,
and, of course, to all +crackers and to the +HCU!
"Special" thanks to the "programmers" of
Aladdin Knowledge Systems Ltd. for their laziness and
their lame attempts to obfuscate their really dumb and
ugly code...
APPENDIX
--------
// TOTAL DISCLOSURE of HASP codegen!!!
// ------- slightly bugfixed.. --------
/**************************************************************************
*
* This code is only for demo and educational use!
*
* The HASP(R)codegenerator and its documentation are copyrighted by //UCL.
* All rights reserved.
*
* This is *complete* HASP seed code generator for NetHASP(TM), MacHASP(TM),
* DataHASP(TM), TimeHASP(TM), SerialHASP(TM), HASP36(TM), MemoHASP36(TM),
* NetHASP36(TM), OpenHASP(TM), HASPCard(TM) of Aladdin Knowledge Systems Ltd.
*
* (c)1998 by MeteO, Fixit
* e-mail us: meteo@null.net
* admin@fixit.spb.ru
*************************************************************************/
#include
long pwd;
char al_buf[8];
static unsigned char ch[10];
unsigned int tab[64];
unsigned int seed,j,k;
HASP_rows[8][8]={
{0,0,0,0,0,0,0,0},
{0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0},
{0,0,1,1,0,0,1,1},
{1,1,0,0,1,1,0,0},
{0,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,0},
{1,1,1,1,1,1,1,1}
};
/***************************************
The table is represented as triads
***************************************/
void xor_pwd(void)
{
int i;
pwd^=0x09071966; /* Guess, whose birthday.. ;) */
for(i=0;i<8;i++)
{
al_buf[i]= pwd & 7;
pwd = pwd >> 3;
}
};
/***************************************
Main function (HASP_seed)
Original code by bajunny
****************************************/
void emulate_func2( unsigned short seed)
{
int i, j;
for(i=0;i<8;i++)
{
ch[i] = 0;
for(j=0;j<8;j++)
{
seed *= 0x1989;
seed += 5;
ch[i] |= (tab[(seed>>9)&0x3f]) <7-j);
}
}
}
void main(void)
{
int i;
printf("\nInput 1st HASP password:");
scanf("%4X",(int*) &j);
printf("Input 2nd HASP password:");
scanf("%4X",(int*) &k);
pwd=(long) k*0x10000+j;
printf("\nInput HASP seedcode:");
scanf("%x", (int*) &seed);
xor_pwd();
/************************************
Compute universal secret table
*************************************/
for(i=0;i<8;i++){
for(j=0;j<8;j++){tab[i+j*8]=HASP_rows[al_buf[i]][j];}
}
for(i=0;i<8;i++){
for(j=0;j<8;j++){printf("%1.1d",tab[i*8+j]);}
printf("\n");
}
emulate_func2(seed);
for(i=0;i<4;i++)
{printf("%2.2X%2.2X ", ch[i*2+1],ch[i*2]);}
}
// ------------- end of transmission -----------------
I *strongly* believe the contents of this "Ob Duh" section should
be obvious to you after all that reading, so just close the eyes
and let it visualize in your head..
You are deep inside fravia's page of reverse engineering,
choose your way out:
Back to Advanced
Back to
project 3
homepage
links
search_forms
+ORC
students' essays
academy database
reality cracking
how to search
javascript wars
tools
anonymity academy
cocktails
antismut
CGI-scripts
mail_fravia+
Is reverse engineering legal?