spring-data-redis 動態切換資料來源
SQL注入是因為後臺SQL語句拼接了使用者的輸入,而且Web應用程式對使用者輸入資料的合法性沒有判斷和過濾,前端傳入後端的引數是攻擊者可控的,攻擊者可以通過構造不同的SQL語句來實現對資料庫的任意操作。比如查詢、刪除,增加,修改資料等等,如果資料庫的使用者許可權足夠大,還可以對作業系統執行操作。
SQL注入可以分為平臺層注入和程式碼層注入。前者由不安全的資料庫配置或資料庫平臺的漏洞所致;後者主要是由於程式設計師對輸入未進行細緻地過濾。SQL注入是針對資料庫、後臺、系統層面的攻擊!
mysql中註釋符:# 、/**/ 、 --
一、分類
-
依據注入點型別分類
-
數字型別的注入
-
字串型別的注入
-
搜尋型注入
-
-
依據提交方式分類
-
GET注入
-
POST注入
-
COOKIE注入
-
HTTP注入(XFF注入、UA注入、REFERER注入)
XFF:X-Forwarded-For(XFF)是用來識別通過
UA:使用者代理(User Agent,簡稱 UA),是一個特殊字串頭,使得伺服器能夠識別客戶使用的
REFERER:HTTP Referer是
-
-
依據獲取資訊的方式分類
-
基於布林的盲注
-
基於時間的盲注
-
基於報錯的注入
-
聯合查詢注入
-
堆查詢注入(可同時執行多條語句)
-
二、判斷是否存在SQL注入
-
工具掃描:網站漏掃工具、AWVS、AppScan、OWASP-ZAP、Nessus等
-
手動測試:
-
單雙引號、括號;進行組合測試,看是否報錯
-
對於數字型:?id=3-1 ?id=2#
如果顯示的是?id=2時的正常頁面,可判斷注入點是數字型注入;如果返回不正常,則可判斷非數字型注入
-
對於字元型:?id=2a ?id=2'#
Mysql 中,等號兩邊如果型別不一致,會發生強制型別轉換。當數字與字串進行比較時, 首先先將字串轉換成數字,然後再進行比較。
-
對於布林盲注:
盲注:就是在伺服器沒有錯誤回顯時完成的注入攻擊。伺服器沒有錯誤回顯,對於攻擊者來說缺少了非常重要的資訊,所以攻擊者必須找到一個方法來驗證注入的SQL語句是否得到了執行。
?id=1' and '1 ?id=1' and 'a
這裡沒有使用註釋符號進行後面的單引號閉合,使用的是手工單引號閉合
或者, ?id=1' and 1=1# ?id=1' and 1=2#
兩者的頁面截然不同,一個正常回顯,一個沒有回顯的話,就可判斷是布林盲注。
-
對於時間盲注:
?id=1' and sleep(3)#
在MySQL中,有一個Benchmark() 函式,它是用於測試效能的。 Benchmark(count,expr) ,這個函式執行的結果,是將表示式 expr 執行 count 次 。
因此,利用benchmark函式,可以讓同一個函式執行若干次,使得結果返回的時間比平時要 長,通過時間長短的變化,可以判斷注入語句是否執行成功。這是一種邊通道攻擊,這個技巧在 盲注中被稱為Timing Attack,也就是時間盲注。
-
-
常見SQL注入功能點
只要是存在資料庫互動的地方都有可能出現 SQL 注入。
常出現在 登入頁面、訂單頁面、文章或新聞展示頁面、修改密碼頁面(二次注入)、涉及獲 取 HTTP 頭(XFF等)的功能點等。
三、MySQL注入
-
必備
-
元資料庫 information_schema
元資料庫 information_schema 中:
存放資料庫資訊的表:schemata
schemata 表中
欄位 schema_name 存放所有資料庫名;
存放表資訊的表:tables
tables 表中
欄位 table_name 存放所有表名
欄位 table_schema 存放所有表所在的資料庫名;
存放所有欄位資訊的表:columns
columns 表中
欄位 column_name 存放所有欄位名,
欄位 table_name 存放所有欄位所在的表名,
欄位 table_schema 存放所有欄位所在的資料庫名; -
語句分類
1.DQL(資料查詢語言):查詢語句,所有的 select 語句
2.DML(資料操作語言):insert , delete , update , 對錶中的 資料 進行 增刪改
3.DDL(資料定義語言):create , drop , alter 對錶 結構 的 增刪改
4.TCL(事務控制語言):commit 提交資料,rollback 回滾資料 Transaction
5.DCL(資料控制語言):grant 授權,revoke 撤銷許可權等 -
基本語句
# 查庫:
show databases;
select schema_name from information_schema.schemata;
# 建庫:
create database + 庫名;
# 刪庫:
drop database + 庫名;
# 進入資料庫:
use + 庫名;
# 查表:
show tables;
select table_name from information_schema.tables where table_schema='security'
select table_name from information_schema.tables where table_schema=database
# 查列:
select * from users;
select column_name from information_schema.columns where table_name='users'
# 查欄位:
select username,password from security.users; -
基本函式
#資料庫安裝、路徑,使用者 資訊
version(); Mysql 資料庫版本
database(); 當前 資料庫名
user(); 資料庫的使用者名稱
current_user(); 當前使用者名稱
session_user(); 連線到資料庫的使用者名稱
system_user(); 系統使用者名稱
@@datadir(); 資料庫檔案的存放路徑
@@version_compile_os; 作業系統版本
@@basedir; 資料庫的安裝目錄
#字串長度、擷取
length(); 返回字串的長度
substring(a,b,c); 擷取字串
substr(a,b,c);
mid(a,b,c);
三個引數:a.擷取的字串 b.擷取的起始位置 c.長度
left(a,b); 從左側擷取a的前b位,正確返回1,錯誤返回0
#字串配對連線
concat(a,0x5e,b); 字串配對連線
concat_ws('~',A,B); 含有分隔符的連線字串
group_concat(); 將字串連線為一個組,可將不同列分到同一行中
#字串特殊處理
ord(); 返回ASCII碼
ascii('a'); 將字母 a 轉換為ascii值
rand(); 返回0~1之間的隨機浮點數
round(); 返回最近的整數值
md5(); 返回MD5值
hex(); 將字串轉換為十六進位制
unhex(); hex()的反向操作
floor(x); 返回不大於x的最大整數
load_file(); 讀取檔案,返回檔案內容作為一個字串
sleep(a); 沉睡a秒
if(true,t,f); 判斷語句為true ,執行第一個,否則第二個
find_in_set(); 返回字串在字串列表中的位置
benchmark(); 指定語句執行的次數
name_const(); 返回表作為結果 -
匯入資料
當希望匯入一個 較大 的檔案或者是想要批量的執行sql語句時,可以使用 mysql 中的 source 使用方法:source + 檔案路徑(直接拖拽)
-
-
# insert
insert into 表名(欄位名1,欄位名2,欄位名3......) values(值1,值2,值3......);
# delete
delete from 表名 where 條件;//可回滾
對於大表:
truncate table 表名;//不可回滾,將會永久丟失
# update
update 表名 set 欄位名1=值1,欄位名2=值2,......where 條件;# select
select 欄位1,欄位2,...... from + 表名 where + 條件;# between and
select * from users where id between 2 and 8;
select * from users where id >=2 and id <=8;# in not in
select password from users where id not in(5,8);
指查找出 id不等於5 和 id不等於8 的使用者的密碼
注:不是 5~8,in之後不是一個區間# like
1.% 代表任意多個字元
2._ 代表任意一個字元
select username from users where username like '%b%';
指查找出使用者名稱中帶有字母b的使用者名稱
select username from users where username like '_a%';
指查找出使用者名稱中帶第二個字母為a的使用者名稱
select username from users where username like '%b';
指查找出使用者名稱中帶最後一個字母為b的使用者名稱
select username from users where username like '%\_%';
指查找出使用者名稱中帶有下劃線_的使用者名稱
注:特殊字元需要轉義# order by
select username from users order by 欄位名;
注:預設為升序排列
指定升序:asc
select username from users order by 欄位名 asc;
指定降序:desc
select username from users order by 欄位名 desc;
雙重需求:
select username from users order by 欄位名1 desc,欄位名2 asc;# 分組函式
select sum(grade) from users;
select avg(grade) from users;
select max(grade) from users;
select min(grade) from users;# 空處理函式
select sum(ifnull(salary,0)*12), from crew;
求一年的薪水之和,當薪水為NULL時,被當作0來處理# group by 與 having
group by:按照某個欄位或某些欄位進行分組
having:對分組之後的資料進行再次過濾,即having 必須跟在 group by 後面使用
select max(grade) from students group by classes;
先根據班級分組,再查出各個班級的成績最高學生的成績
1.分組函式一般與 group by 聯合使用,並且任何一個分組函式(count,sum,avg,max,min)都是堆一組資料進行操作的
2.當一條sql語句沒有 group by 時,整張表會自成一組
3.當sql語句中使用group by時,select之後只能跟參與分組的欄位或者分組函式# distinct 去重
distinct 關鍵字 去除重複記錄
select distinct job from company;
查詢該公司中的工作崗位# 語句執行順序
select 5號:挑選出滿足條件的資料
from 1號:定表
where 2號:過濾原始資料
group by 3號:進行分組
having 4號:對資料進行再次過濾
order by 6號:進行排序1.字串資料 sum,avg 為 0,max,min 按字母大小取
2.分組函式會自動忽略 NULL
3.數學運算 中如果有NULL參與,結果為定為NULL
4.分組函式不能直接出現在 where 後面,原因是 group by 是在where語句執行結束之後執行的
5.分組函式可組合使用# inner join
select a.ename,b.dname from emp a join dept b on a.deptno=b.deptno;
# left/right join
select dname,ename from dept a left join emp b on a.deptno=b.deptno;