sql注入
意义是:用户在提交表单时输入恶意的sql语句,欺骗后端把其当作正常的数据执行
注入方式分类有两种
按照注入方式分:union注入、布尔盲注、时间注入、报错注入
按照注入点类型分:字符型、数字型
一、按照注入点类型的sql注入步骤:
1-寻找注入点
2-判断注入点类型,是数字型还是字符型
3-如果是字符型则根据真假页面或者报错语句判断闭合方式
4-判断回显列数 group by/order by(WAF防御监控比较严格)
5-判断回显位 union select 并且将前面的语句判定为假值
二、union注入
步骤: 1-拿到当前数据所在数据库库名
2-进入到information_schema.tables中找当前数据库里的所有表
3-拿到表名之后,进information_schema.columns中找步骤2的表中的列
4-有表名有列名,直接输出
group_concat() 确保所有查询信息能放到一行显示出来
3-表名太多,于是将拿到的表名进行过滤,where table_schema=database()
4-拿到想要的表后过滤去informaion_schema.columns拿想知道列,也用where语句过滤
5-知道列,知道表,group_concat()拿吧
三、报错注入
***一次只返回32个字符
所以使用substring()函数
substring([控制输出的字符串],[从哪儿显示],[一共显示几个字符])
12种大约
什么时候需要用显错注入?::拿到注入点页面关键信息不回显的时候,利用数据库报错来回显
1-extractValue()报错注入 查询xml里面的内容 select extractValue(=数据库的列名=,=要查找的数据内容路径=)
*原理:输错第二个参数,即把查询参数格式符号写错,就会报错,所以:
格式不重要,重要的是出现显错的内容,根据显示出来的错误来看自己想要的东西
select 1,2,extractValue(1,concat(0x7e,(select database())))
拼接 1,2【执行的命令】
2-updateXml()报错注入 updateXml(XML_document,XPath_string,new_value)
XML_document: string格式,是XML对象名称
XPath_string: 路径,XPath格式的字符串
new_value: string格式,替换查找到的符合条件的数据
原理:输错第二个参数
3-floor报错【难度最高,函数多,报错抽象】
rand(k):随机返回0~1之间的小数
k:随机数种子,实际上rand函数是一种伪随机
floor()函数:向下取整
ceiling():向上取整
concat_ws(1,2,3):括号内的数据用第一个字段连接起来
1:用什么来拼接2,3字符串
2、3:被拼接的字符串
group by: 分组语句,对结果进行分组
as:起别名
便于统计数量
count():统计数量
此时出现报错【实属偶然】下一次就不一定报错的
- 如何固定报错?尝试切换rand种子数,试出一定会报错的伪随机数k
- 为什么【count()+floor()】有时候会报错?
i. 官方废话:rand()函数进行分组group by和统计count()时可能会多次执行,导致键值key重复
ii. 人话:如果要分组统计,分组名重复,在上面的选项是指security*1和 security*0重复【如果写入group_key中,key值不存在则要将数据返回在进行一次计算存入,即第一次存的实际上为第二次计算】
limit:用于显示指定行数
select rand() from [表名] : 用来统计表的行数,最后出来的数据有多少行,意味着rand()执行多少次,表里的数据就有几行
找到报错的种子数k,就可以进行floor报错注入了
Limit 0,1:从0开始显示第1行
4-盲注:页面无报错回显【观察页面是否有真假值】,不知道数据库具体返回值的情况下,对数据库中的内容进行猜解,实行sql注入
- 布尔盲注【basic】
【**原理】根据web页面只返回True真,False假两种类型,利用页面的返回不同,逐个猜解数据
所用函数:ascii() 字符变成其ASCII码对应的数字
Q:为什么字母要变成数字???
数字更好找,更好进行比较,效率更高【其实字母也行】
盲注中查询命令可以执行,但是不回显
所以用ascii()把查询到的内容转换成数字,用真假页面的显示判断数字对应的字母是什么
【挨个比】
>select ascii((select database())) *ascii()函数只转换第一个字符
所以用到第二个函数:substring((),1,1)
>select ascii(substr(1,2,3)) à select ascii(substr((select database()),1,1))
>select ascii(substr(1,2,3)) à select ascii(substr((select database()),2,1))
例如:
当前页面不回显,表明页面为假,即ascii函数里的database()的第一个字符<130
当前页面回显,表明页面为真,即ascii函数里的database()的第一个字符>=110
利用二分法判断出database()函数的返回值第一个字符的ascii码为115,对应的字符为s
第一个字符完成依此类推,每个都遍历一遍,最后推算出database()的结果
得到的每个字符判断其ascii码的大小【二分法】,最后拼接
- 时间盲注
前提:数据库执行代码,只是页面信息不做反馈
函数:sleep(n) 数据库执行语句后等待n秒后进行反馈
参数是休眠时常,单位是秒,可以是小数
因为页面不回显,所以用正常方法无法判断注入点类型,所以用sleep()
url/?id=1‘ and sleep(3)[意思是如果命令正常执行,则页面在三秒钟后进行反馈,根据页面响应时常判断自己的语句执行有无]
If(1,2,3)
1:判断条件,返回值为bool类型
2:为真执行的内容
3:为假执行的内容
因此,可以利用页面响应时间来判断语句1的真假,语句1可以放入布尔盲注里面的ascii()函数比大小,根据页面响应时间长短来判断语句1的结果为真为假,后面步骤同布尔盲注
sql注入的防御
1-使用预编译语句
2-严格控制数据类型
3-将特殊字符进行转义
标签:database,基础,报错,sql,页面,ascii,select,注入 From: https://www.cnblogs.com/adongFfavourite/p/17556516.html