Unbreakable Encryption

“Emangnya nggak bisa dibongkar virusnya?”. Masih terkait dengan ransomware. Banyak orang yang sulit menerima bahwa dalam kasus tertentu tidak ada cara membongkar file yang terenkripsi tanpa mengetahui keynya walaupun kita bisa membongkar algoritmanya sampai sangat detail.

Konsep yang sepertinya sulit diterima oleh orang awam yang tidak memiliki dasar dalam kriptografi: bahwa ada kriptografi yang tidak bisa dijebol meskipun kita tahu dengan tepat apa algoritmanya (bahkan jika punya source codenya yang lengkap). Bahwa satu-satunya cara menjebol adalah dengan mengetahui kunci-nya. Dan bahwa kadang satu-satunya cara mencari keynya adalah dengan mencoba semua kemungkinan yang ada yang jumlahnya sangat besar.

Enkripsi Simetrik

Mari kita mulai dengan satu konsep kriptografi yang sederhana: one time pad. Ini adalah bentuk enkripsi sangat sederhana, tapi tidak mungkin bisa dipecahkan tanpa mengetahui key-nya. Dalam one time pad, keynya harus sama panjangnya atau lebih panjang dari pesan yang akan kita enkrip, dan keynya hanya boleh dipakai sekali.

Saya contohkan sederhana sekali: anggap huruf A=1, B=2, C=3, … , Z=26 dan 0 adalah spasi.  Sekarang jika saya punya pesan rahasia ini:XYZABCD. Apakah isi pesannya? Kuncinya adalah serangkaian bilangan, bisa negatif ataupun positif.

Jika kuncinya adalah: 1 -10 -18 0 12 2 15, maka pesannya ternyata adalah: YOHANES. Jika kuncinya adalah: -10 -4 -19 17 13 5 11, maka isi pesannya adalah: NUGROHO. Jika keynya adalah: -10 -4 -19 17 -1 5 -3, maka pesannya adalah NUGRAHA. Jika keynya dalah: -22 -20 -12 6 9 2 8 maka isinya adalah: BENGKEL.

Dalam kasus one time pad, meskipun saya sudah memberitahu BAGAIMANA (algoritma) enkripsinya, dan apa CIPHERTEXT-nya (teks yang sudah dienkripsi), maka Anda bisa mencoba-coba berbagai key yang bisa menghasilkan teks apapun (bisa saja kurang dari 7 huruf, dan sisanya spasi).

Kelemahan dari algoritma di atas adalah ini: jika saya ingin mengirim pesan ke seseorang, maka orang tersebut harus punya key yang sama. Sebuah key cuma bisa dipakai SEKALI, jika lebih dari sekali, maka ada kemungkinan tidak aman. Biasanya di jaman dulu ini dilakukan dengan menggunakan buku berisi angka-angka, dan buku yang sama dimiliki oleh pengirim dan penerima. Pengirim dan penerima hanya perlu membuat janji: di hari ke N tahun ini, gunakan halaman ke N.

Bagaimana angka-angka di buku itu dihasilkan? dengan acak, misalnya melempar dadu. Tapi kadang buku seperti itu terlalu rumit. Kita bisa juga menggunakan kode, daripada memiliki buku khusus, kita bisa saja menggunakan buku lain sebagai kuncinya. Contohnya kita bisa menyebutkan: “Buku Hitchikers Guide To Galaxy, edisi pertama, mulai halaman ke-7, kata ke-8”.

Jika pemilihan bukunya cukup acak, dan jumlah bukunya sangat banyak, maka cara ini cukup  aman dari serangan manual (masih mungkin bisa dipecahkan dengan komputer jika diberikan semua teks dari semua buku). Saya hanya ingin menekankan bahwa dari sebuah teks singkat (judul buku, edisi, nomor halaman) kita bisa membuat pesan yang panjang dan hampir sama amannya dengan one time pad.

Tentunya ini tetap tidak seaman one time pad karena jumlah buku di dunia ini terbatas, bisa dicek satu persatu mencari yang mana yang membentuk kalimat yang masuk akal, sedangkan di one time pad, jika kita mengecek setiap bilangan, maka pesannya bisa menjadi apa saja (tidak jelas mana pesan yang benar).

