目录
MYSQL语句一个很重要的概念:成对出现
注释符的概念
使用注释符,mysql注释符有#、-- -(或者--+-)、/**/三种
注释符#,-- -(--+-)都是把后面的语句全部注释掉了,而内联注释/**/则是注释指定部分,需要一前一后闭合。
被单引号' '包括的字符无实际意义
注释符“-- -“将它后面的——' LIMIT 0,1全部注释掉了,而程序编译时,不对注释作任何处理,所以程序执行时只执行到SELECT * FROM users WHERE id='1',这里。
判断MYSQL语句闭合方式:
闭合的概念:MYSQL数据库的包容性较强,如果输入了错误的数据类型,MYSQL数据库会自动将其转换成正确的数据类型,
如:输入 1)、1"、1-等,只要数字后面的字符不是闭合符的,数据库都会把你输入的错误数据类型转换成正确的数据类型。
但是,若输入的数字后面的字符恰好是闭合符,则会形成闭合,若闭合后形成的sql语句是错误的,那么sql语句执行就会错误,从而造成页面显示错误。
sql的注入可以分为数字型,字符型。
简单分辨方法:
看\斜杠后面跟着的字符,是什么字符,它的闭合字符就是什么,若是没有,就为数字型。
数字型
测试步骤:
1、加单引号,URL:xxx.xxx.xxx/xxx.php?id=3';
对应的sql:select * from table where id=3' 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
2、加and 1=1 ,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=1;
对应的sql:select * from table where id=3' and 1=1 语句执行正常,与原始页面没有差异;
3、加and 1=2,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=2;
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异;
字符型
测试步骤:
1、加单引号:select * from table where name='admin'';
由于加单引号后变成三个单引号,则无法执行,程序会报错;
2、 加 ' and 1=1 此时sql 语句为:select * from table where name='admin' and 1=1' ,也无法进行注入,还需要通过注释符号将其绕过;
因此,构造语句为:select * from table where name ='admin' and 1=--' 可成功执行返回结果正确;
3、 加and 1=2— 此时sql语句为:select * from table where name='admin' and 1=2–'则会报错;
如果满足以上三点,可以判断该url为字符型注入。
判断MYSQL注入闭合方式:
方法1:
首先我们可以使用 \ (转义字符)来判断SQL注入的闭合方式。
原理,当闭合字符遇到转义字符时,会被转义,那么没有闭合符的语句就不完整了,就会报错,通过报错信息我们就可以推断出闭合符。
分析报错信息:看\斜杠后面跟着的字符,是什么字符,它的闭合字符就是什么,若是没有,就为数字型。
Less-1:'(单引号)
Less-2:无(数字型)
Less-3:')(单引号+括号)
Less-4:")(双引号+括号)
Less-5:'(单引号)
方法二:
首先尝试:
?id=1’
?id=1”
结果一:如果都报错
判断闭合符为:整形闭合。
结果二:如果单引号报错,双引号不报错。
继续尝试
?id=1’ -- -
结果一:无报错
判断闭合符为:单引号闭合。
结果二:报错
判断闭合符可能为:单引号加括号。
结果三:如果单引号不报错,双引号报错。
继续尝试
?id=1" -- -
结果一:结果无报错
判断闭合符为:双引号闭合。
结果二:报错
判断闭合符可能为:双引号加括号。
思考题:
1、为什么当我们输入id=1' and 1=1 -- -和id=1' and 1=2 -- -时会出现两种不一样的结果?
2、为什么将单引号消除之后id=1 and 1=1 -- - 和id=1 and 1=2 -- -都可以成功显示id=1?
删除单引号之前
删除单引号之后
原因:
1、为什么当我们输入id=1' and 1=1 -- -和id=1' and 1=2 -- -时会出现两种不一样的结果?
删除单引号之前id='1' and 1=1 -- -'LIMIT 0,1和id='1' and 1=2 -- -'LIMIT 0,1,我们可以将这两个语句都分为三个部分:
id='1'和and 1=1和-- -'LIMIT 0,1 id='1' 和and 1=2和-- -'LIMIT 0,1
id='1'意义是一样的,但是这两者所处的状态下,and1=1和and1=2都独立出来了,都具有实际意义(也就是说这时候的and是一个逻辑判断符,判断真假),注释符 -- - 把后面的 'LIMIT 0,1 注释掉了,因此会有两种不同的结果。
2、为什么将单引号消除之后id=1 and 1=1 -- - 和id=1 and 1=2 -- -都可以成功显示id=1?
删单引号之后id=1 and 1=1 -- - 和id=1 and 1=2 -- -分别为一个整体,都被单引号包括了起来形成闭合,而被单引号包括的字符是没有实际意义的,所以两种结果一致。
3、为什么将单引号消掉以后,我们输入id=1 and 1=2 -- -可以查到对应id?
数据库中并没有id=1 and 1=2的数据,甚至我们在后面随便输入一串东西也可以出现对应id
原因:
数据库中的id类型是int型,只取纯数字的整数部分,所以不管我们输入什么,他都只读取id后面的纯数字。
在这里要注意的是,在它读取我们输入的数字或字符字符时遵循一个规则:
当所读取的数据首位是数字,下一位是字符时,包括字符在内后面的东西全部舍去不读,当读取的数据首位是字符时,为空(dull)
例如:1aa=1,1a1=1,11a=11,a11=dull
Mysql中 int(3) 类型的含义
当我们在选择使用int的类型的时候,不论是int(3)还是int(11),它在数据库里面存储的都是4个字节的长度,在使用int(3)的时候如果你输入的是10,会默认给你存储位010,也就是说这个3代表的是默认的一个长度,当你不足3位时,会帮你不全,当你超过3位时,就没有任何的影响。
int()型也就是intval()型,返回值是整型,1或者0。
作用于数组时当数组为空,返回值是0,不为空则为1,并无报错。
intval()只是获取变量的整型值(截取变量的整数部分,直接舍去小数),并没有实际改变变量的值。对于不需要四舍五入的数值可直接使用。