03SQL注入中information_schema的作用

简介: 【1月更文挑战第5天】给单位零基础小伙伴准备的网安入门教程,本教程是基于蚁景实验室搭建,基于自建虚拟机搭建需自行准备前置环境,03SQL注入中information_schema的作用 ,请遵守网络安全法!请遵守网络安全法!请遵守网络安全法!请勿破坏公共网络网络安全!

预备知识

MySQL语法:
https://dev.mysql.com/doc/refman/5.7/en/select.html

MySQL查询数据:
http://www.runoob.com/mysql/mysql-select-query.html

实验目的

通过本次实验,掌握SQL注入中,通过information_schema这个数据库爆库名、表名以及字段名的原理。

实验步骤

在MySQL数据库的注入中,如果你有仔细看过SQL注入语句的话,你可能就会发现,在获取数据库名、表名和字段的时候,注入语句中information_schema这个数据库出现得很频繁,那么有没有想过为什么会需要用到这个数据库呢? 这个数据库又是什么?它里面保存了什么?

information_schema数据库是MySQL自带的,MySQL 5以下没有这个数据库,它提供了访问数据库元数据的方式。什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。也就是说information_schema中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。在INFORMATION_SCHEMA中,有数个只读表。

在phpmyadmin中,在左侧点击information_schema数据库。

image.png

展开后如下图,显示了该数据库中的所有表,由于表数量太多,只截了一部分,可以拉动右边的滚动条查看所有表。

image.png

也可以执行如下SQL语句来查看该库中的所有表:

show tables;

image.png

需要注意的是,要在information_schema这个数据库中执行该SQL语句。如何进入information_schema数据库执行SQL语句,请参考前面进入sqli数据库执行SQL语句的步骤。

这上面显示的表,它们实际上是视图,而不是基本表,所以你在数据库的数据保存目录,会看不到这个数据库的实体文件。数据库的数据保存在 C:\wamp\bin\mysql\mysql5.6.17\data 目录,在这个目录下一共有如下4个目录:

image.png

想要查看数据库的数据保存目录,可以执行 select @@datadir ,如下图:

image.png

每一个目录对应数据库中的一个数据库,在数据库中执行show databases;的时候,可以看到存在5个数据库,正是少了information_schema这个数据库。

image.png

在SQL注入中,我们重点关注的表有如下几个,因为主要的时候主要利用这几个表来获取数据:

SCHEMATA:提供了当前mysql数据库中所有数据库的信息,其中SCHEMA_NAME字段保存了所有的数据库名。show databases的结果取自此表。

TABLES:提供了关于数据库中的表的信息,详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息,其中table_name字段保存了所有列名信息,show tables from schemaname的结果取自此表。

COLUMNS:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息,其中column_name保存了所有的字段信息。show columns from schemaname.tablename的结果取自此表。

为了更好地说明这些表的作用,我们进入mysql终端。

点击右下角的wampserver图标,如果没有该图标,可以双击桌面的WampServer运行。

image.png

然后在弹出来的列表中点击MySQL,再选择MySQL控制台。

image.png

会弹出一个命令行窗口,这就是mysql客户端,此时要求输入密码,由于root的密码为空,直接回车即可。

image.png

进入information_schema 数据库,命令为: use information_schema; 。一定要注意后面记得加分号,分号表示一个语句结束,如果没有检测到你输入分号,它会认为你一个语句还没结束,直到碰到分号后,才开始执行语句。

image.png

首先执行 show databases; 查看所有的数据库,然后再执行 select schema_name from schemata;

image.png

可以看到他们的作用是一样的,都是列出所有数据库,跟我们前面说的一样,SCHEMA_NAME字段保存了所有的数据库名。

所以,在注入中,我们可以通过注入select schema_name from schemata 来查询的当前数据库中所有的数据库名,如果你去查看一些爆数据库名的注入语句,就会发现里面包含这么一句:select schema_name from information_schema.schemata limit 0,1 ,其原理就是通过查询information_schema.schemata中schema_name的结果,其中limit 0,1用来获取第一条记录,通过递增第一个参数,可以每次获取一条记录,也就是一次获取一个数据库名,直到出现错误为止,说明没有更多的错误。

通常在获取了数据库名后,就会选择感兴趣的数据库,然后来获取其中的数据,首先需要获取感兴趣的数据库中的所有表名,通过查询information_schema库中的TABLES表就可以获取表名。

