news 2026/10/18 7:29:56

SQL注入入门:从原理到实战,数字型与字符型详解(2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL注入入门:从原理到实战,数字型与字符型详解(2)

摘要:本文以 SQL 注入为主题,先回顾数字型注入与字符型注入的区别,再重点讲解两个关键探测手段:order by用于判断查询结果的列数,union用于把自定义查询结果拼接到原查询后面。文章结合靶场实例,详细演示了先用 order by 逐次递增探测列数、再用 union select 对齐列数找出回显点、最后把回显点替换成目标数据的完整配合流程,并强调所有操作都应在合规靶场中进行。

一:上一篇文章我们了解了关于SQL注入的基本流程,这次我们来深度剖析一下数字型注入和字符型注入

(1):注:下面操作均在合规靶场进行!!!

注:下面操作均在合规靶场进行!!!

注:下面操作均在合规靶场进行!!!

(2):我们知道,数字型注入和字符型注入根本的区别就是后端执行SQL代码的时候,有没有对用户输入这块进行校验,例如下面这段SQL代码:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; $result=mysql_query($sql); $row = mysql_fetch_array($result);

因为在

id='$id' LIMIT 0,1";

这里后端没有对'$id'进行字符处理,所以导致攻击者输入{1'},后,后端的SQL代码就为这样:

$sql="SELECT * FROM users WHERE id='1'' LIMIT 0,1";

因为原始SQL已经用单引号包裹了 $id,攻击者输入的 1' 带来了一个闭合单引号,导致剩下的 ' 变成了多余的语法错误。这就叫“打破原有的闭合规则

这样SQL代码不会被执行,而是抛出一个异常:{You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1'' LIMIT 0,1' at line 1}

意思就是在:{'1'' LIMIT 0,1' at line 1}这里有一个SQL语句错误,这就导致攻击者可以通过这个报错信息来反推这段SQL代码的闭合类型,这也就是攻击者最喜欢看到的信息,比起盲注,这个反而简单了,因为就等于告诉攻击者,注入的结果是直接回显在前端HTML页面里的。

二:在SQL注入中,order by 和 union 是两个非常关键的探测手段,它们能帮助攻击者快速判断SQL语句的结构,为后续的注入利用打下基础。

(1):order by 的用法

order by 在SQL中原本用于对查询结果进行排序,但在注入探测中,它有一个更重要的用途:判断查询结果的列数。

例如,对于前面的SQL代码:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

我们打开靶场SQLI-LABS/Less-1,过一遍,感受一下。

当在URL后面加上?id=1'参数后,页面就把SQL代码的异常回显在页面上(因为我是直接在原生的HTTP请求里加的参数,浏览器自动进行了URL编码,在URL编码里,{ %20 +} 代表空格,%26代表{#号},%27则代表单引号{ ' }),你用的如果是BP(Burp Suite),则空格用{ + },注释掉后面的SQL代码,可以用{ -- 和 %26 }

回到正题,order by可以帮助我们更快的知道页面最多可以回显多少的字段,同样,当输入{ 1' order by 1 -- } 时,后端的SQL代码就为:

$sql="SELECT * FROM users WHERE id='1' order by 1 -- ' LIMIT 0,1";

{ order by "这里的数字可以任意输入" -- },输入{ 3 }时页面没有报错,但输入{ 4 }时,页面如果爆破了,那么,前端回显的最大列数为{ 3 }列,以此类推,例如:

这就可以确定页面回显的最大字段为{ 3 }列。

为什么先探测列数?因为后面的 union 注入要求前后两个查询的列数必须一致,否则会报错。所以 order by 是 union 注入的前置步骤。

二、union 的用法

union 的作用是把两个查询的结果合并在一起。在注入中,我们利用它来把自定义的查询结果拼接到原查询后面,从而获取我们想要的数据。

union 的使用前提有两个:

  • 前后两个查询的列数必须相同(这就是为什么要先用 order by 探测列数)。
  • 前后两个查询的列类型要兼容。

例如,假设我们探测出原查询有 3 列,那么可以这样构造:

$sql="SELECT * FROM users WHERE id='-1' union select 1,2,3";

这里的{ -1} 不是 SQL 的特殊关键字,它只是传给原查询参数的一个值,作用是:让 union前面那一段查询查不到任何数据,从而让页面显示 union 后面的 1,2,3 结果,如果页面回显了2和3,那就说明第 2 列和第 3 列是回显点,例如:

我们可以把占位符替换成想要查询的内容,比如:

$sql="SELECT * FROM users WHERE id='1' union select 1,2,username from users LIMIT 0,1";

页面是这样回显的:

这里有一个要说的,这段SQL代码后面的{ LIMIT 0,1 }是这样的:

{ LIMIT 0,1 },LIMIT后面的0,1是LIMIT的子参数,意思是:{ 0 }从一整个结果集里面,从第0条记录(也就是第一条开始),{ 1 }表示是只显示第一条数据,这也是为什么我们使用{ -1' } 这个非法ID,因为原查询查不到数据,页面留出空位,正好让我们的 union select 数据补位回显。

像pikachu靶场就没有对数据限制,这里做一个对比,方便好理解:

三、order by 和 union 的配合流程

在实际注入中,两者的配合流程通常是这样的:

  1. 先用order by N逐次递增,探测出查询的列数。
  2. 再用union select 1,2,3...对齐列数,找出回显点。
  3. 最后把回显点替换成目标数据(如库名、表名、字段名、数据)。

下面我们把这个流程拆开,结合前面的例子一步步走一遍,看看每一步到底在做什么、为什么要这么做。

第一步:用 order by 探测列数。这一步是整个注入的“地基”。我们并不知道后端查询到底返回几列,所以从order by 1开始,逐次把数字加 1,直到页面报错为止。比如在 Less-1 中,order by 3页面正常,order by 4页面报错,就说明原查询只有 3 列。为什么必须知道列数?因为 union 合并结果时,前后两个查询的列数必须完全一致,多一列或少一列都会直接报错,导致注入失败。

第二步:用 union select 对齐列数,找出回显点。知道了列数是 3 之后,我们把查询参数改成一个查不到数据的值(比如-1),再拼接union select 1,2,3。这样前面那段查询返回空结果,页面就会显示 union 后面的内容。如果页面上出现了数字 2 和 3,就说明第 2 列和第 3 列是回显点——也就是我们可以把想要的数据“塞”进去的位置。这一步相当于在目标系统里找到了两个可以输出信息的“窗口”。

第三步:把回显点替换成目标数据。回显点确定之后,剩下的就是“换内容”了。比如把2换成database()就能看到当前数据库名,把3换成username就能看到用户名字段。以此类推,我们可以一步步把库名、表名、字段名、具体数据都查出来。整个过程就像在填一张表格,先确定表格有几列,再找到能显示内容的格子,最后往格子里填我们想要的信息。

这个流程是手工注入的核心思路,理解之后,后续的报错注入、盲注等技巧都是在这个基础上的延伸。比如报错注入是利用数据库报错信息来带出数据,盲注则是通过页面是否正常来逐字符猜测数据,它们的本质都是在“探测结构”和“获取数据”这两个环节上做文章。把 order by 和 union 的配合流程吃透,后面再学其他注入方式就会轻松很多。

四、总结

本文围绕 SQL 注入中的两个核心探测手段展开:order by用于判断查询结果的列数,union用于把自定义查询结果拼接到原查询后面。两者的配合流程可以概括为三步:先用 order by 逐次递增探测列数,再用 union select 对齐列数找出回显点,最后把回显点替换成目标数据(如库名、表名、字段名、具体数据)。

理解这个流程的关键在于把握两个前提:前后两个查询的列数必须相同、列类型要兼容。这也是为什么 order by 是 union 注入的前置步骤。掌握了这套手工注入的核心思路,后续的报错注入、盲注等技巧都是在这个基础上的延伸——它们的本质都是在“探测结构”和“获取数据”这两个环节上做文章。

最后提醒一句:以上所有操作都应在合规靶场中进行,切勿用于未经授权的真实系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 7:29:45

fp32,fp16,bf16的区别

谈到FP32,FP16,BF16的区别是什么,可能我们的第一反应是:FP32:32 bit表示FP16、BF16:16bit表示所以他们能表示的数值范围、精度不同,如果仅仅是知道这点,那就太表面了。一个浮点数如何在计算机中存储的我们以FP32来举例…

作者头像 李华
网站建设 2026/10/18 7:29:34

PPT设计教程安装包:约4GB PowerPoint培训资料,演示文稿制作技能自学资源

什么是这套PPT教程资源 这套资源是一套以安装程序形式分发的PPT设计教程,打包成单个可执行安装文件,体积约为4GB。它主要面向希望系统学习演示文稿制作、幻灯片排版以及视觉设计技巧的用户群体,涵盖从基础操作到进阶设计的多个方向。 配套内…

作者头像 李华
网站建设 2026/10/18 7:27:59

VS Code 高效配置指南:从插件管理到远程开发避坑

简介:微软 VS Code 代码编辑器程序目录资源包,适合需要在离线环境安装、定制或研究其内部结构的前后端开发者与运维人员。资源共有七千零九十四份文件,以 JavaScript 脚本、JSON 配置、Markdown 文档、TypeScript 类型定义和 CSS 样式为主&am…

作者头像 李华
网站建设 2026/10/18 7:27:23

把编程作业当项目管理:从拆题到提交的全流程实践

这周的作业标题是“第五周作业 0430”,我刚看到时只把它当成作业编号,翻了一下课程平台才发现 0430 其实是截止日期。前几周我的作业都是靠熬夜踩点才交上的,每次都是在最后两个小时里一边改 Bug 一边后悔。这次我决定换个思路:提…

作者头像 李华
网站建设 2026/10/18 7:26:58

SSM物流信息管理系统实战:从数据库设计到核心代码实现

提到基于SSM的物流信息管理系统,这应该是这两年课题清单里出现频率最高的Java Web方向之一。很多人一听"SSM"就觉得老套,但真正动手做过一遍的人都知道,物流系统涉及的业务实体多、状态流转复杂、权限粒度细,恰好是检验…

作者头像 李华
网站建设 2026/10/18 7:23:15

Map Join与Reduce Join选型实战:内存、倾斜与Semi-Join破局

1. 项目概述:Map Join与Reduce Join不是“选哪个”,而是“什么时候必须用哪个”在某高校大数据实验室带学生做电商用户行为分析项目时,我亲眼见过三组人用同一份日志数据跑相同SQL,结果一个任务跑了47分钟,另外两个分别…

作者头像 李华