注入攻擊的本質(zhì)就是數(shù)據(jù)被當(dāng)做代碼執(zhí)行,注入成功兩個(gè)關(guān)鍵原因
1.用戶可以控制輸入數(shù)據(jù)
2.原來執(zhí)行的代碼拼接了用戶的輸入數(shù)據(jù)
1.我們做個(gè)實(shí)驗(yàn)如下,先創(chuàng)建一張測(cè)試表
create table t_test_injection
(
id int not null,
constraint t_test_sql_pk
primary key (id)
);
正常查詢語句如下,輸入?yún)?shù)id值為1
select * from t_test_injection where id=1
然后構(gòu)造注入語句,輸入?yún)?shù)值改為"1;drop table t_test_injection"
select * from t_test_injection where id=1;drop table t_test_injection
通過語句執(zhí)行監(jiān)控發(fā)現(xiàn)硝逢,sql語句分為兩次執(zhí)行,一次為查詢操作,另一次為刪除table操作
schema_test0> select * from t_test_injection where id=1
[2021-08-17 17:07:47] 1 row retrieved starting from 1 in 113 ms (execution: 9 ms, fetching: 104 ms)
schema_test0> drop table t_test_injection
[2021-08-17 17:07:47] completed in 17 ms
2.我們?cè)倏戳硗庖粋€(gè)例子百拓,通過構(gòu)造sql語句琴锭,規(guī)避掉本身查詢限制,查詢出所有數(shù)據(jù)
正常查詢語句如下耐版,輸入?yún)?shù)id值為1,原本語義為查詢出id為1的數(shù)據(jù)
select * from t_test_injection where id=1
構(gòu)造注入語句祠够,輸入?yún)?shù)值改為"1 or 1=1"
select * from t_test_injection where id=1 or 1=1
通過語句執(zhí)行監(jiān)控發(fā)現(xiàn),查詢出了所有數(shù)據(jù)(表中準(zhǔn)備了3條測(cè)試數(shù)據(jù))
schema_test0> select * from t_test_injection where id=1 or 1=1
[2021-08-17 17:10:48] 3 rows retrieved starting from 1 in 140 ms (execution: 10 ms, fetching: 130 ms)
隨意sql注入是非常危險(xiǎn)的漏洞,存在數(shù)據(jù)泄露粪牲,數(shù)據(jù)庫被破壞的風(fēng)險(xiǎn)古瓤,所以我們不僅需要防范sql注入,同時(shí)不要將數(shù)據(jù)庫相關(guān)錯(cuò)誤信息回顯給用戶腺阳。
3.再看一個(gè)如何獲取數(shù)據(jù)庫版本,我們先查看下我們現(xiàn)在使用的版本
select @@version from t_test_injection where id=1 ;
構(gòu)造語句
select * from t_test_injection where id=1 and substring(@@version,1,1)=8
查詢出結(jié)果落君,可以知道m(xù)ysql大的版本,當(dāng)然可以多次執(zhí)行亭引,獲取到最終的mysql版本绎速。
最后介紹下常用的sql注入工具,比如sqlmap焙蚓。
4.防御sql注入手段
1.利用代碼和數(shù)據(jù)隔離原則纹冤,采用預(yù)編譯語句,綁定變量的方式
2.使用最小權(quán)限原則购公,為應(yīng)用使用的數(shù)據(jù)庫用戶設(shè)置合理的權(quán)限