SQL注入-学习笔记-入门
一、SQL注入基础
概述与原理
- 定义: Web应用未验证用户输入,导致攻击者可控的参数被拼接到SQL查询中,从而能执行任意数据库操作。
- 核心原理:
- 参数用户可控:用户能控制传入后端的数据。
- 参数带入查询:该参数被直接用于构建SQL语句并执行。
- 本质: 攻击者通过前端输入(如URL、表单)构造恶意SQL片段,传递给后端数据库执行,并根据返回结果获取信息或进行破坏。
基础SQL与关键知识
- 基础查询:
SELECT column_name FROM table_name;(查询列)SELECT column_name FROM table_name WHERE condition;(带条件查询)
information_schema数据库 (MySQL 5.0+): 存储元数据(数据库、表、列的信息)。SCHEMATA:存有库名 (SCHEMA_NAME)。TABLES:存有库名 (TABLE_SCHEMA) 和表名 (TABLE_NAME)。COLUMNS:存有库名 (TABLE_SCHEMA)、表名 (TABLE_NAME) 和列名 (COLUMN_NAME)。
LIMIT m, n: 限制查询结果数量。m是起始行索引(从0开始),n是返回的行数。例:LIMIT 0, 1返回第一条记录。- 注释符:
# ...-- ...(注意--后通常需要一个空格)/* ... */(多行或内联注释)/*! ... */(内联注释,可执行内部语句)
- 基础查询:
注入流程与常用函数
- 判断流程:
- 寻找注入点(GET/POST参数等)。
- 判断数据类型(数字型/字符型)。
- 构造闭合(字符型需要引号、括号等)。
- 判断查询的列数 (
ORDER BY)。 - 确定回显位置 (
UNION SELECT)。 - 查询数据库信息 (库名、表名、列名)。
- 获取敏感数据。
- 常用函数:
UNION SELECT:合并多个SELECT结果集(列数和类型需兼容)。ORDER BY n:按第n列排序,用于判断列数。CONCAT()/CONCAT_WS():连接字符串。GROUP_CONCAT():将分组后的多行结果连接成一个字符串。SUBSTR()/SUBSTRING():截取字符串。ASCII():返回字符的ASCII码。LENGTH():返回字符串长度。DATABASE()/SCHEMA():返回当前数据库名。VERSION():返回数据库版本。USER():返回当前用户。IF(condition, true_val, false_val):条件判断。SLEEP(seconds):延迟执行。UPDATEXML(),EXTRACTVALUE():用于报错注入的XML函数。
- 判断流程:
二、SQL注入漏洞种类
Union注入 (联合查询注入)
- 特点: 利用
UNION SELECT将恶意查询结果拼接到正常查询结果中,并在页面上显示出来。 - 前提: 页面需要有回显点显示查询结果。
- 步骤: 判断列数 -> 找到回显位 -> 构造查询语句获取数据。
- 类型:
- 数字型:
id=1 UNION SELECT ... - 字符型:
id='1' UNION SELECT ... #(需要闭合引号并注释掉后续代码)
- 数字型:
- 特点: 利用
Boolean注入 (布尔盲注)
- 特点: 页面只返回True/False两种状态(或内容有明显差异),无具体数据回显。
- 方法: 构造SQL语句,利用
AND、OR等逻辑,结合LENGTH(),SUBSTR(),ASCII()等函数逐个字符判断信息。 - 示例:
id=1 AND LENGTH(DATABASE()) > 5,根据页面返回判断库名长度是否大于5。 - 缺点: 效率低,通常需要脚本自动化。
Error-based注入 (报错注入)
- 特点: 页面会显示数据库的错误信息。
- 方法: 利用特定函数(如
UPDATEXML(),EXTRACTVALUE(),FLOOR(),EXP())构造错误的SQL语句,使数据库在报错信息中带出想要查询的数据。 - 示例:
id=1 AND UPDATEXML(1, CONCAT(0x7e, (SELECT DATABASE()), 0x7e), 1)(0x7e是~,用于标记数据)
Time-based注入 (时间盲注)
- 特点: 页面无任何有用回显,也无状态差异。
- 方法: 利用
IF()语句结合SLEEP()或BENCHMARK()函数。如果条件为真,则执行延迟,通过响应时间判断条件真假,从而逐个推断信息。 - 示例:
id=1 AND IF(ASCII(SUBSTR(DATABASE(), 1, 1)) = 115, SLEEP(3), 0)(如果库名首字母ASCII是115,则延迟3秒) - 缺点: 比布尔盲注更慢,受网络波动影响。
Stacked Queries注入 (堆叠查询注入)
- 特点: 利用分号
;执行多条SQL语句。 - 用途: 可以执行非
SELECT语句(如INSERT,UPDATE,DELETE,DROP,ALTER),或执行SHOW DATABASES,SHOW TABLES等。在某些环境下可绕过SELECT限制。 - 示例:
id=1'; SHOW TABLES; #
- 特点: 利用分号
Second Order注入 (二次注入)
- 特点: 恶意输入在第一次提交时被存储(可能经过转义),但在后续被取出并再次拼接到SQL语句执行时未被充分处理,导致注入。
- 流程: 注册/添加数据时输入带payload的内容 -> 后续操作(如修改密码、查看详情)触发该数据 -> 数据未经处理代入SQL执行。
Cookie注入
- 特点: 注入点在HTTP请求的Cookie头中。
- 方法: 修改浏览器Cookie中的参数值,构造SQL注入语句。
- 类似: 其他HTTP头注入(如User-Agent, Referer, X-Forwarded-For)。
Outfile注入 (文件读写注入)
- 特点: 利用
SELECT ... INTO OUTFILE 'filepath'将查询结果写入服务器文件,或LOAD_FILE('filepath')读取服务器文件。 - 前提:
- 数据库用户有文件读写权限 (
FILE权限)。 - 知道服务器上的绝对路径。
- MySQL的
secure_file_priv配置允许写入目标路径(空值表示允许任意路径,特定路径表示仅限该路径,NULL表示禁止)。
- 数据库用户有文件读写权限 (
- 用途: 写入Webshell,读取配置文件等。
- 特点: 利用
Wide-Byte注入 (宽字节注入)
- 特点: 发生在数据库使用多字节编码(如GBK)且PHP使用了
addslashes()等函数转义单引号时。 - 原理: 输入
%df',addslashes()变为%df\'(\的URL编码是%5c)。在GBK编码下,%df%5c被解析为一个合法的宽字节字符(“連”),从而“吃掉”了反斜杠,使得单引号'成功逃逸,可以闭合前面的引号。 - 后续: 可能需要使用十六进制编码或嵌套查询来避免注入的语句中出现单引号。
- 特点: 发生在数据库使用多字节编码(如GBK)且PHP使用了
三、其他相关知识
绕过登录
- 原理: 利用SQL逻辑漏洞绕过登录验证。
- 常见形式: 用户名输入
admin' OR '1'='1,密码任意。 - SQL语句分析:
WHERE username='admin' OR '1'='1' AND password='...'。AND优先级高于OR,但'1'='1'恒为真,导致整个WHERE子句为真。
绕过技巧
- 大小写混合:
SeLeCt,UnIoN - 双写关键字:
selselectect - 替换空格:
/**/,()(某些情况),%0a(换行符),Tab键 (%09) - 编码绕过: URL编码, Hex编码, Unicode编码
- 替换操作符:
=可用LIKE,REGEXP,<>(不等于) - 替换关键字:
UNION SELECT可尝试报错注入、盲注;SELECT可尝试堆叠查询中的SHOW,DESC,HANDLER或预处理语句。 - 内联注释:
/*! ... */可绕过一些WAF对关键字的检测。
- 大小写混合:
- Title: SQL注入-学习笔记-入门
- Author: KaldX
- Created at : 2025-04-10 20:00:00
- Updated at : 2025-04-16 20:00:00
- Link: https://blog.kaldx.com/2025/04/10/SQL注入-学习笔记/
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments