SQL Injection

Posted by Tattoo on 2019-01-03
Estimated Reading Time 8 Minutes
Words 2.2k In Total
Viewed Times

认识SQL注入漏洞


  • 漏洞介绍:

  SQL注入漏洞可以说是在企业运营中会遇到的最具破坏性的漏洞之一,它也是目前被利用得最多的漏洞。要学会如何防御SQL注入,首先要对它的原理进行了解。

  SQL注入 (SQL Injection)是这样一种漏洞:当我们的Web app向后台数据库传递SQL语句进行数据库操作时。如果对用户输入的参数没有经过严格的过滤处理,那么恶意访问者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。通过构造特殊的输入作为参数插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作。用户输入的内容直接用来构造动态SQL命令或作为存储过程的输入参数。

  • 漏洞危害:
      1.直接就造成数据库中的数据泄露
      2.如果数据库连接用户具备高权限,可能导致恶意访问者获取服务器控制权
      3.众多安全事件的切入点

  • SQL注入分类:
      数字型:在MySQL语句中数字型不需要闭合
      字符型:在MySQL语句中,如果字符是字符串格式则需要考虑闭合和注释

寻找SQL注入点

  • 无特定目标:
      inurl:.php?id=  (.php/.jsp/.asp/…)

  • 有特定目标:
      inurl:.php?id=  site:target.com(目标域名)

  • 工具爬取:
      spider,对搜索引擎和目标网站的链接进行爬取

注入识别

  • 手工简单识别:
      ’ (单引号)  —报错
      and 1=1 / and 1=2
      and ‘1’=’1 / and ‘1’=’2
      and 1 like 1 / and 1 like 2

  • 工具识别:
      sqlmap -m filename (filename中保存检测目标,批量检测网址)
      sqlmap –crawl (sqlmap对目标网站先进行爬取,再进行注入测试)

  • 高级识别:
      扩展识别广度和深度:
        sqlmap –level 增加测试级别,对header中的参数也进行测试
        sqlmap -r filename (filename中为网站请求头数据)

    利用工具提高识别效率:
       bp + sqlmap

tips:
  可以在参数后键入星号(*)来确定想要测试的参数
  e.g. :id=1*&user=tattoo,即测试参数id

思考可能出现注入的点:新闻、登陆、搜索、留言,站在开发的角度寻找

代码审计

  • 搜索关键代码和函数:
      select 语句   —-从中反过来找参数,倒序审计
      获取的外部参数GET、POST、REQUEST   —-正序审计

  • 梳理业务流程

MySQL数据库结构

  MySQL版本大于5.0时,有个默认数据库information_schema,它提供了访问数据库元数据的方式。里面存放着所有数据库的信息(比如表名、 列名、对应权限等),通过这个数据库,我们就可以跨库查询,爆表、爆列等操作。
  在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。

information_schema数据库表说明:

SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。

TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。

COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。

SQL注入流程

  • 信息搜集:
      数据库类型 –根据报错信息判断
      数据库版本 –函数version()、@@version、v$version判断
      数据库用户 –内置函数user()、SYSTEM_USER()
      数据库权限 –内置函数suoer_priv、IS_SRVROLEMEMBER

  • 数据获取:
      语句查询:
      获取字段数
      获取库信息
      获取表信息
      获取列信息
      获取数据

  • 暴力破解:
      特别的Access数据库:
        先判断表是否存在 select [*] from system
        再判断列是否存在 select [username] from system

  • 权限提升:
      执行命令 –利用高权限 sa等 xp.cmdshell、–os-shell(sqlmap)
      读文件 –低权限时,读中间件、数据库配置文件
      写文件 –写webshell到网站目录 即–os-shell sqlmap将webshell写入网站目录,直接执行命令

MySQL手工注入方法

  • 核心原理:
      MySQL内置的information_schema库,功能强大,是我们进行MySQL注入的基石!

  • 查询数据核心语法:

查库:

1
select schema_name from information_schema.SCHEMATA

查表:

1
select table_name from information_schema.TABLES where TABLE_SCHEMA=数据库(十六进制)

查列:

1
select column_name from information_schema.COLUMNS where TABLE_NAME=表名(十六进制)

查数据:

1
select 列名 from database_name.table_name

其中,库名和表名可用十六进制代替,防止拦截


tips1:
  所有类型的sql注入,都是基于查库、表、列语句

tips2:
  如果数据太多,导致无法的返回查询结果:
    1.查询的场景:可利用limit限定返回的数量以及位置,依次查询 limit 0,1 、limit 1,1、limit x,1,每次查询一个
    2.回显数据的场景:concat()函数连接多个数据成为一条返回结果

tips3:
  在一些场景中,想要快速获取数据,利用工具辅助,如bp、sqlmap

MySql注入常用函数

  • 常用函数:
    system_user() 系统用户名
    user() 用户名
    current_user() 当前用户名
    session_user() 连接数据库的用户名
    database() 数据库名
    version()、@@version 数据库版本
    @@datadir 数据库路径
    @@basedir 数据库安装路径
    @@version_compile_os 操作系统
    count() 返回执行结果数量

    concat() 没有分隔地连接字符串
    concat_ws() 含有分隔符地连接字符串,第一个参数指定连接符(可用十六进制)
    group_concat() 连接一个组的所有字符串,并以逗号分隔每一条数据
    load_file() 读取本地文件

  • -select load_file(‘/路径’) into outfile 写文件

  • -select ‘文件内容’ into outfile ‘/路径’ ascii() 将某个字符转换为ascii值
    ord() 返回字符串第一个字符的ascii值
    mid(‘mysql’,1,1) 返回一个字符串的一部分
    substr() 返回一个字符串的一部分
    length() 返回字符串的长度

    left() 返回字符串的最左边几个字符
    floor(x) 返回小于或等于x的最大整数(向下取整)
    rand() 返回0-1之间的一个随机数
    extravalue(1,XPath) 从目标XML中返回包含所查询值的字符串
    updatexml(1,XPath,1) 改变文档中符合条件的节点的值

    sleep() 让此语句运行N秒
    if() 类似三目运算符 ?:
    char() 返回整数ascii代码字符组成的字符串
    STRCMP() 比较字符串内容,返回-1、0、1
    IFNULL() 假如参数1不为NULL,则返回值为参数1,否则其返回值为参数2
    exp() 返回e的x次方

  • 比较运算符:
    between and 在…之间
    in 包含
    like 模式匹配
    regexp 正则表达式

  • 逻辑运算符:
    &&或AND 与 (有假即假)
    ||或OR 或 (有真即真)
    !或NOT 非
    XOR 异或

万能密码登陆

登陆处的SQL语句:select * from users where username=’admin’ and pwd=’pass’;

万能密码: ‘ or ‘1’=’1
username=’’、pwd=’’:值为空,FALSE

select * from users where username=’’ or ‘1’=’1’ and pwd=’’ or ‘1’=’1’;
              FALSE or TRUE | |     ||
                 TRUE     and FLASE  ||
                      FLASE     or  TRUE ==》TRUE

总结

  本文介绍了SQL Injection的基本原理和MySQL数据库的架构,虽然大多数网站都会把漏洞补上或者部署WAF,看似严防死守,但百密一疏,有输入的地方就有危险,没有绝对的安全。


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !