GET型SQL注入【四】——数字型和字符型

发布于 2020-07-02  138 次阅读


我们常说的判断数字型和字符型都是基于http://xxx.com/?id=1这种,这里可能存在我们常见的如:union注入,报错注入,盲注

0x01 为什么要判断

拿SQLI-LABS的 LESS1和LESS2举个例子

less1(字符型)的查询语句为:

SELECT * FROM users WHERE id='$id' LIMIT 0,1;

less2(数字型)的查询语句为:

SELECT * FROM users WHERE id=$id LIMIT 0,1;

当我们构造url为:?id=1 and 1=1来判断是否存在注入点时

less1执行的语句为:

SELECT * FROM users WHERE id='1 and 1=1' LIMIT 0,1;

less2执行的语句为:

SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1;

仔细对比一下两条查询语句的区别,我们很直观的可以看到哪有问题

在less1,也就是是我们的字符型注入中,我们传入的and 1=1也被引号包裹住了,着就会使得查询语句在数据库中查询的内容是字段名为1 and 1=1(最终会通过隐形转换,转换为1,所以我们的and 1=1也就没起到该有的作用

这就是我们为什么要判断注入参数是数字型还是字符型的原因了

例:如果我们判断出了其是被单引号字符型,我们可以构造:?id=1' and 1=1 --+,这样执行的查询命令就是:

SELECT * FROM users WHERE id=1 and 1='1' and 1=1 LIMIT 0,1 --+';
/*--+表示注释,这样把原来的单引号注释了就不会报错*/

这样就达到我们想要的效果了

0x02 怎么判断

上面我们知道了怎么判断是数字型还是字符型注入,当然字符型不仅仅只是会用单引号包裹,所以我们就通过实例来学习怎么判断注入参数具体的字符型包裹形式

基于报错注入的判断

下面的原理就是构造错误语句,让报错信息带有系统的SQL周围的语句,从而判断真实情况

数字型

sqli-labs less2

首先是这个样子的

我们在id=1后加上反斜杠,当然加单引号也是可以的,但是当遇到双引号包裹的字符型时就不好判断了

因为双引号包裹的加单引号或者双引号都不会报错;同样单引号包裹的无论加单引号还是双引号都不会报错
加入了反斜杠后

可以看到报错了,把报错信息复制出来

'\ LIMIT 0,1'
\ LIMIT 0,1    /*去掉包裹错误信息的单引号*/

发现报错原因是我们的反斜杠,其作用是转义,如果这里有引号包裹就会把引号转义,会爆出引号的错误,所以可以判断注入参数类型是数字型

字符型

单引号包裹

sqli-labs less1

首先依旧是这样的

我们在id=1后加上反斜杠

加入反斜杠之后

可以看到报错了,把报错信息复制出来

''1\' LIMIT 0,1'
'1\' LIMIT 0,1   /*去掉包裹错误信息的单引号*/

报错原因是因为反斜杠把后面的单引号转义了,所以造成语句错误

我们从上面很清晰的可以发现我们传入的是1\,但是在报错信息中可以发现其被单引号包裹,所以判断注入参数是是单引号包裹的字符型

单引号加括号包裹

sqli-labs less3

首先是这样

我们在id=1后加上反斜杠

加入反斜杠后

可以看到报错了,把报错信息复制出来

''1\') LIMIT 0,1'
'1\') LIMIT 0,1   /*去掉包裹错误信息的单引号*/

对比参数是单引号包裹的注入,这里在单引号后多了括号,那么我猜测在其前面也有,所以判断是被单引号和括号包裹的

验证一下

构造?id=1') --+

果真没有报错

所以判断注入参数类型为被单引号和括号包裹的字符型注入

例子就到这把,当然还有被双引号包裹的,双引号加括号包裹的,也是一样判断

0x03 字符型注入闭合方法

SQL语句常见的注释

  • --空格
    • --+(+可以作为空格的占位符)
    • --%20(%20是空格的url编码)
  • #
    • %23是#的url编码

原则:判断出其具体字符类型,先让其报错,再让其不报错

单引号包裹的字符型

先加上单引号让其报错

再通过闭合后面的多余单引号让其不报错

成功让其不报错

这样就可以在id’后构造自己的语句了

如果一种闭合的注释方式不行,可能是浏览器过滤,可以多试几种
其他的字符类型的闭合也是同理,就不演示了

0x04 基于报错和联合注入的判断

弊端:

  • 这是一种只适用于有回显的简便判断
  • 只能用于判断是字符型还是数字型

判断方法:

改变传入的id值,利用MySQL会对传入的字符型作强制转换这个特性来判断

例如:

sqli-labs/less1和sqli-labs/less2来举例

数字型:sqli-labs/less2

访问:?id=1

访问:?id=2-1和?id=3-2

字符型:sqli-labs/less1

访问:?id=1

访问?id=2-1或者?id=3-1

如果是数字型,MySQL可以对传入的id进行计算,可是在这2-1和3-1都不是id=1的页面,说明肯定是字符型,传入的2-1和3-2被分别强制成转换了2和3

强制转换后的结果

0x05 基于其他注入的判断

1.判断注入参数类型

由于除报错注入外,其他都是不显示报错内容的,但是实际情况又是不管是字符型还是数字型,只要我们加了反斜杠,单引号,双引号这些页面返回结果都会不正常,但是我们可以利用and来判断

当在?id=1后加上and 1=1and 1=2时,页面都返回正常,与不加 and 1= 一样,这时就可以判断是字符型,反之不一样则表示是数字型

原理:那是因为有符号包裹了and 1= 然后系统会进行隐形转换,将输入的 1 and 1=1 转换为 1,所以页面返回和原来一样

2.判断具体字符注入符号

首先在?id=1后加上闭合语句(注释),然后依此实验下面包裹符号

  • ?id=1 ' --+
  • ?id=1 " --+
  • ?id=1") --+

2,当遇见页面显示正常(布尔盲注)或者判断为true时,就判断出来了具体包裹符合

但是这里有一个非常大的坑就是,如果不加and 1=2,单引号包裹的换成双引号一样返回true,所以造成了不好判断包裹的具体符号

所以还需要再验证一下加上and 1=2,页面返回不正常才能确定

  • ?id=1 ' and 1=2 --+
  • ?id=1 " and 1=2 --+
  • ?id=1") and 1=2 --+

0x06 通用型判断方法

别问为什么放在最后,毕竟让你多踩踩坑也挺好的

这里用到了sleep(),思路就是先加注释闭合,然后构造语句,通过不断更换包裹的符号,当符号正确时,返回true,sleep执行,这样不管页面包不报错都能很容易的判断注入参数类型

用法举例:

?id=1 and sleep(3) --+
?id=1' and sleep(3) --+
?id=1") and sleep(3) --+
?id=1" and sleep(3) --+

0x06 post型的判断


一个热爱技术的白帽子