Senin, 06 Agustus 2012
Simple Technique for SQLi Form Login Bypass
SQL Injection merupakan salah teknik eksploitasi web yang cukup lama, namun hingga saat
ini teknik tersebut masih cukup mumpuni dan efektif untuk dilakukan. Buktinya saat ini masih
ada saja (dan banyak) website yang mengidap penyakit vuln terhadap serangan SQL Injection.
Inti dari penyebab bug ini yaitu terletak pada si pembuat web (web programmer), anggap saja
ada kesalahan logika berpikir atau ketidaktahuaannya dalam membuat website yang aman. :)
Saya tekankan sekali lagi, masalah bug ini terletak pada diri programmer web. Jadi, sehandal
apapun sistem operasi atau web server yang digunakan akan menjadi percuma manakala si programmer
memiliki kekeliruan logika ketika membangun sebuah web, khususnya SQL Injection.
Sekilas tentang SQLi pada Form Login
Seperti yang kita ketahui, Form Login adalah Form untuk melakukan Login, halahhh :D. From
Login menjadi gerbang atau pintu yang akan membedakan dan memilah-milah pengunjung satu dengan
yang lainnya, apakah dia hanya sebagai pengunjung biasa, user biasa (pengupdate), atau sebagai
administrator, atau user dengan kategori lainnya.
Yang umum kita ketahui, dan ini yang saya ketahui dari cara berpikir programmer, secara
sederhana, autentikasi pada Form Login mempunyai teknik sebagai berikut:
Pertama, ada sebuah form untuk memasukkan username dan password. Misalnya seperti berikut:
Misal, nama filenya adalah login.html
----------- login.html --------------------------------------------------------------
---------------------------------------------------------------------------------------
Kedua, ada script untuk memvalidasi username dan password yang dimasukkan user.
Misal, namanya adalah auth.php
----------- auth.php ------------------------------------------------------------------
// bikin koneksi database
if($_POST['login']=="Login"){
$user = $_POST['username']; // ambil username
$pass = md5($_POST['password']); // ambil password lalu jadikan md5
$q = pg_query("SELECT * FROM users WHERE username='$user' AND password='$pass'");
//-- bla bla bla, dan seterusnya --
}
?>
---------------------------------------------------------------------------------------
Selanjutnya, misalkan struktur tabel "users" sebagai berikut:
+---------+----------+----------------------------------+
| id_user | username | password |
+---------+----------+----------------------------------+
| 1| admin | 21232f297a57a5a743894a0e4a801fc3 |
| | | |
+---------+----------+----------------------------------+
"21232f297a57a5a743894a0e4a801fc3" adalah bentuk md5 dari "admin".
Sehingga, secara sederhana, proses perjalanan dengan input username = 'admin' dan
password = 'admin' adalah sebagai berikut, u = username, p = password:
+---------------------+
|u : admin, p : admin |
+----------+----------+
|
+----------+----------+
|u : admin, p : admin |
+----------+----------+
|
+----------+------------------------------------+
|u : admin, p : 21232f297a57a5a743894a0e4a801fc3|
+----------+------------------------------------+
|
+----------+--------------------------------------------------------------------------------+
| SELECT * FROM users WHERE username='admin' AND password='21232f297a57a5a743894a0e4a801fc3'|
+-------------------------------------------------------------------------------------------+
Perhatikan, kita fokus pada "password". Dari proses di atas, kita tahu bahwa setiap password
yang diberikan akan diubah ke dalam bentuk md5, baru kemudian dicocokkan pada data dalam database
user (baca: tabel user). Hal itulah yang akan menjadi teknik sederhana dalam tulisan ini. :D
#3. Contoh Serangan
Untuk melakukan teknik serangan SQL Injection, saya pikir kita minimal tahu fungsi atau tata
cara pemanggilan atau perintah-perintah SQL (SQL Command). Dan saya pikir, semua database memiliki
perintah SQL yang relative sama, :D. Misalnya penggunaan komentar, ada yang menggunakan "--" atau
"/**/". Secara logika, kita bisa melakukan bypass terhadap form login dengan teknik tersebut,,,
sederhana bukan? Misalkan kita masukkan username = ''--', dan password dikosongkan.
maka perintah SQL diatas akan berubah menjadi seperti ini:
SELECT * FROM users WHERE username=''--' AND password='d41d8cd98f00b204e9800998ecf8427e'
ket: 'd41d8cd98f00b204e9800998ecf8427e' adalah bentuk md5 dari karakter kosong / tidak ada.
Maka, perintah SQL yang akan dieksekusi hanya :
SELECT * FROM users WHERE username=''
Sedangkan sisanya menjadi komentar lantaran ini, '--'. Nah, begitulah ceritanya kenapa kita bisa
menggunakan teknik SQL Injection untuk mem-bybass Form Login.
Selanjutnya, agar kita bisa dikenali sebagai user tertentu, maka perintah SQL kita harus bernilai
TRUE. Jika kita hanya menggunakan string " '-- " (tanpa double kutip), maka kita tidak akan
dikenali oleh sistem karena username '' tidak ada. Untuk itu, kita bisa menambahkan pernyataan
yang bernilai TRUE, misalnya:
' or true--
' or 1=1--
' or 'a'='a'--
Di lain pihak, kalau misalnya kita sudah tahu username-nya, namun tidak tahu passwordnya, kita bisa
menggunakan teknik seperti ini:
admin'--
admin' or true--
admin' or '1'='1'--
Dengan teknik yang sederhana tersebut, kita bisa menjadi user (atau bahkan administrator) dalam
website tersebut. :D
#4. Penanggulangan Sederhana
Coba ingat-ingat lagi pada bagian kedua tadi. Saya sudah wanti-wanti agar Anda mengingat suatu
hal terkait proses autentikasi username dan password :D. Ingat, setiap password akan dihash menjadi
md5 baru kemudian dicocokkan.
Nah, mari kita berpikir kritis sejenak. Kenapa perintah SQL untuk mencocokkan username dan password
seperti itu? Kemudian kenapa hanya password yang dihash md5? Haha, tentu saya tidak akan membuat orang
susah dengan meng-hash username menjadi md5... :p. Tapi, coba lihat perintah SQL berikut:
SELECT * FROM users WHERE username='admin' AND password='21232f297a57a5a743894a0e4a801fc3'
Ada yang kepikiran gag? Setiap password, apa saja, akan dihash dan menjadi 32 karakter biasa.
Ya! Selalu 32 Karakter!!! Artinya, perintah SQL yang dimasukkan sebagai tidak akan diterjemahkan sebagai
perintah SQL, tapi akan menjadi 32 karakter yang acak. :D
Sekarang, bagaimana jika perintah SQL tersebut saya ganti begini?
SELECT * FROM users WHERE password='21232f297a57a5a743894a0e4a801fc3' AND username='admin'
Maka, jika ada orang yang mencoba "admin'--", paling tidak akan seperti ini:
SELECT * FROM users WHERE password='di_sini_pasti_karakter_md5' AND username='admin'--'
Artinya, perintah SQL apapun tidak akan bisa dimasukkan karena 'password' harus sesuai dengan password
yang ada dalam tabel :D. Oke, itu dulu, semoga saya bisa tidur dengan tenang malam ini.
Nah, itulah teknik yang saya bilang sederhana. Sangat sederhana bukan? Tapi, semoga banyak orang yang
sadar dengan kesederhanann ini. :D Mungkin, karena terlampau sederhana, jadi tidak terpikirkan.
#5. Ucapan Terima Kasih
- Thx kepada Sang Khaliq yang mengaruniakan Otak 'sederhana' ini :D
- jasakom (haiii, saya masih pembaca biasa eihh..)
- echo (huaa, ezine-nya tiap hari saya baca... thx y3dips dan smua kru di sana??)
- temen-temen komunitas eth0 dan uinbuntu di UIN Malang, hayoo...
© Offensive Security 2011
Senin, 12 Maret 2012
Method Pada Java
Method adalah sekumpulan kode yang diberi nama, untuk merujuk ke sekumpulan kode tersebut
digunakan sebuah nama yang disebut dengan nama method. Method mempunyai parameter
sebagai input dan nilai kembalian sebagai output. Kita bisa juga membayangkan method itu
adalah sebuah mesin, ada input yang dibutuhkan dan output yang dihasilkan.
Deklarasai method terdiri dari beberapa bagian, bagian pertama adalah access modifer dari
method, apakah public, private, protected atau default. Bagian berikutnya adalah tipe kembalian
dari method, kalau method tidak mengembalikan apa-apa maka keyword void yang digunakan.
Bagian ketiga adalah nama method, sesuai dengan aturan java code convention, nama method
diawali dengan huruf kecil dan setiap kata setelahnya diawali dengan huruf besar (camel case).
Setelah nama method ada parameter. Sebuah method bisa juga tidak mempunyai parameter,
punya satu, dua dan seterusnya. Setelah java 5 ada feature yang disebut dengan varargs, feature
ini memungkinkan method untuk mempunyai jumlah parameter yang bervariasi. Varargs akan
kita bahas di bab tentang Java 5 Language enhancement, jadi tidak akan dibahas dalam bab ini.
Bagian terakhir dari method adalah deklarasi throws exception, dimana kita bisa
mendeklarasikan tipe exception yang akan dithrows oleh method. Bab tentang exception akan
membahas lebih lanjut tentang throws exception.
Nama method dan parameter adalah pembeda antara satu method dengan method yang lainya.
Kalau dua method namanya beda ya pasti dianggap dua buah method berbeda. Kalau dua method
namanya sama dianggap sebagai method yang berbeda kalau parameternya berbeda, method
dengan nama sama dan parameter berbeda ini disebut dengan overloading dalam konsep OOP.
Kalau method mempunyai nama yang sama dan parameter yang sama tetapi tipe return atau
throws exceptionya berbeda maka akan menyebabkan error pada waktu kompilasi. Jadi kalau
mendefnisikan method baru, pastikan bahwa namanya tidak sama dengan method lain atau
setidaknya parameternya berbeda baik dari sisi jumlahnya, tipe parameter atau posisi parameter.
Dari penjelasan di atas, struktur method seperti di bawah ini adalah benar:
digunakan sebuah nama yang disebut dengan nama method. Method mempunyai parameter
sebagai input dan nilai kembalian sebagai output. Kita bisa juga membayangkan method itu
adalah sebuah mesin, ada input yang dibutuhkan dan output yang dihasilkan.
Deklarasai method terdiri dari beberapa bagian, bagian pertama adalah access modifer dari
method, apakah public, private, protected atau default. Bagian berikutnya adalah tipe kembalian
dari method, kalau method tidak mengembalikan apa-apa maka keyword void yang digunakan.
Bagian ketiga adalah nama method, sesuai dengan aturan java code convention, nama method
diawali dengan huruf kecil dan setiap kata setelahnya diawali dengan huruf besar (camel case).
Setelah nama method ada parameter. Sebuah method bisa juga tidak mempunyai parameter,
punya satu, dua dan seterusnya. Setelah java 5 ada feature yang disebut dengan varargs, feature
ini memungkinkan method untuk mempunyai jumlah parameter yang bervariasi. Varargs akan
kita bahas di bab tentang Java 5 Language enhancement, jadi tidak akan dibahas dalam bab ini.
Bagian terakhir dari method adalah deklarasi throws exception, dimana kita bisa
mendeklarasikan tipe exception yang akan dithrows oleh method. Bab tentang exception akan
membahas lebih lanjut tentang throws exception.
Nama method dan parameter adalah pembeda antara satu method dengan method yang lainya.
Kalau dua method namanya beda ya pasti dianggap dua buah method berbeda. Kalau dua method
namanya sama dianggap sebagai method yang berbeda kalau parameternya berbeda, method
dengan nama sama dan parameter berbeda ini disebut dengan overloading dalam konsep OOP.
Kalau method mempunyai nama yang sama dan parameter yang sama tetapi tipe return atau
throws exceptionya berbeda maka akan menyebabkan error pada waktu kompilasi. Jadi kalau
mendefnisikan method baru, pastikan bahwa namanya tidak sama dengan method lain atau
setidaknya parameternya berbeda baik dari sisi jumlahnya, tipe parameter atau posisi parameter.
Dari penjelasan di atas, struktur method seperti di bawah ini adalah benar:
public void main(String[] args){ } public String methodReturnString(){ return "ini string"; } private void methodBerparameter(String parameter1, Integer parameter2) {} public void methodThrowsException() throws IOException {} protected String protectedMethod(Sting parameter1, Integer parameter2) throws IOException { return "ini string"; } public void methodBerbeda() {} public void methodBerbeda(String parameter1) {} public void methodBerbeda(String parameter1, Integer parameter2) {} public void methodBerbeda(Integer parameter1, String parameter2) {} public void methodBerbeda(Double parameter1, Double parameter2) {}
Ada beberapa keyword yang bisa ditambahkan dalam deklarasi method. Keyword yang paling sering digunakan adalah static. Bagian kode Java yang dideklarasikan dengan menggunakan static akan menjadi anggota dari class, bukan anggota dari object, silahkan kembali ke bab berikutnya kalau masih belum bisa membedakan mana class dan mana object. Karena method yang ditandai dengan static adalah bagian dari class, maka bisa diakses langsung dari nama Class itu sendiri, tidak perlu membuat object. Method static hanya bisa memanggil method lain dalam satu class yang juga ditandai static. Method main yang biasa kita gunakan untuk menjalankan aplikasi java juga ditandai dengan static, misalnya kita akan memanggil method lain dari method static, maka method lainya ini juga harus ditandai dengan static. Kita lihat contoh berikutnya :
public class StaticTest { public static void main(String[] args) { //static method memanggil static method lain dalam class yang sama contohMethodStatic(); //method static juga bisa dipanggil dari nama classnya StaticTest.contohMethodStatic(); } public static void contohMethodStatic() { System.out.println("method static dipanggil"); } }
Kalau kode di atas dicompile, kemudian dijalankan maka hasilnya seperti di bawah ini :
$ javac StaticTest.java $ java StaticTest method static dipanggil method static dipanggil $
terlihat bahwa method contohMethodStatic dipanggil dua kali, baik menggunakan nama class maupun tidak. Keyword lain yang bisa digunakan oleh method adalah fnal, synchronize dan native. Keyword fnal akan menyebabkan method tidak bisa dioverride, kita bahas topik ini di bab OOP. Keyword synchronize akan menyebabkan hanya satu thread yang bisa mengeksekusi method ini dalam satu waktu, kalau ada thread lain maka harus mengantri sampai thread sebelumnya selesai menjalankan method tersebut. Keyword native menandai implementasi method akan diletakkan dalam kode native, misalnya ditulis menggunakan C/C++, kemudian menggunakan Java Native Interface (JNI) untuk mengakses implementasi method tersebut.
Sabtu, 10 Maret 2012
Game Tebak Angka Menggunakan Java
/** * This program lets the user play one or more guessing games. In each * game, the computer selects a number in the range 1 to 100. The use * tries to guess the numbers. If the user's guess is right, the user * wins the game. If the user makes six incorrect guesses, the user * loses the game. The computer tells the user whether his guess is * high or low. After each game, the computer askes the user whether * the user wants to play again. */ public class GuessingGame { public static void main(String[] args) { TextIO.putln("Let's play a game. I'll pick a number between"); TextIO.putln("1 and 100, and you try to guess it."); boolean playAgain; do { playGame(); // call subroutine to play one game TextIO.put("Would you like to play again? "); playAgain = TextIO.getlnBoolean(); } while (playAgain); TextIO.putln("Thanks for playing. Goodbye."); } // end of main() /** * This subroutine lets the user play one guessing game and tells * the user whether he won or lost. */ static void playGame() { int computersNumber; // A random number picked by the computer. int usersGuess; // A number entered by user as a guess. int guessCount; // Number of guesses the user has made. computersNumber = (int)(100 * Math.random()) + 1; // The value assigned to computersNumber is a randomly // chosen integer between 1 and 100, inclusive. guessCount = 0; TextIO.putln(); TextIO.put("What is your first guess? "); while (true) { usersGuess = TextIO.getInt(); // Get the user's guess. guessCount++; if (usersGuess == computersNumber) { TextIO.putln("You got it in " + guessCount + " guesses! My number was " + computersNumber); break; // The game is over; the user has won. } if (guessCount == 6) { TextIO.putln("You didn't get the number in 6 guesses."); TextIO.putln("You lose. My number was " + computersNumber); break; // The game is over; the user has lost. } // If we get to this point, the game continues. // Tell the user if the guess was too high or too low. if (usersGuess < computersNumber) TextIO.put("That's too low. Try again: "); else if (usersGuess > computersNumber) TextIO.put("That's too high. Try again: "); } TextIO.putln(); } // end of playGame() } // end of class GuessingGame
Apabila Terjadi Error tambahkan File TextIO.java yang bisa di unduh disini
Membuat Konverter Jarak Menggunakan Java
/* * This program will convert measurements expressed in inches, * feet, yards, or miles into each of the possible units of * measure. The measurement is input by the user, followed by * the unit of measure. For example: "17 feet", "1 inch", * "2.73 mi". Abbreviations in, ft, yd, and mi are accepted. * The program will continue to read and convert measurements * until the user enters an input of 0. */ public class LengthConverter { public static void main(String[] args) { double measurement; // Numerical measurement, input by user. String units; // The unit of measure for the input, also // specified by the user. double inches, feet, yards, miles; // Measurement expressed in // each possible unit of // measure. TextIO.putln("Enter measurements in inches, feet, yards, or miles."); TextIO.putln("For example: 1 inch 17 feet 2.73 miles"); TextIO.putln("You can use abbreviations: in ft yd mi"); TextIO.putln("I will convert your input into the other units"); TextIO.putln("of measure."); TextIO.putln(); while (true) { /* Get the user's input, and convert units to lower case. */ TextIO.put("Enter your measurement, or 0 to end: "); measurement = TextIO.getDouble(); if (measurement == 0) break; // terminate the while loop units = TextIO.getlnWord(); units = units.toLowerCase(); /* Convert the input measurement to inches. */ if (units.equals("inch") || units.equals("inches") || units.equals("in")) { inches = measurement; } else if (units.equals("foot") || units.equals("feet") || units.equals("ft")) { inches = measurement * 12; } else if (units.equals("yard") || units.equals("yards") || units.equals("yd")) { inches = measurement * 36; } else if (units.equals("mile") || units.equals("miles") || units.equals("mi")) { inches = measurement * 12 * 5280; } else { TextIO.putln("Sorry, but I don't understand \"" + units + "\"."); continue; // back to start of while loop } /* Convert measurement in inches to feet, yards, and miles. */ feet = inches / 12; yards = inches / 36; miles = inches / (12*5280); /* Output measurement in terms of each unit of measure. */ TextIO.putln(); TextIO.putln("That's equivalent to:"); TextIO.putf("%12.5g", inches); TextIO.putln(" inches"); TextIO.putf("%12.5g", feet); TextIO.putln(" feet"); TextIO.putf("%12.5g", yards); TextIO.putln(" yards"); TextIO.putf("%12.5g", miles); TextIO.putln(" miles"); TextIO.putln(); } // end while TextIO.putln(); TextIO.putln("OK! Bye for now."); } // end main() } // end class LengthConverter
Apabila terjadi error, tambahkan file TextIO.java yang dapat di unduh disini.
Langganan:
Postingan (Atom)