在TABLES表中,它保存了所有数据库中的所有表名以及这个表所属的库,意思是说,不管你在哪个数据库中的表,在这里都会有一条记录对应,如果你在一个数据库中创建了一个表,相应地在这个表里,也会有一条记录对应你创建的那个表。

desc 可以用来看表结构。看下tables的表结构,执行 desc tables; ,结果如下图:

image.png

注意上图中标记的那2条记录,每一条记录中,他们分别记录一个表名和一个这个表所属的库名。其中TABLE_NAME保存的是表名,而TABLE_SCHEMA保存的是这个表名所在的数据库。我们可以查询一条记录看看,在查询前,先看看有多少条记录,避免记录太多查看不方便,执行 select count(*) from tables; 结果如下图:

image.png

说明当前所有数据库中的表数量为142。查询任意一条记录查看,我这里选择最后一条记录,SQL语句为: select * from tables limit 141,1\G 由于在客户端中,默认查询结果显示不友好,所以,可以把语句后面的分号改成\G,他会让一条记录显示一行,看起来不那么乱。\G只支持在客户端中用,在其他连接数据库的软件中,使用\G会报错。

image.png

可以看到,最后一条记录的TABLE_NAME是user,TABLE_SCHEMA为sqli。查看sqli数据库中的表,SQL语句为: show tables from sqli; 可以看到确实存在user表。

image.png

既然information_schema的TABLES表中的TABLE_SCHEMTA字段是保存的数据库名,而TABLE_NAME保存了表名,那么我们就可以使用TABLE_SCHEMTA字段作为查询条件,查询TABLE_NAME,即可得知所有指定数据库中的所有表名。比如,我们想要通过information_schema数据库来查询sqli数据库中所有的表,那么就可以使用如下SQL语句:

select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = 'sqli';

如果当前库为information_schema,则可以省略不写,否则跨库查询的时候,需要带上库名。结果如下图:

image.png

通过修改TABLE_SCHEMA 的限制,可以查询任意数据库中的所有表名,网上的通过注入爆表名便是这个原理。

知道了表名,那么如何获取表中的字段呢?要知道我们没有表名的话,会把所有的数据查询出来,而如果注入没有回显,不能进行union查询,那么想要获取我们的标目数据,无疑效率极低。

幸运的是,在information_schema数据库中,同样存在一个表,它保存了整个数据中,所有的列名,这个表就是COLUMNS。同样先查看该表结构。

image.png

这里面,与注入相关的存在3个字段,分别是TABLE_SCHEMA、TABLE_NAME以及COLUMN_NAME,不难猜到,如果在该表中查询一条记录,TABLE_SCHEMA保存了这条记录保存的字段所属的数据库名,而TABLE_NAME保存的是该字段所属表名,COLUMN_NAME则是一个列名记录,查询一条记录验证一下,首先确定该表有多少条记录,执行 select count(*) from columns; ,得知一共有1662条记录,结果如下图:

image.png

我们获取最后一条记录,执行

select * from columns limit 1661,1\G

image.png

其中COLUMNS_NAME为ip,TABLE_NAME为user,TABLE_SCHEMA为sqli,这说明,在sqli这个数据中,user表存在一个ip的列,也就是我们常说的ip字段。

查看sqli的user表是否存在该字段,执行SQL语句:

show columns from sqli.user;

image.png

可以看到确实存在该字段。

既然在columns中,TABLE_NAME保存了字段所属的表名,TABLE_SCHEMA保存了该字段所属的库名,与通过TABLES表获取表名一样,我们就可以查询把TABLE_NAME 和TABLE_SCHEMA做为查询条件,查询符合条件的COLUMN_NAME,也就是查询指定数据库中某表中的字段。

比如,我们要通过information_schema数据库的columns表查询sqli数据库中user表中所有的字段,可以执行如下SQL语句:

select column_name from information_schema.columns where TABLE_SCHEMA='sqli' and TABLE_NAME='user';

image.png

查询结果与 show columns from sqli.user; 一致。

知道了库名、表名、字段,如果有回显且支持联合查询,就可以直接通过在注入点后面注入一个联合查询语句,即可直接获取数据,如果不能回显,则可能需要通过盲注获取数据,可以参考MySQL盲注实验。

课后问题:为什么网上的SQL注入语句中,数据库名都是用的字符的16进制值?

在SQL注入攻击中,攻击者尝试通过输入恶意构造的SQL语句来利用目标应用程序的安全漏洞。当应用程序不恰当地处理用户输入时,攻击者可能能够篡改或控制原本设计为执行静态查询的部分参数,进而达到非法访问、修改或破坏数据库的目的。

