Kausalität betrifft die Abfolge aufeinander bezogener Ereignisse und Zustände.
Ein Ereignis ist den Browser Opera seit wirklich langer Zeit zu nutzen und sich auch dabei gut zu fühlen.
Das andere Ereigniss ist der Moment in dem man mitbekommt das Facebook vielleicht Opera kauft. Die Wirkung kann man sich vorstellen ツ
Wenn man jetzt noch seine ganzen Passwörter in Opera gespeichert hat, ist man vor ein Problem mit einer Datei namens wand.dat gestellt. Man unterliegt dem Zwang bei einem vielleicht stattfindenden
Browserwechsel die Passwörter aus dieser Datei herauszubekommen.
Man könnte nun wine, Windows in einer virtuellen Maschine etc. installieren, ein Windowsprogramm aus obskuren Quellen dafür nutzen oder eine Datei unter Linux kompilieren und das ganze per Shell lösen.
Bei letzerer Wahl ist der Vorteil, man hat Einblick in die Source und ist sich sicher, dass die Passwörter in den eigenen Händen bleiben.
// sna@reteam.org - 6th of April 2005 // updated by theultramage@gmail.com - 12th of August 2009 #include "md5/md5.h" // TODO:from openssl/crypto #include "des/des.h" // from openssl/crypto #include <io.h> // filelength() #include <memory.h> #define MAX_DATA_SZ 1024 struct block { unsigned int blocksize; unsigned int keysize; unsigned char key[DES_KEY_SZ]; // assume fixed size unsigned int datasize; unsigned char data[MAX_DATA_SZ]; // assume max. length }; const unsigned char opera_salt[11] = { 0x83, 0x7D, 0xFC, 0x0F, 0x8E, 0xB3, 0xE8, 0x69, 0x73, 0xAF, 0xFF }; unsigned int reverse(unsigned int value) { unsigned char oldA[4], newA[4]; memcpy(oldA, &value, 4); newA[0] = oldA[3]; newA[1] = oldA[2]; newA[2] = oldA[1]; newA[3] = oldA[0]; memcpy(&value, newA, 4); return value; } int wmain(int argc, wchar_t **argv) { if(argc != 3) { printf("Usage: unwand <opera wand file> <output file>n"); return 1; } FILE *fdWand = _wfopen(argv[1], L"rb"); if(NULL == fdWand) { perror("Failed to open file"); return 1; } unsigned long fileSize = filelength(fileno(fdWand)); unsigned char *wandData = (unsigned char *)malloc(fileSize); if(NULL == wandData) { fclose(fdWand); perror("Memory allocation failed"); return 1; } rewind(fdWand); fread(wandData, fileSize, 1, fdWand); fclose(fdWand); FILE* fdPass = _wfopen(argv[2], L"w, ccs=UTF-8"); if( fdPass == NULL ) { perror("Failed to open file"); return 1; } // my file starts here ^^; unsigned long wandOffset = 36; // main loop, find and process encrypted blocks while(wandOffset < fileSize) { // try do { block b; block* pb = (block*)(wandData + wandOffset); // length of following data b.blocksize = reverse(pb->blocksize); b.blocksize += sizeof(b.blocksize); // key length and key b.keysize = reverse(pb->keysize); if( b.keysize != DES_KEY_SZ ) break; // no match memcpy(b.key, pb->key, b.keysize); // data length and data b.datasize = reverse(pb->datasize); if( b.blocksize != sizeof(b.blocksize) + sizeof(b.keysize) + b.keysize + sizeof(b.datasize) + b.datasize ) break; // no match memcpy(b.data, pb->data, b.datasize); // hashing of (salt, key) and (hash, salt, key) unsigned char hashSignature1[MD5_DIGEST_LENGTH]; unsigned char hashSignature2[MD5_DIGEST_LENGTH]; unsigned char tmpBuffer[256]; memcpy(tmpBuffer, opera_salt, sizeof(opera_salt)); memcpy(tmpBuffer + sizeof(opera_salt), b.key, DES_KEY_SZ); MD5(tmpBuffer, sizeof(opera_salt) + DES_KEY_SZ, hashSignature1); memcpy(tmpBuffer, hashSignature1, sizeof(hashSignature1)); memcpy(tmpBuffer + sizeof(hashSignature1), opera_salt, sizeof(opera_salt)); memcpy(tmpBuffer + sizeof(hashSignature1) + sizeof(opera_salt), b.key, DES_KEY_SZ); MD5(tmpBuffer, sizeof(hashSignature1) + sizeof(opera_salt) + DES_KEY_SZ, hashSignature2); // schedule keys. key material from hashes DES_key_schedule key_schedule1, key_schedule2, key_schedule3; DES_set_key_unchecked((const_DES_cblock *)&hashSignature1[0], &key_schedule1); DES_set_key_unchecked((const_DES_cblock *)&hashSignature1[8], &key_schedule2); DES_set_key_unchecked((const_DES_cblock *)&hashSignature2[0], &key_schedule3); // initialization vector from result of above code DES_cblock iVector; memcpy(iVector, &hashSignature2[8], sizeof(DES_cblock)); // decrypt wand data in place using 3DES-CBC DES_ede3_cbc_encrypt(b.data, b.data, b.datasize, &key_schedule1, &key_schedule2, &key_schedule3, &iVector, DES_DECRYPT); // printf("%4.4X - %u - %u - %un", wandOffset, b.blocksize, b.keysize, b.datasize); // zero-terminate string for safety wchar_t* text = (wchar_t *)b.data; text[b.datasize/2] = '\0'; /* for( unsigned int i = 0; i < b.datasize/2; ++i ) if( text[i] == L'u0606' || text[i] == L'u0808' ) text[i] = '\0'; // wtf... */ // finally, write output fwprintf(fdPass, L"%sn", text); } while(0); // finally // crawl the data file byte by byte :) wandOffset++; } free(wandData); return 0; }
Nun wird das ganze noch kompiliert und dann kann man seine Datei auslesen. Vorrausetzung dafür sind bei Debian installierte build-essentials und libssl-dev.
seraphyn@takeshi: ~/tmp $ g++ -Wall -o unwand -lssl unwand.cpp seraphyn@takeshi: ~/tmp $ ./unwand ~/.opera/wand.dat >> Decryptoperawand
Opera, bitte verkaufe Dich nicht an Facebook.
leider nicht kompilierbar!
~/wand# g++ -Wall -o unwand -lssl decrypt.cpp
decrypt.cpp:35:5: warning: second argument of ‘int main(int, wchar_t**)’ should be ‘char **’ [-Wmain]
decrypt.cpp: In function ‘int main(int, wchar_t**)’:
decrypt.cpp:43:39: error: ‘_wfopen’ was not declared in this scope
decrypt.cpp:50:52: error: ‘filelength’ was not declared in this scope
decrypt.cpp:138:31: error: ‘fwprintf’ was not declared in this scope
Gruß
Oliver
Kann ich mir bei einem Programm aus dem Jahre 2009 mit einem Post aus dem Jahr 2012 definitiv vorstellen, dass es nicht mehr geht.
Sollte man auf eine neuen Versionsstand bringen. Du kannst ja dann den Code auf Github legen und den Link hier posten.
Danke für die Information.
Frohes Fest und einen guten Rutsch