0


【SQL注入漏洞-01】SQL注入漏洞原理及分类

SQL注入简介

结构化查询语言(Structured Query Language,缩写︰SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。

SQL注入(SQL Injection)是一种常见的Web安全漏洞,主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱库、被删除、甚至整个服务器权限陷)。

  • sql注入在安全问题中排行第一

  • sql注入攻击是输入参数未经过滤,然后直接拼接到sql语句当中解析

  • sql注入是一种将sql代码添加到输入参数中,传递到服务器解析并执行的一种攻击手法

注入流程:由于关系型数据库系统,具有明显的库/表/列/内容结构层次,所以我们通过SQL注入漏洞获取数据库中信息的时候,也依据这样的顺序。首先获取库名,其次获取表名,然后获取列名,最后获取数据。

SQL注入原理

web应用程序在接收相关数据参数时未做好过滤,直接将其带入到数据库中查询,从而攻击者可以拼接执行构造的sql命令,导致了sql注入的发生。其成因可以归结外以下原因叠加造成的:

  1. 攻击者在页面提交恶意字符(例如单引号、空格、1=1等)

  2. 服务器未对提交参数进行过滤或过滤不足

  3. 攻击者利用拼接sql语句方式获取数据库敏感信息

SQL注入危害

攻击者利用SQL注入漏洞,可以获取数据库中的多种信息(例如︰管理员后台密码),从而脱取数据库中内容(脱库)。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell(脚本木马,是通过服务器开放的端口获取服务器的某些权限)或者服务器系统权限

  • 获取web网页数据库--数据泄露

  • 用户数据被非法买卖

  • 危害web应用安全

sql注入分类

sql注入漏洞根据不同的标准,有不同的分类。

从数据类型分类来看,sql注入分为数字型和字符型。

数字型注入:注入点的数据,拼接到sql语句中是以数字型出现的,即数据两边没有被单引号、双引号包括。

字符型注入:注入点的数据两边有单引号、双引号括起来

根据注入手法分类,大致可分为以下几个类别:

  • UNION query SQL injection (可联合查询注入) union联合查询注入

  • Error-based SQL injection(报错型注入) 报错注入 这两种属于正常注入

  • Boolean-based blind SQL injection(布尔型注入) 布尔盲注

  • Time-based blind SQL injection(基于时间延迟注入) 延时注入 这两种属于盲注类别

  • Stacked queries SQL injection(可多语句查询注入) 主要目的是增删改,也叫堆叠查询

  1. union查询注入:union查询注入是最基础的注入。在SQL中, UNION 操作符用于合并两个或多个 SELECT 语句的结果。union 查询注入利用 UNION 关键字可以追加一条或者多条额外的 SELECT 查询,并将结果追加到原始查询中

  2. 报错注入:攻击者在攻击时常根据错误回显进行判断,都是现在很多web应用程序没有正常得错误回显,我们就需要利用报错注入来进行sql注入

  3. 盲注:指的是在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入,主要分为基于布尔的盲注和基于时间的盲注

  4. 堆叠查询注入:堆叠查询注入为攻击者提供了很多的攻击手段,通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的

根据提交数据的位置进行分类:

可以分为get注入、post注入、cookie注入 GPC

sql注入点存在位置

根据SQL注入漏洞的原理,在用户“可控参数"中注入SQL语法,也就是说web应用在获取用户数据的地方,只要带入数据库查询,都有存在SQL注入的可能,这些地方通常包括:

  • GET 数据

  • POST 数据

  • HTTP 头部(HTTP 请求报文其他字段)

  • Cookie 数据

SQL注入点的判断

变换id参数

?id=1 变换id参数+1/-1,前提是有sql注入漏洞,页面发生变化则考虑为联合查询

也就是说,数据库中的内容会回显到网页中来。

初步判定,id参数会带入数据库查询,根据不同的id查询数据库,得到不同的网页内容。

猜测后台执行的SQL语句大致结构为:

select * from tbName where id=1;

单引号

【?id=1'】 判断sql注入类型,是字符型还是数字型

执行的SQL主语则变为

select * from tbName where id=1'

(报错显示有1是字符型注入,未显示1则是数字型注入)

页面报错,并且报错信息会回显在页面中,报错信息如下:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1 

错误信息提示单引号位置出现错误,由此说明,SQL语句是由单引号包裹的

因此,此注入点(可能)为字符型注入。

【and 1=1】