使用数据库名或其他SQL关键字的16进制值(hexadecimal)的主要原因有以下几点:

  • 绕过过滤:许多安全措施会简单地对常见的SQL特殊字符进行过滤,例如单引号(')、分号(;)和破折号(-)等。但它们可能不会对看似无害的数字和字母字符串进行同样的严格过滤,尤其是十六进制编码形式的字符串。因此,将数据库名转换为16进制可以绕过一些基础的输入验证机制。

  • 隐写术(Steganography):十六进制编码可以隐藏真实的意图,使得恶意代码更难被察觉。例如,在攻击语句中直接写出SELECT * FROM mydatabase很容易被发现并阻止,而其16进制表示则不容易一眼看出是数据库名。

  • 编码兼容性:在某些情况下,数据传输或存储过程中,为了保持数据的一致性和正确解析,可能会涉及编码转换。16进制是一种通用且跨平台的表示方法,确保无论在哪种环境中都能被正确解码回原始字符。

  • SQL Server特性:在SQL Server中,有一种技术允许通过十六进制表示法插入二进制或非ASCII字符,如NCHAR或NVARCHAR类型的数据。攻击者可以利用这种特性将数据库名以十六进制形式嵌入到SQL语句中,然后通过内置函数如 CONVERT 或 CAST 进行还原,欺骗服务器执行恶意命令。

综上所述,使用16进制编码数据库名是为了规避检测,增强攻击的隐蔽性和成功率。

参考资料https://www.cnblogs.com/hzhida/archive/2012/08/08/2628826.html

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
Web App开发 索引
正则表达式匹配域名、网址、url
DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母。标号中除连字符(-)外不能使用其他的标点符号。级别最低的域名写在最左边,而级别最高的域名写在最右边。由多个标号组成的完整域名总共不超过255个字符。
32040 0
将时间格式转化成时间戳和时间戳转化成时间格式的公式
将时间格式转化成时间戳和时间戳转化成时间格式的公式
Kam
|
druid
druid数据连接池异常 connection holder is null 解决方案
druid数据连接池异常 connection holder is null 解决方案
Kam
2944 0
|
缓存 小程序 JavaScript
从零开始搭建uni-app框架的小程序开发环境
从零开始搭建uni-app框架的小程序开发环境
1570 0
从零开始搭建uni-app框架的小程序开发环境
|
8月前
|
人工智能 安全 网络安全
科技云报到:2026网络安全六大新趋势:AI重构攻防,信任成为新防线
2026年,网络安全迈入“数字信任”时代。AI驱动下,AI Agent身份认证、API攻击泛滥、智能体基础设施风险等新威胁涌现,推动安全从被动防御转向主动信任重构。融合AI的主动防护、数据治理与合规体系,将成为企业构建可信数字生态的核心竞争力。(238字)
1761 0
|
10月前
|
人工智能 监控 安全
91_提示注入:安全提示工程
随着大型语言模型(LLM)技术的快速发展和广泛应用,AI系统正以前所未有的方式改变着我们的工作和生活。然而,这种强大的技术也带来了新的安全挑战,其中提示注入(Prompt Injection)攻击已成为最具威胁性的安全问题之一。提示注入攻击通过精心构造的输入,操纵或欺骗AI系统执行非预期行为,可能导致数据泄露、权限绕过、输出不当内容等严重后果
1302 0
|
监控 安全 JavaScript
DVWA CSP Bypass 通关解析
DVWA CSP Bypass 通关解析
|
JSON 安全 测试技术
什么是API接口测试?这可能是全网最全的教程了!
API 是应用程序间的“中间人”,用于实现通信和数据交换。随着微服务架构的普及,API 数量激增,其质量对系统稳定性至关重要。API 测试可验证功能、性能与安全性,帮助开发者在部署前发现并修复问题,提升系统可靠性。测试内容包括请求方法、URL、请求头、请求体、响应状态码与响应数据等。常用工具如 Postman、AREX 可辅助测试,确保 API 在不同场景下的正确性与稳定性。
|
网络协议 关系型数据库 Linux
Debian 13 Trixie 发布 - 通用操作系统
Debian 13 Trixie 发布 - 通用操作系统
1823 0
|
SQL 安全 网络安全
DVWA SQL Injection (Blind) 通关解析
DVWA SQL Injection (Blind) 通关解析

热门文章

最新文章