-
什么是SQL注入
2019-07-10 21:40:10什么是sql注入: sql注入(注入结构化查询语言) 所谓SQL注入,就是通过把SQL命令插入到Web表单中[此处涉及到sql注入的点]提交最终达到欺骗服务器执行恶意的SQL命令。 具体来说,它是利用现有的web应用程序,将...本文纯属以个人的角度去看待SQL注入,有些地方不足,请各位读者指点批评
什么sql注入,为什么会发生sql注入,sql注入的危害,怎样预防sql注入
什么是sql注入:
sql注入(注入结构化查询语言)
所谓SQL注入,就是通过把SQL命令插入到Web表单中[此处涉及到sql注入的点]提交最终达到欺骗服务器执行恶意的SQL命令。
具体来说,它是利用现有的web应用程序,将(恶意的)SQL命令注入到后台数据库引擎,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句.
为什么会发生sql注入
简单的解释:由于代码处理逻辑不严谨,攻击者可以注入恶意的sql语句,使原本的意思产生歧义,从而造成危害
因为应用程序需要和后端数据库引擎进行交互,例如,在前端接收用户输入的查询语句时,因为其中的代码不严谨,未进行相应的过滤,导致用户的恶意输入引起数据库返回异常,从而导致攻击者可以拼接相应的数据库语句进行sql注入,提取想要的信息.
sql注入的危害:
- 数据库内的信息全部被外界窃取
- 数据内容被篡改
- 登录认证被绕过
- 其他,例如服务器上的文件被读取或修改/服务器上的程序被执行
怎样预防sql注入:
尽管表现的形式和利用的手段的复杂程度各不相同,但是,sql注入仍然是最容易防御的漏洞之一
1:部分有效的防御措施:
过滤危险字符,使用预编译语言(参数化查询)
注意,所有安全都是因为人,有人说可以使用存储过程来完成所有的数据库访问,但是要考虑到使用存储过程对程序性能的要求,同时要考虑到编写的存储过程本身是否存在问题
2参数化查询,使用API对不可信的输入进行安全处理
参数化查询:
a:应用程序指定查询的结构,为用户输入的每一个数据预留占位符
b:应用程序指定每一位占位符的内容
注意:开发人员会忽略二阶注入这一点,所以要规定整个应用程序中都使用参数化查询更安全
3:深层防御
a:降低数据的权限,尽可能使用最低权限的用户
b:删除数据库不常用的大量默认功能
c:及时打补丁
sql注入的几点笔记
sql注入请求方式:
- get
- post
sql注入的类型
- 盲注
- 显注
sql注入的主要点
- 数据提交参数
- cookie
- user-agent
- referer
sql注入的其他攻击方式:
堆叠查询注入攻击
二次注入攻击
cookie注入攻击
宽字节注入攻击
xff注入攻击
base64注入攻击
sql注入的某些绕过方式
大小写绕过技术
双写绕过技术
编码绕过技术
内联注释绕过技术
-
什么是sql注入
2019-04-12 21:23:20什么是sql注入? 注入攻击是攻击者通过web把恶意的代码传播到其他的系统上,这些攻击包括系统调用和后台数据库调用等。当一个web用用程序通过HTTP请求把外部请求的信息传递给应用后台时,必须非常小心,否则注入攻击就...什么是sql注入?
注入攻击是攻击者通过web把恶意的代码传播到其他的系统上,这些攻击包括系统调用和后台数据库调用等。当一个web用用程序通过HTTP请求把外部请求的信息传递给应用后台时,必须非常小心,否则注入攻击就可以将特殊字符、恶意代码或者命令改变器注入这些信息中,并传输到后台执行。
由于SQL注入是从正常的web端口攻击的,而且看起来和一般的web页面一样,所以目前防火墙无法发现SQL注入攻击。如果网站管理员没有查看IIS日志的习惯.则可能在被注入攻击后很长时间都不会发觉,所以SQL注入攻击是目前黑客比较喜欢的攻击方式。举个栗子!!
我这边用的是原生代码
login.html<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>简单SQL注入页面</title> </head> <body style="background-color: #006400"> <h2 align="center" style="color: white">图书管理系统后台登录</h2> <!--将用户输入的user,和pass提交到login.php--> <form align="center" action="login.php" method="post" enctype="multipart/form-data"> <!--用户输入的账号存储在user变量,密码存储在pass变量--> <p style="width: 100%;height: 30px;display: block;line-height: 200px;text-align: center;color:white;font-size:16px;">账 号:<input type="text" name="user" value="" max="10"></p> <p style="width: 100%;height: 30px;display: block;line-height: 200px;text-align: center;color:white;font-size:16px;">密 码:<input type="password" name="pass" value="" min="6" max="16"></p> <p style="width: 100%;height: 30px;display: block;line-height: 200px;text-align: center;"><input type="submit" name="submit" value="登录"></p> </form> </body> </html>
login.php
<?php $con=mysqli_connect("localhost","root","root","test"); if(!$con) {//连接失败会输出error+错误代码 die("error:".mysqli_connect_error()); } //把用户在index.html输入的账号和密码保存在$user和$pass两个变量中 $user=$_POST['user']; $pass=$_POST['pass']; $sql="select * from user where username='$user' and pwd='$pass'"; // print_r($sql); $res=mysqli_query($con,$sql); print_r($res); // $row=mysqli_fetch_array($res,MYSQLI_NUM); if($res->num_rows == 1) { echo "登录成功!"; } else { echo "登录失败!"; } ?>
数据库就这样
我们故意输入错误密码. 账号abc 密码456 就会显示登录失败
如果我们使用sql注入的话
在用户名输入’ or 1=1 --,然后随便输入一个密码 或者不输入密码 直接点击登录
就会显示登录成功.
为什么呢??
今天工作一天累死 至于怎么防止呢 下篇文章见 !! -
什么是sql 注入
2019-01-11 09:08:05Sql 注入 例子: 根据商品名称查询商品 sql 语句应该值这样的: 输入 苹果手机 select * from goods where goods_name = '苹果手机' 但是假设输入 ' or 1=1 or '1 那么sql 语句就变成了这样: select * from ...Sql 注入
例子:
根据商品名称查询商品 sql 语句应该值这样的: 输入 苹果手机 select * from goods where goods_name = '苹果手机' 但是假设输入 ' or 1=1 or '1 那么sql 语句就变成了这样: select * from goods where goods_name ='' or 1 = 1 or '1' 那么这条sql 语句就查出了所有的商品 这就是sql 注入。
-
究竟什么是SQL注入?
2020-06-03 20:39:43SQL注入是Web安全层面最高危的漏洞之一,长期霸榜OWASP Top10首位,但是究竟什么事SQL注入?SQL注入又是怎么产生的?接下来本篇文章将详细介绍SQL注入产生的原理。本篇文章并没有描述具体的注入方法,而是侧重于对...文章目录
1.前言
SQL注入是Web安全层面最高危的漏洞之一,长期霸榜OWASP Top10首位,但是究竟什么事SQL注入?SQL注入又是怎么产生的?接下来本篇文章将详细介绍SQL注入产生的原理。本篇文章并没有描述具体的注入方法,而是侧重于对原理的描述,并分别分析了GET和POST注入。
2.实验环境搭建
在弄清SQL注入的基本原理之前,我们首先要来搭建实验的环境,我们需要一台L(Linux)NMP服务器或者W(Windows)NMP服务器,具体服务器的搭建可以参考我之前的文章《一篇文章告诉你如何搭建LNMP》,或者直接使用phpStudy完成搭建。
完成服务器的搭建后,我们要准备好测试用的数据库,执行下面的SQL命令完成数据库的建立create database SQLInjection; use SQLInjection create table users(id int,username varchar(255),password varchar(255));
创建完成后,可以插入几条用于测试的数据
insert into users value(1,'Tom','123456'); insert into users value(2,'Alice','654321'); insert into users value(3,'Jerry','qwerty');
3.原理介绍
3.1 HTTP协议
HTTP协议是Web应用层协议,全称是超文本传输协议。这个协议是Web应用的核心,HTTP由两个程序实现,一个是客户端程序,通常是我们使用的浏览器,一个是服务器程序,运行在我们所访问俄的服务器上。这两个程序通过HTTP协议进行交流,HTTP定义了这些报文的语法、语义和时序。这里我们并不需要对HTTP协议做过深的了解。但是我们依旧需要明确以下几个知识点:
1.客户端程序与服务器程序之间是通过报文进行交流的,通常是客户端请求数据,服务器响应客户端请求的数据; 2.报文是包含了不同的字段,不同的字段代表的不同的信息 3.报文中携带了客户端程序与服务器程序之间通信的数据 4.数据在报文中的位置不同,服务器接收该数据的方式也不同
3.1.1 HTTP报文
客户端与服务器端的报文,根据发送方的不同被分为请求报文和响应报文,从客户端发往服务器端的被称为请求报文,从服务器端发往客户端的被称为响应报文。请求报文和响应报文都有不同的固定格式,请求报文的一般报文格式如下
响应报文的一般格式如下
因为本文主要主要讲述的是SQL注入,SQL注入我们是无法操作服务器的,只能通过影响从客户端发送的请求报文进而从服务器获取数据,所以我们只需要了解请求报文,在上面的请求报文结构图中,我们可以看到请求报文主要包含请求行、首部行、空行、实体体4个模块。各个模块的功能说明如下
模块名 说明 请求行 方法 说明传递数据的方法 URL 指明想要访问的文件 版本 协议的版本HTTP /1.1 首部行 首部行中包含众多的字段,不同的报文可能会携带不同的字段,在请求报文中主要用来说明客户端的相关信息 空行 实体体 当使用POST方式传递数据的时候,该模块会填充POST想要传递的数据 在前面的内容中不断的提到数据的传递,数据传递的方法会在请求行的方法中说明,主要有4种数据传递的方法,这里只介绍两种与SQL注入有关的
3.1.2 GET方法
当请求报文的方法字段被设置为GET的时候,表明该请求报文使用GET方式进行传参。通常GET方法是用来获取服务器上的指定文件,比如
GET /index.php HTTP/1.1
上面的请求行用来获取网站根目录下的index.php文件,当站点接收到该请求后会将用户请求的文件内容进行解析,然后通过响应报文响应用户的请求。但是也会遇到某些文件需要接收参数的情况,客户端程序会使用下面的方式对文件完成传参
GET /index.php?id=1 HTTP/1.1
这样服务器上的文件便能够接受id=1的传参。然后根据用户的传参作出响应的处理。
3.1.3 POST方法
当请求报文的方法字段被设置为POST的时候,表明该请求报文使用POST方式进行传参。通常POST方式用来提交用户输入的表单信息,这些协议存放在请求报文的实体体中。比如
POST /user/login.html HTTP/1.1 //...... user=admin&pass=admin
上面是一个用户登录报文的示例,通过POST方式提交用户输入的用户名和密码。
3.1.4 从页面到报文
上面所说到的报文或者传参方式都是客户端程序生成的,作为用户只需要在页面上点击鼠标或者输入内容即可。那么客户端程序是怎么确定要使用什么样的方式传参呢?简单来说我们在表格中输入的数据会通过POST进行传参,而我们的点击页面的操作一般会通过GET传参。
POST传参的方式比较好理解,但是我们还要重点说明一下GET方式,比如当我们浏览某个站点的时候,点击了站点中的一篇文件,页面就给我们显示了我们点击的文章。现在我从数据包的角度分析站点为什么可以准确的显示我们所点击的文章。首先我们点击文章,服务端会发送类似于下面的数据包GET /index.php?p=1234 HTTP/1.1 Host: www.test.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0 Accept: text/html, */*; q=0.01 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate X-Requested-With: XMLHttpRequest Connection: close Referer: http://www.test.com
可以看到由于是GET方法,所以报文的实体体为空。Host字段表示站点的域名。通过域名可以找到该站点的服务器,然后将报文传递到该站点,站点接收报文后发现用户请求的是/index.php文件,并且有传参p=1234,站点便会在根目录下寻找index.php文件,执行index.php文件并完成传参,执行的结果就是我们请求的文章,然后将文章发送给我们。我们会发现当页面显示文章后,浏览器的的URL栏变成了
可以看到URL栏会显示我们通过GET方式传递的参数p=1234。其实我们通过GET方式对文件传递的参数都会显示在URL栏中,我们可以直接修改URL栏中的内容为
http://www.test.com/?p=1234
或者
http://www.test.com/index.php?p=1234
都会发送同样的数据包,显示同样的内容。也就是说我们可以通过修改URL栏中的内容控制传参的内容。
补充:因为站点会默认请求index.php或者index.html文件所以在请求index.php文件的时候可以不写index.php文件,站点就会直接请求index.php文件。3.2 SQL注入
说到这里我们才正式进入SQL注入的原理分析,但是看完上面的内容我们已经完成一大半了,接下来就是将上面的知识应用到SQL注入中。这里仅仅介绍两种典型的注入GET和POST。SQL注入的方式有很多但是基本原理都差不多的。
站点存在SQL注入必须满足下面的三个条件1.用户能够控制输入 2.待执行的代码拼接了用户输入的数据 3.执行了待执行的代码
3.2.1 GET注入
(1)验证GET传参
首先我们来模拟一下上传的传参方式,首先在我们的LNMP或者WNMP服务器(下称“服务器”)的网站的某个你喜欢的目录下放置下面的脚本
test.php<?php echo 'hello,world!'; $id=$_GET['id']; #接收GET传参 echo $id; ?>
这里将该脚本放置在SQLInjection目录下,随后我们在URL栏输入路径访问该文件,页面显示效果如下
页面成功的显示了hello,world!,接着我们需改URL栏为
http://192.168.25.147/SQLInjection/test.php?id=1234
并抓取浏览器发送的数据包,数据包内容如下
GET /SQLInjection/test.php?id=1234 HTTP/1.1 Host: 192.168.25.147 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: PHPSESSID=0871f074b43a28eb3e15dcf7b0635b6d Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0
可以看到该数据包使用GET方式进行传参,并在URL字段指定了文件的路径和我们对文件的传参。同时返回的页面显示了我们在URL栏中传递的参数
上面的操作也就验证了通过URL栏的方式传递参数是GET方式的传参。并且测试了我们的文件可以接受GET传参的内容。
(2)SQL注入
将上面的代码修改为
echo 'hello,world!'.'<hr/>'; #1.获取get传参 $id=$_GET['id']; echo '你传入的参数'.$id.'<hr/>'; #2.链接数据库 $conn=mysqli_connect('localhost','root','root','sqlinjection'); if(!$conn) die("<script>alert('Sorry,cannot connect to database')</script>"); #3.构造SQL命令 $sql="select * from users where id=$id"; echo '执行的SQL语句'.$sql.'<hr/>'; #4.查询数据库 $result=mysqli_query($conn,$sql); #5.显示查询结果 echo '查询结果'.'<br/>'; while($row=mysqli_fetch_array($result)) { echo 'id:'.$row['id'].';'.'username:'.$row['username'].';'.'password:'.$row['password'].'<br/>'; } #6.断开链接 mysqli_close($conn);
代码修改完成后,我们接着访问该代码,然后传入参数id=1,页面显示如下
可以看到站点成功的接收了我们的传参,并根据我们的传参访问数据库,并显示了数据库的访问结果。这是正常情况下的传参,可以理解为我们登录用户后,页面通过GET传参的方式从数据库中取出我们的用户信息显示在页面上。因为我们可以控制传参的内容,那我们尝试将URL栏修改为
http://192.168.25.147/sqlinjection/test.php?id=1 union select * from users where id=2
站点显示的内容变成了
也就是说我们修改URL栏中的内容将id的值变成了
id=1 union select * from users where id=2
站点在接收到该值后,将该变量的值与SQL命令进行拼接,形成了如下的SQL命令
select * from users where id=1 union select * from users where id=2
随后执行了该SQL命令,显示了预期之外的数据。
在正常操作下id接收的是一个数字,然后将该数字拼接到SQL命令中执行。但是我们通过人为修了id传参的值,也就是说我们可以控制id的值,并将其修改为一个恶意的值;接着系统会将我们输入的内容拼接道SQL命令中,即待执行的代码拼接了用户输入的内容;最后拼接了用户输入内容的代码执行了,获取了数据库中的数据。3.2.1 POST注入
理解了前面的GET注入的原理,POST注入的原理和GET完全一致,不同点在于传参方式的不同。
(1)验证POST传参
准备了如下的程序将其放置在sqlinjection目录下
login.html<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>login</title> </head> <body> <form action="login.php" method="POST" target="_self"> username:<input type="text" name="username"/><br /> password:<input type="password" name="password"/><br /> <input type="submit" value="login"><hr /> </form> </body> </html>
login.php
<?php #1.从前端获取数据 $username=$_POST["username"]; $password=$_POST["password"]; echo '你输入了如下的内容'.'<br/>'; echo 'username:'.$username.'<br/>'; echo 'password:'.$password.'<hr/>'; ?>
随后我们访问login.html,页面显示如下
输入如下的内容后
字段名 内容 username Tom password 123456 点击login并抓取数据包,得到的数据包内容如下
POST /sqlinjection/login.php HTTP/1.1 Host: 192.168.25.147 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 28 Origin: http://192.168.25.147 Connection: close Referer: http://192.168.25.147/sqlinjection/login.html Cookie: PHPSESSID=0871f074b43a28eb3e15dcf7b0635b6d Upgrade-Insecure-Requests: 1 username=Tom&password=123456
可以看到数据包使用的是POST的方式,并且在实体体中携带了我们输入的用户名和密码信息。随后页面会显示下面的内容
可以看到我们在表单是输入的内容是使用POST方式携带在实体体中进行传参的。同时login.php能够成功的接收我们传入的数据
(2)SQL注入
将login.php脚本修改为
<?php #1.接收用户传参 $username=$_POST["username"]; $password=$_POST["password"]; echo '你输入了如下的内容'.'<br/>'; echo 'username:'.$username.'<br/>'; echo 'password:'.$password.'<hr/>'; #2.链接数据库 $conn=mysqli_connect('localhost','root','123456','sqlinjection'); if(!$conn) die("<script>alert('Sorry,cannot connect to database,please login later!')</script>"); #3.构造查询语句 $sql="select * from users where username='$username' and password='$password'"; echo '执行的SQL命令为:'.$sql.'<hr/>'; #4.进行查询并获得结果 $result=mysqli_query($conn,$sql); $row=mysqli_fetch_array($result); if(isset($row)) { echo '---登录成功---'.'<hr/>;'; }else{ echo '---登录失败---'.'<hr/>'; } ?>
当我们输入正确的用户名和密码的时候页面会显示
如果输入的用户名或者密码是错误的时候,页面会显示
也就是说站点能够正确的验证用户名和密码的正确情况,但是我们尝试输入下面的内容
字段名 字段值 username Tom password ’ or 1=1 or ’ 我们发现居然也登录成功了
仔细观察我们输入的内容拼成的SQL语句
select * from users where username='Tom' and password='' or 1=1 or ''
在执行select的时候判断条件有4个,分别是
条件1.username='Tom' 条件2.password='' 条件3.1=1 条件4.''
其中条件1与条件2使用and链接,其他的条件使用or链接,当程序从左往右判断条件成立的时候,执行到条件1的时候能找到使条件成立的记录,虽然执行到条件2的时候发现不成立,但是因为后面使用了or连接了一个恒成立的式子1=1,因此重要1=1存在其他的条件就算不成立也可以查找到对应的记录。所以在这里即使我们不是输入密码也可能成功的登录。这也是常用的万能密码。
以上便是POST注入的基本原理,可以看到和GET注入类似。当我们输入用户名的时候可以输入任意的内容,也就是说用户可以控制输入。当程序带着我们输入的内容查找数据库的时候,也就是拼接我们输入的内容并执行。 -
什么是SQL注入,如何解决SQL注入
2019-09-13 17:55:35什么是SQL注入? 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入地址域或页面请求的查询字符串中,欺骗服务器执行恶意的SQL命令。 mybatis防止SQL注入: <select id="getBlogById" resultType=... -
什么是SQL注入?
2019-05-02 19:16:46什么是SQL 注入? SQL 注入是一种非常常见的数据库攻击手段,SQL 注入漏洞也是网络世界中最普遍的漏洞 之一。大家也许都听过某某学长通过攻击学校数据库修改自己成绩的事情,这些学长们一 般用的就是 SQL 注入方法... -
什么是sql注入,如何防止sql注入
2019-08-14 17:26:50什么是sql注入 一:如何理解sql注入? sql注入是一种将sql代码添加到输入参数中,传递到sql服务器解析并执行的一种攻击手法 示例: 本地一段代码为get获取id值,输出实际执行sql以及查询id对应内容。 当id值传为1... -
什么是sql注入,怎么防止SQL注入?
2019-08-09 18:16:57什么是SQL注入? 用户提交带有恶意的数据与SQL语句进行字符串方式的拼接,从而影响了SQL语句的语义,最终产 生数据泄露的现象 如何防止SQL注入? SQL语句参数化 SQL语言中的参数使用%s来占位,此处不是python中的... -
什么是SQL注入以及如何处理SQL注入问题
2019-10-17 09:58:341、什么是SQL注入 SQL注入是一种注入攻击,可以执行恶意SQL语句,它通过将任意SQL代码插入数据库查询,使攻击者能够完全控制WEB应用程序后面的数据库服务器,攻击者可以使用SQL注入漏洞绕过应用程序安全措施;可以绕...