SSL (Secure Socket Layer)
Penjelasan ini adalah versi sangat sederhana, yang seharusnya bisa dimengerti orang awam, maupun programmer yang fokusnya bukan di bidang security.
Kalau kita ingin berkirim pesan 📄 secara aman, kita bisa memakai enkripsi. Sekarang ini topiknya akan saya batasi: komunikasi aman antara client (Anda yang memakai browser atau app) dan server.
Ada banyak algoritma enkripsi di dunia ini (istilahnya cipher). Yang mungkin pernah Anda dengar: DES, AES, RSA, dsb. Tiap cipher punya kunci. Berdasarkan jenis kuncinya, algoritma enkripsi dibagi dua: simetrik dan asimetrik.
Jenis algoritma pertama adalah yang sifatnya simetrik: pengirim dan penerima perlu memiliki kunci yang sama. Contohnya yang paling sederhana adalah caesar cipher, yang intinya hanya menggeser N karakter. Jika kuncinya adalah plus 2: A jadi C, B jadi D, dst. Contoh lain adalah substitution cipher, yang intinya mengganti tiap karakter sesuai tabel tertentu. Misalnya kita punya tabel bahwa A jadi X, B jadi M, dst.
Dalam simetric cipher: masing-masing pihak harus punya kunci yang sama. Jika kita sepakat kuncinya apa, maka ini mudah dilakukan. Enkripsi jenis simetrik ini umumnya sangat cepat, bisa untuk memproses data sangat besar. Masalah utama dengan kunci simetrik adalah: bagaimana caranya bertukar kunci secara aman? Ini bisa diselesaikan dengan jenis algoritma kedua.
Jenis algoritma kedua adalah asimetrik. Jika saya jelaskan secara matematis ini bisa cukup panjang, jadi saya jelaskan dengan cara lain. Bayangkan begini, Anda punya kunci publik berupa sebuah gembok 🔓 , dan kunci private berupa kunci untuk gembok tersebut 🔑. Jika ada orang ingin berkirim pesan pada Anda, maka dia perlu memasukkan pesan ke dalam kotak 📦 , lalu kotak itu digembok. Dengan asumsi bahwa gembok itu aman, maka cuma Anda yang bisa membuka pesan dalam kotak yang digembok tersebut.
Baik kunci dan gembok dalam ilustrasi tersebut hanyalah data di komputer, dan proses mengunci dan membuka kunci merupakan proses matematika yang rumit. Untuk memproses data yang besar, algoritma asimetrik ini kurang efisien. Tapi metode ini cocok sekali untuk mengirimkan data kecil, misalnya key untuk algoritma pertama.
Cara berkomunikasi menggunakan SSL secara sederhana seperti ini (anggap saja ini V1, akan saya jelaskan nanti kelemahan versi ini).
- Client -> server : Halo server 🙋, saya mau ngirim data nih ke kamu (example.com)
- Server -> client : Ok, ini gembok saya 🔓 untuk example.com
- Client -> server : Ok, saya bikin key yang random ya (bikin kunci X), saya kirimkan dengan gembok kamu 🔒
- Server -> client : Ok, saya buka gemboknya, kita sepakat pake kunci X ya.
Berikutnya, client dan server bisa berkirim data besar dengan kunci X yang sudah disepakati bersama. Tata cara berkomunikasi dalam sebuah sistem komputer disebut sebagai protokol.
Membuat gembok adalah proses yang biasanya cuma dilakukan sekali saja. Gembok ini adalah bilangan yang besar yang memenuhi syarat tertentu, yang dihasilkan secara random. Dengan perintah yang sama, hampir mustahil kita mendapatkan bilangan yang sama, jadi kunci/gembok ini unik untuk masing-masing server.
MITM
Man in the middle attack (MITM) adalah serangan di mana ada orang yang bisa menangkap komunikasi kita, lalu mendengarkan atau mengganti isi pesan kita. Jika diimplementasikan dengan benar, dengan SSL kita bisa menghindari serangan MITM.
Secara praktis MITM itu gimana sih? ada banyak jenis serangan yang bisa dilakukan, dari mulai menyerang router, mengganti DNS, spoofing, dsb. Tapi contoh yang paling praktis adalah WIFI: seseorang bisa membuat access point WIFI yang lebih kuat signalnya dari yang "asli", dan device kita akan otomatis berpindah ke WIFI tersebut (jika nama WIFI/SSID dan passwordnya sama). Kenapa WIFI dirancang begitu? ini supaya memudahkan handover ke access point WIFI yang lain. Bagi end user, ini sangat nyaman, jika ketemu KFC atau Starbucks ☕ di cabang lain, kalau nama access pointnya sama, saya nggak perlu join lagi, otomatis nyambung.
Sebenarnya banyak operator mobile di Indonesia juga melakukan MITM, dengan menangkap request kita ke web server, dan memasukkan iklan ke dalam browser pelanggan.
Setelah mendapat gambaran bagaimana MITM bekerja, sekarang kita masuk ke bagian SSL dan MITM
SSL dan MITM
Jika serangan MITM bisa dilakukan maka SSL versi pertama di atas percuma, kenapa? Bayangkan ada Client, Server, dan Attacker seperti ini:
Client <---> Attacker <--> Server
Di langkah pertama "Client: Halo server 🙋, saya mau ngirim data nih ke kamu.", pesan yang dikirimkan client tidak sampai ke server langsung, tapi melalui attacker:
Yang terjadi adalah:
- Client -> attacker : Halo server 🙋, saya mau ngirim data nih ke kamu ke example.com.
- Attacker -> server : OK, bentar. Halo server 🙋, saya mau ngirim data nih ke kamu ke example.com.
- Server -> attacker: Ok, ini gembok saya 🔓 untuk example.com
- Attacker -> client: Ok, ini gembok saya 🔓 untuk example.com (bukan gembok sever yang asli)
- Client -> attacker : Ok, saya bikin key yang random ya (bikin kunci X), saya kirimkan dengan gembok kamu 🔒 (client tidak tahu bahwa ini adalah gemboknya attacker)
- Attacker -> client: ok, kita pake kunci X ya.
- Attacker -> server: Ok, saya bikin key yang random ya (bikin kunci Y), saya kirimkan dengan gembok kamu 🔒(gembok server yang asli)
- Server -> attacker: OK, kita pake kunci Y ya
Jadi yang terjadi ketika komunikasi adalah, client ngobrol ke attacker dengan kunci X (yang diketahui attacker), dan attacker ngobrol ke server dengan kunci Y yang diketahui attacker juga. Server di sini tidak tahu bahwa komunikasi client dibajak.
Client <-X-> Attacker <-Y-> Server
Di sini attacker bisa:
- Membaca pesan yang lewat
- Memodifikasi pesan yang lewat
Certificate Authority (CA)
Ketika client menerima "gembok" sebenarnya yang diterima adalah sertifikat dari server. Client tidak tahu apakah benar gembok ini memang gemboknya server. Untuk mengetahui apakah benar atau tidak, orang-orang di dunia ini menyepakati ada pihak-pihak tertentu yang boleh memberi "cap/stempel/sign" (tanda tangan digital) pada gembok, yang menyatakan bahwa sertifikat (gembok) ini benar merupakan milik server tertentu. Pihak-pihak ini disebut sebagai certificate authority.
Pertanyaan berikutnya lagi: bagaimana caranya saya tahu capnya itu "asli"? siapa saja yang boleh memberi "cap" ini? Di device kita ada daftar root CA, yang merupakan Certificate Authority paling atas. Jadi ada langkah tambahan ketika client menerima sertifikat dari server: saya cek dulu apakah ini ditandatangani oleh salah satu root CA yang tercantum di daftar client.
Saya sebutkan bahwa root CA ini adalah yang "paling atas", karena biasanya sertifikat tidak langsung ditandatangani oleh root CA ini, tapi oleh pihak bawahnya. Misalnya: sertifikat X ditandatangani A, dan sertifikatnya A ditandatangani oleh salah satu yang ada di daftar root CA.
Mungkin ada yang bertanya: kok bisa sebuah CA didaftarkan jadi root CA di berbagai device di dunia ini? jawabnya karena mereka bekerja sama dengan pembuat OS dan device supaya CA mereka dimasukkan (istilah halus dari "membayar"). Untuk mendapatkan "cap" dari pihak yang berwenang, biasanya kita perlu membayar (tapi sekarang sudah ada yang namanya https://letsencrypt.org/), dan ada batas waktu kapan "cap" ini berlaku.
Daftar CA ini biasanya statik, tapi sebagian orang suka menghapus CA tertentu dari device mereka (misalnya takut disadap negara tertentu), sebaliknya sebagian perusahaan mewajibkan CA tertentu diinstall di device karyawan perusahaan (untuk bisa memonitor lalu lintas SSL).
Perhatikan bahwa sebuah sertifikat (gembok) yang sama bisa dicap oleh berbagai pihak. Mungkin tahun ini pihak tertentu ada yang menarik biaya lebih murah untuk administrasinya, jadi kita pindah ke CA lain.
Dengan adanya CA, maka protokolnya menjadi:
- Client -> server : Halo server 🙋, saya mau ngirim data nih ke kamu ke example.com
- Server -> client : Ok, ini gembok saya 🔓 untuk example.com
- Client: bentar, saya cek dulu apakah benar gemboknya valid, ok bener ✅ di-cap oleh CA yang ada di daftar CA saya
- Client -> server : Ok, saya bikin key yang random ya (bikin kunci X), saya kirimkan dengan gembok kamu
- Server -> client : Ok, saya buka gemboknya, kita sepakat pake kunci X ya.
Jika ada attacker, maka attacker tidak akan bisa membuat gembok valid dengan nama example.com karena CA hanya mau menandatangani jika kita bisa membuktikan kita punya domain example.com tersebut.
Meski saya menyebutkan di atas bahwa key bisa tidak di-"cap", sebenarnya semua sertifikat SSL harus di-"cap" dengan sebuah key (terserah key siapa saja, termasuk oleh kita sendiri). Untuk keperluan internal/development biasanya kita tidak mau repot-repot, dan memberikan "cap" kita sendiri (istilahnya self-signed certificate). Terkadang dengan alasan tertentu orang juga tidak mau meminta tanda tangan digital bahkan di versi rilis/produksi.
MITM dengan tujuan baik
Beberapa perusahaan dan lembaga besar menerapkan deep packet inspection. Tiap paket keluar masuk harus diperiksa sampai isi dalamnya, termasuk juga koneksi ke situs SSL. Untuk bisa melakukan ini, maka firewall perusahaan menggunakan teknik MITM.
Tiap komputer dan device (HP, Tablet, dsb) yang ada di perusahaan diinstall root CA baru milik perusahaan tersebut, supaya tidak ada peringatan ketika browser atau app yang ada di device berusaha melakukan koneksi ke luar.
Certificate Pinning
Jika kita berhasil menginstall root CA ke device seseorang, kita juga bisa membuat certificate palsu. Tapi menginstall root CA ke device seseorang itu tidak mudah, biasanya perlu akses fisik, dan bahkan di Android kita perlu setup PIN dulu baru bisa. Serangan jenis ini juga sangat spesifik terhadap device tertentu, jadi kalau misalnya seseorang berhasil menginstall root CA baru di HP saya, tapi tidak di komputer saya, maka saya akan melihat ada yang aneh jika koneksi dibajak.
Dengan adanya Certificate Authority, maka kita aman dari serangan pihak-pihak biasa, tapi jika NSA (badan intelijen Amerika) atau MSS (badan intelijen China) ingin menyerang kita, maka dengan mudahnya mereka "minta" ke CA tertentu (CA mana saja asalkan ada di root list device kita) untuk menandatangani sertifikat palsu mereka.
Teknik certificate pinning bisa digunakan untuk mewajibkan bahwa "gembok" yang dipakai harus tepat yang itu. Ini biasanya dilakukan oleh aplikasi yang penting (misalnya banking). Jika kunci berubah sedikit saja, maka aplikasi tidak mau melakukan koneksi.
Ada beberapa jenis pinning, yang paling strict adalah seperti ini: jika kunci yang saya terima dari server berbeda dengan yang tercantum di app, maka saya nggak mau konek sama sekali. Masalah dengan pinning jenis ini adalah: jika kunci bocor (contoh kasus: bug heartbleed) atau sertifikat server diubah (misalnya karena expired), maka semua app harus segera diupdate (bayangkan jika app-nya terinstall di jutaan device).
Jenis pinning berikutnya adalah public key pinning: secara sederhana app hanya akan menerima kalau root CA atau sub CA yang menandatangani sertifikat adalah yang tercantum dalam daftar saya. Kalo ada root CA baru yang diinstall di device, saya tidak akan percaya pada root CA tersebut. Jenis ini lebih fleksibel: kalau sertifikat diubah (karena expired atau bocor), asalkan ditandatangani pihak yang sama, maka tidak apa-apa. Kelemahannya adalah jika root CA tersebut dibobol (baik oleh badan intelijen atau hacker), maka semua akan bobol (tapi sama halnya dengan kasus pinning sebelumnya: jika kita dibobol, maka game over).
Certificate pinning mengamankan app, tapi tidak kompatibel dengan deep packet inspection. Biasanya deep packet inspection akan membiarkan paket lewat untuk situs kesehatan dan finansial (setidaknya di Amerika, karena ini hak warga negara, bahwa perusahaan tidak boleh mencampuri urusan kesehatan dan finansial mereka), dan akan memblok semua koneksi SSL lain yang tidak bisa dilihat isinya.
Facebook, Twitter, Google, dan banyak app lain mengimplementasikan certificate pinning (public key pinning). Mereka tidak ingin traffic penggunanya diintip oleh berbagai badan intelijen negara ataupun oleh perusahaan. Tentunya berbagai instansi atau enterprise yang menangani data penting tidak ingin datanya diposting ke facebook/twitter/google, jadi jika app tersebut ter-blok oleh deep content firewall, maka itu wajar bagi perusahaan (supaya lebih jelas lagi: versi web dari berbagai aplikasi tersebut masih bisa diinspeksi).
Kesalahan umum app yang memakai SSL
Berikut ini beberapa kesalahan umum yang sering saya temui:
SSL certificate tidak dicek sama sekali 🙈
Defaultnya API untuk melakukan koneksi HTTPS (HTTP dengan SSL) akan otomatis melakukan pengecekan sertifikat, tapi dalam testing, pihak developer memakai server development tanpa SSL certificate yang "resmi" (memakai self-signed certificate). Seringkali developer mengambil jalan pintas dengan sengaja mematikan pengecekan SSL di sisi client, dan lupa diaktifkan kembali di versi rilis.
Menggunakan SSLSocketFactory di Android
Sebagian aplikasi tidak menggunakan HTTPS tapi menggunakan SSL Socket secara langsung. Di Android SSLSocketFactory tidak mengecek sertifikat, API yang seharusnya dipakai adalah SSLCertificateSocketFactory.
Menganggap SSL adalah proteksi segalanya
SSL tidak mencegah data dilihat di sisi client ataupun server. Fakta sederhana ini kadang tidak diperhatikan oleh banyak orang, terutama para pembuat aplikasi.
Beberapa contoh kasus:
Menganggap data dari app menuju server tidak akan bisa dibaca oleh pengguna app. Contohnya ada app yang memakai token tersembunyi (dienkrip/obfuscate dalam app-nya), yang hanya terlihat ketika datanya dikirimkan ke server.
Menganggap data dari app menuju server tidak mungkin diubah oleh pengguna app, misalnya harga barang dalam HTTP POST. Ini sama naifnya dengan hidden form input di browser. Meski terdengar sederhana: banyak app naif seperti ini, dan sisi server tidak mengecek lagi.
SSL juga tidak memberi perlindungan ekstra selain dalam hal bebas sadap/bebas MITM, kalau server Anda punya bug lain (misalnya SQL injection, XSS, dsb), ya SSL tetap tidak akan membantu.
Tidak menggunakan pinning untuk aplikasi super penting
Jika aplikasi Anda memakai pinning, tapi sebenarnya tidak terlalu dibutuhkan, maka pengguna di lingkungan corporate tidak akan bisa memakai app Anda. Mungkin ini hal bagus, mungkin juga tidak, misalnya mungkin Anda tidak ingin game Anda jalan di lingkungan corporate/enterprise.
Sebaliknya: jika app Anda sangat penting, tanpa pinning maka app akan bisa ditargetkan oleh penyerang.
Menggunakan konfigurasi SSL yang kurang baik
Standar SSL berubah dari dulu untuk menangani berbagai kemungkinan attack yang ada. Sebagian besar attack ini sifatnya sulit sekali dilakukan, tapi lebih baik bersiap-siap daripada menyesal. Ada jenis cipher tertentu yang perlu didisable, atau konfigurasi tertentu yang perlu diaktifkan di sisi server untuk keamanan maksimum.
Website seperti SSLTest bisa membantu Anda mengecek apakah konfigurasi SSL Anda sdah baik atau belum.
Penutup
Artikel ini hanya merupakan pengenalan sangat dasar terhadap SSL. Masih banyak hal menarik yang bisa dipelajari yang berkaitan dengan SSL ini. Hal-hal yang berhubungan dengan SSL dan enkripsi lain juga kadang muncul di berbagai CTF.
Contoh soal yang pernah ditemui oleh team Rentjong (team CTF saya dulu, tapi sekarang kami sudah tidak aktif):
- PlaidCTF2014 curlcore
- PlaidCTF2014 rsa tidak spesifik SSL, tapi public key cryptography.
Copyright © 2009-2018 Yohanes Nugroho