SQLi —— 逗号,空格,字段名过滤突破

时间:2021-08-23 03:04:17

前言

出于上海大学生网络安全大赛的一道easysql,促使我积累这篇文章。因为放了大部分时间在DecadeBabyt5上,easysql一点没看,事后看了WP,发现看不懂怎么回事,于是了解了一番。

无列名注入

前提:easysql中过滤了or,这样information_schema就不能用了,需要通过innodb存储引擎利用获取表名,不知道列名,所以需要通过无列名注入获取字段数据。

其实就是边看文章边自己实践记录,自己写的更详细点,便于理解的更透彻。

直接select 1,2,3,4 这样不就是一个表了吗,可以看作是虚拟表。

SQLi —— 逗号,空格,字段名过滤突破

 

SQLi —— 逗号,空格,字段名过滤突破

我们可以通过union select 将这个虚拟表填充你想要读取的表的数据(记得用union时,保证左右两边的字段数相同,即列数)

SQLi —— 逗号,空格,字段名过滤突破

SQLi —— 逗号,空格,字段名过滤突破

 

再通过设置这样的虚拟表别名,就可以实现无列名注入了

可以看到我们需要的表的数据导入了虚拟表,并且以我们设定的1,2,3,4作为列名

SQLi —— 逗号,空格,字段名过滤突破

 

 SQLi —— 逗号,空格,字段名过滤突破

第二列开始才是我们想要的表中数据,可用limit来取limit 2,1 或者limit 1 offset 2(这里不选用第二行数据是因为比较下limit 2,1和可以bypass逗号的limit 1 offset 2的区别,容易对应参数混淆)

limt 2,1 :从第三行开始,取一行数据

limit 1 offset2 :取一行数据,从第二行开始

SQLi —— 逗号,空格,字段名过滤突破

 

这样就完成了无列名注入

innodb存储引擎

因为本地是5.5.53的mysql,也不想再docker去pull部署了,直接照搬文章里的内容把。(谢罪)

红帽杯wp中,需要通过innodb来获取表名,原因是过滤了or,无法用上information_schema

Mysql>5.6.x

在Mysql中,存储数据的默认引擎分为两类。一类是在5.5.x之前的MyISAM数据存储引擎,另一类是5.5.x版本后的innodb引擎。并且mysql开发团队在5.5.x版本后将innodb作为数据库的默认引擎。

而在mysql 5.6.x版本起,innodb增添了两个新表,一个是innodb_index_stats,另一个是innodb_table_stats。查阅官方文档,其对这两个新表的解释如下图:

从官方文档我们可以发现两个有用的信息:

  1. 从5.6.x版本开始,innodb_index_stats和innodb_table_stats数据表时自动设置的。
  2. 两个表都会存储数据库和对应的数据表。

唯一遗憾的是没有字段名

 

本地试验:

Mysql 5.6.40

SQLi —— 逗号,空格,字段名过滤突破

 

 

 

innodb_index_stats

 

select * from mysql.innodb_index_stats limit 0,3;

 

SQLi —— 逗号,空格,字段名过滤突破

 

 

 

innodb_table_stats

select * from mysql.innodb_table_stats limit 0,1

  SQLi —— 逗号,空格,字段名过滤突破

 

 

 

有效载荷:select table_name from mysql.innodb_table_stats where database_name = schema()

前提mysql>5.6x

用来查表的payload:

select group_concat(table_name) from mysql.innodb_table_stats where database_name like database()

bypass

对于bypass waf有很多骚姿势,把一些最基本的列出来。

1.首先我们空格被过滤,这个绕过方法有很多

  • 使用注释绕过,/**/,如果因为’/‘被过滤,导致此方法无法使用
  • 使用括号绕过,括号可以用来包围子查询,任何计算结果的语句都可以使用()包围,并且两端可以没有多余的空格
  • 使用符号替代空格