SQL注入可以绕过认证,对数据进行读、改、删。某些情况下可能造成执行命令的效果。
作为一种攻击方式,其本质原因在于后端接收了用户输入,并将其拼接到SQL语句中,造成了数据和指令的混淆。将本该是数据的地方注入了额外的指令,实现了攻击的效果。
SQL主要可以分为三类:
1、带内(In-band)SQLi,也叫经典SQLi
顾名思义,带内的意思就是攻击者可以在同一个信道里进行攻击,并且拿到结果。
最常见的两种带内SQLi 就是基于报错(Error-based)的SQLi,和基于联合查询语句(Union-based)的SQLi。
基于报错(Error-based)的SQLi
比如mysql中的mysql_error()函数。这种功能本来是为了给开发用来调试代码找问题的。而攻击者可以利用程序中的报错,拿到SQLi的结果。
示例参考:
http://rickgray.me/2014/11/16/error-based-sql-injection/
缓解措施:
线上环境禁用报错的功能。
基于联合查询语句(Union-based)的SQLi
利用SQL语句中的UNION操作符拼接两个或更多的SELECT语句,得到一个结果,然后作为HTTP响应返回来的攻击方式。
2、推测SQL注入(盲注)
这种SQLi,跟带内SQLi 相比,就可能要花费更长的时间了。这种攻击方式下,攻击者并不能在带内看到SQLi成功的数据结果,但是他可以通过构造大量的SQL语句,通过观察返回的响应来推测数据库中的数据。
盲注分两种:布尔(Boolean-based)盲注,和时间(Time-based)盲注。
布尔盲注
布尔盲注,是攻击者通过发起不同请求观察响应内容的相同与否,判断某条SQL判断的结果是TRUE还是FALSE,来间接地猜测数据库中的数据。
时间盲注
时间盲注就是攻击者通过注入延时语句(比如sleep )强制数据库延时一种长的时间,用于判断某条判断语句是TRUE还是FALSE,从而间接地猜测数据库中的数据。
3、带外SQLi
依赖于具体的DBMS上是否开启某些发起HTTP/DNS请求的功能。比如SQL Server的xp_dirtree命令,可以用来向攻击者可控的域名发起DNS请求,实现带外注入;比如Oracle数据库的UTL_HTTP包,可以发起HTTP请求。
参考
- https://www.acunetix.com/websitesecurity/sql-injection2/
- https://www.quora.com/How-many-types-of-SQL-injections-are-there
- https://pentest-tools.com/blog/sql-injection-attacks/