前言
官方一点的原理是:SQL注入的本质是利用应用程序未对用户输入进行有效过滤的漏洞,将恶意SQL代码插入到Web表单、URL参数或请求报文中。
说人话就是你输入的恶意语句没被有效过滤直接被SQL所执行了,一般注入点会在各种Web表单、URL的参数和请求的报文里。
所谓过滤就相当于一个漏斗(Web表单等),块大(恶意语句)的过不去被拦截在外边了,绕过滤就是把语句切成各种形状,比如说条状,竖着就能过去。举个例子,它不允许出现or这两个字母组合在一起,那我们就Or或者OR就能过,电脑是很死板的。
目录
常见的攻击手法及类型的分类
按输入类型分类
数字型注入
攻击参数是整数,比如说ID、页码这类的,比如说URL里有个id=1页面显示一些文字,把id=1改成id=2就变了一个界面例如显示了一些照片,还可以试试id=1+2例如它显示了一些视频。逻辑漏洞绕过验证的方法最常见的就是or 1=1一般在账号密码用的多
字符型注入
参数为字符串,比如说我们用数字型的or 1=1过不了,因为字符需要用“东西”包裹起来,假如闭合方式是单引号,那么我们的语句就应该是'or' 1 '=' 1这样的。
按攻击方式分类
联合查询注入
通过union合并查询结果,比如说我们要查数据库名,就要union select database(),比如这样
这里用到的语句是'union select 1,database() #,'的作用是闭合前面,前面的数据库语句是SELECT first_name, last_name FROM users WHERE user_id = '$id';这里的$id就是我们传参过去的东西,两边有单引号,我们需要让我们的语句到单引号外面,把前面的单引号闭合掉,然后在后面加我们的payload(恶意语句),这里的1,是因为测试它有两列,union select查询标准是要列数相同,所以后面就是我们的查询数据库名的语句,最后的#是注释。
布尔盲注
首先举个例子,id=1'and (select substr(user(),1,1)='a') #,这段payload是通过页面差异来判断user里1,1(第一行,第一列)的字符是否为a,如果substr函数被过滤了,可以用mid()、right()或者lpad()来代替。
时间盲注
就是通过数据库给我们的延时响应判断是否注入成功,例如if(1=1,sleep(5)),意思是如果1=1那么就让SQL“睡”5秒。
报错注入
触发数据库的报错来泄露敏感数据,比如有的就在报文的UA头里,例如updataxml(1,concat(0x7e,(select user()),0x7e),1),这里给出的报错回显大概是XPATH syntax error: '~root@localhost~',如果回显量太大的话直接Ctrl+F搜索~。
堆叠注入
这个需要数据库支持才行,比如说SQL Server支持,但是MySQL默认是禁用的。简单来说就是允许一次性执行多条的SQL语句,比如id=1'; drop table users; select 1 #。
二次注入
这个要分两步,第一步要去正常的注册一个用户,名字为admin'#,当没被过滤正常存入数据库之后,第二去正常修改密码,中间的SQL语句可能是update users set password='123' where user='admin'#',因为我们的用户名是admin'#,第一个单引号跟前面的单引号相互闭合,#把后面的单引号或者是后续条件给注释掉,就导致我们把管理员(admin)的密码给篡改了。
tips
order by可以用二分法,节省时间快速定位字段数。比如说,order by 10没有回显,order by 5有回显那么我们就在order by 7基本就能断定字段数了。
union select后边可以跟null,因为null兼容任意的数据类型,可以减少报错的风险。
group_concat()函数可以将多行数据合并
limit 1,1可以逐条获取数据