# sql注入详解

## SQLI介绍

SQLI,sql injection,我们称之为sql注入,sql(Structured Query Language),叫做结构化查询语句。在我们的应用系统使用 sql 语句进行管理应用数 据库时,往往采用拼接的方式形成一条完整的数据库语言,而危险的是,在拼接 sql 语句的 时候,我们可以改变 sql 语句。从而让数据执行我们想要执行的语句,这就是我们常说的 sql 注入。

## 一、漏洞原理分析

sql注入的原理通俗的来说,就是通关SQL命令将web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令。

举个例子,以sqli-labs第一关为列,(sqli-labs是一个sql注入的靶场),按要求查询?id=1


得到的结果为:name和Password均为Dumb。

当我们输入?id=2时,又得到了不同的结果。

我们进入数据库去查看一下。(默认知道了数据库名字security)

可以发现我们查询的信息存在users这个表中。这里我们就可以知道了我们输入的SQL命令最终进入数据库中进行相应的查询,试想一下,如果我们构造一个恶意的SQL语句,是不是就可以达到我们想要的目的——数据库信息泄露,网页篡改,网站挂马,数据库恶意操作,服务器被远程控制等等。

为了更加清楚sql语句的执行和变化过程,我们可以查看源码,打开Less-1/index.php,在源码中添加几行语句。

