Klien sebagai pengirim request memiliki kontrol penuh atas apa saja data yang dikirimkan ke server. Bila server lalai melakukan validasi input maka akibatnya bisa berbahaya. Umumnya attacker melakukan injeksi melalui parameter pada GET atau form data pada POST. Padahal banyak jalan masuk lain yang bisa dicoba untuk menyerang server. Kali ini saya akan jelaskan bagaimana melakukan serangan XSS dan SQL injection dengan mengirimkan malicious tag/sql lewat header http.
Referer Header
Header ini berguna untuk menunjukkan dari mana request dilakukan. Contohnya ketika seseorang membuka halaman A, di dalamnya mengandung gambar yang lokasinya di B, maka browser akan me-request image di B dengan menambahkan referer header berisi url A. Header referer ini bisa dimanfaatkan untuk mencuri sessionid bila session id ditaruh di URL seperti pada webmail telkom.net/plasa.com. Tapi kali ini fokus kita adalah tentang injection bukan session hijacking, lain kali saya akan bahas di artikel khusus tentang itu.
Untuk melihat bagaimana header referer dipakai dalam request, saya gunakan contoh ipmonkey.com yang dibuka dengan browser Firefox+Live Http Header addon. Pada halaman ipmonkey.com ada image tag yang URLnya adalah ipmonkey.com/ipmonkey.gif. Karena image tersebut berada pada URL www.ipmonkey.com, maka request image tersebut ditambahkan referer header berisi url http://www.ipmonkey.com.
http://www.ipmonkey.com/ipmonkey.gif GET /ipmonkey.gif HTTP/1.1 Host: www.ipmonkey.com 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: image/png,image/*;q=0.8,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://www.ipmonkey.com/
XSS bisa dilakukan dengan memasukkan script atau tag html di header ini. Bila ada web application yang menampilkan isi header referer tanpa di-filter, maka code xss kita berhasil diinjeksi. Sebagai contoh bisa dicoba di web http://pgl.yoyo.org/http/browser-headers.php. Web itu menampilkan header http tanpa difilter. Bagaimana cara menginjeksi header referer? Saya menggunakan addon Modify Header di Firefox. Coba tambahkan header Referer yang berisi javascript seperti pada gambar di bawah ini:
Setelah header referer ditambahkan, ketika saya coba mengakses web http://pgl.yoyo.org/http/browser-headers.php, maka javascript saya akan dieksekusi browser, hasilnya seperti pada gambar berikut:
Failed Attack on Feedjit
Lho kalau begitu kan serangan ini tidak ada gunanya karena harus mengubah header referer dulu, jadi cuma bisa xss di browser sendiri dong? Bagaimana caranya agar serangan jenis ini bisa menyerang orang lain? Agar serangan ini bisa berakibat ke orang lain, maka web application yang diserang haruslah menyimpan header referer pengunjungnya kemudian menampilkannya di halaman webnya.
Saya belum menemukan contoh web yang menyimpan header referer pengunjung dan menampilkannya kembali dalam bentuk list. Namun agar bisa terbayang, saya gunakan contoh hipotetis saja Feedjit.com. Ingat, Feedjit tidak vulnerable terhadap serangan ini, jadi saya akan berikan contoh serangan xss saya yang gagal di feedjit sehingga anda bisa terbayang bagaimana akibatnya bila serangan itu berhasil.
Ada 3 hal penting yang ditampikan feedjit dalam widgetnya, yaitu:
- Daerah asal, yang ditunjukkan dengan bendera negara dan kotanya.
- Dari mana asal request berasa yang ditunjukkan dengan kalimat “arrived from”.
- Halaman apa yang sedang dibaca.
Dari ketiga elemen tersebut yang bisa kita kendalikan adalah asal request dan apa yang sedang dibaca. Sedangkan daerah asal ditentukan oleh IP address yang tidak bisa kita kendalikan. Kita mungkin bisa membuat kita tampak dari negara lain dengan proxy, tapi tetap saja yang muncul adalah bendera dan kota yang sudah fixed.
Sekarang saya coba untuk menginjeksi tag html melalui header referer dengan harapan akan muncul di widget tersebut. Pertama saya ubah dulu header referer dari addon Modify Header, kemudian saya klik salah astu artikel di ilmuhacking.com. Request yang terjadi yang disniff dengan Live http header adalah:
http://feedjit.com/router/?w=trafficList&ign=0&wn=1&cen=1&nv=1&fl=0&vid=new&rn=0&lg=1&u=http://www.ilmuhacking.com/web-security/menjebol-captcha-dengan-ocr/&r=http://cobain&t=Menjebol Captcha dengan OCR | Web Security | IlmuHacking.com&sw=1280&sh=960&fjv=2&rand=769547649 GET /router/?w=trafficList&ign=0&wn=1&cen=1&nv=1&fl=0&vid=new&rn=0&lg=1&u=http%3A%2F%2Fwww.ilmuhacking.com%2Fweb-security%2Fmenjebol-captcha-dengan-ocr%2F&r=http%3A%2F%2F%3Cb%3Ecobain%3C%2Fb%3E&t=Menjebol%20Captcha%20dengan%20OCR%20%7C%20Web%20Security%20%7C%20IlmuHacking.com&sw=1280&sh=960&fjv=2&rand=769547649 HTTP/1.1 Host: feedjit.com 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: */* 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 Proxy-Connection: keep-alive Referer: http://cobain Cookie: fjdt100=1232528992
Ketika kita membuka halaman yang mengandung widget feedjit, maka javascript yang ada akan mengirimkan request ke server feedjit.com yang berisi referer, judul artikel dan url artikel yang dibaca. Perhatikan URL yang direquest, 3 variabel yang mengirimkan data tersebut adalah:
u=http://www.ilmuhacking.com/web-security/menjebol-captcha-dengan-ocr/ r=http://cobain t=Menjebol Captcha dengan OCR | Web Security | IlmuHacking.com
Ternyata tag html saya gagal diinjeksi karena sudah di-escape dengan benar. Seharusnya teks cobain dicetak tebal. Tapi ternyata cobain berubah menjadi bcobain, artinya injeksi gagal total.
Bayangkan bila injeksi ini berhasil. Maka halaman web yang mengandung widget ini bisa diinjeksi dengan script untuk mencuri cookie. Bila kebetulan admin sedang login, kemudian mengecek blognya, tentu cookie berisi sessionid dia akan terancam. Mari kita coba seandainya injection berhasil dengan mengubah htmlnya dengan addon Firebug. Tampilannya akan seperti pada gambar di samping. Itu baru tag bold bagaimana bila tag script? Tenu akibatnya akan fatal karena session bisa di-hijack. Beruntung untuk wordpress karena cookie session id di-set hanya dikirim bila path URL /wp-admin/ maka cookie tersebut tidak akan terkirim ketika admin sedang membaca artikel dalam keadaan login. Namun bila cookienya diset path / maka cookie dipastikan akan terkirim bila admin membaca artikel ketika sedang login.
Header User-Agent
Header ini menunjukkan jenis browser yang dipakai. Dalam user agent biasanya akan terlihat sistem operasinya juga. Hedaer ini biasanya sudah ditentukan oleh browser, namun dengan addon User Agent Switcher saya bisa mengubahnya menjadi teks apapun, termasuk menginjeksi script atau tag html.
Sebagai contoh sederhana bisa dicoba www.ipmonkey.com. Web ini menampilkan user agent dan ip address. Bila saya ganti user agent browser saya menjadi maka script saya akan dieksekusi browser seperti pada gambar di bawah ini:
Seperti pada header referer, bila hanya serangan model begini tidak ada gunanya karena cuma bisa menyerang diri sendiri. Agar bisa menyerang orang lain, maka web application yang diserang harus menyimpan apa yang saya injeksi dan kemudian ditampilkan di webnya agar bisa dilihat orang lain. Sayangnya saya juga belum menemukan contoh web yang seperti itu. Contoh jenis web application yang menampilkan user-agent dalam webnya adalah cpanel. Namun ingat, cpanel tidak vulnerable terhadap serangan ini. Saya hanya memberi contoh hipotetis saja untuk ilustrasi saja.
Cpanel ada menu untuk melihat latest visitor yang menunjukkan ip address, url yang diakses, referer dan user agent. Saya akan coba menyisipkan script/tag html melalui user agent dan berharap cpanel menampilkannya tanpa filter. Hasilnya seperti pada gambar di bawah ini:
Terlihat bahwa tag script yang saya injeksikan telah diubah menjadi entity html < dan > sehingga tidak dieksekusi browser. Jadi serangan xss saya gagal total juga, hehe. Sebagai ilustrasi bila saya injeksikan tagTEST dan bila tidak difilter, maka hasilnya akan tampak seperti gambar berikut:
Halaman itu adalah salah satu halaman dalam cpanel, jadi hanya yang sudah login di cpanel yang bisa melihat latest visitor itu. Jadi bila script saya dieksekusi, maka saya bisa mengambil alih session cpanel orang itu. Untungnya (atau sayangnya) cpanel tidak vulnerable terhadap serangan ini.
Halaman itu adalah salah satu halaman dalam cpanel, jadi hanya yang sudah login di cpanel yang bisa melihat latest visitor itu. Jadi bila script saya dieksekusi, maka saya bisa mengambil alih session cpanel orang itu. Untungnya (atau sayangnya) cpanel tidak vulnerable terhadap serangan ini.
SQL Injection via Header
Oke dari tadi saya hanya bicara tentang XSS, bagaimana dengan sql injection? Mungkinkah serangan sql injection dilakukan dari header referer dan user agent? Jawaban saya sangat MUNGKIN sekali. Karena tidak adanya contoh yang vulnerable terhadap sql injection dengan header referer/user-agent saya hanya menjelaskan konsepnya saja.
Bayangkan ada web application yang mencatat log visitornya dalam tabel bernama visitor. Field tabel visitor adalah id, ipaddress,useragent, referer dan time semuanya bertipe varchar kecuali id bertipe int dan time yang bertipe timestamp. Setiap ada pengunjung baru, php akan meng-insert ke tabel visitor dengan sql berikut:
$sql = "insert into visitor (ipaddress,useragent,referer) values('$ipaddress','$useragent','$referer')";
Dari ketiga variabel itu yang bisa dikendalikan hanyalah user agent dan referer sebab ip address tidak bisa kita ubah seenaknya. Kalau saya injeksikan code sql yang diawali dengan karakter single quote (‘) melalui header user agent atau referer, tentu akan malicious code sql saya akan berhasil.
Kesimpulan
Saya sudah tunjukkan cara untuk menginjeksikan malicious code melalui header http. Ada banyak jalan yang bisa dipakai untuk menyerang web application. Hacker selalu mencoba menginjeksikan malicious data/code melalui semua pintu yang tersedia. Aplikasi yang prosesnya bergantung dari masukan klien bisa jadi sasaran tembak hacker.
Agar selamat dari serangan hacker, semua input harus benar-benar dijaga. Jangan percaya begitu saja dengan input dari klien. Terapkan whitelist filter, semua masukan yang diluar daftar yang diperbolehkan agar direject.