当前位置: 首页 > news >正文

SQL注入漏洞学习笔记

SQL注入漏洞学习笔记(第一部分:数据库基础)


1. 数据库基础

1.1 什么是数据库?

  • 定义:数据库是一个电子仓库,用于存储和管理数据。用户可以对数据进行新增、查询、更新、删除等操作。
  • 示例:通讯录是一个简单的数据库,存储姓名和电话号码。

1.2 查询语句(SELECT)
功能:从数据库中检索数据。
示例与原理

SELECT * FROM users;  
  • * 表示所有列。
  • 执行后返回 users 表中所有用户的信息。
SELECT name, email FROM users WHERE gender = 'male';  
  • 仅返回 nameemail 列,且筛选条件为 gender = 'male'
SELECT COUNT(*) FROM users;  
  • COUNT(*) 统计表中的总行数。

1.3 UNION 查询
功能:合并多个 SELECT 的结果集,并自动去重。
语法规则

  • 每个 SELECT 的列数必须相同。
  • 列的数据类型必须兼容。

示例

SELECT name FROM students UNION SELECT name FROM teachers;  
  • 合并 studentsteachers 表的 name 列,并去重。

UNION vs UNION ALL

  • UNION 去重,UNION ALL 保留所有记录(效率更高)。

1.4 information_schema 数据库
功能:存储数据库的元数据(如库名、表名、列名等)。
核心表

  • schemata:存储所有数据库名(schema_name)。
  • tables:存储所有表信息(table_schema 表所属数据库,table_name 表名)。
  • columns:存储所有列信息(column_name 列名)。

示例

SELECT table_name FROM information_schema.tables WHERE table_schema = 'test_db';  
  • 查询 test_db 数据库中的所有表名。

1.5 SQL 高级操作
1.5.1 排序(ORDER BY)

SELECT * FROM users ORDER BY name ASC;  
  • ASC 表示升序,DESC 表示降序。

利用 ORDER BY 判断列数(SQL注入关键步骤):

SELECT user, password FROM users ORDER BY 2;  
  • 按第2列(password)排序。若改为 ORDER BY 3 报错,则说明表中只有2列。

1.5.2 限定行数(LIMIT)

SELECT * FROM users LIMIT 2;  
  • 返回前2行数据。
SELECT user, password FROM users LIMIT 0,1;  
  • 从第0行开始,返回1行数据(常用于分页)。

1.6 字符连接函数

  • CONCAT(str1, str2, …):无分隔符连接。

    SELECT CONCAT(user_id, username) FROM users;  
    

    输出示例:1admin

  • CONCAT_WS(分隔符, str1, str2, …):带分隔符连接。

    SELECT CONCAT_WS('-', user_id, username) FROM users;  
    

    输出示例:1-admin

  • GROUP_CONCAT():合并组内所有值,逗号分隔。

    SELECT GROUP_CONCAT(username) FROM users;  
    

    输出示例:admin,user1,user2


1.7 截取函数

  • SUBSTR(str, start, length)

    SELECT SUBSTR("abcdef", 2, 3);  
    

    输出:bcd(从第2个字符开始截取3个字符)。

  • MID(str, start, length)

    SELECT MID(database(), 1, 1);  
    

    输出当前数据库名的第一个字符(如 t)。


1.8 常用函数

  • version():返回数据库版本。
  • user():返回当前登录用户。
  • database():返回当前数据库名。
  • @@datadir:返回数据库存储路径。

示例

SELECT database(), user();  

输出示例:test_db, root@localhost


1.9 注释符

  • 单行注释
    SELECT * FROM users; # 注释内容  
    SELECT * FROM users; --+ 注释内容  
    
  • 多行注释
    /* SELECT * FROM users WHERE id = 1; */  
    

SQL注入中的应用

SELECT * FROM users WHERE id = '1' AND 1=1--+';  
  • --+ 注释掉后续代码,使 AND 1=1 生效,绕过密码验证。

SQL注入漏洞学习笔记(第二部分:SQL注入漏洞简介)


2. SQL注入漏洞简介

2.1 什么是SQL注入?

  • 定义:SQL注入是一种Web安全漏洞,攻击者通过向应用程序输入恶意SQL语句,操控数据库查询逻辑,从而获取未授权数据或执行恶意操作。
  • 成因:前端输入未经过严格过滤,直接拼接到SQL语句中执行。

示例

SELECT * FROM users WHERE id = '$id';  
  • 正常输入:$id = 1,查询用户ID为1的信息。
  • 恶意输入:$id = 1' OR '1'='1,拼接后:
    SELECT * FROM users WHERE id = '1' OR '1'='1';  
    
    返回所有用户信息('1'='1' 永远为真)。

2.2 SQL注入的危害

  1. 数据库信息泄露:获取用户隐私数据(如密码、邮箱)。
  2. 网页篡改:通过修改数据库内容,篡改网页显示。
  3. 挂马攻击:在数据库中插入恶意链接,传播恶意软件。
  4. 数据库被恶意操作:删除表、修改数据等。
  5. 服务器被控制:通过数据库执行系统命令,获取服务器权限。
  6. 系统瘫痪:破坏数据库或服务器数据,导致系统崩溃。

