Crack*. mdb currently all versions of the password-vulnerability warning-the black bar safety net

ID MYHACK58:62200610011
Type myhack58
Reporter 佚名
Modified 2006-06-26T00:00:00


On the Access97 password hack, in a lot of sites and magazines have been introduced. Here I simply repeat it.

In the mdb file the 0x42 Byte 1-3 byte, respectively, with 0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13 XOR can be obtained after the database password. But in Access 2 0 0 0 2 0 0 2 The Version key is no longer fixed 1 3 bytes. And the encrypted mode also has changed.

After ccrun with an afternoon of time to study, and finally the Access2000 encryption way of figuring out. Hey. This will be a coupling of the ideas posted, I hope useful for everyone.

I used the analysis tool is UltraEdit32 v10. 0 0, the programming tool is C++ Builder 6.0

Through the use UltraEdit32 analysis, found that Access2000 and Access2002 database encryption in the same manner, so the following is only for Access2000 mdb file. There is I use the 1 6 hexadecimal number representation, so the front of the 0x if you're using VB or other, pay attention to the value, Oh.

First with AccessXP created with an empty password database file db1. mdb, contains a table which has a field that is not filled with any data. Save and exit and then copy a copy for db2. mdb to open exclusive 2. mdb, and add a password 1 3 2 4 5 6 7 8 9 0 1 2 3 Save and exit.

With UltraEdit32 open the two databases, and compare. My comparison method is also very simple. In UltraEdit32, a quick click Back and forth is the open file's tab(that is in two files between the switch back and forth, huh. Stupid way?), found from the beginning of the file 0x42 bytes change.

db1. mdb 00000040h: BC 4E BE 6 8 EC 3 7 6 5 D7 9C FA FE CD 2 8 E6 2B 2 5; The 00000050h: 8A 6 0 6C 0 7 7B 3 6 CD E1 DF B1 4F 6 7 1 3 4 3 F7 3C;

00000060h: B1 3 3 0C F2 7 9 5B AA 2 6 7C 2A 4F E9 7C 9 9 0 5 1 3; and db2. mdb 00000040h: BC 4E 8F 6 8 DE 3 7 5 6 D7 A8 FA CB CD 1E E6 1C 2 5; The 00000050h: B2 6 0 5 5 0 7 4B 3 6 FC E1 ED B1 7C 6 7 1 3 4 3 F7 3C;

00000060h: B1 3 3 0C F2 7 9 5B AA 2 6 7C 2A 4F E9 7C 9 9 0 5 1 3; and

In order to see clearly, I put a different byte plus the color. Seen in the doorway of the bar, Access97 later versions, the password bytes are no longer stored in a row, but separated by a one-byte memory one. And after the encryption. To to the decrypt method?, or the old-fashioned way“exclusive or”! 0xBE ^ 0x8F = 0x31, which happens to be the Ascii code"1". The next 0xEC ^ 0xDE = 0x32 happens to be the Ascii code of"2", huh. Until finally a different 0x4F ^ 0x7C =0x33, will be made of the character of synthetic string, is the password clear text“1 2 3 4 5 6 7 8 9 0 1 2 3", don't think this is a knock off. Because this one is just touching the right. Huh. I just started also think it's that simple, so with CB made a small program to try to understand a few mdb password are OK, but try to move the web forum of the mdb file when found out the password is wrong, the dizzy. So with the addition of a Remove mdb password tool looked, found that people can correctly remove the password, is Access2000 format, so feel Microsoft encrypted way still haven't study finish. Continue to work with UltraEdit32 open Action Network Forum database dvbbs. mdb, and I previously been encrypted database to do comparison and found different places a lot. Had to one byte one byte of the test。。。。 nnn times after the discovery of the first 0x62 at this byte plays a crucial role, temporarily referred to as the encryption flag.

db1. mdb //empty password 00000040h: BC 4E BE 6 8 EC 3 7 6 5 D7 9C FA FE CD 2 8 E6 2B 2 5; The 00000050h: 8A 6 0 6C 0 7 7B 3 6 CD E1 DF B1 4F 6 7 1 3 4 3 F7 3C;

00000060h: B1 3 3 0C F2 7 9 5B AA 2 6 7C 2A 4F E9 7C 9 9 0 5 1 3; and

db2. mdb //password:1 2 3 4 5 6 7 8 9 0 1 2 3 00000040h: BC 4E 8F 6 8 DE 3 7 5 6 D7 A8 FA CB CD 1E E6 1C 2 5; The 00000050h: B2 6 0 5 5 0 7 4B 3 6 FC E1 ED B1 7C 6 7 1 3 4 3 F7 3C;

00000060h: B1 3 3 0C F2 7 9 5B AA 2 6 7C 2A 4F E9 7C 9 9 0 5 1 3; and

dvbbs. mdb //密码 为

00000040h: BC 4E DB 6A 8 9 3 7 1 4 D5 F9 FA 8C CF 4F E6 1 9 2 7; and

00000050h: E4 6 0 1 5 0 5 0F 3 6 D1 E3 DF B1 5 3 6 5 1 3 4 3 EB 3E; and

00000060h: B1 3 3 1 0 F0 7 9 5B B6 2 4 7C 2A 4A E0 7C 9 9 0 5 1 3; and

How to test it, or XOR. Take 0x42 at the beginning of the byte 0xDB with empty password file 0x42 byte at the exclusive or, take 0x62 at the encryption flag and an empty password file 0x62 at byte exclusive-OR, then again to obtain the two values differ or:

(0xDB^0xBE)^(0x10^0x0C)=0x79 Hey. This value is the Ascii of"y", and then take the next bytes to remember the compartment of one byte takes one

(0x89^0xEC)^(0x10^0x0C)=0x79 Hey, would this byte should be"e", how to turn into a"y"? Try not with the latter two exclusive or values of the dissimilarity or, counting only 0x89^0xEC=0x65 get"e",ha. Oh right. Next

(0x14^0x65)^(0x10^0C)=0x6D get"m", the next

(0xF9^9C)=0x65 get"e", note that here are just these two numbers XOR. Behind everyone can be their try.

This summed up the law.

When decrypting, first remove the encrypted file from the file head start 0x62 at the bytes, with empty password database file the first 0x62 at dissimilar or, get an encryption flag.

Then from 0x42 at the beginning of every byte take a byte, to obtain 1 3 A encrypted password bytes, respectively, with empty password database file 0x42 at every one byte made of 1 to 3 bytes think of the XOR, to obtain 1 3 a password semi-finished products. Why is semi-finished yet, because the also to the 1 3-byte password for every one byte, and the encryption flag or dissimilar, and finally get 1 of the 3 bytes is the real password. Of course, if the middle of the 0x0 byte, then the password digit is not enough 1 3 bit. Directly show out of it.

In addition, I found that the encryption flag over time or the machine is different, so there is no panacea, but there is a reference on it. The following code is I'm writing this program when the acquired number, and I am writing this article is not a time, so the values are not the same, but the final decrypted result is the same. We can refer to it.

Oh, and one important thing is to first determine the database version, I use a simple approach, take 0x14 at byte, if it is 0 It is judged to be Access97, if it is 1 It is considered to be Access2000 or 2 0 0 2. Just at present there is no research out determine 2 0 0 0 2 0 0 2 The way, if who know, please pointing.


//Defined here to be 1 to 3 bytes as Access2000 exclusive OR of the source code. With the corresponding encryption flag is 0x13, the ccrun is hereby noted

//Of course you can use this group: BE EC 6 5 9C FE 2 8 2B 8A 6C 7B CD DF 4F and the A group corresponding to the encryption flag is 0x0c

//Oh. Program some Chaos, I hope you can understand. char PassSource2k[1 3]={0xa1,0xec,0x7a,0x9c,0xe1,0x28,0x34,0x8a,0x73,0x7b,0xd2,0xdf,0x50};

//Access97 the exclusive OR of the source code char PassSource97[1 3]={0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13};

void __fastcall TMainForm::GetMdbPass() { char PassStrTemp[2 6],Ver,EncrypFlag,t1; int FileHandle; String MdbPassword,MdbVersion,MdbFileName;

FileHandle=FileOpen(MdbFileName,fmOpenRead); if(FileHandle<0) { ShowMessage("File Open error!"); return; }

//Obtain the database version FileSeek(FileHandle,0x14,0); FileRead(FileHandle,&Ver,1);

//Obtain the encryption flag FileSeek(FileHandle,0x62,0); FileRead(FileHandle,&EncrypFlag,1);

//Read the encrypted password into the buffer FileSeek(FileHandle,0x42,0); FileRead(FileHandle,&PassStrTemp,2 6); FileClose(FileHandle);

if(Ver<1) { MdbVersion="Access 9 7"; if(int(PassStrTemp[0]^PassSource97[0])==0) MdbPassword="password is empty!"; else { MdbPassword=""; for(int i=0;i<1 3;i++) MdbPassword=MdbPassword+char(PassStrTemp[i]^PassSource97[i]); } } else { MdbVersion="Access 2 0 0 0 or 2 0 0 2"; MdbPassword=""; for(int i=0;i<1 3;i++) { if(i%2==0)


//Every byte with the encryption flag dissimilar or. Here the encryption flag is 0x13


t1=char(PassStrTemp[i*2]^PassSource2k[i]); MdbPassword=MdbPassword+t1; } } if(MdbPassword[1]<0x20||MdbPassword[1]>0x7e) MdbPassword="password is empty!"; EditMdbFileName->Text=MdbFileName; EditMdbPassword->Text=MdbPassword; EditMdbVersion->Text=MdbVersion; }