Sekarang jika Anda diberi tahu ALGORITMA pertukaran pesan menggunakan judul buku, edisi dan nomor halaman. Anda juga diberitahu teks hasil enkripsinya (CIPHERTEXT), tapi tidak diberi tahu keynya (buku apa, edisi berapa, halaman berapa), maka Anda tetap tidak bisa membaca pesannya. Anda perlu mencoba-coba semua buku.

Bentuk enkripsi seperti yang saya sebutkan termasuk dalam kategori: enkripsi simetrik, artinya yang menerima dan mengirim pesan harus punya kunci yang sama. Enkripsi yang saya pakai juga hanya merupakan “substitusi”, artinya hanya mengganti satu teks dengan teks lain. Cara lain enkripsi adalah dengan permutasi, artinya menukar posisi teks dengan sebuah kunci tertentu. Dan tentunya kombinasi keduanya bisa dipakai agar aman.

Contoh permutasi sangat sederhana adalah seperti ini: tiap 4 karakter ABCD menjadi CDAB, jadi JONATHAN dipecah menjadi JONA dan THAN. JONA dipermutasi menjadi NAJO dan THAN menjadi ANTH dan gabungannya menjadi NAJOANTH.  Dengan key yang pendek, enkripsi dengan permutasi SAJA akan mudah dipecahkan, tapi permutasi DAN substitusi akan menambah kesulitan analisis.

Kriptografi simetrik modern memiliki kemiripan dengan penjelasan sebelumnya: key yang sepertinya kecil misalnya 16 byte (1 byte = 8 bit, 16 byte = 128 bit) bisa dipakai untuk mengenkripsi file sebesar apapun dengan substitusi dan permutasi. Ini bisa dianalogikan seperti memakai “judul buku, nomor halaman” menjadi sebuah “kunci” untuk pesan yang panjang.

Walaupun 16 byte itu sepertinya kecil (dibandingkan ukuran file yang dalam orde megabyte atau gigabyte), tapi untuk mencoba satu persatu kemungkinan 16 byte kita harus mencoba 340282366920938463463374607431768211456 (2 pangkat 128) kemungkinan. Jika ada satu trilyun (10 pangkat 12) komputer yang bisa melakukan satu trilyun operasi perdetik, dibutuhkan lebih dari sejuta tahun untuk mencoba semua kemungkinan 2 pangkat 128.

Meskipun kita diberitahu dengan tepat setiap langkah yang dilakukan, dan diberi tahu data hasil enkripsinya, kita tetap tidak bisa membaca pesan aslinya tanpa keynya. Salah satu contoh enkripsi modern adalah AES, ada penjelasan bagus algoritma AES di sini. Setiap langkah enkripsi dijelaskan dalam bentuk karikatur.

Perlu dicatat bahwa proses enkripsi simetrik AES, DES, dsb sebenarnya sangat sederhana dan bisa diimplementasikan dengan mudah, hanya butuh ketelitian saja. Tidak ada hal ajaib atau algoritma kompleks yang perlu diimplementasikan. Tapi karena rawan bug, mengimplementasikan sendiri hanya bagus untuk tujuan belajar, bukan untuk dipakai di produk.

Sekarang bisa dipahami bahwa titik kelemahan sebuah sistem enkripsi adalah pada KEY-nya. Jika kita memiliki sebuah program enkripsi SIMETRIK, maka yang mengenkripsi dan yang mendekripsi harus memiliki key yang sama.

Jika Anda pergi ke rumah seorang mata-mata yang mengirim pesan dengan enkripsi simetrik, maka kemungkinan besar Anda akan menemukan kunci enkripsi di rumah itu. Kunci itu bisa dipakai untuk membongkar pesan-pesan yang ada.

Enkripsi Asimetrik

Sekarang saya akan jelaskan enkripsi “ajaib” berikutnya: Asymmetric encryption. Tidak ada versi sederhana enkripsi ini yang tidak melibatkan matematika, jadi saya analogikan saja dengan benda. Anda tahu gembok seperti ini:

