常用函数
Mysql里面可以使用一些函数来更加便捷的使用它,这些信息在SQL之母那里面是没有提到的。
select version();
select database();
select user();
group_concat() #可以把它这一列的所有行的数据拼接为一行,不同行数据用逗号分隔。
concat() #字符串拼接,把传入参数进行拼接。
substr() #字符串截取,传入三个参数,字符串、起始位置、长度。这个起始位置写1那就是从第一位,而不是和写代码时候那样表示第二位。
-- 还有一些就是对检索到的信息进行编码,对后端检查进行绕过。
ascii() / ord() #获取ascii码
hex() #对字符串进行十六进制编码
to_base64() #对参数进行base64编码
还有就是mysql的注释符有三种,--+空格是第一种,第二种是一个#,第三种是多行注释/**/。
在sql注入的时候最开始都是查看到底有多少列,这样可以正常回显数据(大概吧,我也不确定,之后如果说错了我会尽量改正的)。
那么就需要使用联合查询union或者排序order by,当然后者后面跟的是数值型数据1、2、3之类,这表示按照第几列进行排序,如果是使用字段的名称那就是按照具体字段名称排序。
注入也分很多种,比如字符型注入,整数型注入等等,我觉得其中不同的就是条件查询where后面的那些句子数据类型不一样,那么具体的应对方法也不一样。
还是后续在题中细讲:
来开这个SQL的整形注入:
它让输入一个1看看:
下面那一行小字写出了它的类型,后面where没有使用''来包裹,那也就说明了是整数型注入(标题已经写出来了还分析个啥)。
我们需要先在判断一下到底是多少字段的表,这样才能回显信息。
通过第一个字段排序可以。
通过第二个字段排序可以。
通过第三个字段就不可以了,那也就是一共有两个字段。
现在我们通过联合查询来尝试一下:
那么前面那个字段是可以回显信息的,可以使用它来注入,其实后面的那个字段也可以回显信息。值得注意的是我这里把前面的那个条件查询的条件设置成了-1,因为这个网页的回显只会回显一行,如果填写存在的数值则会看不到后面的联合查询的信息(联合查询概念可以去SQL之母那里学习,简单来说就是把两个查询信息放在同一张表里面,这就要求表的字段数目相同)。
但是到了后面当我想要用前面字段查数据库名的时候却办不到了,因为它就不回显信息了,无奈只能选择后面的那个位置来做。
那么很明显,它只回复一行数据让我们很难办啊,我需要所有这一个字段的信息啊......我能想到的是两种解决办法,一个是使用limit来做限制查询,一列一列找,这也是SQL语法,可以自行了解一下。另外一种就是使用group_concat()来做,把所有信息放在一行输出。
现在我们看看返回的这些数据库名称,前几个都是默认的数据库名,最后一个很可疑,进去看看(其实这是一个尝试的过程)。
仔细说一下,information_schema数据库里面的tables表里面有table_name和table_schema两个字段,前面是表明,后面是数据库名。我们可以通过数据库名来进行条件查询,这样就可以得到具体table_name都有什么了,同时一起把所有行信息用一行返回。
现在我们看到里面有两个表,比较明显地是我们要找flag,那就去flag表里面找比较合适一些。
使用group_concat()是这么一种效果:
继续查询,我们继续深入查找这个flag表里面到底有什么字段:
那么如果我们不在后面进行条件限制,会如何呢?
没错,就会这样,所有数据库的所有表的所有字段名称都会出现。
因为我们本来就在那个sqli的数据库里面,所以可以不用加数据库名成为sqli.flag,直接flag就可以查表:
这样就得到答案了。