第五篇 SQL注入基礎知識
阿新 • • 發佈:2022-03-13
1 什麼是SQL注入
一種將SQL語句插入到使用者輸入的引數中,進行攻擊,這些會通過後端伺服器傳入到SQL伺服器,執行對應的SQL語句,比如可以獲取資料庫資訊、使用者資訊、管理員許可權等
2 常見的SQL注入技巧
2.1 識別資料庫型別
常見的資料庫型別有:Oracle、MySQL、SQL Server、Access、Postgresql等
- 首先根據web前端的技術棧,如:
asp和.net 通常使用sqlserver,asp有的時候也適用access
php通常使用mysql,postgresql
java通常使用oracle,mysql
-
其次根據使用的作業系統進行判斷,比如windows,使用的資料庫很有可能就是sqlserver,linux一般都是mysql,postgresql
-
再次,基於查詢、報錯資訊進行識別
1. 基於version: sqlserver : 1)select @@version, 返回結果示例: Microsoft SQL Server 2019 (RTM-CU14) (KB5007182) - 15.0.4188.2 (X64) mysql: 1)select @@version,返回結果示例: +-----------+ | @@version | +-----------+ | 8.0.26 | +-----------+ 2) select version(),返回結果示例: +-----------+ | version() | +-----------+ | 8.0.26 | +-----------+ postgresql: 1)select version(),返回結果示例: PostgreSQL 14.1 (Debian 14.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit oracle: 1) select banner from v$version,返回結果示例: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production 2. 基於字串的拼接方式:somestring sqlserver: select 'some'+'string'; mysql:select 'some' 'string' postgresql:select 'some' || 'string' oracle:select 'some' || 'string' from dual 3. 使用數字引數 sqlserver: 1) @@pack_reveived:返回資料包資訊,示例: 1> select @@pack_received 2> go ----------- 132 2) @@rowcount:返回上一句影響的行數,示例: 1> select @@rowcount 2> go ----------- 1 mysql: 1)connection_id():返回連線的id,示例: mysql> select connection_id(); +-----------------+ | connection_id() | +-----------------+ | 12 | +-----------------+ 1 row in set (0.00 sec) 2)last_insert_id():獲取最近插入主鍵的id,示例: mysql> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 0 | +------------------+ 3)row_count():獲取上次受影響的行數,示例: mysql> select row_count(); +-------------+ | row_count() | +-------------+ | -1 | +-------------+ oracle: 1)bitand:返回按位進行運算的結果,示例: SQL> select bitand(1,1) from dual; BITAND(1,1) ----------- 1 postgresql: 1)extract():提取時間或者日期資訊,示例: postgres=# select extract(dow from now()); extract --------- 4 (1 row) 4. 註釋 mysql:#,--,/* */ oracle和sqlserver:--,/* */,oracle不支援;符號
2.2 常用注入語句
2.2.1 UNION語句
用來合併兩條或多條SELECT語句的查詢結果
SELECT col1,col2 ... coln FROM table1
UNION
SELECT col1,col2 ... coln FROM table2
預設情況下,結果中只包含不同的值,如果需要包含所有的值,就需要改為:UNION ALL,如果應用程式返回第一個表查詢所得的資料,那麼就可以利用UNION來查詢任何一張表,但是也需要滿足一定的條件
1)兩個查詢返回的列數必須相同。想要獲取準確的列數,有兩種方法: a)通過對第二個語句進行注入多次,每次逐漸增大列數,直到查詢正確執行,為了避免資料型別不一致導致錯誤,可以使用null來代替 b)使用ORDER BY子句,可以增大列的數字來判斷列數,示例:ORDER BY 1(2,3,等),如果ORDER BY 3報錯,證明是2列,該方法比較推薦,主要原因是可以使用二分查詢的方式,速度更快,同時留下的痕跡更少 2)兩個SELECT語句對應列所返回的資料型別必須相同(或至少是相容的)。在獲取列數之後,想要判斷資料型別,就可以通過null的方式來進行替換,比如:UNION SELECT 'test', NULL,NULL ...
2.2.2 條件語句
有的情況,查詢結果只有兩種答案:是或否,這個時候就可以通過使用條件語句,格式示例:
IF 條件 THEN 執行 ELSE 執行其他
2.2.2.1 基於時間
比如想知道執行查詢的語句是不是系統管理員賬號
常用的有:
-
獲取資料庫資訊,比如:資料庫名(substr(),left()),資料庫長度(length()),示例猜測資料庫長度
-
獲取資料表資訊,示例猜測表名長度
-
獲取列資訊,示例猜測列名長度
2.2.2.2 基於錯誤
基於時間不適用於提取多位資訊,比如出現1和0的概率都是一樣的,主要方法有利用回顯的報錯注入和利用報錯資訊的報錯注入