Gembok ini bisa dipakai untuk mengirimkan pesan rahasia, caranya: yang ingin mengirim pesan ke saya saya berikan gemboknya, silahkan masukkan pesan ke kotak, dan kunci dengan gembok itu. Sekarang pesan itu sudah terkunci dan hanya saya yang bisa membukanya dengan kunci yang saya pegang.

Tentunya gembok biasa memiliki banyak kelemahan, misalnya dari lubang kuncinya bisa dianalisis kuncinya seperti apa. Gembok juga bisa dipatahkan atau dirusak. Tapi coba bayangkan gembok yang sangat canggih, memakai finger print recognition, memakai logam yang tidak bisa dipecahkan, atau mungkin mengandung bomb jika berusaha dibuka paksa.

Di dalam kriptografi Asimetrik, gembok dan kunci hanyalah dua bilangan yang memiliki relasi tertentu. Gembok dan kuncinya bisa dihasilkan dari bilangan acak yang memenuhi syarat tertentu. Gembok di sini adalah kunci publik (public key) dan kuncinya adalah kunci privat (private key). Jika dilakukan operasi X=enkrip(Y, KUNCI PUBLIK) maka dekrip hanya bisa dilakukan dengan Y=dekrip(X, KUNCI PRIVAT).

Salah satu contoh kriptografi asimetrik adalah RSA (nama ini dari nama depan para penemunya:Ron Rivest, Adi Shamir, dan Leonard Adleman) contoh yang lain misalnya ECC (Elliptic Curve Cryptography).

Kriptografi RSA ini juga tidak sulit, dan bisa diimplementasikan di berbagai bahasa dengan relatif mudah. Khusus untuk bahasa low level seperti C, kesulitannya biasanya adalah mengimplementasikan penanganan big integer (bilangan bulat dengan digit sangat banyak), sedangkan di bahasa lain seperti Python, PHP, Ruby, Java, C#, library Big Integer ini sudah built in. RSA ini begitu sederhana sehingga jadi tugas kuliah di banyak tempat (ini contohnya).

Harap jangan terpaku pada analogi gembok saya di level implementasi, analogi itu tidak akan cocok dengan implementasi algoritmanya. Gembok bersifat fisik yang bisa dibongkar dengan mudah, tapi bilangan memiliki sifat yang lebih sulit dimengerti. Kesamaan dari analogi gembok adalah: kriptografi asimetrik memiliki “biaya” besar, dalam arti butuh komputasi besar (artinya waktu yang lama) untuk mengenkrip file besar.

Sekarang jika Anda menemukan gembok saja di rumah seorang agen rahasia, Anda tetap tidak bisa membuka pesan yang ada. Anda butuh anak kunci untuk membuka gembok yang ada. Inilah kelebihan kritografi asimetrik: kunci dan gembok terpisah. Kita bisa menyebar gembok ke ribuan orang dan hanya pemilik kunci yang bisa membukanya.

Sebagai informasi: sistem enkripsi asimetrik ini dipakai untuk berkirim email dengan aman menggunakan PGP.

Mencari Kunci

Ada banyak ransomware di dunia ini, dan banyak yang memiliki kelemahan. Ada yang memakai enkripsi simetrik, ada yang memakai enkripsi asimetrik tapi keynya tapi disimpan lokal.

Dalam kasus ransomware: enkripsi dilakukan lokal, jadi ada kunci yang sempat ada lokal. Beberapa ransomware cukup ceroboh sehingga keynya disimpan di memori, dan bisa diekstraksi dengan melakukan RAM dump. Beberapa ransomware cukup ceroboh, keynya dikirim via jaringan, sehingga jika kita melakukan sniffing terhadap paket jaringan, maka kita bisa mendapatkan keynya.

Enkripsi yang dilakukan malware tertentu sangat bagus, sehingga tidak mungkin bisa mendapatkan keynya. Contoh dari malware ini adalah Teslaware, tapi untungnya mereka “menyerah” dan memberikan master keynya ke publik.

Sekarang mari saya detailkan dengan contoh dari WannaCry. WannaCry memakai kombinasi enkripsi simetrik untuk mengenkrip file, dan asimetrik untuk mengenkrip key yang dipakai mengenkrip file.

Pertama sebuah kunci RSA X dihasilkan di komputer lokal. Kunci ini adalah gembok (public) dan anak kuncinya (private). Ingat: dalam RSA kunci dan gembok hanyalah bilangan acak yang memiliki sifat tertentu.

Malware ini juga punya sebuah kunci RSA Y, tapi hanya public keynya saja (gemboknya saja). Setelah kunci RSA X dihasilkan, private key X langsung dienkrip (anak kunci X dimasukkan kotak dan digembok dengan kunci Y) dan lenyap dari memori. Malware ini menyimpan private key X yang sudah dienkrip tadi ke dalam sebuah file (namanya 00000000.eky). Public key X (gembok X) disimpan di 00000000.pky.

Hanya sepersekian detik (beberapa microsecond) saja private key (anak kunci) X ini ada di memori, tidak akan sempat dicari dan disimpan siapapun. Kalau kita iseng menjalankan malware di dalam debugger, menjalankan malware langkah demi langkah, baru kita bisa menangkap key ini, tapi jika sudah lewat key ini sudah hilang dari memori. Kalaupun ditemukan untuk satu komputer, key ini tidak akan berfungsi untuk komputer lain. Private key X ini juga tidak pernah dikirim ke manapun dalam proses enkripsi.

Berikutnya malware akan mencari semua file untuk dienkrip dari semua drive. Untuk tiap file yang akan dienkripsi, malware akan menghasilkan bilangan acak yang dijadikan kunci simetris S untuk file tersebut. File dibaca, dienkrip, dituliskan ke namafile.wncry. Tiap file punya kunci S yang berbeda. Tentunya jika kunci S ini disimpan apa adanya, maka kita bisa membukanya dengan mudah.

Sebelum mulai mengenkripsi satu file, key S segera digembok dengan kunci X dan dituliskan di header file namafile.wncry. Lalu S yang belum digembok dipakai untuk mengenkrip isi file. Setelah selesai, key S dihapus dari memori.

Jika misalnya malware belum selesai mengenkripsi sebuah dan kita bisa mem-pause seluruh proses dan mengambil “snapshot” isi seluruh RAM, maka kita mungkin bisa mendapatkan key file yang sedang diproses. Tapi file-file sebelumnya semuanya memiliki key S yang berbeda, jadi percuma saja. Jika kita bisa menghentikan prosesnya berarti file tersebut belum dihapus dan bisa dikembalikan, jadi keynya tidak berguna.

Sekarang bagaimana file-file itu bisa dibuka nantinya? Pertama perlu dijelaskan bahwa malware ini punya mode “trial”, yang sebenarnya agak curang. Di atas saya sebutkan bahwa enkripsi dilakukan dengan key S lalu disimpan di file setelah S dienkripsi. Malware ini memilih secara acak beberapa file yang bisa didecrypt gratis, dengan cara membuat beberapa file dengan ekstensi .wncyr (cyr bukan cry) yang tidak dienkripsi S-nya.

Pembukaan file hanya bisa dilakukan jika kita bisa mendekrip private key X (anak kunci X) yang telah dienkrip dengan public key Y (digembok dengan Y). Dekripsi private key X ini hanya bisa dilakukan dengan private key Y (yang dipegang oleh pembuat ransomware).

Jika seseorang membayar, maka pembayar perlu mengirimkan private key X yang sudah dienkrip tadi, lalu mengembalikan X yang didekrip. Jadi pembuat malwarenya tidak mengirimi kita dengan private key Y (karena jika begitu, semua X yang dikunci bisa dibuka).

Jadi dengan asumsi bahwa pembuat malwarenya tidak membuat kesalahan dalam proses enkripsinya (sejauh ini sih belum ada yang menemukan kesalahan), maka enkripsi ini aman. Satu-satunya cara membuka adalah dengan memiliki private key Y yang dipegang pembuat malware ini.

Cara lain yang mungkin adalah jika seseorang berhasil menemukan cara prime factorization yang cepat atau jika komputer kuantum bisa dibuat yang bisa menangani bilangan sebesar ini (perkiraan saat ini: 20-30 tahun lagi). Sejauh ini yang berhasil dibongkar adalah RSA 768 bit (akhir 2009, butuh 2 tahun), sedangkan yang dipakai oleh malware ini 2048 bit.

