zoukankan      html  css  js  c++  java
  • sql注入基础

    sql注入

    • 漏洞的原理
    • 漏洞的利用方式
    • 漏洞的修复

    1. 什么是sql

    [简介]

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

    准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系式数据库管理系统的标准言

    (ANSI X3.135-1986) , 1987年得到国际标准组织的支持下成为国际标准。

    2. 什么是SQL注入

    SQL注入(SQLInjection)是一种常见的web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在

    的数据库漏洞进行攻击。

    [漏洞原理]

    针对SQL注入的攻击行为可描述为通过用户可控参数中注入SQL语法 , 破坏原有SQL结构达到编写程序时意料之外

    结果的攻击行为。

    [原因]

    1. 程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句。
    2. 对用户可控参数未进行足够的过滤便将参数内容拼接进入到SQL语句中。

    页面接收的相关参数未进行过滤限制直接和原有的sql语句拼接然后带入到数据库查询

    sql注入属于服务端攻击,和操作系统,数据库类型,以及脚本语言类型都是无关的,他是程序代码的漏洞

    注入提交的方式:

    根据SQL注入漏洞的原理,在用户可控参数中注入SQL语法,也就是说web应用在获取用户数据的地方,只要

    带入数据库查询,都有存在SQL注入的可能 , 这些地方通常包括 :

    • GET 数据
    • POST 数据
    • HTTP 头部 (HTTP请求报文其他字段)
    • Cookie 数据
    • user-agent
    • referer

    注入点可能存在的页面:

    • 用户登录页面
    • 用户注册页面
    • 用户修改个人信息页面
    • 留言板等一系列与数据库交互的页面都有可能存在sql注入

    [漏洞危害]

    攻击者利用SQL注入漏洞,可以获取数据库中的多种信息(例如︰管理员后台密码),从而脱取数据库中内容

    (脱库)。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据

    库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或者服务器系统权限。mysql数据库可以

    利用mof|udf提权

    3. sql注入分类

    3.1 按照数据类型分类

    SQL注入漏洞根据不同的标准,有不同的分类。但是从数据类型分类来看,SQL注入分为数字型字符型

    [数字型注入]

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

    -- 数字型注入,无单双引号
    select * from user where id=1;  
    

    [字符型注入]

    字符型注入就是说注入点的数据,拼接到SQL语句中是以字符型出现的 , 即数据两边有单引号或双引号包括

    -- 字符型注入,有单或双引号
    select * from user where name = "alex";  
    

    [搜索型注入]

    -- 一般存在于一些搜索框
    select * from user where name  like "%x%";
    

    [xx型注入]

    -- 当不是以上几种类型的注入,你可以尝试一下是否是xx型注入
    select * from user where name  = ("alex")
    

    [补充]

    在sql注入的时候判断是数字型还是字符型注入很重要,因为你要考虑单引号双引号的闭合问题

    在数据库中数据大体可以分为三类,数字型,字符型,时间型,注意不是数据类型的划分

    3.2 按照手法分类

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

    UNION query sQL injection (可联合查询注入) 联合查询,也有人成为union注入

    Error-based sQL injection (报错型注入) 报错注入

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

    Time-based blind sQL injection (基于时间延迟注入) 延时注入

    Stacked queries sQL injection(可多语句查询注入) 堆叠查询 , 可拼接多条语句

    个人总结:以上是按手法分类的四大基本手法,因为以上都是查的操作,而多语句查询更倾向于增删改的操作

    也可以分为三大类,联合查询,报错注入和盲注,联合查询和报错注入能看到数据库的回显,无论是错误信息还是

    正确信息,而布尔盲注和延时注入看不到数据库的回显,只能通过页面的状态分析

    [补充]

    也可以按照注入的位置分类,get注入,post注入以及cookie注入,网上流传的GPC就是指他们三个

    所有的分类都是有交叉的,是从不同的角度划分的

    4. mysql注入相关函数

    既然要探讨SQL注入漏洞,需要对数据库有所了解,此处以mysql为例,这里只是起到抛砖引玉的作用,其他数据

    库环境下的SQL注入,读者可以按照本课程的思路去学习,唯一不同的只是数据库的特性。

    4.1 注释

    -- (杠杠空格)  是大多数据库支持的注释
    #      --->      mysql独有的注释
    
    /*.....*/
    /*! .... */ 内联查询
    

    4.2 元数据

    mysql是一个数据库管理系统,里面存放着很多库,表,字段,对于mysql这些库名表名字段名就是元数据

    这些元数据代表了数据库的结构,mysql数据库会把它存到一个数据库中,即information_schema库

    image-20201215194438892

    在information_schema这个数据库中,tables这个表存储了mysql中所有的表的信息,tables_name字段是表
    名,tables_schema这个字段是指表所属的数据库的名字
    
    columns这个表存储了mysql中所有的字段的信息,columns_name字段是指字段名,tables_name字段是字段所在的表名,tables_schema这个字段是指字段所处的库名
    
    在mysql数据库下有一个user表,里面存放着可以连接数据库的账号和密码
    

    4.3 运算符

    >        <              >=           <=             !=           <>       and     or
    大于     小于     大于等于    小于等于    不等于    不等于     并且    或者
    
    mysql> select 1 > 2;
    +-------+
    | 1 > 2   |
    +-------+
    |     0      |
    +-------+
    1 row in set (0.00 sec)
    
    mysql> select 1 < 2;
    +-------+
    | 1 < 2   |
    +-------+
    |     1     |
    +-------+
    1 row in set (0.00 sec)
    
    mysql> select 1 = 1 and 1 > 3;
    +-----------------+
    | 1 = 1 and 1 > 3 |
    +-----------------+
    |               0          |
    +-----------------+
    1 row in set (0.00 sec)
    
    mysql> select 1 = 1 or 1 > 3;
    +----------------+
    | 1 = 1 or 1 > 3  |
    +----------------+
    |              1          |
    +----------------+
    1 row in set (0.00 sec)
    

    4.4 函数

    version( ) 查看mysql数据库版本

    mysql> select version();+-----------+| version()   |+-----------+| 5.7.26        |+-----------+1 row in set (0.01 sec)
    

    database( ) 查看当前数据库名

    mysql> select database();+------------+| database()  |+------------+| world          |+------------+1 row in set (0.00 sec)
    

    user( ) 查看用户名

    mysql> select user();+----------------+| user()               |+----------------+| root@localhost|+----------------+1 row in set (0.00 sec)
    

    current_user( )查看当前用户名

    mysql> select current_user();+----------------+| current_user()   |+----------------+| root@localhost|+----------------+1 row in set (0.00 sec)
    

    system_user( ) 查看系统用户名

    mysql> select system_user();+----------------+| system_user()  |+----------------+| root@localhos |+----------------+1 row in set (0.00 sec)
    

    @@datadir查看数据路径

    mysql> select @@datadir;+-----------------------------------------------------------------+| @@datadir                                                                             |+-----------------------------------------------------------------+| E:\developTools\tools\phpstudy_pro\Extensions\MySQL5.7.26\data\|+-----------------------------------------------------------------+1 row in set (0.00 sec)
    

    @@basedir查看数据库的安装路径

    mysql> select @@basedir;+--------------------+| @@basedir           |+--------------------+| D:/phpStudy/MySQL/ |+--------------------+1 row in set (0.00 sec)
    

    @@versoin_compile_os查看操作系统版本

    mysql> select @@version_compile_os;+----------------------+| @@version_compile_os |+----------------------+| Win64                        |+----------------------+1 row in set (0.00 sec)
    

    length( )返回字符串的长度

    mysql> select length("1234");+----------------+| length("1234") |+----------------+|              4          |+----------------+1 row in set (0.00 sec)
    

    substring( ),substr( ),mid( )截取字符串

    mysql> select substring("1234",1,2);+-----------------------+| substring("1234",1,2) |+-----------------------+| 12                               |+-----------------------+1 row in set (0.00 sec)mysql> select substr("1234",1,2);+--------------------+| substr("1234",1,2) |+--------------------+| 12                          |+--------------------+1 row in set (0.00 sec)mysql> select mid("1234",1,3);+-----------------+| mid("1234",1,3) |+-----------------+| 123                    |+-----------------+1 row in set (0.00 sec)
    

    left( ) 从左侧开始取指定字符个数的字符串

    mysql> select left("qwerr",2);+-----------------+| left("qwerr",2)    |+-----------------+| qw                      |+-----------------+1 row in set (0.00 sec)
    

    concat( ) 没有分隔符的连接字符串

    mysql> select concat("hell","owrod");+------------------------+| concat("hell","owrod") |+------------------------+| hellowrod                    |+------------------------+1 row in set (0.01 sec)
    

    concat_ws ( )含有分割符的连接字符串

    mysql> select concat_ws("-","hello","word");+-------------------------------+| concat_ws("-","hello","word") |+-------------------------------+| hello-word                             |+-------------------------------+1 row in set (0.00 sec)
    

    ord ( ) ascii( ) 返回ASCII码

    mysql> select ord('a');+----------+| ord('a')     |+----------+|       97      |+----------+1 row in set (0.01 sec)mysql> select ascii("a");+------------+| ascii("a")     |+------------+|         97       |+------------+1 row in set (0.00 sec)
    

    char( ) 返回ascii码对应的字符

    mysql> select char(97);+----------+| char(97)   |+----------+| a              |+----------+1 row in set (0.01 sec)
    

    hex( ) 将10进制转换为十六进制

    mysql> select hex(17);+---------+| hex(17)  |+---------+| 11          |+---------+1 row in set (0.00 sec)
    

    md5( ) 返回MD5值

    mysql> select md5("admin");+----------------------------------+| md5("admin")                            |+----------------------------------+| 21232f297a57a5a743894a0e4a801fc3 |+----------------------------------+1 row in set (0.01 sec)
    

    floor(x) 返回不大于x的最大整数

    mysql> select floor(5);+----------+| floor(5)    |+----------+|        5       |+----------+1 row in set (0.01 sec)
    

    round( ) 返回参数×接近的整数,四舍五入

    mysql> select round(4.4);+------------+| round(4.4) |+------------+|          4        |+------------+1 row in set (0.00 sec)
    

    group_conat( ) 连接一个组的字符串

    mysql> select group_concat(id) from city where id < 10;+-------------------+| group_concat(id)  |+-------------------+| 1,2,3,4,5,6,7,8,9     |+-------------------+1 row in set (0.00 sec)mysql> select group_concat("id","user","password");+--------------------------------------+| group_concat("id","user","password") |+--------------------------------------+| iduserpassword                               |+--------------------------------------+1 row in set (0.01 sec)
    

    rand ( ) 返回0-1之间的随机浮点数

    mysql> select rand();+--------------------+| rand()             |+--------------------+| 0.4978868081214715 |+--------------------+1 row in set (0.01 sec)mysql> select left(rand(),3);    -- 随机一个小数,并保留小数点后一位+----------------+| left(rand(),3) |+----------------+| 0.9            |+----------------+1 row in set (0.00 sec)
    

    load_file( ) 读取文件,并返回文件内容作为一个字符串

    mysql> select load_file("/tmp/a.txt");+--------------------------+| load_file("/tmp/a.txt") |+--------------------------+| hello                    |+--------------------------+1 row in set (0.00 sec)
    

    @@secure_file_priv 查看读写文件的范围

    MYSQL新特性secure_file_priv对读写文件的影响 此开关默认为NULL,即不允许导入导出。secure_file_priv 为空是 的时候 方可读写 由于这个参数不能动态更改,只能在mysql的配置文件mysql.ini中的[mysqld]中进行修改,然后重启生效。 可以通过命令查看这个属性

    mysql> select @@secure_file_priv;+--------------------+| @@secure_file_priv |+--------------------+|                               |+--------------------+1 row in set (0.00 sec)secure_file_priv 为空可以在任意路径下读写文件
    

    写入一句话木马

    select "<?php @eval($_POST['pass']);?>" INTO OUTFILE "D:\Wamp\2.php"
    

    into outfile 写文件,把一个字符串写进一个文件中 , 注意gpc是否开启 , 开启会转义特殊字符 ' --> \'

    sleep( ) 睡眠时间为指定的秒数

    if(true,t,f) if判断

    find_in_set( ) 返回字符串在字符串列表中的位置

    benchmark( )指定语句执行的次数

    name_const( )返回表作为结果

    5. 注入流程

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

    候,也依据这样的顺序。首先获取数据库名,其次获取表名,然后获取字段名,最后获取数据。

  • 相关阅读:
    C++11常用特性的使用经验总结
    Websocket协议的学习、调研和实现
    高性能后台服务器架构设计
    Linux下ping命令、traceroute命令、tracert命令的使用
    docker-4-Dockerfile配置文件详解
    Docker 国内仓库和镜像
    centos7.0查看IP
    tomcat报错:This is very likely to create a memory leak问题解决
    windows 环境下搭建docker私有仓库
    Docker 修改镜像源地址
  • 原文地址:https://www.cnblogs.com/xcymn/p/15721570.html
Copyright © 2011-2022 走看看