[SQL注入]在select_expr中使用as别名进行注入

导言

阅读《从0到1:CTFer修炼之路》时,其在讲解select注入时,指出当注入点在select_expr中,可以采用as别名的方法,直接将查询的结果显示到界面中,但是其给出的示例,需要将别名命名为被查询表中已有的列名,使我产生了疑惑:为什么非要将别名命名为已有的列名?如果不使用表中存在的列名呢?

问题概述

首先将书中的示例放在这节: 源代码如下所示:

php 复制代码
<?php     
$conn = mysqli_connect("127.0.0.1", "root", "root", "test"); 	
$res = mysqli_query($conn, "SELECT ${_GET['id']}, content FROM wp_news"); 	
$row = mysqli_fetch_array($res); 	
echo "<center>";
echo "<h1>".$row['title']."</hl>";
echo"<br>";
echo"<hl>".$row['content']."</h1>";
echo "</center>";

这里,"SELECT ${_GET['id']}, content FROM wp_news"为可以被注入的SQL查询,其中注入点在SELECT操作符后,即表名的输入位置。 这里已知的是,we_news表中一共只有两列:title列和content列,而理论上该查询需要输入的id为"title"。

书中指出,可以采取时间盲注的方式,但是根据 MySQL 的语法,有更优的解决方法,即利用 AS 别名的方法,直接将查询的结果显示到界面中。

payload?id=(select pwd from wp_user as title)

这里的wp_user中存储着用户名和密码,通过这种注入方式可以使得界面回显出密码,如下图:

但是,书中并没有解释,为什么要将别名也设置为已有表中存在的列相同的名"title",此外,也没有解释这个嵌套查询的执行顺序。本文接下来就将说明这两个问题。

为什么非要使用已存在的列名

事实上,如果只谈SQL注入本身,别名设置为任何名字都可以,而在本文的示例中,必须要将注入部分的列名命名为"title"的原因在代码的第6行:echo "<h1>".$row['title']."</hl>";。在查询出结果后,前端只会将列名为"title"的列进行回显 ,由于别名 titlewp_news 表中的现有列名相同,注入的 SQL 查询结果会覆盖原始 title 列的值。如果将别名改为一个在 wp_news 表中不存在的列名,注入的 SQL 仍然会执行,但是它的结果会作为一个新的列添加到查询结果中,就无法在前端回显orz。使其退化为布尔盲注。

例如,如果的 payload 是 ?id=(SELECT pwd FROM wp_user AS new_column),并且 wp_news 表中没有名为 new_column 的列,那么 SQL 注入会导致 new_column 列(含有 wp_user 表中的 pwd 数据)被添加到查询结果中。但是,由于第6行代码只打印 titlecontent 列的值,这个新添加的列的内容并不会直接显示在页面上。

嵌套查询的执行顺序

这里就顺便说一下,注入后的嵌套查询:SELECT (select pwd from wp_user as title), content FROM wp_news的执行顺序。

  1. 执行子查询 :对于主查询中的每一行,都会执行一次子查询。这意味着如果 wp_news 表中有 N 行,子查询就会执行 N 次。每次执行时,子查询都从 wp_user 表中检索 pwd 列的值,而后外部的主查询会从wp_news中取出一行。
  2. 组合结果 :子查询的结果(即 wp_user 表中的 pwd 值)与主查询出的 content列进行拼装。
  3. 返回最终结果 :最终的结果集包含两列:子查询返回的 pwd 列和 wp_news 表的 content 列。

这里需要注意,对于select_expr中的子查询必须是标量子查询,即如果子查询返回多行,它通常会导致一个错误,因为标量子查询应该只返回一个单一的值(只有一行一列)来拼装进主查询中的每一行。

总结

这种AS别名的注入方法,必须要设置别名为已有列名的原因在于前端限制了回显,同时这种诸如能成功的前提在于查询必须是标量子查询,即?id=(select pwd from wp_user as title)这里所返回的密码只能有一个值,不然由于SQL语法错误查询无法执行。

相关推荐
W.Buffer1 小时前
通用:MySQL-深入理解MySQL中的MVCC:原理、实现与实战价值
数据库·mysql
心态特好2 小时前
详解redis,MySQL,mongodb以及各自使用场景
redis·mysql·mongodb
一只小bit2 小时前
MySQL 库的操作:从创建配置到备份恢复
服务器·数据库·mysql·oracle
养生技术人5 小时前
Oracle OCP认证考试题目详解082系列第57题
运维·数据库·sql·oracle·开闭原则
程序新视界7 小时前
MySQL中,IS NULL和IS NOT NULL不会走索引?错!
数据库·mysql·dba
简色8 小时前
题库批量(文件)导入的全链路优化实践
java·数据库·mysql·mybatis·java-rabbitmq
CS Beginner9 小时前
【Linux】Mysql的基本文件组成和配置
linux·运维·mysql
养生技术人9 小时前
Oracle OCP认证考试题目详解082系列第53题
数据库·sql·oracle·database·开闭原则·ocp
szxinmai主板定制专家12 小时前
一种基于 RK3568+AI 的国产化充电桩安全智能交互终端的设计与实现,终端支持各种复杂的交互功能和实时数据处理需求
arm开发·人工智能·嵌入式硬件·安全
豆沙沙包?12 小时前
2025年--Lc171--H175 .组合两个表(SQL)
数据库·sql