一、介紹
1.什麼是SQL注入?
sql 注入是一種将 sql 代碼添加到輸入參數中,傳遞到 sql 伺服器解析并執行的一種GJ手法。
2.SQL注入的原理
SQL 是操作資料庫資料的結構化查詢語言,網頁的應用資料和背景資料庫中的資料進行互動時會采用 SQL。而 SQL 注入是将 Web 頁面的原 URL、表單域或資料包輸入的參數,修改拼接成 SQL 語句,傳遞給 Web 伺服器,進而傳給資料庫伺服器以執行資料庫指令。
3.形成SQL注入的原因
使用者輸入的資料被 SQL 解釋器執行。
4.SQL注入的危害
1、GJ者未經授權可以通路資料庫中的資料,盜取使用者的隐私以及個人資訊,造成使用者的資訊洩露。2、通過操作資料庫對某些網頁進行篡改;3、修改資料庫一些字段的值,嵌入網馬連結,進行挂馬GJ。4、伺服器被遠端控制,被安裝後門。可以對資料庫的資料進行增加或删除操作,例如私自添加或删除管理者賬号。5、資料庫被惡意操作:資料庫伺服器被GJ,資料庫的系統管理者帳戶被篡改。6、破壞硬碟資料,導緻全系統癱瘓。
5.SQL注入基本知識
注:以下指令語句均基于 MySQL 資料庫
(1)增删改查語句
增 Insert
基本文法
INSERT INTO 表名稱 VALUES (值1, 值2,....)
例子
insert into student(name,sex,age) values('張三',18,'男')
删 delete
基本文法
DELETE FROM 表名稱 WHERE 列名稱 = 值
例子
delete from student where id=1
改 update
基本文法
UPDATE 表名稱 SET 列名稱 = 新值 WHERE 列名稱 = 某值
列子
update student set name = '張三' where id=1
查 select
基本文法
SELECT 列名稱 FROM 表名稱
例子
select * from student
(2)系統函數
- version()——MySQL 版本
- user()——資料庫使用者名
- database()——資料庫名
- @@datadir——資料庫路徑
- @@version_compile_os——作業系統版本
(3)字元串連接配接函數
concat(str1,str2,...)
沒有分隔符地連接配接字元串
concat_ws(separator,str1,str2,...)
含有分隔符地連接配接字元串
group_concat(str1,str2,...)
連接配接一個組的所有字元串,并以逗号分隔每一條資料
(4)一般流程
Mysql 有一個系統資料庫 information_schema,存儲着所有的資料庫的相關資訊,一般的, 我們利用該表可以進行一次完整的注入。以下為一般的流程。
猜資料庫
select schema_name from information_schema.schemata
猜某庫的資料表
select table_name from information_schema.tables where table_schema=’xxxxx’
猜某表的所有列
Select column_name from information_schema.columns where table_name=’xxxxx’
擷取某列的内容
Select *** from ****
二、分類
根據輸入參數分為:
- 數字型注入
- 字元型注入
根據注入技巧分為:
- 聯合注入
- 盲注
- 堆疊注入
- 報錯注入
- 二次注入
- 寬位元組注入
根據送出類型分為:
- GET 注入
- POST 注入
- COOKIE 注入
- HTTP 頭部注入
1.根據輸入參數分類的 SQL 注入
(1)數字型注入
我們經常可以看到這樣的 url http://xxx.com/users.php?id=1 基于此種形式的注入,一般被叫做數字型注入,這是因為其注入點 id 類型為數字。這一類的 SQL 語句原型一般為 select * from 表名 where id=1。
(2)字元型注入
我們有時又會看到這樣的 url http://xxx.com/users.php?name=admin 基于此種形式的注入,一般被叫做字元型注入,這是因為其注入點 name 類型為字元串。這一類的 SQL 語句原型一般為 select * from 表名 where name='admin'
2.根據注入技巧分類的 SQL 注入
(1)聯合注入
什麼是聯合注入?
聯合注入顧名思義,就是使用聯合查詢進行注入的一種方式,是一種高效的注入的方式,适用于有回顯同時資料庫軟體版本是5.0以上的 MYSQL 資料庫。
union 操作符介紹
UNION 操作符用于合并兩個或多個 SELECT 語句的結果集。請注意,UNION 内部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料類型。同時,每條 SELECT 語句中的列的順序必須相同。
(2)盲注
什麼是盲注?
盲注就是在注入過程中,擷取的資料不能回顯至前端頁面。此時我們需要利用一些方法進行判斷或嘗試,這個過程稱為盲注
盲注的分類
a.布爾盲注
什麼是布爾盲注?
布爾盲注是指利用頁面傳回的對錯資訊來間接推測資料庫中的資訊的一種手段。(構造邏輯判斷)
适用條件:布爾盲注一般适用于頁面沒有回顯字段(不支援聯合查詢),且 web 頁面傳回 True 或者 false 時。
常用函數
截取函數:left() right() substr() mid()
轉換函數:ascii() hex()
比較函數:if()
b.時間盲注
什麼是時間盲注?
時間盲注又稱延時注入,指通過頁面執行的時間來判斷資料内容的注入方式。
什麼時候使用?
當注入時,無論我們傳入什麼值,網頁正常或報錯都顯示一種頁面時,那麼網頁的是否正常顯示将不是我們用來判斷是否注入成功的依據,就要用基于時間的盲注。
方法:通過if判斷語句與 sleep 函數結合,通過網站通路的響應時間來判斷sql語句的正确性
示例:
if(left(database(),1)='s',0,sleep(3))
這段 payload 的含義是如果資料庫的第一位為's'時,網頁正常執行,否則延時3秒
c.報錯盲注
什麼是報錯盲注?
是指通過構造特定的SQL語句,讓GJ者想要查詢的資訊通過頁面的錯誤提示回顯出來的注入方式
什麼時候使用:當正常的回顯注入無法顯示結果,網頁可以顯示報錯資訊時,就可以使用報錯注入
常見的報錯函數
1)floor 報錯注入
在進行報錯注入時,floor()函數一般需要與rand()、count()、group by聯用。
示例:
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a
原理:
rand() 随機産生0~1的數值,floor() 向下取整,是以 floor(rand()*2結果是0或1。
group by 用于分組,當同時執行count和group by函數時,MYSQL會建立一個虛拟表,虛拟表進行計數和分組。在執行group by語句的時候,group by語句後面的字段會被運算兩次。
floor會報錯的原因就是group by在向臨時表插入資料時,插入重複主鍵導緻的報錯,又因為報錯之前concat()裡的語句已經執行過了,是以會直接爆出concat函數裡執行後的結果
2)exp 報錯注入
示例:
select exp(~(select * FROM(SELECT USER())a))
原理:
exp()即為以e為底的對數函數,exp中的函數成功執行後傳回0,對0按位取反會傳回一個無符号的BIGINT值,是以會造成Double型資料溢出錯誤進而報錯,借此得到資料。
3)extractvalue 和 updatexml 報錯注入
示例:
extractvalue(1,concat(0x7e,(select @@version),0x7e))
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
原理:
當使用 extractvalue(xml_frag, xpath_expr) 函數時,若 xpath_expr 參數不符合 xpath 格式,就會報錯。而 ~ 符号(ascii 編碼值:0x7e)是不存在 xpath 格式中的, 是以一旦在 xpath_expr 參數中使用 ~ 符号,就會産生 xpath syntax error (xpath文法錯誤),通過使用這個方法就可以達到報錯注入的目的。
updatexml同理