[

访问后得到

红色框出来的语句就是执行的sql语句,我们输入的变量‘1’也在其中。通常我们构造的SQL语句就是这个‘1’的内容。在1后面加一个单引号。

显示语法错误,说靠经'1'' limit 0,1有语法错误,我们输入的1’被完整的带入到SQL语句中。这里错误的原理是我们输入的单引号与前面的单引号进行闭合,导致后面的单引号变成了多余的。而sql语句中的引号必须是成对出现的。否则就会报错。

那么问题来了,我们如何才能写入我们想要的sql语句呢,既然这里对我们输入的单引号没有进行过滤,那么我们是不是可以在闭合后的语句后面插入我们想要查询的语句,这样就达到了我们的目的。

在这之间,我们需要了解sql语句的基本用法——[myslq基础学习](https://blog.csdn/qq_44159028/article/details/114327303?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163875545216780269895046%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163875545216780269895046&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-1-114327303.pc_v2_rank_blog_default&utm_term=mysql&spm=1018.2226.3001.4450)

## 二、漏洞危害

SQL注入漏洞对数据安全的影响:

```
数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。网页篡改:通过操作数据库对特定网页进行篡改。
网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
服务器被远程控制,被安装后门:经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
破坏硬盘数据,瘫痪全系统。
```

## 三、注入流程

 1.判断网站是否存在数据库注入漏洞。
        and 1=1 --> 页面有内容 
        and 1=2 --> 页面没有内容
            ==> 推断出该网站存在数据库注入漏洞。
                原因:我们输入的数据库语句,该网站执行。
2.判断字段(列)数 ,order by ,作用:排序。
    ps:一个网站存在数据库注入漏洞,意味着我们输入的数据库语句都会执行。
        order by 1 --> 页面有内容 --> 说明网站的表里面有1列。
        order by 2 --> 页面有内容 --> 说明网站的表里面有2列。
        order by 3 --> 页面没有内容 --> 说明网站的表里面没有3列,只有2列。
    ps:当and被网站过滤的时候,可以使用order by 来判断。
3.判断回显点。union 作用:能够同时执行两条查询语句。关键点:必须保证前后两条查询的语句【列的个数保持一致】。
        回显点:能够将我们输入的数据库语句,执行,并且将执行的结果显示到页面上。
        and 1=2 union select 1,2
 4.查询数据
        version() # 作用:查询版本号。
        database()# 作用:当前数据库库名。

查询表名:

?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_schema=database() limit 0,1

查询列名:
?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 0,1

limit m,n # 从第m+1行开始查询n条数据。  limit 2,2

information_schema 库名,mysql自带的。
tables 表的名字,mysql自带的。 information_schema.tables ,库.表 (指定什么库里面的什么表)
columns 表的名字,mysql自带的。
table_schema 列的名字,存储的是网站管理员创建的库名
table_name 列的名字,存储的是网站管理员创建表的名字
column_name  列的名字 ,存储的是网站管理员创建列的名字
总结来说分为以下几步:

```
一、判断注入点
二、判断字段(列)数
三、判断回显点
四、查询数据  数据库——>表——>列——>列中的数据
```

## 四、SQL注入必备知识

在进行正式的注入前,我们需要了解的知识。

1、数据库的结构:库、表、行、列—(字段)

```
select ··· from ··· where 
        select  翻译:查询
        from  翻译:来自
        where 翻译:条件,当····条件成立的时候
```

2、在mysql5.0以上版本中,MySQL存在一个自带数据库名位information_schema,t它是一个存储记录所有数据库名,表名,列名的数据库,也相当于通过查询它获取指定数据库下面的表名或者列名信息。

## 五、SQL注入简单演示

以sqli-labs为例子,假如我是一名黑客,拿到了sqli-labs这个网站,我的老板要求我查出网站里面存储的用户到底有多少,数据库的名字是什么,版本是多少,甚至我还想改数据库的信息。那我应该怎么做呢?

对于sql注入,目前常用的手段分两种,手工注入和工具注入,这里我们选择手工注入,这样能帮助我们更快的了解。

前面说到了加单引号进行闭合后,在后面插入我们想要查询的语句,这里我们来试一试。

第一步,判断注入点

PS:--+表示注释,这里的作用是注释掉后面的语句,只保留我们插入的语句。

观察两个图的区别,当我们输入and 1=1的时候,由于前面的单引号被闭合,最终sql语句识别到的为 '1' and 1=1 恒为真,正确,输出语句,当输入and1=2时,语句变成了'1' and 1=2 为假。错误,没有返回信息。这里就可以判断这里存在注入点。

试想一下,如何将1=1 换成我们插入的语句,那么我们的注入是否就成功了。 这就sql注入的思路。

第二步,判断字段数

当我们进行到order by 4的时候,页面返回错误,得出字段数为3。

第三步、判断回显点

第四步、查询数据

得到数据库名字。然后依次:数据库——>表——>列——>列中的数据,就不依次演示了。建议感兴趣的同学都去试试。

以上就是一个通关sql注入得到数据库信息的一个过程。

## 六、sql注入防范

解决SQL注入问题的关键是对所有可能来自用户输入的数据进行严格的检查、对数据库配置使用最小权限原则。通常修复使用的方案有:

1、分级管理

对用户进行分级管理,严格控制用户的权限,对于普通用户,禁止给予数据库建立、删除、修改等相关权限,只有系统管理员才具有增、删、改、查的权限。

2、参数传值

程序员在书写SQL语言时,禁止将变量直接写入到SQL语句,必须通过设置相应的参数来传递相关的变量。从而抑制SQL注入。数据输入不能直接嵌入到查询语句中。同时要过滤输入的内容,过滤掉不安全的输入数据。或者采用参数传值的方式传递输入变量,这样可以最大程度防范SQL注入攻击。

3、基础过滤与二次过滤

SQL注入攻击前,入侵者通过修改参数提交and等特殊字符,判断是否存在漏洞,然后通过select、update等各种字符编写SQL注入语句。因此防范SQL注入要对用户输入进行检查,确保数据输入的安全性,在具体检查输入或提交的变量时,对于单引号、双引号、冒号等字符进行转换或者过滤,从而有效防止SQL注入。

当然危险字符有很多,在获取用户输入提交参数时,首先要进行基础过滤,然后根据程序的功能及用户输入的可能性进行二次过滤,以确保系统的安全性。

4、使用安全参数

SQL数据库为了有效抑制SQL注入攻击的影响。在进行SQLServer数据库设计时设置了专门的SQL安全参数。在程序编写时应尽量使用安全参数来杜绝注入式攻击,从而确保系统的安全性。

5、漏洞扫描

为了更有效地防范SQL注入攻击,作为系统管理除了设置有效的防范措施,更应该及时发现系统存在SQL攻击安全漏洞。系统管理员可以采购一些SQL漏洞扫描工具,通过专业的扫描工具,可以及时的扫描到系统存在的相应漏洞。

6、多层验证

现在的网站系统功能越来越庞大复杂。为确保系统的安全,访问者的数据输入必须经过严格的验证才能进入系统,验证没通过的输入直接被拒绝访问数据库,并且向上层系统发出错误提示信息。同时在客户端访问程序中验证访问者的相关输入信息,从而更有效的防止简单的SQL注入。但是如果多层验证中的下层如果验证数据通过,那么绕过客户端的攻击者就能够随意访问系统。因此在进行多层验证时,要每个层次相互配合,只有在客户端和系统端都进行有效的验证防护,才能更好地防范SQL注入攻击。

7、数据库信息加密

上层系统发出错误提示信息。同时在客户端访问程序中验证访问者的相关输入信息,从而更有效的防止简单的SQL注入。但是如果多层验证中的下层如果验证数据通过,那么绕过客户端的攻击者就能够随意访问系统。因此在进行多层验证时,要每个层次相互配合,只有在客户端和系统端都进行有效的验证防护,才能更好地防范SQL注入攻击。

7、数据库信息加密

传统的加解密方法大致分为三种:对称加密、非对称加密、不可逆加密。
 

更多推荐

sql注入详解