[?id=1' and 1=1 --+]

可能得SQL语句为

select * from tbName where id=1' and 1=1 --+

页面正常。

【and 1=2】

[?id=1' and 1=2 --+]

可能得SQL语句

select * from tbName where id=1' and 1=2 --+

页面没有内容,并且数据库没有报错。由于1=2是恒假式,也就是查询条件[where id=35and 1=2--+]恒假,这样的SQL语句在数据库中执行后,没有返回结果,没有网页内容。

反过来看,页面没有内容,也就是SQL语句查询条件为假。也就是说,我们写的语句[and1=2 --+],起到了将查询条件置为假的作用。

那么,可以通过构造语句来控制SQL语句的查询结果并且,SQL语句查询条件真假性,在页面回显中有体现。

?id=35 and 1=1               是否有布尔类型的状态(如果是布尔类型的状态,则
?id=35 and 1=2               这两次页面的状态不同,如果相同则没有布尔类型 )  
select * from tbName where id=35 and 1=1         True
select * from tbName where id=35 and 1=2         False

【and sleep(5)】

[?id=1' and sleep(5)] 是否有延时响应

注入sleep(5)语句,可以通过网络时间线看到延时。

说明sleep(5)语句起到了作用

综上,此连接存在SQL注入漏洞(除了变换id参数之外,其他判断条件出现其中任意一个,则存在sql注入)。

SQL语句

结构化查询语言(Structured Query Language)简称SQL,1974年由Boyce和Chamberlin提出,是一种关系型数据库查询的标准编程语言,用于存取数据以及查询、更新、删除和管理 关系型数据库。为什么强调标准语言?我们知道关系型数据的主要三大实现者分别是,Mysql,MS SQLServer,Oracle。

它们实现数据存储的底层引擎或许不同,但提供出来管理数据的编程语言必须遵循 SQL 规范,但可以定制添加属于自己的额外语法,这些额外的、SQL 之外的语法又被称作它们各自的『SQL方言』。

所以如果你拿着 SqlServer 的方言跑到 Mysql 里去执行,那很大程度上是会报错的。因为sqlserver和mysql虽然都遵循着sql规范,但是它们又添加了属于自己的语法。所以语法是有区别的

关系型数据库系统:具有非常明显的层次结构,库名/表名/字段名/字段内容.

MySQL注释

MySQL数据库注释大概有以下几种:

  • --(杠杠空格) (注入中经常用到的)

  • /* ..... */

  • /*! .... */ 内联查询

MySQL基础详情——>MySQL基础

MySQL元数据库information_schema

MySQL 5.0版本之后产生了一个虚拟数据库information_schema,在这个数据库中有三个很重要的表:

information_schema: 该数据表存储了mysql数据库中的所有数据库的库名

information_schema.tables: 该数据库存储了mysql数据库中的所有数据库的表名

information_schema.columns: 该数据库存储了mysql数据库中的所有列的列名

MySQL常用函数与参数

=/>/>=/<=/<> 例:select 1<>2;        比较运算符(等于、大于、大于等于、小于等于、不等于)
and(&/&&/与运算)/or(|/||/或运算)   逻辑运算符(例:select true and false;)
select version()                        返回MySQL数据库版本
select database()                       返回当前数据库名
select user()                           返回用户名
select current_user()                   返回当前用户名
select system_user()                    返回系统用户名
select @@datadir                          返回数据库路径                                                  
select @@version_compile_os               返回操作系统版本
select length()例:select('123456');    返回字符串的长度{例:select length(database());}

select substring()                         返回截取字符串
substr()例:select substr(database(),1,1)   截取字符串{例:select substr(database(),1,1)
mid()                                      截取字符串
                      1.截取的字符串
                      2.截取起始位置,从1开始计数
                      3.截取长度

left()例:select left("123456",4);                    从左侧开始取指定字符个数的字符串
concat()例: select concat('a','b','c');                没有分隔符的连接字符串
concat_ws()例:select concat_ws("-",'a','b','c');       含有分隔符的连接字符串
group_conat()例:select group_conat(id) from student;  连接一个组的字符串
select ord()例:select ord('a');          返回ASCII码
select rand()例: select rand();          返回0-1之间的随机浮点数 最近的那个整数
           select left(rand(),3);
hex()                             将字符串转换为十六进制
unhex()                           hex的反向操作
select md5()                             返回MD5值
select floor(x)                          返回不大于x的最大整数 向下取值
select round()                           返回参数x接近的整数
load_file(文件的绝对路径)            读取文件,并返回文件内容作为一个字符串
sleep()例:select sleep(5);         睡眠时间为指定的秒数
if(true,t,f)例:select if(true,1,2);   if判断
select find_in_set()                       返回字符串在字符串列表中的位置
benchmark()                       指定语句执行的次数
select name_const()                        返回表作为结果

@逻辑运算

在SQL语句中逻辑运算与(and)比或(or)的优先级高

【select 1=2 and 1=2 or 1=1;】

注入流程:

由于关系型数据库系统,具有明显的库/表/列/内容结构层次,所以我们通过SQL注入漏洞获取数据库中信息时候,也依据这样的顺序

首先获取数据库名,其次获取表名,然后获取列名,最后获取数据。

sql注入中的常见函数汇总

ascii(str) :                     返回给定字符的ascii值     如 ascii("a")=97
length(str) :                    返回给定字符串的长度,如  length("string")=6
 
substr(string,start,length)      对于给定字符串string,从start位开始截取,截取length长度 ,如  substr("chinese",3,2)="in"
 
substr()、stbstring()、mid()      三个函数的用法、功能均一致
 
concat(username):                将查询到的username连在一起,默认用逗号分隔
  
group_concat(字段1,'*',字段2):   将字段1和字段2的数据查询到一起,中间用*连接
count(table_name)                 返回表的个数
 
if(expr1,expr2,expr3)             如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。
标签: mysql sql 数据库

本文转载自: https://blog.csdn.net/2301_76334474/article/details/128833537
版权归原作者 百事都可樂. 所有, 如有侵权,请联系我们删除。

“【SQL注入漏洞-01】SQL注入漏洞原理及分类”的评论:

还没有评论