1、什么是sql注入
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。[1] 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.
2、sql注入是怎么产生的
1)在应用程序中使用字符串联结方式或联合查询方式组合SQL指令。
2)在应用程序链接数据库时使用权限过大的账户(例如很多开发人员都喜欢用最高权限的系统管理员账户(如常见的root,sa等)连接数据库)。
3)在数据库中开放了不必要但权力过大的功能(例如在Microsoft SQL Server数据库中的xp_cmdshell延伸存储程序或是OLE Automation存储程序等)
4)太过于信任用户所输入的数据,未限制输入的特殊字符,以及未对用户输入的数据做潜在指令的检查。
3、SQL注入攻击分类
1)注入点的不同分类
- 数字类型的注入
- 字符串类型的注入
2)提交方式的不同分类
- GET注入
- POST注入
- COOKIE注入
- HTTP注入
3)获取信息的方式不同分类
- 基于布尔的盲注
- 基于时间的盲注
- 基于报错的注入
4、SQL注入实例
1)数字类型注入
在浏览器地址栏输入:learn.me/sql/article.php?id=1,这是一个get型接口,发送这个请求相当于调用一个查询语句:
$sql = "SELECT * FROM article WHERE id =",$id
正常情况下,应该返回一个id=1的文章信息。那么,如果在浏览器地址栏输入:learn.me/sql/article.php?id=-1 OR 1 =1,这就是一个SQL注入攻击了,可能会返回所有文章的相关信息。为什么会这样呢?
这是因为,id = -1永远是false,1=1永远是true,所有整个where语句永远是ture,所以where条件相当于没有加where条件,那么查询的结果相当于整张表的内容
2)字符串类型注入
- '#':'#'后所有的字符串都会被当成注释来处理
SELECT * FROM user WHERE username = 'user'#'ADN password = '111'
2.'-- ' (--后面有个空格):'-- '后面的字符串都会被当成注释来处理
SELECT * FROM user WHERE username = 'user'-- 'AND password = '111'
以上两条语句等同于
SELECT * FROM user WHERE username = 'user'
3)get请求加减法
加法:http://www.blog.com/test.php?id=1%2b1 (%2b是url编码后的 +)
减法:http://www.blog.com/test.php?id=3-1
通过以上加减法注入,在原请求的基础上获得数据表中的其他数据
还有诸如 UNION、order by语句获取数据表列,枚举获取数据库的表、列,获取WebShell、sql盲注等由于篇幅,请自行google
或可参考 https://ctf-wiki.github.io/ctf-wiki/web/sqli/
4、SQL注入防护
根据已知的sql注入原理及场景等,建议做如下防范措施
- 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。
- 检查输入的数据是否具有所期望的数据格式,严格限制变量的类型,例如使用regexp包进行一些匹配处理,或者使用strconv包对字符串转化成其他基本类型的数据进行判断。
- 对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。Go 的
text/template
包里面的HTMLEscapeString
函数可以对字符串进行转义处理。如MySQL中的 mysql_real_escape_string() (PHP 4 >= 4.3.0, PHP 5),mysqli_real_escape_string() (PHP 5, PHP 7),PDO::quote() (PHP 5 >= 5.1.0, PHP 7, PECL pdo >= 0.2.1) - 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。例如使用
database/sql
里面的查询函数Prepare
和Query
,或者Exec(query string, args ...interface{})
。 - 在应用发布之前建议使用专业的SQL注入检测工具进行检测,以及时修补被发现的SQL注入漏洞。网上有很多这方面的开源工具,例如sqlmap、SQLninja等。
- 避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,把代码里的SQL语句暴露出来,以防止攻击者利用这些错误信息进行SQL注入。