• SQL注入之 无列名注入 原理详解


    为什么会需要无列名注入?

    我们常用的SQL注入方法是通过information_schema这个默认数据库来实现,可是你有没有想过,如果过滤了该数据库那么我们就不能通过这个库来查出表名和列名。不过我们可以通过两种方法来查出表名:

    1. InnoDb引擎

      从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats两张表(mysql.innodb_table_stats),这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。高版本的 mysql 中,还有 INNODB_TABLES 及 INNODB_COLUMNS 中记录着表结构。

    2. sys数据库

      在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns(sys.schema_auto_increment_columns)来获取表名。

    但是上述两种方法都只能查出表名,无法查到列名,这时我们就要用到无列名注入了。无列名注入,顾名思义,就是不需要列名就能注出数据的注入。

    无列名注入使用条件

    无列名注入主要是适用于已经获取到数据表,但无法查询列的情况下,在大多数 CTF 题目中,information_schema 库被过滤,使用这种方法获取列名。

    无列名注入原理

    无列名注入的原理其实很简单,就是联合查询创建虚拟数据。可以看作将我们不知道的列名进行取别名操作,在取别名的同时进行数据查询,所以查询字段数一定要相同,如果我们查询的字段多于数据表中列的时候,就会出现报错。

    实战演示:

    正常查user表的数据是select * from user;

    image-20230917145304914

    用联合查询的方式来查一下表中数据select 1,2,3 union select * from user;。很明显创建了虚拟数据(虚拟字段值123和虚拟表),虚拟表中列名变成了123。

    image-20230917145419828

    只查一个列的字段值的话我们可以用:
    解释一下,xxx就是自己命名的虚拟表的表名,可以自定义。这条sql语句在联合查询创建虚拟表xxx,虚拟列1,2,3的同时查询虚拟表第二列的数据。

    select `2` from (select 1,2,3 union select * from user)xxx;
    
    • 1

    image-20230917145701326

    同时查多个列

    select concat(`2`,`3`) from (select 1,2,3 union select * from user)xxx;
    
    • 1

    image-20230917150452258

    不过有时候 ` 也会被过滤,这时候我们就又要用到取别名(as)的操作了,把列名都换一换,那样查数据时候列名就不需要反引号了。

    select 1 as a,2 as b,3 as c union select * from user;
    
    • 1

    image-20230917150229489

    select b from (select 1 as a,2 as b,3 as c union select * from user)xxx;
    
    • 1

    image-20230917150304333


    还有一种是利用JOIN去进行无列名注入,通过JOIN建立两个表之间的内连接,也就是说将两张表的列名给加起来,可能会爆出相同的列的名字,我们利用的就是这个特性来爆出列名。

    select * from (select * from user as a join user as b)xxx;
    
    • 1

    image-20230917152950066

    得到了第一个列名id,下面这个payload就会给我们回显第二列的数据。

    select * from (select * from user as a join user as b using(id))xxx;
    
    • 1

    image-20230917153008543

    剩下的以此类推。

    select * from (select * from user as a join user as b using(id,username))xxx;
    
    • 1

    image-20230917153055650

    实战sqli-labs第一关的payload:

    ?id=-1' union all select * from (select * from users as a join users as b)as c--+
    
    • 1

  • 相关阅读:
    高校教室预约使用管理系统(PHP+Mysql)毕业论文+项目源码+数据库sql文件
    深入了解Web3:区块链技术如何改变我们的数字世界
    编写程序,建立一动态链表,其中包含学生学号,姓名,年龄,输入一个学生学号删除相对应的节点
    全国机动车达4.3亿辆 驾驶人达5.2亿人 新能源汽车保有量达1821万辆
    Python读取CSV文件,数值精度丢失
    容灾演练月报 | 雅安市商业银行四大业务系统完成容灾切换演练
    搭建Umijs环境并创建一个项目 介绍基本操作
    SpringCloud文件上传
    中端酒店迈入“30+”,维也纳酒店如何化解行业的三大难关
    【蓝桥杯冲击国赛计划第7天】模拟和打表 {题目:算式问题、求值、既约分数、天干地支}
  • 原文地址:https://blog.csdn.net/Jayjay___/article/details/132956870