台中市网站建设_网站建设公司_定制开发_seo优化
2025/12/29 6:48:19 网站建设 项目流程

第一关

先来判断是否可以在url上直接打开地址栏,post传入的内容是否直接会拼接到数据库语句中

?id=1%20%27and%201=2%20--%20ads

%20是空格的url的代码

具体操作流程如下

1,判断是否是注入类型

若输入?id=1页面正常,输入?id=1'页面报错,就证明了单引号闭合的字符型注入存在。

?id=1%20%27and%201=2%20--%20ads

?id=1%20%27and%201=1%20--%20ads

百分号27是单引号

看两个显示结果会不会变

2,判断字段

ORDER BY关键字的核心作用(MySQL 语法):

用于对查询结果集进行排序,语法格式为ORDER BY 字段名/字段索引。这里的关键特性:ORDER BY支持用数字「字段索引」代替字段名,数字N表示 “对查询结果的第 N 个字段进行排序”。

步骤 2:判断字段数(order by)

order by N猜解查询的字段数量:

输入?id=1' order by 1--+--+是注释符,让后面的 SQL 失效),页面正常。

输入?id=1' order by 2--+,页面正常。

输入?id=1' order by 3--+,页面正常。

输入?id=1' order by 4--+,页面报错,说明字段数是3