2.3 SQL注入原理
攻击流程

  1. 攻击者在页面输入恶意字符(如 1' OR '1'='1)。
  2. 服务器未过滤输入,直接拼接到SQL语句中执行。
  3. 攻击者通过构造恶意SQL语句,获取敏感信息或执行恶意操作。

示例

SELECT * FROM users WHERE id = '$id';  
  • 输入:$id = 1' AND 1=1--+
  • 拼接后:
    SELECT * FROM users WHERE id = '1' AND 1=1--+';  
    
    • AND 1=1 永远为真,返回用户ID为1的信息。
    • --+ 注释掉后续代码,避免语法错误。

2.4 SQL注入分类
2.4.1 基于响应方式

  1. 基于错误的SQL注入:通过错误信息获取数据库结构。
  2. 联合查询注入(UNION注入):利用 UNION 合并查询结果。
  3. 堆查询注入:一次执行多条SQL语句(如 ; 分隔)。
  4. 盲注
    • 布尔盲注:通过页面返回的真假判断信息。
    • 时间盲注:通过延时函数(如 SLEEP())判断。

2.4.2 基于输入数据类型

  1. 字符串型注入:输入被单引号包裹(如 '$id')。
  2. 数字型注入:输入为数字(如 $id)。

2.5 SQL注入示例
示例1:基于错误的注入

SELECT * FROM users WHERE id = '$id';  
  • 输入:$id = 1'
  • 拼接后:
    SELECT * FROM users WHERE id = '1'';  
    
    • 单引号未闭合,导致SQL语法错误,返回数据库错误信息。

示例2:联合查询注入

SELECT name, email FROM users WHERE id = '$id';  
  • 输入:$id = 1' UNION SELECT username, password FROM admins--+
  • 拼接后:
    SELECT name, email FROM users WHERE id = '1' UNION SELECT username, password FROM admins--+';  
    
    • 返回 users 表和 admins 表的数据。

2.6 SQL注入步骤

  1. 判断是否存在注入

    • 输入 1' AND 1=1--+1' AND 1=2--+,观察页面响应。
    • 1=1 返回正常,1=2 返回异常,则存在注入。
  2. 判断注入类型

    • 输入 1',若报错则为字符串型注入。
    • 输入 1,若无报错则为数字型注入。
  3. 判断数据库类型

    • 通过错误信息或特定函数(如 version())判断。
  4. 获取数据库信息

    • 查询库名、表名、列名(利用 information_schema)。
  5. 提取数据

    • 使用 UNION 查询或盲注技术获取数据。
  6. 进一步操作

    • 修改数据、执行命令等。

2.7 SQL注入工具(SQLMap)
功能:自动化检测和利用SQL注入漏洞。
支持数据库:MySQL、PostgreSQL、SQL Server等。
常用命令

sqlmap -u "http://example.com/page?id=1"  
  • 检测目标URL是否存在SQL注入漏洞。
sqlmap -u "http://example.com/page?id=1" --dbs  
  • 获取所有数据库名。
sqlmap -u "http://example.com/page?id=1" -D test_db --tables  
  • 获取 test_db 数据库中的所有表名。

SQL注入漏洞学习笔记(第三部分:SQL注入防护与延伸)


3. SQL注入防护

3.1 采用预编译语句(Prepared Statements)
原理

  • SQL语句与用户输入分离,输入内容仅作为参数传递,不会被解析为SQL代码。
  • 预编译语句在数据库端预先编译,执行时仅传递参数值,避免SQL注入。

示例

String sql = "SELECT * FROM users WHERE id = ?";  
PreparedStatement pstmt = connection.prepareStatement(sql);  
pstmt.setInt(1, userId);  
ResultSet rs = pstmt.executeQuery();  
  • ? 是占位符,setInt 方法将 userId 作为参数传递,避免拼接SQL语句。

优点

  • 提高代码可读性和可维护性。
  • 防止SQL注入,提升安全性。

3.2 输入验证与过滤
原则

  • 对用户输入进行严格验证,确保符合预期格式(如数字、字母等)。
  • 过滤特殊字符(如单引号、双引号、分号等)。

示例

$id = $_GET['id'];  
if (!is_numeric($id)) {  
    die("Invalid input");  
}  
  • 确保 id 为数字,否则拒绝请求。

过滤函数

  • PHP:mysqli_real_escape_string()
  • Python:escape_string()

3.3 参数化查询
原理

  • 将用户输入作为参数传递,而非直接拼接到SQL语句中。

示例

query = "SELECT * FROM users WHERE id = %s"  
cursor.execute(query, (user_id,))  
  • %s 是占位符,user_id 作为参数传递,避免SQL注入。