Untuk Anda yang masih penasaran bagaimana enkripsinya bekerja, sudah ada yang membaca dengan teliti isi malwarenya dan mengekstrasi bagian enkripsinya saja, tanpa bagian eksploitasi, tanpa pesan malware, dsb.

Hasil ekstraksi ini kemudian dituliskan ke file dalam bahasa C dan bisa dicompile di Windows. Sejauh perbandingan saya dengan melakukan reverse engineering sendiri, yang ada di github ini akurat.

https://github.com/odzhan/wanafork

Anda bisa mengenkrip file Anda sendiri, satu per satu, bisa mencoba mempelajari cara kerja enkripsinya menggunakan debugger langkah demi langkah. Jadi Anda nggak perlu melihat assemblynya ataupun menyiapkan virtual machine.

Di dalam link tersebut juga ada contoh public dan private key X dan juga public key Y yang dipakai oleh malware. Perhatikan baik-baik ini CONTOH key X ini dari satu PC, key X ini beda untuk tiap PC dan di contoh ini pemilik repository tersebut rajin untuk mengeksekusi malware di dalam debugger dan menangkap private key  X untuk PC-nya dia. Seperti telah dijelaskan di atas, normalnya private key X ini tidak bisa kita dapatkan.

Salah satu alasan saya menyebarkan link ke repository tersebut adalah karena banyak orang yang masih insist bahwa “pasti ada caranya”, atau “Sayang saya udah lama nggak liat assembly”, atau “enkripsinya pasti ada kelemahannya”. Nah semua sudah disediakan di depan mata dan sudah saya deskripsikan dalam bahasa awam bahasa Indonesia (versi bahasa Inggris juga banyak beredar), jika memang ada yang bisa menemukan cara membuka filenya tanpa key dari pembuat malware, seluruh dunia akan sangat berterima kasih pada Anda.

Di masa depan saya yakin akan lebih banyak lagi Ransomware yang seperti ini, yang tidak bisa didekripsi tanpa “master key” dari pembuatnya. Jadi bukan kesalahan pihak reverse engineer yang “kurang bisa membaca kode”, tapi memang kodenya sudah bagus. Andaikan diberikan source code malware yang sempurna lengkap dengan komentar sekalipun, tetap saja tidak akan ada yang bisa membongkar tanpa keynya.

Untuk Anda yang belum membaca posting sebelumnya: kemungkinan recovery yang masih mungkin adalah melalui program recovery yang sejenis melakukan operasi “undelete” terhadap free space. Windows juga memiliki sistem backup otomatis, tapi ini pun akan dihapus malware. Dalam kasus sangat jarang, jika kebetulan ransomware gagal menghapus volume shadow copy, maka ada kemungkinan file bisa dikembalikan. Jadi secara umum, recovery yang ada tidak melakukan dekripsi, dan tidak semua file bisa kembali.

Update 18 Mei 2017

Seseorang telah menemukan solusi untuk Windows XP (saja) yang belum pernah direstart sejak kena infeksi.

WannaCry memakai fungsi-fungsi kriptografi yang ada di OS Windows. Khusus untuk Windows XP, ada bug di fungsi milik Microsoft. Teorinya kode program ransomware ini sudah benar, menghapus key dengan memanggil CryptDestroyKey/CryptReleaseContext, tapi di Windows XP:

CryptDestroyKey and CryptReleaseContext does not erase the prime numbers from memory before freeing the associated memory.

Dalam kasus jika: WannaCry mengenkrip Windows XP DAN
Komputer tersebut belum pernah direstart sejak kena infeksi, Maka ada kemungkinan kunci private untuk komputer itu bisa didapatkan untuk mendekrip file di komputer tersebut (kunci ini tidak bisa dipakai di komputer lain). Jika komputer sudah direstart/dimatikan sejak infeksi ya tidak bisa.

https://github.com/aguinet/wannakey

Update: 19 Mei 2017 bug tersebut ternyata berlaku juga untuk  Windows 7,Vista, Server 2003 & 2008 yang belum pernah direstart sejak kena infeksi.

https://github.com/gentilkiwi/wanakiwi

2 thoughts on “Unbreakable Encryption”

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.