【八个月网安课程】第五周·周二:数字型与字符型注入检测,闭合方式
2026/9/12 19:02:58 网站建设 项目流程

今天你首次真正地“攻击”一个 Web 应用,学会如何通过简单的符号和逻辑判断来发现 SQL 注入点,并精准确定闭合方式。这是手工注入的起手式,也是区分脚本小子与安全研究者的关键分水岭。


第五周·周二:数字型与字符型注入检测,闭合方式

🎯 今日学习目标(达成效果)

  • 准确区分数字型注入与字符型注入的原理:参数是否被引号包裹,决定了注入语法;
  • 通过简单的输入测试(添加单引号、双引号、运算符号)判断目标参数是否存在 SQL 注入漏洞;
  • 识别数据库错误信息,并从中推断出服务器使用的数据库类型以及大致的 SQL 语句结构;
  • 熟练使用注释符(--#) 截断原始语句的后续部分,构造属于自己的可控查询;
  • 在 sqli-labs Less-1 中独立找出闭合方式为单引号闭合,并成功使用' OR '1'='1使 SQL 语句逻辑永真;
  • 写出完整的注入 payload,解释每一步符号的作用(闭合、逻辑操作、注释)。

📘 一、SQL 注入的本质:打破原有语句结构

SQL 注入漏洞发生在用户输入被拼接到 SQL 查询语句中,且未作任何过滤或参数化。正常登录查询可能是:

SELECT*FROMusersWHEREusername='admin'ANDpassword='pass123';

如果用户输入的用户名是admin' --,拼接后就变成:

SELECT*FROMusersWHEREusername='admin'-- ' AND password='...';
  • 第一个单引号闭合了原本的引号;
  • --是 SQL 单行注释,后面的所有语句都被数据库忽略;
  • 最终执行的逻辑变为:username='admin'成立就返回用户,密码验证被完全绕过。

这就是注入的核心:用特殊字符打破代码与数据的边界。今天我们将系统学习如何寻找这个“边界”,并确定需要用什么符号来闭合它。


📘 二、数字型注入 vs 字符型注入

根据参数在 SQL 语句中是否被引号包围,注入分为两类,它们的检测方法截然不同。

1. 数字型(Numeric)

  • SQL 中类似:SELECT * FROM news WHERE id=123
  • 参数123没有引号,直接是数字。
  • 检测方法:
    • 算数运算:输入1+1,如果页面返回 id 为 2 的内容,说明运算被执行(存在注入);输入1-1如果返回 id=0 的内容,也证实了注入。
    • 逻辑判断and 1=1页面正常,and 1=2页面异常或内容消失,说明注入存在(因为id=123 and 1=2永远不成立,查询无结果)。
  • 闭合需求:数字型不需要闭合引号,可直接追加逻辑,但若需要 UNION 查询,可能需要注释掉后续排序等。

2. 字符型(String)

  • SQL:SELECT * FROM users WHERE username='admin'
  • 参数admin被单引号(或双引号)包围。
  • 检测方法:
    • 添加单引号':输入admin',SQL 变成... username='admin'',多出一个引号导致语法错误。如果页面显示数据库错误或白屏,说明输入未经处理直接进入 SQL,极可能存在注入。
    • 永真/永假测试:如果能确定闭合符号,尝试' OR '1'='1(需要正确闭合)。比如对于单引号闭合,' OR '1'='1 --会使得 WHERE 条件永真,返回所有数据。
  • 闭合方式:必须知道前面使用的是什么引号,以及是否有括号。常见的闭合组合:
    • '(单引号)
    • "(双引号)
    • ')(单引号+括号)
    • ")(双引号+括号)
    • '))等嵌套形式

如何确认闭合?
通过报错信息或逐步尝试。典型方法:输入\(反斜杠)有时可以转义后面的引号而暴露原始语句(在某些编码下),更通用的方法是使用注释符和永真条件不断测试,直到页面正常且逻辑成立。


📘 三、注释符:截断语句的利器

确定闭合后,我们需要把原始语句后面多余的部分(如' AND password='...')注释掉,才能自由控制查询。不同数据库的注释符有差异,MySQL 支持以下三种:

注释符说明示例
--(两个短横+空格)单行注释,注意必须后面有空格(或控制符),在 URL 中常写作--++会被解码为空格' OR '1'='1 --
#单行注释,不需要空格,但 URL 中#通常用于锚点,不会被发送到服务器,因此常使用%23(URL编码的#)' OR '1'='1 %23
/*...*/多行注释,用于绕过某些过滤或注释掉一段代码' UNION SELECT 1,2,3 /*

今天重点使用--+%23


✍️ 四、动手实践:搭建 sqli-labs 靶场并对 Less-1 进行注入检测

Sqli-labs 是经典的 SQL 注入练习平台,包含了各种闭合和过滤的关卡。我们今天先攻克 Less-1。

1. 安装 sqli-labs 环境(使用 Docker 最简单)

如果你已有 PHP 环境(如 Apache + MySQL),可以手动部署。更推荐使用 Docker:

dockerpull acgpiano/sqli-labs# 或 vulhub 中的 sqli-labsdockerrun-d-p80:80 acgpiano/sqli-labs

或者本地搭建:将 sqli-labs 源码放到 Web 目录,设置好数据库连接。为了实验方便,可以临时使用公开在线靶场(但注意稳定性),例如http://sqli-labs:8080/(假设),务必确认是自己搭建的。

假设服务运行在http://192.168.1.100:80(本地虚拟机或本机),我们开始。

2. Less-1 页面分析

访问http://192.168.1.100/Less-1/,你会看到一个提示Please input the ID as parameter with numeric value。正常访问?id=1会显示用户信息Your Login name:Dumb, Your Password:Dumb等。

此时后台 SQL 类似:

SELECT*FROMusersWHEREid='1'LIMIT0,1

(注意 id 是被单引号包围的,这是一个字符型注入。)

3. 检测注入点

  • 数字型测试?id=1 and 1=2,页面无变化或仍正常显示?因为'1'被视为字符串,and 1=2是在字符串外部,可能没有作用。数字型测试不能直接判断。

  • 字符型测试:加单引号?id=1'。页面返回错误:

    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'',说明多出一个引号。这证实了注入点存在,且是单引号闭合

  • 永真条件测试:尝试?id=1' and '1'='1
    原始语句变为:WHERE id='1' and '1'='1' LIMIT 0,1
    这是合法的,页面正常显示 id=1 的数据。再尝试?id=1' and '1'='2,页面无显示(因为条件为假)。这进一步确认注入有效,且闭合方式就是'

  • 使用注释符关闭多余部分?id=1' --+
    --+--注释掉后面的LIMIT 0,1,页面正常。

至此,闭合方式确定为单引号'

4. 经典永真注入

?id=1' OR '1'='1' --+
SQL 变成:

SELECT*FROMusersWHEREid='1'OR'1'='1'-- ' LIMIT 0,1

OR '1'='1'使得整个 WHERE 条件永真,返回所有用户。实际页面会显示多组用户名密码(由于 PHP 代码可能只取一行,Less-1 默认显示第一行,但仍可证明注入成功)。

你还可以尝试?id=-1' OR '1'='1' --+以查看其他数据。


📝 五、课后测试题与解析

测试题:在 sqli-labs Less-1 中找出闭合方式。请描述你的测试步骤以及最终确定的闭合符号。

参考答案与步骤

  1. 访问http://靶机/Less-1/?id=1,页面正常显示用户信息;
  2. 添加单引号测试:?id=1',页面返回数据库语法错误,提示'1'' LIMIT 0,1。说明参数被单引号包围,且单引号未过滤;
  3. 尝试双引号测试:?id=1",可能无报错或不同,排除双引号闭合(Less-1 仅单引号);
  4. 使用?id=1' and '1'='1页面正常,?id=1' and '1'='2页面异常,证明注入逻辑生效且闭合方式为单引号;
  5. 使用注释符闭合:?id=1' --+正常,最终确定闭合方式为单引号'

核心 payload' OR '1'='1' --+
分解:

  • 第一个'用于闭合前端的引号;
  • OR '1'='1'添加永真条件,且末尾的'1'实际是用来与后面的原单引号配对,让语法正确(虽然被注释掉了,但为了严谨);
  • --+注释掉后续的' LIMIT 0,1等,避免干扰。

✅ 今日学习效果自检清单

  • 我能区分数字型注入与字符型注入,并分别说出各自的检测方法
  • 我亲手在 sqli-labs Less-1 中通过加单引号触发了数据库错误
  • 我使用' and '1'='1' and '1'='2确认了注入存在
  • 我知道了至少两种注释符的用法(--+%23
  • 我成功通过' OR '1'='1' --+改变了查询逻辑
  • 我明白了闭合的本质:让用户输入跳出数据区域,进入代码区域

⚠️ 阶段避坑重点

  • 注释符空格不可丢--后面必须有空格或#,URL 编码中常使用--+(+ 解码为空格)或--%20。如果忘记空格,注释无效,可能导致语法错误。
  • 区分大小写和数据库特性:MySQL 中--可行,而#注释在 URL 中需编码为%23。Access 不支持注释符,但通常有限制。
  • 不要只依赖报错:有的站点关闭了错误显示,这时使用永真/永假测试(盲注),今天先掌握有报错的容易情况。
  • 测试时记录每一种尝试:闭合方式可能多种,形成表格记录,养成良好的手工渗透习惯。

明天我们将深入学习联合查询注入(UNION SELECT)手工步骤,利用今天找到的闭合方式,在 Less-1 中逐步获取数据库名、表名和字段名。请确保你的 sqli-labs 环境正常运行,明天将直接进入实战数据提取。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询