3.4 使用安全参数
数据库安全配置

  • 设置数据库的安全参数,限制用户权限。
  • 例如,MySQL 的 secure_file_priv 参数控制文件读写权限。

查看配置

SHOW VARIABLES LIKE 'secure_file_priv';  
  • NULL:禁止文件读写。
  • 指定路径:仅允许读写指定目录。
  • 空值:无限制(不推荐)。

3.5 权限控制
原则

  • 普通用户与管理员用户权限分离。
  • 普通用户禁止执行高危操作(如 DROP TABLE)。

示例

  • 普通用户仅允许 SELECT 操作。
  • 管理员用户允许 CREATEDROPALTER 等操作。

3.6 分级管理
原则

  • 对用户进行分级管理,严格控制权限。
  • 普通用户禁止操作数据库结构(如创建、删除表)。

示例

  • 应用程序用户仅能访问特定表,无法访问系统表。

4. SQL注入延伸

4.1 SQLMap 工具
功能

  • 自动化检测和利用SQL注入漏洞。
  • 支持多种数据库(MySQL、PostgreSQL、SQL Server等)。

常用命令

sqlmap -u "http://example.com/page?id=1"  
  • 检测目标URL是否存在SQL注入漏洞。
sqlmap -u "http://example.com/page?id=1" --dbs  
  • 获取所有数据库名。
sqlmap -u "http://example.com/page?id=1" -D test_db --tables  
  • 获取 test_db 数据库中的所有表名。

4.2 SQL注入 Getshell
条件

  • 数据库支持文件读写(secure_file_priv 为空或指定路径)。
  • 目标服务器存在可写目录。

示例

SELECT '<?php phpinfo(); ?>' INTO OUTFILE '/var/www/html/shell.php';  
  • 将PHP代码写入服务器文件,生成Webshell。

防护

  • 限制数据库文件读写权限。
  • 检查服务器目录权限。

4.3 ASP/PHP 防注入实验
ASP 防注入

  • 过滤 Request.QueryStringRequest.Form 中的特殊字符。

PHP 防注入

  • 使用 mysqli_real_escape_string()PDO 预处理语句。

示例

$id = mysqli_real_escape_string($conn, $_GET['id']);  
$sql = "SELECT * FROM users WHERE id = '$id'";  
  • 对用户输入进行转义,防止SQL注入。

5. 总结

SQL注入的核心防护措施

  1. 预编译语句:避免SQL语句拼接。
  2. 输入验证与过滤:确保输入数据合法。
  3. 权限控制:限制用户操作权限。
  4. 安全配置:设置数据库安全参数。

学习建议

  • 动手实践:搭建测试环境,尝试SQL注入与防护。
  • 使用工具:熟悉SQLMap等工具的使用。
  • 关注安全:了解最新的SQL注入攻击与防护技术。

附录:常见SQL注入Payload

  1. 检测注入点

    ' AND 1=1--+  
    ' AND 1=2--+  
    
  2. 获取数据库信息

    ' UNION SELECT 1, version(), 3--+  
    
  3. 获取表名

    ' UNION SELECT 1, table_name, 3 FROM information_schema.tables--+  
    
  4. 获取列名

    ' UNION SELECT 1, column_name, 3 FROM information_schema.columns WHERE table_name='users'--+  
    
  5. 获取数据

    ' UNION SELECT 1, username, password FROM users--+  
    

相关文章:

  • kettle插件-高性能插入更新插件Upsert
  • 自学微信小程序的第十二天
  • 【不是广告】华为昇腾的一小步,Pytorch的一大步
  • Django模型数据查询:深入探索模型管理器Model.objects
  • Linux+apache之 浏览器访问云服务器磁盘的图片,通过tomcat
  • 浅浅认识一下js中的闭包
  • 聊天室Python脚本——ChatGPT,好用
  • 通用信息抽取大模型PP-UIE开源发布,强化零样本学习与长文本抽取能力,全面适配多场景任务
  • Leetcode 378-有序矩阵中第 K 小的元素
  • Linux安装Redis、远程连接Redis
  • Python使用SFTP批量上传和下载一个目录下的所有文件
  • flink tranform算子详解
  • 从厨电模范到数字先锋,看永洪科技如何助力方太集团开启数字新征程
  • 写一个python程序,找出1000以内的质数
  • c++ 接口/多态
  • 【开源免费】基于SpringBoot+Vue.JS疫情管理系统(JAVA毕业设计)
  • Java Web 相关技术概念与知识点
  • [MySQL初阶]MySQL(2)数据类型精讲静态类型和动态类型的对比
  • ubuntu20系统下conda虚拟环境下安装文件存储位置
  • 大模型在呼吸衰竭预测及围手术期方案制定中的应用研究
  • c asp做网站/北京seo优化wyhseo
  • 做外贸哪几个网站好/中国时事新闻网
  • 建设校园网站的好处/seo网站推广seo
  • 网站建设进展情况汇报/百中搜
  • 建设银行网站驱动/seo优化排名价格
  • 公司网站建设大概多少钱/怎么开网站平台挣钱