Artikel ini adalah artikel lanjutan dari session hijacking basics. Session fixation attack adalah salah satu dari 3 jurus untuk mendapatkan sessionid korban. Jurus ini sangat berbahaya karena attacker tidak perlu capek menebak atau menangkap sessionid korban.
Stealing Session ID
Dalam artikel saya tentang Session Hijacking Basics, saya menjelaskan bahwa session id adalah kunci dari sebuah session. Jadi untuk membajak session, attacker tidak perlu username atau password, attacker cuma perlu session id. Lebih tepatnya adalah session id dari korban yang sessionnya masih hidup (korban sudah login dan belum logout).
Bagaimana cara attacker mendapatkan session id korban? Dalam artikel session hijacking basics saya juga menjelaskan bahwa ada 3 cara untuk mendapatkan sessionid, yaitu:
- Predict
- Capture
- Fixate
Lebih lengkapnya silakan baca di artikel saya tersebut, dalam artikel ini saya hanya akan fokus membahas tentang cara ke-3 yaitu Fixation.
Session Fixation Attack
Mencari tahu session id korban dalam situasi tertentu sulit untuk dilakukan. Berbeda dengan serangan lainnya, tujuan dari session fixation attack bukanlah mencuri sessionid, tapi membuat korban menggunakan sessionid yang telah disiapkan sebelumnya.
Dalam serangan session fixation, attacker MEMILIHKAN sessionid untuk korban
Dengan memilihkan sessionid untuk korban, attacker tidak perlu repot mencari tahu sessionid korban karena attacker sudah mengetahuinya sejak awal (karena dia yang memilih).
Sessionid dikirimkan ke server dengan dua cara:
- query string (url rewriting), contohnya index.php?PHPSESSID=abcd
- cookie
Inisiatif pembangkitan/pemilihan sessionid seharusnya dilakukan oleh server, bukan oleh client. Serangan session fixation bisa terjadi karena server mau menerima usulan sessionid dari client baik yang dikirimkan melalui cookie maupun query string (url rewriting). Usulan sessionid dari client bisa digenerate sendiri oleh client secara bebas, atau digenerate oleh server.
Fixation attack bisa terjadi karena server mau menerima usulan sessionid dari client
Bila server mau menerima usulan sessionid yang dikirim melalui query string, berarti serangan session fixation bisa dilakukan secara remote. Tapi bila server hanya mau menerima usulan sessionid dari cookie, maka serangan hanya bisa dilakukan secara lokal di browser korban. Serangan remote jauh lebih berbahaya karena cukup dengan memberikan link dan membuat korban mengklik link tersebut, maka korban sudah termakan jebakan attacker untuk memakai sessionid yang sudah dipilih attacker.
Remote Session Fixation
Serangan remote session fixation secara dengan sessionid bebas dipilih oleh attacker diperlihatkan pada gambar berikut:
Ada juga server yang tidak mengijinkan penggunaan sessionid yang tidak dibuat oleh server. Dalam kasus ini skenarionya mirip namun ditambahkan satu langkah untuk me-request sessionid dari server. Perhatikan gambar berikut ini:
Mirip dengan skenario sebelumnya, gambar di atas memperlihatkan attacker meminta session id ke server terlebih dahulu. Perhatikan bahwa server mungkin memberikan sessionid dalam bentuk cookie, namun ketika attacker menjebak korban, attacker memberikan sessionid dalam bentuk query string kepada korban. Jangan bingung, server biasanya menerima sessionid dalam cookie maupun url rewriting.
Dalam server yang menerima sessionid dalam cookie dan url rewriting, cookie mempunyai prioritas lebih dibanding url rewriting.
Jadi bila di browser sudah ada cookie JSESSIONID=abcd, ketika browser mengakses url dengan query string ?JSESSIONID=wxyz, maka sessionid yang dianggap adalah abcd karena berasal dari cookie.
Ada server yang lebih suka menggunakan cookie daripada query string sehingga server itu selalu memberikan cookie berisi sessionid bila menerima usulan sessionid melalui query string. Jadi untuk request selanjutnya klien tidak perlu menggunakan query string lagi, karena setiap request sessionid otomatis terikirim melalui cookie. Dalam kasus seperti ini serangan menjadi lebih mudah karena begitu korban mengklik link yang mengandung sesionid pada query stringnya, maka selanjutnya korban tidak perlu lagi menambahkan query string sessionid pada requestnya.
Local Session Fixation
Bila server hanya menerima usulan sessionid dari cookie, maka jurus session fixation tidak bisa dilakukan secara remote. Attacker harus menciptakan cookie berisi sessionid ke dalam browser korban. Untuk itu diperlukan akses fisik atau akses remote shell/desktop di komputer korban. Bila memiliki akses fisik atau remote desktop/shell, maka serangan ini mudah sekali dilakukan, cukup dengan membuat cookie berisi sessionid yang tanggal expirednya ditentukan masih sangat lama di komputer korban. Selanjutnya setiap korban membuka halaman yang ditarget attacker, maka sessionid yang dipakai adalah sessionid yang sudah dipilih oleh attacker.
Skenarionya adalah attacker mengakses situs yang ditargetnya, sehingga akan tercipta cookie di browser korban. Attacker memodifikasi waktu expired cookie tersebut menjadi sangat lama. Kemudian attacker mencatat sessionid tersebut dan meninggalkan komputer korban seperti semula.
Agar session tidak dianggap expired oleh server, dari komputer lain, attacker akan terus menerus mengakses situs target dengan cookie berisi sessionid tersebut. Begitu korban login dengan sessionid tersebut, maka attacker akan bisa mengakses account korban juga.
Mencoba Session Fixation di Komputer Sendiri
Untuk lebih mengerti mekanisme kerja session handling, saya akan membuat program kecil dalam php di URL komputer sendiri http://192.168.0.10/mylab/counter.php. Sebelumnya perlu diketahui bahwa sessionid dalam php defaultnya diberi nama PHPSESSID dan dalam contoh ini saya menggunakan nama defaultnya.
1 2 3 4 5 6 7 8 9 10 11 | <?php session_start(); print "Session ID: ".session_id()."<br/>"; if (!isset($_SESSION["c"])) { $_SESSION["c"] = 0; } else { $_SESSION["c"]++; } print $_SESSION["c"]."<br/>"; ?> |
Bila saya me-request URL tersebut tanpa mengirimkan sessionid dalam cookie maupun query string, maka server akan men-generate sessionid sendiri dan memberikan saya cookie. Sebelum request saya menghapus semua cookie dari host 192.168.0.10 agar tidak ada sessiondid yang terkirim dalam request. Beginilah request yang dilakukan browser saya:
1 2 3 4 5 6 7 8 9 10 11 | http://192.168.0.10/mylab/counter.php GET /mylab/counter.php HTTP/1.1 Host: 192.168.0.10 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive |
Perhatikan bahwa pada request tersebut tidak ada satupun sessionid yang dikirimkan dalam bentuk cookie maupun query string. Mari kita lihat response yang diberikan server.
1 2 3 4 5 6 7 8 9 10 11 12 | HTTP/1.x 200 OK Date: Mon, 02 Feb 2009 08:12:07 GMT Server: Apache/2.2.3 (Fedora) X-Powered-By: PHP/5.1.6 Set-Cookie: PHPSESSID=of6k7hsg17vl9jrg0b7lhrlck6; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 49 Keep-Alive: timeout=60000, max=489 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 |
Pada baris ke-5 dari response terlihat bahwa server memberikan sessionid “of6k7hsg17vl9jrg0b7lhrlck6″ dalam bentuk cookie. Dalam kasus ini terlihat bahwa server yang menentukan sessionid dari sebuah session.
Client Menentukan Session ID dengan Query String Kalau attacker ingin melakukan session fixation, maka sessionid harus ditentukan oleh client, bukan server. Sekarang kita coba memberikan sessionid dalam query string dan kita lihat request dan response yang terjadi. Seperti biasa saya menghapus semua cookie dari host tersebut sebelum melakukan request. Berikut requst yang terjadi:
1 2 3 4 5 6 7 8 9 10 11 | http://192.168.0.10/mylab/counter.php?PHPSESSID=abcdef1234567890 GET /mylab/counter.php?PHPSESSID=abcdef1234567890 HTTP/1.1 Host: 192.168.0.10 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive |
Dalam query string saya menambahkan PHPSESSID=abcdef1234567890 dengan maksud untuk memaksa server memakai sessionid tersebut sebagai sessionid dari session yang akan saya pakai. Mari kita lihat response yang diberikan server.
1 2 3 4 5 6 7 8 9 10 11 12 13 | HTTP/1.x 200 OK Date: Mon, 02 Feb 2009 08:22:42 GMT Server: Apache/2.2.3 (Fedora) X-Powered-By: PHP/5.1.6 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 39 Keep-Alive: timeout=60000, max=490 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 Session ID: abcdef1234567890<br/>0<br/> |
Terlihat bahwa server menerima usulan saya untuk memakai “abcdef1234567890″ sebagai sessionid, terlihat dari hasil fungsi session_id() yang menghasilkan string tersebut. Dalam kasus ini saya sukses memaksa server memakai sessionid yang saya pilih melalui query string. Bila link http://192.168.0.10/mylab/counter.php?PHPSESSID=abcdef1234567890 saya berikan pada korban, dan korban mengkliknya, maka saya dan korban akan sama-sama memakai sessionid “abcdef1234567890″. Apa saja yang bisa diakses oleh korban saya juga bisa mengaksesnya.
Client Menentukan Session ID dengan CookieSetelah mencoba query string, sekarang kita coba memberikan sessionid dalam cookie dan kita lihat request dan response yang terjadi. Kali ini saya harus menambahkan cookie berisi “PHPSESSID=0123456789″ sebelum melakukan request. Berikut requst yang terjadi:
1 2 3 4 5 6 7 8 9 10 11 12 | http://192.168.0.10/mylab/counter.php GET /mylab/counter.php HTTP/1.1 Host: 192.168.0.10 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: PHPSESSID=01234567890 |
Pada baris terakhir terlihat cookie yang saya kirimkan berisi sessionid. Saya ingin server menerima usulan saya untuk memakai “01234567890″ sebagai sessionid. Berikut adalah response dari server.
1 2 3 4 5 6 7 8 9 10 11 12 13 | HTTP/1.x 200 OK Date: Mon, 02 Feb 2009 08:34:08 GMT Server: Apache/2.2.3 (Fedora) X-Powered-By: PHP/5.1.6 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 34 Keep-Alive: timeout=60000, max=500 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 Session ID: 01234567890<br/>0<br/> |
Terlihat bahwa hasil dari fungsi session_id() menunjukkan bahwa session tersebut menggunakan “01234567890″ sebagai sessionid. Jadi saya sukses memaksa server memakai usulan saya sebagai sessionid.
PencegahanAnda telah melihat dalam contoh php di atas bahwa serangan session fixation tidak akan terjadi bila sessionid ditentukan oleh server, bukan oleh client. Dalam contoh php di atas bila client tidak memberikan sessionid dalam bentuk apapun, maka serverlah yang akan memberi sessionid. Jadi agar anda tidak terjebak memakai sessionid yang sudah diketahui orang lain, sebelum anda melakukan koneksi atau login, pastikan:
- Tidak ada cookie berisi sessionid untuk domain situs yang akan anda kunjungi.
- Pastikan URL yang anda kunjungi tidak mengandung query string yang berisi sessionid.
Session fixation adalah teknik mendapatkan sessionid yang sangat efektif. Cara ini lebih mudah dilakukan karena tidak perlu menebak sessionid, melakukan sniffing atau melakukan exploitasi XSS. Namun sayang awareness akan adanya teknik ini masih kurang, padahal di luar sana banyak situs yang rentan terhadap serangan ini. Dalam artikel berikutnya saya akan memberikan contoh serangan session fixation pada situs internet banking.
0 komentar:
Posting Komentar