3,确定回显位置(-1' union select 1,2,3--+

输入?id=-1' union select 1,2,3--+,页面显示23,确定这两个位置为回显位。

数据库原理拆解

  1. UNION SELECT联合查询的核心规则(MySQL 语法):

    • 用于将两个或多个SELECT语句的查询结果集合并为一个结果集返回。

    • 必须满足核心前提条件:多个SELECT语句查询的「字段数量必须相同」,且对应字段的数据类型兼容(否则报错)。

    • 例如:SELECT 1,2,3 UNION SELECT 4,5,6;合法(均为 3 个字段),SELECT 1,2 UNION SELECT 3,4,5;非法(字段数不一致)。

  2. 为什么要用id=-1

    • 原始 SQL 中id='1'会查询到有效数据(存在id=1的用户),此时UNION SELECT的结果集会被原始查询结果覆盖,页面只显示原始数据,无法看到联合查询的内容。

    • 传入id=-1,拼接后的 SQL 为SELECT * FROM users WHERE id='-1' UNION SELECT 1,2,3--+;,由于数据库中不存在id=-1的用户,原始查询结果集为空。

    • 根据 MySQL 联合查询的规则:当第一个SELECT结果集为空时,会直接显示第二个SELECT(联合查询)的结果集,这是我们能看到1,2,3的关键。

  3. 回显位置的含义:

    • 页面最终显示23,说明原始 SQL 查询结果集中,第 2 个和第 3 个字段的内容会被渲染到页面上(第 1 个字段可能不显示或被隐藏)。

    • 后续我们只需要将23替换为实际的查询语句(如查数据库名、账号密码),就能让查询结果在页面上显示出来,这是联合查询注入的核心价值。

4:查询数据库信息(核心注入操作)

操作回顾

通过替换回显位的2,3,依次查询数据库名、表名、字段名、账号密码。

数据库原理拆解(分步骤解析)

1. 查询当前数据库名(?id=-1' union select 1,database(),3--+

  • database():MySQL 内置系统函数,作用是返回当前正在使用的数据库名称(即原始 SQL 所属的数据库)。

  • 拼接后的 SQL 为:SELECT * FROM users WHERE id='-1' UNION SELECT 1,database(),3--+;

  • 原理:联合查询的第 2 个字段被替换为database(),数据库执行该函数后返回当前数据库名(通常是security),并通过页面的回显位展示出来。

2. 查询数据库中的表名(group_concat(table_name)+information_schema.tables

  • 核心语法:SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database();

  • 各部分原理拆解:

  1. information_schema.tables:系统数据库information_schema中的tables表,存储了 MySQL 中所有数据库的表元数据(包括数据库名table_schema、表名table_name、表类型等)。

  2. WHERE table_schema=database():过滤条件,只查询当前数据库(database()返回的结果)中的表,避免查询到其他数据库(如mysqlinformation_schema)的表。

  3. group_concat(column_name):MySQL 内置聚合函数,作用是将多行查询结果拼接为一行字符串返回(用逗号分隔)。

    • 若不用group_concat(),直接SELECT table_name,联合查询只会返回单行结果(默认只取第一行),无法看到所有表名;

    • group_concat()可以将所有表名(emails,referers,uagents,users)拼接为一行,一次性在回显位展示完整,这是注入中高效查询多行数据的核心技巧。

  4. 拼接后的 SQL 执行后,会从information_schema.tables中提取当前数据库的所有表名,拼接后通过回显位展示。

3. 查询users表的字段名(group_concat(column_name)+information_schema.columns

  • 核心语法:SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='users';

  • 各部分原理拆解:

  1. information_schema.columns:系统数据库information_schema中的columns表,存储了 MySQL 中所有表的字段元数据(包括数据库名table_schema、表名table_name、字段名column_name、字段类型等)。

  2. 过滤条件table_schema=database() AND table_name='users':精准定位「当前数据库」中的「users表」,只查询该表的字段信息。

  3. 同样使用group_concat(column_name)将所有字段名(id,username,password)拼接为一行,通过回显位完整展示。

4. 查询users表的账号密码(group_concat(username,':',password)

  • 核心语法:SELECT group_concat(username,':',password) FROM users;

  • 各部分原理拆解:

  1. users表:是 SQLi-Labs 中存储管理员账号密码的核心业务表(从步骤 2 中查询得到)。

  2. username,':',password:MySQL 中支持用逗号,拼接字符串,这里将username(用户名)、分隔符:password(密码)拼接为一个字符串(如admin:admin),方便阅读。

  3. group_concat():将users表中所有行的账号密码拼接为一行,一次性展示所有数据,避免多次查询,高效获取全部核心信息。

  4. 拼接后的 SQL 执行后,数据库会从security数据库的users表中提取所有账号密码,通过回显位展示,完成核心注入目标。

总结

  1. 整个注入流程的核心是篡改后台原始 SQL,利用 MySQL 语法特性(注释符、ORDER BYUNION SELECT、系统表 / 函数)实现非法查询。

  2. 关键节点:闭合单引号(突破字符型注入限制)→ 猜字段数(满足联合查询前提)→ 找回显位(获取查询结果出口)→ 查元数据(通过information_schema获取核心信息)。

  3. 所有操作的底层支撑都是 MySQL 的基础语法和系统表 / 函数的特性,这也是 SQL 注入的核心

所以为

发现这个界面加载粗我要

第二关

,和上面只有闭合方式的区别,闭合方式为双引号

第三关

,和上面只有闭合方式的区别,闭合为单引号和括号

第四关

,和上面只有闭合方式的区别,闭合为单引号和括号

SQLi-Labs 5-7 关原理讲解(注入类型与核心技巧)

这三关分别对应报错注入、盲注(布尔型)、盲注(时间型)

第五关

核心特征

页面只返回 “正确 / 错误” 提示(无数据回显),但会输出 SQL 语法错误信息(如 “you have an error in your SQL syntax”)。

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

利用MySQL 报错函数(如extractvalue()updatexml()),让数据库在执行恶意 SQL 时抛出错误,并将查询结果嵌入错误信息中返回,实现 “无回显下获取数据”。

常用报错函数:
  1. extractvalue()语法:extractvalue(1, concat(0x7e, 查询语句, 0x7e))

    • 作用:从 XML 文档中提取值,当第二个参数包含特殊字符(如~)时,会抛出错误并显示参数内容。
    • 示例(查数据库名):

      plaintext

      ?id=1' and extractvalue(1,concat(0x7e,database(),0x7e))--+
      页面会返回错误:XPATH syntax error: '~security~',其中security就是数据库名。
  2. updatexml()原理与extractvalue()类似,语法:updatexml(1, concat(0x7e, 查询语句), 1)

核心逻辑

通过构造包含报错函数的 SQL,强制数据库输出错误信息,间接获取查询结果(无需页面回显数据)。

第六关

核心特征

页面仅返回 “存在数据” 或 “不存在数据”(如 “you are in”/“you are not in”),无任何错误提示或数据回显。

原始 SQL

sql

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

(字符型注入,双引号闭合)

原理

利用SQL 逻辑判断的布尔结果true/false),通过 “逐字符猜解” 的方式获取数据。

核心技巧:

  1. 逐字符判断(利用substr()ascii()函数)

    • substr(目标字符串, 位置, 1):截取字符串指定位置的字符;

    • ascii(字符):将字符转换为 ASCII 码值。

    • 示例(猜数据库名第 1 个字符):

      plaintext

      ?id=1" and ascii(substr(database(),1,1))>100--+
      • 若页面显示 “you are in”,说明数据库名第 1 个字符的 ASCII 码大于 100;

      • 逐步缩小范围,最终确定字符(如security的第 1 个字符s的 ASCII 码是 115)。

核心逻辑

通过构造逻辑判断语句,根据页面的 “存在 / 不存在” 提示,逐个字符推导目标数据(效率低,但适用于无回显、无报错的场景)。

第七关

核心特征

页面无任何回显、无错误提示(无论 SQL 是否正确,页面均显示相同内容)。

原始 SQL

sql

SELECT * FROM users WHERE id=((('$id'))) LIMIT 0,1;

(字符型注入,单引号 + 括号闭合,需用')))闭合)

原理

利用MySQL 的延时函数sleep(N)),通过 “是否延时” 判断 SQL 逻辑的布尔结果,进而逐字符猜解数据。

核心技巧:

  1. 延时判断(结合if()函数)语法:if(条件, sleep(3), 1)

    • 作用:若条件为真,数据库延时 3 秒执行;若为假,立即执行。

    • 示例(猜数据库名第 1 个字符):

      plaintext

      ?id=1'))) and if(ascii(substr(database(),1,1))=115, sleep(3), 1)--+
      • 若页面加载时间超过 3 秒,说明条件为真(数据库名第 1 个字符是s);

      • 若立即加载,说明条件为假,需调整字符的 ASCII 码值。

第八关

第 8 关:布尔盲注(单引号闭合,无任何回显增强版)

核心特征

  1. 页面仅返回两种状态:You are in...........(条件为真)、无该提示 / 空白页面(条件为假),无错误回显、无数据回显
  2. 与第 6 关核心逻辑一致,仅闭合方式不同,属于纯布尔盲注场景。

原始 SQL

sql

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

(字符型注入,单引号闭合,无报错输出,是第 6 关的单引号版本)

原理

与第 6 关布尔盲注核心原理完全一致,利用SQL逻辑判断的布尔结果,通过substr()(截取字符)、ascii()(转换 ASCII 码)逐字符猜解数据。

  • 核心差异:第 6 关是双引号闭合,第 8 关是单引号闭合,注入语句前缀需对应调整。
  • ?id=1' and ascii(substr(database(),1,1))=115--+

第九关

第十关

第十一关

  1. 注入点从URL 的 GET 参数转移到页面的 POST 表单参数(用户名uname、密码passwd)。
  2. 页面有登录成功 / 失败提示(Your Login name or Password is wrong),支持报错注入或布尔盲注。

原始 SQL

sql

SELECT * FROM users WHERE username='$uname' AND password='$passwd' LIMIT 0,1;

(字符型注入,单引号闭合,POST 参数传递,无数据回显但有登录状态反馈)

原理

  1. POST 注入与 GET 注入的核心区别

    • GET 注入:参数通过 URL 传递,可直接在地址栏构造语句。

    • POST 注入:参数通过 HTTP 请求体传递,需借助工具(如 Burp Suite)或浏览器开发者工具构造表单数据。

  2. 注入核心逻辑:

    • 与 GET 型字符注入一致,先闭合单引号,再构造注入语句,最后用注释符注释多余内容。

    • 示例(用报错注入查数据库名,在uname字段输入):

      plaintext

      admin' and extractvalue(1,concat(0x7e,database(),0x7e))--+
      • 密码字段可任意输入(如123),提交后页面会返回报错信息,包含当前数据库名。

核心逻辑

注入原理与 GET 型注入一致,仅参数传递方式不同,需掌握 POST 表单数据的构造方法。

第十二关

  1. 注入点为 POST 表单参数(unamepasswd),与第 11 关场景一致。
  2. 闭合方式为双引号 + 括号id="($id)"),是闭合类型的进阶场景。

原始 SQL

sql

SELECT * FROM users WHERE username=("$uname") AND password=("$passwd") LIMIT 0,1;

(字符型注入,双引号 + 括号闭合,POST 参数传递)

原理

  1. 闭合核心技巧:需要先闭合双引号,再闭合括号,才能让后续注入语句生效。
    • 闭合格式:"(闭合双引号)+)(闭合括号),即admin")
  2. 示例(用报错注入查数据库名,在uname字段输入):

    plaintext

    admin") and extractvalue(1,concat(0x7e,database(),0x7e))--+
    • 提交后,页面返回报错信息,提取其中的数据库名即可。

第十三关

核心特征

原始 SQL

sql

SELECT * FROM users WHERE username=('$uname') AND password=('$passwd') LIMIT 0,1;

(字符型注入,单引号 + 括号闭合,POST 参数传递,无登录状态反馈,仅支持报错注入)

原理

    1. 注入点为 POST 表单参数,闭合方式为单引号 + 括号
    2. 页面无登录成功反馈,仅在 SQL 语法错误时返回报错信息,无其他状态差异,属于POST 型报错盲注
    1. 闭合核心技巧:先闭合单引号,再闭合括号,即admin')
    2. 注入核心逻辑:
      • 由于无登录状态反馈,无法使用布尔盲注,只能依赖报错注入获取数据。
        • plaintext

          admin') and extractvalue(1,concat(0x7e,database(),0x7e))--+
        • 提交后,页面会抛出 XPATH 语法错误,包含当前数据库名,实现无状态反馈下的数据获取。
      • 核心逻辑

        复合闭合方式 + POST 注入 + 报错盲注的结合,强化 “根据页面反馈选择注入方式” 的能力。

第十四关

  1. 注入点为 POST 表单参数,闭合方式为纯双引号,与第 6 关、第 10 关的双引号闭合一致。
  2. 页面有登录成功 / 失败提示,支持报错注入或布尔盲注,是 POST 型双引号注入的基础场景。

原始 SQL

sql

SELECT * FROM users WHERE username="$uname" AND password="$passwd" LIMIT 0,1;

(字符型注入,双引号闭合,POST 参数传递,有登录状态反馈)

原理

  1. 闭合核心技巧:直接用双引号闭合原始字符串,即admin"
  2. 示例(用报错注入查数据库名,在uname字段输入):

    plaintext

    admin" and extractvalue(1,concat(0x7e,database(),0x7e))--+
    • 密码字段任意输入,提交后页面返回报错信息,提取数据库名即可。

核心逻辑

POST 注入的基础双引号版本,与 GET 型双引号注入原理一致,进一步巩固 POST 表单的注入技巧。

第十五关

第十七·关·

原理

  1. 场景差异:UPDATE 注入与 SELECT 注入的核心区别
    • SELECT 注入:目的是 “查询数据”,语句构造围绕SELECT/UNION SELECT/ 报错函数。
    • UPDATE 注入:目的是 “通过报错获取数据”(无需更新真实密码),语句构造围绕 “破坏 UPDATE 语法,嵌入报错函数”,利用 UPDATE 执行时的语法错误返回查询结果。
  2. 核心前提:用户名需存在(如admindumb),否则 UPDATE 语句不会执行,注入无效。
  3. 核心技巧:
    • 闭合方式:单引号闭合密码字段的原始字符串,嵌入报错函数,最后用--+注释多余内容。
    • 报错函数依旧使用extractvalue()/updatexml(),与第 5 关报错注入原理一致。
  4. 示例(猜数据库名,用户名填dumb(存在的账号),新密码字段输入):

    plaintext

    123' and extractvalue(1,concat(0x7e,database(),0x7e))--+
    • 拼接后的 UPDATE 语句:

      sql

      UPDATE users SET password='123' and extractvalue(1,concat(0x7e,database(),0x7e))--+' WHERE username='dumb';
    • 判断逻辑:执行 UPDATE 语句时,报错函数触发 XPATH 语法错误,页面返回错误信息,其中包含当前数据库名(security),且不会真正修改dumb的密码(后续内容被注释)。

核心逻辑

基于 UPDATE 语句的报错注入,核心是 “利用存在的用户名触发 UPDATE 执行,通过报错函数间接获取数据,不破坏目标账号的原始数据”,是业务场景中常见的注入类型。

第十九关

核心特征

  1. 注入点是HTTP 请求头的 Referer 字段(请求来源页面标识),与第 18 关场景高度相似。
  2. 同样需要登录成功触发 INSERT 语句,页面回显 Referer 信息并支持报错反馈。

原始 SQL(登录日志记录)

sql

INSERT INTO security.referers (referer, ip_address, username) VALUES ('$referer', '$ip', '$uname');

(字符型注入,单引号闭合$referer对应 Referer 头)

原理

  1. 场景前提:同第 18 关,需先登录成功(如dumb/dumb),触发 INSERT 语句。
  2. 注入逻辑
    • 与第 18 关完全一致,仅注入点从 User-Agent 改为 Referer 头。
  3. 核心操作(Burp 抓包)
    1. 抓取登录成功的请求包,找到Referer字段。
    2. 修改 Referer 字段为注入语句:

      plaintext

      ' and extractvalue(1,concat(0x7e,version(),0x7e))--+
    3. 发送请求后,页面返回报错信息,包含 MySQL 版本号。

核心逻辑

与 User-Agent 头注入原理一致,进一步强化 “HTTP 头任意字段均可作为注入点” 的认知,关键是识别业务逻辑中被代入 SQL 的头信息。

第20关

  1. 注入点是HTTP 请求的 Cookie 字段(存储登录状态的uname参数)。
  2. 登录成功后,页面会回显 Cookie 中的用户名信息,支持报错 / 联合查询注入。

原始 SQL(Cookie 验证)

sql

SELECT * FROM users WHERE username='$uname' LIMIT 0,1;

(字符型注入,单引号闭合$uname对应 Cookie 中的uname参数)

原理

  1. 场景前提:登录成功后,浏览器会保存uname=dumb的 Cookie,页面通过读取该 Cookie 显示用户名。
  2. 注入逻辑
    • Cookie 中的uname参数被作为字符串代入 SELECT 语句,通过单引号闭合后,可构造报错 / 联合查询语句。
  3. 核心操作(Burp 抓包)
    1. 登录成功后,抓取页面请求包,找到Cookie: uname=dumb字段。
    2. 修改 Cookie 为注入语句(以联合查询为例):

      plaintext

      uname=dumb' union select 1,2,database()--+
    3. 发送请求后,页面回显位会显示当前数据库名(security)。

核心逻辑

注入点转移到 Cookie 字段,原理与 GET 参数注入一致,关键是 “识别 Cookie 参数的 SQL 代入逻辑,通过抓包修改 Cookie 值”。

第二十一关

核心特征

  1. 注入点是 Cookie 的uname参数,但Cookie 值被 Base64 编码后传输。
  2. 闭合方式为单引号 + 括号,增加了解码与闭合的双重难度。

原始 SQL

sql

SELECT * FROM users WHERE username=('$uname') LIMIT 0,1;

(字符型注入,单引号 + 括号闭合$uname是 Base64 解码后的 Cookie 值)

原理

  1. 编码逻辑
    • 正常情况下,Cookie 中的uname=dumb会被编码为uname=ZHVtYg==dumb的 Base64 编码),后端接收后先解码,再代入 SQL。
  2. 注入逻辑
    • 需先构造闭合后的注入语句,再对语句进行 Base64 编码,才能被后端正确解码并执行。
  3. 核心操作(Burp 抓包)
    1. 构造注入语句(先闭合单引号 + 括号,再写联合查询):

      plaintext

      dumb') union select 1,2,database()--+
    2. 对该语句进行 Base64 编码,结果为:ZHVtYicpIHVuaW9uIHNlbGVjdCAxLDIsZGF0YWJhc2UoKS0tKw==
    3. 修改 Cookie 为:uname=ZHVtYicpIHVuaW9uIHNlbGVjdCAxLDIsZGF0YWJhc2UoKS0tKw==
    4. 发送请求后,页面回显位显示当前数据库名。

核心逻辑

Cookie 注入 + Base64 编码 + 复合闭合的结合,核心是 “先构造注入语句,再编码传输”,需掌握常见编码的处理方式。

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

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

立即咨询