Membongkat FED 1.30
Membongkar Program enkripsi FED versi 1.30
oleh: Budi Sukmawan
Program FED (File Encryptor and Decryptor) versi 1.30 tampaknya dibuat menggunakan Delphi 3.0 (atau 2.0) terdiri dari dua buah unit yaitu uUtama (uUtama.pas) dan uAbout (uAbout.pas). Unit uUtama terdiri dari form bernama MainForm dengan beberapa method, yang terpenting adalah: procedure DecryptFile dan procedure EncryptFile.
Dari hasil pengamatan, bagian penting dari program ini adalah kurang lebih sebagai berikut:
type
TFEDHeader = packed record
r: array [0..2] of byte;
Id: array [0..6] of Char;
pad1: byte;
pad2: byte;
end;
procedure TMainForm.DecryptFile;
var
n: Integer;
begin
.
.
for n := 0 to buflen-1 do
begin
bufferp[n] := buffer[n] xor Hi(kunci);
Inc(kunci, buffer[n]);
kunci := kunci * $3565 + 1;
end;
.
.
end;
procedure TMainForm.EncryptFile;
var
n: Integer;
begin
.
.
for n := 0 to buflen-1 do
begin
buffer[n] := buffer[n] xor Hi(kunci);
Inc(kunci, buffer[n]);
kunci := kunci * $3565 + 1;
end;
.
.
end;
Catatan: kunci adalah sebuah variabel Word, sedangkan buffer dan bufferp adalah variabel array dari tipe Byte.
Fitur-fitur dari program ini adalah sebagai berikut:
- Dapat mengenkrip secara cepat.
- Mensuport drag and drop untuk source file.
- Mengenkrip dengan menggunakan kunci bilangan 1 sampai 65535.
- Interface yang (sangat) sederhana.
- Sebuah file yang dienkrip dengan kunci yang sama tampaknya akan menghasilkan file yang berbeda-beda dengan panjang file yang juga berbeda-beda.
- Tampaknya informasi tentang kunci tidak disimpan dalam file enkripsi dalam bentuk apapun karena program akan mendekrip file walaupun kuncinya salah dan tentu saja dengan menghasilkan file yang salah.
Dari beberapa data di atas dapat disimpulkan bahwa program enkripsi ini mempunyai beberapa kelemahan yang sangat fatal terutama dari segi keamanannya, yang dapat diuraikan sebagai berikut:
- Dengan hanya menggunakan kunci bilangan dari 1 sampai 65535 maka kombinasi kunci sangat sedikit yaitu 2^16 - 1 atau 65535, dengan cara brute force (mencoba semua kunci yang mungkin) menggunakan komputer dengan prosesor Intel Celeron 333 hanya dibutuhkan beberapa detik saja.
- Dari procedure EncryptFile dan DecryptFile di atas dapat dilihat bahwa program ini mengenkripsi dengan menggunakan metoda kombinasi dengan stream dari sebuah Multiplicative Congruential PRNG (Pseudo Random Number Generator) yang tidak aman digunakan sebagai metoda enkripsi.
- Seperti dijelaskan di atas, file yang sama dan dienkrip dengan kunci yang sama tampaknya akan menghasilkan file yang berbeda-beda. Hal ini tidak sepenuhnya benar karena sebenarnya setelah header akan disisipkan bilangan random sebanyak pad1 (lihat format header diatas / TFEDHeader) baru ciphertext lalu rangkaian bilangan random lagi sebanyak pad2. Dengan cara ini akan dihasilkan file enkrip dengan panjang yang berbeda-beda dengan file aslinya tetapi sebenarnya ciphertext nya sendiri akan sama disetiap file dengan lokasi dari awal file sebanyak SizeOf(Header) + Header.pad1.
Untuk membongkar file hasil enkripsi dengan program ini dapat dilakukan dengan beberapa cara yaitu:
- Brute force Attack, yaitu dengan mencoba semua kunci yang mungkin kemudian kita mengamati rangkaian plaintext yang dihasilkan. Dengan cara ini kita harus mengamati sebanyak 65535 rangkaian, tetapi hal ini tidaklah telalu sulit.
- Known Plaintext Attack, bila kita mengetahui format file yang dienkrip maka kita mengetahui data-data dari file tersebut yang dapat digunakan untuk mencari kuncinya. Biasanya sebuah file data dari sebuah aplikasi mempunyai header dengan identifikasi tertentu, misalnya PKZip mempuyai identifikasi 'PK', file exe win32 'MZP', file doc WinWord 97 'D0 CF 11 E0 A1 B1 1A E1', file teks mungkin hanya mempunyai rangkaian karakter dari ASCII 10 sampai 127. Bila kita mempunyai informasi ini maka dengan mudah kita akan mendapatkan kuncinya.
Masih ada metoda-metoda lain untuk membongkar file enkrip dari program ini tetapi baru kedua metoda ini yang telah saya coba terapkan. Dan tampaknya program tidak memeriksa terhadap kesalahan pemasukan kunci jadi kemungkinan tidak ada informasi apapun tentang kunci yang disimpan oleh program di dalam file hasil enkripsi. Mudah-mudahan dugaan saya ini benar dan pembuatnya cukup cerdik untuk tidak menyimpan informasi tentang kunci di dalam file hasil enkripsi karena bila disimpan akan semakin memperlemah keamanannya.
Untuk membongkar file hasil enkripsi dari program ini saya mencoba membuat program yang sangat sederhana untuk mencari kunci dari file enkripsi. Program tersebut merupakan program win32 console dan dapat di download disini [brfed.zip]. Penggunaan program sangat sederhana yaitu dijalankan dari MS-DOS Prompt Windows 95/98, contohnya sebagai berikut:
brfed testfile.txt key.txt
atau
brfed testfile.txt key.txt filter.txt
Pada contoh pertama akan dihasilkan key.txt yang isinya terdiri dari dua kolom yaitu kolom pertama kunci yang dicoba dan kolom kedua plaintext yang dihasilkan. Anda perhatikan baris-baris yang tersebut, kemudian dengan memperhatikan kolom kedua bila ada baris yang dicurigai, coba kunci pada kolom pertama pada program FED. Pada contoh kedua digunakan filter, format file filter adalah sbb:
char=
text=
length=
contohnya:
char=10 - 127
length=16
Maka akan dicoba sebanyak 16 byte dari testfile.txt untuk menghasilkan plaintext yang setiap karakternya ada diantara karakter ASCII nomor 10 sampai 127.
contoh lain:
text=\208\207\17\224\161\177\26\225
length=16
Akan mencari kunci dari sebuah file WinWord 97 yang dienkrip dengan FED.
Seperti dapat dilihat pada contoh terakhir bila karakter tidak ada pada keyboard maka karakter tersebut dapat dituliskan dengan menggunakan tanda backslash ("\") kemudian nomor karakter ASCII-nya. Sedangkan bila kita akan menggunakan karakter backslash itu sendiri tuliskan "\\" (tanpa tanda petik).
Demikian hasil pengamatan saya terhadap program FED versi 1.30, sebenarnya saya masih ingin menyelidiki fungsi 3 byte random pada awal header file enkripsi, apakah ada hubungannya dengan informasi kunci atau tidak? dan terus terang sampai saat ini saya belum mengerti fungsi ke tiga byte ini, sayangnya saya tidak mempunyai banyak waktu untuk melakukan penelitian lebih lanjut. Bagi yang ingin meneliti lebih lanjut disini juga saya sertakan sebagian hasil disassembly dengan Turbo Debuger dan keterangan-keterangan yang saya dapatkan.
;
; procedure TMainForm.EncryptFile;
;
:00445D54 55 push ebp
:00445D55 8BEC mov ebp,esp
:00445D57 81C440F4FFFF add esp,FFFFF440
:00445D5D 53 push ebx
:00445D5E 56 push esi
:00445D5F 57 push edi
:00445D60 33DB xor ebx,ebx
:00445D62 899D48F4FFFF mov [ebp-00000BB8],ebx
:00445D68 894DF8 mov [ebp-08],ecx
:00445D6B 8955FC mov [ebp-04],edx
:00445D6E 8B7508 mov esi,[ebp+08] <--- kunci
:00445D71 8B45FC mov eax,[ebp-04]
:00445D74 E827DEFBFF call FED.00403BA0 <--- _LStrAddRef{str: AnsiString}
:00445D79 8B45F8 mov eax,[ebp-08]
:00445D7C E81FDEFBFF call FED.00403BA0
:00445D81 33C0 xor eax,eax
:00445D83 55 push ebp
:00445D84 68FA5F4400 push 00445FFA
:00445D89 64FF30 push fs:dword ptr [eax]
:00445D8C 648920 mov fs:[eax],esp
:00445D8F 8B55FC mov edx,[ebp-04]
:00445D92 8D8598FEFFFF lea eax,[ebp-00000168]
:00445D98 E845EDFBFF call FED.00404AE2 <--- _Assign(VAR t: Text; s: PChar);
:00445D9D BA01000000 mov edx,00000001
:00445DA2 8D8598FEFFFF lea eax,[ebp-00000168]
:00445DA8 E86CF0FBFF call FED.00404E19 <--- _ResetFile(VAR f: File; recSize: Longint);
:00445DAD E892C9FBFF call FED.00402744 <--- __IOTest
:00445DB2 8B55F8 mov edx,[ebp-08]
:00445DB5 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445DBB E822EDFBFF call FED.00404AE2 <--- _Assign(VAR t: Text; s: PChar);
:00445DC0 BA01000000 mov edx,00000001
:00445DC5 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445DCB E860F0FBFF call FED.00404E30 <--- _RewritFile(VAR f: File; recSize: Longint);
:00445DD0 E86FC9FBFF call FED.00402744 <--- __IOTest
:00445DD5 E8E6C9FBFF call FED.004027C0 <--- Randomize;
:00445DDA B864000000 mov eax,00000064
:00445DDF E8F0CBFBFF call FED.004029D4 <--- random($64)
:00445DE4 8BD8 mov ebx,eax
:00445DE6 B823000000 mov eax,00000023
:00445DEB E8E4CBFBFF call FED.004029D4 <--- random($23)
:00445DF0 40 inc eax
:00445DF1 8945EC mov [ebp-14],eax
:00445DF4 B864000000 mov eax,00000064
:00445DF9 E8D6CBFBFF call FED.004029D4 <--- random($64)
:00445DFE 40 inc eax
:00445DFF 8945E8 mov [ebp-18],eax
:00445E02 889D4CF5FFFF mov [ebp-00000AB4],bl <-- Header.r[0]
:00445E08 8D8548F4FFFF lea eax,[ebp-00000BB8]
:00445E0E 50 push eax
:00445E0F 899D40F4FFFF mov [ebp-00000BC0],ebx
:00445E15 C68544F4FFFF00 mov byte ptr [ebp-00000BBC],00
:00445E1C 8D9540F4FFFF lea edx,[ebp-00000BC0]
:00445E22 33C9 xor ecx,ecx
:00445E24 B814604400 mov eax,00446014
:00445E29 E86A19FCFF call FED.00407798
:00445E2E 8B9548F4FFFF mov edx,[ebp-00000BB8]
:00445E34 8D854CF4FFFF lea eax,[ebp-00000BB4]
:00445E3A B9FF000000 mov ecx,000000FF
:00445E3F E884DBFBFF call FED.004039C8 <----- _LStrToString
:00445E44 8D954CF4FFFF lea edx,[ebp-00000BB4]
:00445E4A 8D45E5 lea eax,[ebp-1B]
:00445E4D B102 mov cl,02
:00445E4F E83CCAFBFF call FED.00402890 <----- _PStrNCpy
:00445E54 8A45E6 mov al,[ebp-1A]
:00445E57 88854DF5FFFF mov [ebp-00000AB3],al <-- Header.r[1]
:00445E5D 8A45E7 mov al,[ebp-19]
:00445E60 88854EF5FFFF mov [ebp-00000AB2],al <-- Header.r[2]
:00445E66 C6854FF5FFFF53 mov byte ptr [ebp-00000AB1],53 \
:00445E6D C68550F5FFFF6F mov byte ptr [ebp-00000AB0],6F |
:00445E74 C68551F5FFFF6E mov byte ptr [ebp-00000AAF],6E |
:00445E7B C68552F5FFFF79 mov byte ptr [ebp-00000AAE],79 > Header.Id
:00445E82 C68553F5FFFF46 mov byte ptr [ebp-00000AAD],46 |
:00445E89 C68554F5FFFF45 mov byte ptr [ebp-00000AAC],45 |
:00445E90 C68555F5FFFF44 mov byte ptr [ebp-00000AAB],44 /
:00445E97 8B45EC mov eax,[ebp-14]
:00445E9A 888556F5FFFF mov [ebp-00000AAA],al <-- Header.Pad1
:00445EA0 8B45E8 mov eax,[ebp-18]
:00445EA3 888557F5FFFF mov [ebp-00000AA9],al <-- Header.Pad2
:00445EA9 8D45F0 lea eax,[ebp-10]
:00445EAC 50 push eax
:00445EAD 8D954CF5FFFF lea edx,[ebp-00000AB4]
:00445EB3 B90C000000 mov ecx,0000000C
:00445EB8 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445EBE E825EDFBFF call FED.00404BE8
:00445EC3 E87CC8FBFF call FED.00402744 <--- __IOTest
:00445EC8 8B5DEC mov ebx,[ebp-14]
:00445ECB 85DB test ebx,ebx
:00445ECD 7E17 jle FED.00445EE6 (00445EE6)
:00445ECF 8DBD4CF5FFFF lea edi,[ebp-00000AB4]
:00445ED5 B8FF000000 mov eax,000000FF
:00445EDA E8F5CAFBFF call FED.004029D4 <--- random($FF)
:00445EDF 40 inc eax
:00445EE0 8807 mov [edi],al
:00445EE2 47 inc edi
:00445EE3 4B dec ebx
:00445EE4 75EF jne FED.00445ED5 (00445ED5)
:00445EE6 8D45F0 lea eax,[ebp-10]
:00445EE9 50 push eax
:00445EEA 8D954CF5FFFF lea edx,[ebp-00000AB4]
:00445EF0 8B4DEC mov ecx,[ebp-14]
:00445EF3 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445EF9 E8EAECFBFF call FED.00404BE8
:00445EFE E841C8FBFF call FED.00402744 <--- __IOTest
:00445F03 8D45F4 lea eax,[ebp-0C]
:00445F06 50 push eax
:00445F07 8D954CF5FFFF lea edx,[ebp-00000AB4]
:00445F0D B900080000 mov ecx,00000800
:00445F12 8D8598FEFFFF lea eax,[ebp-00000168]
:00445F18 E867ECFBFF call FED.00404B84
:00445F1D E822C8FBFF call FED.00402744 <--- __IOTest
:00445F22 8B5DF4 mov ebx,[ebp-0C]
:00445F25 85DB test ebx,ebx
:00445F27 7E25 jle FED.00445F4E (00445F4E)
:00445F29 8D854CF5FFFF lea eax,[ebp-00000AB4]
:00445F2F 8A10 mov dl,[eax] \
:00445F31 0FB7CE movzx ecx,si |
:00445F34 C1E908 shr ecx,08 |
:00445F37 32D1 xor dl,cl |
:00445F39 8810 mov [eax],dl |
:00445F3B 33D2 xor edx,edx |
:00445F3D 8A10 mov dl,[eax] > rutin enkripsi
:00445F3F 6603F2 add si,dx |
:00445F42 6669D66535 imul dx,si,3565 |
:00445F47 42 inc edx |
:00445F48 8BF2 mov esi,edx |
:00445F4A 40 inc eax |
:00445F4B 4B dec ebx /
:00445F4C 75E1 jne FED.00445F2F (00445F2F)
:00445F4E 8D45F0 lea eax,[ebp-10]
:00445F51 50 push eax
:00445F52 8D954CF5FFFF lea edx,[ebp-00000AB4]
:00445F58 8B4DF4 mov ecx,[ebp-0C]
:00445F5B 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445F61 E882ECFBFF call FED.00404BE8
:00445F66 E8D9C7FBFF call FED.00402744 <--- __IOTest
:00445F6B 837DF400 cmp dword ptr [ebp-0C],00000000
:00445F6F 7408 je FED.00445F79 (00445F79)
:00445F71 8B45F0 mov eax,[ebp-10]
:00445F74 3B45F4 cmp eax,[ebp-0C]
:00445F77 748A je FED.00445F03 (00445F03)
:00445F79 8B5DE8 mov ebx,[ebp-18]
:00445F7C 85DB test ebx,ebx
:00445F7E 7E17 jle FED.00445F97 (00445F97)
:00445F80 8DB54CF5FFFF lea esi,[ebp-00000AB4]
:00445F86 B8FF000000 mov eax,000000FF
:00445F8B E844CAFBFF call FED.004029D4 <--- random($FF)
:00445F90 40 inc eax
:00445F91 8806 mov [esi],al
:00445F93 46 inc esi
:00445F94 4B dec ebx
:00445F95 75EF jne FED.00445F86 (00445F86)
:00445F97 8D45F0 lea eax,[ebp-10]
:00445F9A 50 push eax
:00445F9B 8D954CF5FFFF lea edx,[ebp-00000AB4]
:00445FA1 8B4DE8 mov ecx,[ebp-18]
:00445FA4 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445FAA E839ECFBFF call FED.00404BE8
:00445FAF E890C7FBFF call FED.00402744 <--- __IOTest
:00445FB4 8D8598FEFFFF lea eax,[ebp-00000168]
:00445FBA E88DECFBFF call FED.00404C4C
:00445FBF E880C7FBFF call FED.00402744 <--- __IOTest
:00445FC4 8D854CFDFFFF lea eax,[ebp-000002B4]
:00445FCA E87DECFBFF call FED.00404C4C
:00445FCF E870C7FBFF call FED.00402744 <--- __IOTest
:00445FD4 33C0 xor eax,eax
:00445FD6 5A pop edx
:00445FD7 59 pop ecx
:00445FD8 59 pop ecx
:00445FD9 648910 mov fs:[eax],edx
:00445FDC 6801604400 push 00446001
:00445FE1 8D8548F4FFFF lea eax,[ebp-00000BB8]
:00445FE7 E884D7FBFF call FED.00403770
:00445FEC 8D45F8 lea eax,[ebp-08]
:00445FEF BA02000000 mov edx,00000002
:00445FF4 E89BD7FBFF call FED.00403794
:00445FF9 C3 ret
Sebagai kesimpulan akhir: Program enkripsi FED 1.30 sebagai sebuah program shareware seharga US $10 dari segi keamanan sangat lemah dan tidak dapat diandalkan untuk melindungi data-data penting. Masih banyak program enkripsi yang dapat dipergunakan secara bebas yang jauh lebih baik, beberapa diantaranya: Cryptext v3.21 (dengan metoda enkripsi RC4), PGP 6.51i (CAST5, IDEA, Triple DES) yang mempunyai fasilitas self decrypting archive dan WinArchiver 1.30 (Blowfish), dengan tampilan mirip Winzip, dibuat dengan menggunakan Delphi, mempunyai fasilitas self extractor dan tersedia lengkap beserta source programnya.
© 10 November 1999 - Budi Sukmawan.