diff --git a/content/generated/metas.json b/content/generated/metas.json index 2fc787c..5e5852b 100644 --- a/content/generated/metas.json +++ b/content/generated/metas.json @@ -3,12 +3,12 @@ "categories": [["置顶", 1], ["技术", 1], ["日记", 2], ["梦", 1], ["想想想", 1], ["影评", 1]], "pins": [12], "posts": [ - {"id": 12, "title": "部落格索引", "subtitle": "按分类、标签检索", "category": "置顶", "pinned": 1, "file": "content/posts/Index.md", "tags": [], "date": "2024-08-06T05:24:10.792080", "url_name": "Index", "content": "按分类检索:\n\n\n\n按主题检索:\n\n"}, - {"id": 11, "title": "示波器破解移动光光猫", "title_image": "https://profile-content.hydev.org/content/posts/Assets/2024-07-30%20%E5%85%89%E5%85%89%E7%8C%AB/IMG_20240730_100300.avif", "subtitle": "跑不掉了喵~", "tags": ["ctf"], "file": "content/posts/2024-07-30 光光猫.md", "date": "2024-07-30T00:00:00", "url_name": "2024-07-30-光光猫", "content": "今天去 syama 家帮忙破解了移动光光猫 🐱\n\n因为笔记本太重了,syama 想要在外面用 iPad 远程桌面直连到家里的笔记本上工作,但是移动光猫有防火墙 ipv6 没办法直连,而且用户配置界面并没有办法关掉防火墙,所以想要找到 CMCCAdmin 超管密码。\n\n通常来说超管密码直接找宽带师傅要或者找移动内鬼查就能查到,但是这台是公寓提供的集客宽带所以没办法联系师傅,内鬼也查不到密码。\n\n去网络论坛上看了其他人的破解方法,一月份的时候似乎还可以通过 192.168.1.1/hidden_version_switch.html 之类的网页后门直接开启 telnet,但是试了很多全都被堵住了。看来软件是没办法了,拆机看看\n\n
拆机后的完整布局
\n\n光光猫型号是 SK-D747,拆机之后看到了这个 PCB 的完整布局,中间是铠侠的 128MB E2PROM,旁边有八个测试孔,左侧是光纤接入口(系统里是一个 PCIe 设备...??)右边应该是 CPU 和 DDR3 DRAM,上边是两个 LDO 分别转 3.3V 和 5V,右上方还有一些空的焊盘应该是高配版多出来的网口。\n\n
发现了 E2PROM 芯片旁边的八个测试引脚
\n\n在 E2PROM 旁边的这八个测试孔,四个焊了排针,四个没焊。通常光猫上都会留用来测试的 UART 串口,但是串口只能够用到 TX RX GND 三条线,TX 用来向对方发送,RX 用来接收,GND 作为判断传输电压的参照物。排针上显然并没有文档,没有标记每个引脚代表什么,还可能是 RS232,I2C,或者 SPI 也说不定,那要怎样判断每个测试孔代表着什么呢?\n\n先断电用电表测试线路接通的模式戳一戳好了,因为一条线路的所有焊点都连在一起,所以只要确认了一个点就可以找到所有了。首先 GND(地线)是最容易找到的,因为元件的外壳通常就会接到 GND。把电表的一端点到 USB 口的金属外壳上,另一端轮流点一下每个测试孔就能看出从上面数的口 0、4、7 都是接地。\n\n接下来还剩五个不确定的孔,通电测一下电压好了。孔 1 是 5V,孔 5 是 3V,6 是 0.074V。只看电压其实不是很有头绪呢,把照片发到嵌入式群里,群友猜 5 6 分别是 TX 和 RX,但是插上串口工具发现并没有输出,反过来也没有。\n\n
电表针好长感觉不注意就会把什么戳短路
\n\n突然想到,既然之前买了示波器就试试用示波器看看这些孔的波形好了!虽然之前没有用过但是也不会太难理解吧?打开包装有一个主机和两根测笔,像电表一样,那一定是在测量这两根针之间的波形吧?一根戳上 GND 另一根戳上测试点,点一下自动... 不对啊,看上去无论点哪里都是一个正弦 ~ 波?这看起来也不像是时钟啊?\n\n...然后把照片发给群友问问,发现我完全理解错了(悲)测量到的波形也只是无线电噪音 \n\n实际上示波器的每根测笔是单独的波形,有两条线,侧边的夹子是电压的参照,而测针是相对的信号。读结果的时候也理解错了,虽然看上去是很大幅度的正弦波,但是右边显示着只有 5mV/格... 也就是说看到的这个波形上下差距一共不到 10mV,对于任何信号传输都太小了。居然这么小的电压区别也能测量出来哇\n\n学会使用示波器之后把示波器夹子接地,针点到每个引脚,调到 1V/格 的显示比例,发现脚 2 是稳定 3V,脚 3 有零到 3V 的 TTL 高低电平切换,由此推断 2 3 才是 TX 和 RX。这次接上 UART 终于看到日志输出了!\n\n
用示波器看到了上下切换的数据电平,高低电压分别代表 1 和 0
\n\n接上之后就交给 menci 了。重启路由器,终端打了很多日志,似乎是 uboot 在启动被运营商魔改的 OpenWRT。等开机结束之后导出日志,在里面搜索 \"pwd\" 找到了 root 密码 🌚 真安全。登录进 root 之后去读文件 /userconfig/cfg/db_user_cfg.xml 就拿到了超管密码,然后我累累睡睡,menci 念一串魔法配好了桥接和公网 v6 直通,好厉害\n\n
躺在床上听着魔法少女 menci 调网咒语 ASMR 睡着了
\n\n配网相关的事情可以右转去读读 [menci 的博客](https://blog.men.ci/),虽然我也想学学配 ipv6 但是这两天通宵爆肝实在没有力气啦,等加拿大 Bell 有了 ipv6 再学学好了。\n\n总之这次学会了用示波器很开心!~~会用之后就看到什么都想用示波器点一点了~~"}, + {"id": 12, "title": "部落格索引", "subtitle": "按分类、标签检索", "category": "置顶", "pinned": 1, "file": "content/posts/Index.md", "tags": [], "date": "2024-08-06T06:06:08.343977", "url_name": "Index", "content": "按分类检索:\n\n\n\n按主题检索:\n\n"}, + {"id": 11, "title": "示波器破解移动光光猫", "title_image": "https://profile-content.hydev.org/content/posts/Assets/2024-07-30%20%E5%85%89%E5%85%89%E7%8C%AB/IMG_20240730_100300.avif", "subtitle": "跑不掉了喵~", "tags": ["ctf"], "file": "content/posts/2024-07-30 光光猫.md", "date": "2024-07-30T00:00:00", "url_name": "2024-07-30-光光猫", "content": "今天去 syama 家帮忙破解了移动光光猫 🐱\n\n因为笔记本太重了,syama 想要在外面用 iPad 远程桌面直连到家里的笔记本上工作,但是移动光猫有防火墙 ipv6 没办法直连,而且用户配置界面并没有办法关掉防火墙,所以想要找到 CMCCAdmin 超管密码。\n\n通常来说超管密码直接找宽带师傅要或者找移动内鬼查就能查到,但是这台是公寓提供的集客宽带所以没办法联系师傅,内鬼也查不到密码。\n\n去网络论坛上看了其他人的破解方法,一月份的时候似乎还可以通过 192.168.1.1/hidden_version_switch.html 之类的网页后门直接开启 telnet,但是试了很多全都被堵住了。看来软件是没办法了,拆机看看\n\n
拆机后的完整布局
\n\n光光猫型号是 SK-D747,拆机之后看到了这个 PCB 的完整布局,中间是铠侠的 128MB E2PROM,旁边有八个测试孔,左侧是光纤接入口(系统里是一个 PCIe 设备...??)右边应该是 CPU 和 DDR3 DRAM,上边是两个 LDO 分别转 3.3V 和 5V,右上方还有一些空的焊盘应该是高配版多出来的网口。\n\n
发现了 E2PROM 芯片旁边的八个测试引脚
\n\n在 E2PROM 旁边的这八个测试孔,四个焊了排针,四个没焊。通常光猫上都会留用来测试的 UART 串口,但是串口只能够用到 TX RX GND 三条线,TX 用来向对方发送,RX 用来接收,GND 作为判断传输电压的参照物。排针上显然并没有文档,没有标记每个引脚代表什么,还可能是 RS232,I2C,或者 SPI 也说不定,那要怎样判断每个测试孔代表着什么呢?\n\n先断电用电表测试线路接通的模式戳一戳好了,因为一条线路的所有焊点都连在一起,所以只要确认了一个点就可以找到所有了。首先 GND(地线)是最容易找到的,因为元件的外壳通常就会接到 GND。把电表的一端点到 USB 口的金属外壳上,另一端轮流点一下每个测试孔就能看出从上面数的口 0、4、7 都是接地。\n\n接下来还剩五个不确定的孔,通电测一下电压好了。孔 1 是 5V,孔 5 是 3V,6 是 0.074V。只看电压其实不是很有头绪呢,把照片发到嵌入式群里,群友猜 5 6 分别是 TX 和 RX,但是插上串口工具发现并没有输出,反过来也没有。\n\n
电表针好长感觉不注意就会把什么戳短路
\n\n突然想到,既然之前买了示波器就试试用示波器看看这些孔的波形好了!虽然之前没有用过但是也不会太难理解吧?打开包装有一个主机和两根测笔,像电表一样,那一定是在测量这两根针之间的波形吧?一根戳上 GND 另一根戳上测试点,点一下自动... 不对啊,看上去无论点哪里都是一个正弦 ~ 波?这看起来也不像是时钟啊?\n\n...然后把照片发给群友问问,发现我完全理解错了(悲)测量到的波形也只是无线电噪音 \n\n实际上示波器的每根测笔是单独的波形,有两条线,侧边的夹子是电压的参照,而测针是相对的信号。读结果的时候也理解错了,虽然看上去是很大幅度的正弦波,但是右边显示着只有 5mV/格... 也就是说看到的这个波形上下差距一共不到 10mV,对于任何信号传输都太小了。居然这么小的电压区别也能测量出来哇\n\n学会使用示波器之后把示波器夹子接地,针点到每个引脚,调到 1V/格 的显示比例,发现脚 2 是稳定 3V,脚 3 有零到 3V 的 TTL 高低电平切换,由此推断 2 3 才是 TX 和 RX。这次接上 UART 终于看到日志输出了!\n\n
用示波器看到了上下切换的数据电平,高低电压分别代表 1 和 0
\n\n接上之后就交给 menci 了。重启路由器,终端打了很多日志,似乎是 uboot 在启动被运营商魔改的 OpenWRT。等开机结束之后导出日志,在里面搜索 \"pwd\" 找到了 root 密码 🌚 真安全。登录进 root 之后去读文件 /userconfig/cfg/db_user_cfg.xml 就拿到了超管密码,然后我累累睡睡,menci 念一串魔法配好了桥接和公网 v6 直通,好厉害\n\n
躺在床上听着魔法少女 menci 调网咒语 ASMR 睡着了
\n\n配网相关的事情可以右转去读读 [menci 的博客](https://blog.men.ci/),虽然我也想学学配 ipv6 但是这两天通宵爆肝实在没有力气啦,等加拿大 Bell 有了 ipv6 再学学好了。\n\n总之这次学会了用示波器很开心!~~会用之后就看到什么都想用示波器点一点了~~"}, {"id": 10, "title": "Maimai 街机音游逆向!", "subtitle": "从拆包到脱壳到魔改遇到的各种坑", "tags": ["ctf"], "file": "content/posts/2023-11-30 Maimai Reversing.md", "date": "2023-11-30T00:00:00", "url_name": "2023-11-30-Maimai-Reversing", "content": "不久之前某位朋友拿到了最新最热的 maimai DX 某版本的 .app 镜像,然后和ta一起折腾了几天拆包脱壳之后终于成功启动了!在这里简单写一下解包过程和学到的事情,作为记录也作为一个教程吧,希望之后尝试解包的人不需要踩同样的坑了。\n\n## 0x1 解压 .app 包\n\n首先,朋友拿到的文件是一个 .app,通常在官方渠道中通过 U 盘或者网络下发给官方的街机框体,这也是所有 Sega 游戏都在用的传统格式。解压起来也已经有工具和教程。首先 .app 是使用 AES128 加密的,是一个对称密钥加密算法,然而已经有人帮忙把真正街机上的密钥复制出来了,接下来就是按教程解密啦,工具和教程都在[这个仓库](https://gitdab.com/SEGA/sega/src/branch/master/tools/Filesystem)里面。\n\n解密之后是一个两层的 VHD 文件。第一层似乎文件元信息是坏的,大部分硬盘工具分区工具解压工具都打不开,不过试了各种方案发现在 Linux 上用 qemu-nbd 可以挂载,虽然会报错。挂载用了下面那一串指令,之后把 /mnt 里面的第二层 VHD 拷出来就可以直接用 7zip 解压了。\n\n```sh\nsudo modprobe nbd\nsudo qemu-nbd -c /dev/nbd0 \"outer.vhd\"\nsudo mount /dev/nbd0 /mnt\n# /mnt 里面应该有 internal_{N}.vhd\n```\n\n下面分别是两层 VHD 的文件头和 file 信息,`conectix` 开头的是第二层,`eb5290 NTFS` 开头的是第一层(以下用旧版中二节奏举例):\n\n\n\nqemu-nbd 加载了第一层之后连 fdisk 都是懵的,即使是这样乱来也能挂载上也真是好神奇:\n\n\n\n## 0x2 Crackproof 脱壳\n\n解开 .app 包之后脱壳反而是最难的步骤,因为没有找到任何针对 SEGA 街机的脱壳教程(所以我才在写这篇教程!)解压好文件之后发现直接运行会闪退,为什么呢?用文件识别工具 [DIE (detect it easy)](https://github.com/horsicq/Detect-It-Easy) 检测一下发现主程序 Sinmai.exe 被一个叫 HyperTech Crackproof 的工具加密过 (aka. “Htpac”)。\n\n\n\n啊但是 Sinmai.exe 明明就只是一个 Unity 启动器,Unity 的话所有游戏的启动器都是一样的,让每个游戏不同的是 {Game}\\_Data 里面的 dll 文件,所以我直接去下了一个[开源 GTA 圣安地列斯](https://github.com/GTA-ASM/SanAndreasUnity)然后把启动器拷出来改名成 Sinmai.exe 就可以了!\n\n\n\n...然后还是没法启动,怎么回事呢?用 `diec` 扫描一下目录里面的所有 exe 和 dll 发现还有四个文件是加密过的:\n\n* amdaemon.exe\n* Sinmai\\_Data/Managed/Assembly-CSharp.dll\n* Sinmai\\_Data/Plugins/Cake.dll\n* Sinmai\\_Data/Plugins/amdaemon_api.dll\n\n查了一下,首先我看到 SEGA 工具库里面有一个叫 [DecryptCrackproof](https://gitdab.com/SEGA/sega/src/branch/master/tools/Crackproof/DecryptCrackproofExe64) 的工具,感觉这个尝试起来是最简单的,所以就先用它试了一下。这个工具确实自动解出来了 amdaemon.exe,但是剩下三个 DLL 都失败了,报错说 CRC32 算法的长度 out of range of valid values。\n\n\n\n看着这个报错,第一眼觉得应该是这个算法实现的问题,毕竟从 stack trace 可以看出传给 CalcChecksum 的参数是 UInt32,而 CRC32 函数接收的参数是 Int32... 会不会是长度超了 Int32 的最高值呢?所以就用 DotPeek 反编译、导出项目重新编译再 Debug 饶了一大圈,然后发现并不是长度超过 Int32 最高值,而是超过了整个文件的长度... 而请求长度又是一串非常不标准的计算算出来的,看来应该是 HyperTech 他们换了加密算法,并不是改一两行就能修好的。\n\n\n\n接下来有点没有头绪,到处查查也没有查到有用信息,有一个 [iatrepair](https://github.com/rakisaionji/iatrepair) 仓库的脱壳思路是开一个 QEMU 有 2GB 内存的 VM 里面跑游戏,等游戏加载完之后把整个系统的内存 dump 出来再解包分析... 感觉这个方法好灵车,而且这个加密也会检测系统是不是 VM。\n\n接下来去群里问了问,群友给我了一份街机系统上会有的 odd.sys 驱动,用 OSRLoader 加载进系统就可以启动游戏了,虽然是黑屏而且不能正常启动 amdaemon。原本以为解密代码在驱动里面,所以先用 IDA Pro 打开驱动看看能不能提取出来,但是发现似乎只有一些 hashing 的 PID 验证和字符串处理,返回一个处理过的字符串,这样看来这个驱动应该是让用户进程上传识别信息来生成真正解密密钥的工具。\n\n\n\n但是感觉要反汇编找到真正解密的代码再重新实现出来有点太复杂了... 还是试试直接从内存里面找吧。\n\n下载一个 CheatEngine 用来查看内存,然后启动游戏。刚开始发现 CheatEngine 的调试器挂到 Sinmai 进程上会报错,上网查了一下说可以试试在设置的调试器选项里开 DBVM 内核驱动模式,再把 Extras 里面的用内核模式浏览内存选上,然后果然就可以挂了!\n\n\n\n接下来打开内存视图,先看了一遍 Memory Regions 里面标注的 DLL 名,但是似乎没有我想要找的 DLL 的样子。那怎么办呢?看看有没有只属于这个 DLL 的可识别信息吧,用 hexed.it 打开上一代别人解包好的 Assembly-CSharp.dll 发现文件末尾有一串元信息,写着 \"InternalName Assembly-CSharp.dll\",每个字符中间间隔着一个 NULL \\\\0 字符。\n\n\n\n所以我在 CE 内存视图里面搜这段文字然后就找到了!正好只有一个匹配结果。然后记录一下最左边的地址,打开内存区域视图找到这个地址所属的区域,右键把整个区域存下来,然后用 hexed.it 打开把 CE 的文件头去掉(截到 DLL 文件头那里)再把文件尾补到整 32 位,保存改名成 DLL 就可以了!\n\n\n\n之后就只差 Cake.dll 和 amdaemon_api.dll 了,可惜这两个我用同样的方法没有解出来。amdaemon_api 在游戏里并没有加载,而 Cake 是一个包含了依赖的 dll,被拆成了很多不同的内存区域导致让它完整结合回去比较麻烦,但是这两个文件在不同版本中几乎没有改动,所以就直接拿上一个版本别人脱好壳的用了(一般会放在 segatools 文件夹里一起发出来)\n\n## 0x3 魔改\n\n可惜脱完 dll 壳并不是直接就能玩,还要去掉一些街机验证。因为 maimai 是一个 Unity 游戏,是用 C# 写的,而众所周知 .NET 运行时的结构和 Java 差不多都是反编译出来几乎直接是源码的,所以魔改思路就是把 Assembly-CSharp 反编译成源码,改好所有的代码报错,改掉验证然后再编译回去啦。\n\n\n\n...结果还在修报错的时候发现朋友已经魔改完了,所以就先用别人的啦,具体需要做哪些魔改等下次拿到最新最热数据再研究好了 qwq\n\n## 0xF 总结\n\n总之这是我第一次做 Windows 二进制程序脱壳,感觉有别人写好的文档和群友帮忙也没有想象的那么难(以前打 CTF 从来都不敢碰 binary 题的呜呜呜)虽然是朋友先解出来魔改完了有点扫兴,但是学到了很多脱壳技巧还是很开心的!现在就差给 [AquaDX](https://github.com/hykilpikonna/AquaDX) 加服务器支持了...(下次再写 qwq"}, - {"id": 9, "title": "CyberSci 2023 CTF 网安比赛 Writeup", "subtitle": "你是来打网安还是修 Bug 的?🌚", "tags": ["ctf"], "file": "content/posts/2023-11-18 CyberSci Canada Writeup.md", "date": "2023-11-18T00:00:00", "url_name": "2023-11-18-CyberSci-Canada-Writeup", "content": "我解的五道题都是 Defense 分类的,Defense 规则是修好一个服务器端让攻击方的 PoC 脚本失效就能拿分(这不是我维护服务器日常做的事情吗 ;-;\n\n前三道题「CFP」是一套 PhP + Nginx 写的用来上传作业文档的服务器,后两道题「Swag Shop」是一套 Go GIN 写的购物服务器,全都跑在 docker compose 容器里(然而这两个语言我都没用过呜呜呜)\n\n知道问题的时候修一个 bug 很容易,但是 PoC 机并不会告诉你 bug 在哪里,所以解题的第一步是去查 HTTP log 找到被攻击的方法。\n\n## 前三道题 - Call for Presentations\n\n### Attack 1\n\n前三道题的部署结构我真的太熟悉了,因为我自己的所有服务器都是 Nginx + Docker,直接 `tail -f /var/log/nginx/access.log` 读出所有的请求,整理出一个攻击从开始到结束的所有请求,再 `cat /tmp/nginx-req-body/{n}/` 来读出每个请求内容。看一下请求过程如下:\n\n1. 注册一个帐号\n2. 登录这个帐号\n3. 换一个不同的密码登录这个帐号还登进去了??\n\n啊所以难道给我的这套代码登录甚至没有验证密码的吗 (╯’ – ‘)╯︵ ┻━┻\n\n
欣赏一下屎山代码
\n\n看看源代码 lib.php 确实数据库密码验证逻辑写得乱七八糟,数据库直接 string concat,密码甚至没 hash... 好直接让 GPT4 重写了一遍登录和注册这两个函数,然后 PoC 就失效了,拿分拿分 🌚\n\n
GPT4 帮我修好了!
\n\n(不过我至今没弄懂 PhP 要怎样把 log 打到能看到的地方... 打比赛的时候试了几个不同的方法都看不到 log 就算了算了直接把 curl hydev.org/say 写进去了,发到 /say 的东西会转发到我的 Telegram 上hhhh\n\n### Attack 2\n\n第一个好简单。第二个攻击的请求乍一看好像没什么问题,但是仔细看看就会发现 PoC 机注册的帐号的名字和请求提交的 JWT Token 名字不一样然后还莫名过签证验证了... 为什么呢?\n\n
第二个攻击的 Log
\n\n看一眼代码确实,签名居然不是密码学签名,而是直接把请求 JWT 里面的东西 hash 了一遍,验证签名和 hash 相等???🫠 这种客户端能生成的东西还算签名吗?算了交给 GPT4 去改,果然改完就过了。\n\n### Attack 3\n\n第三个攻击感觉是最简单的,看日志内容发现用户上传了五个不同的文件,但是看请求内容那一步就马上发现不对劲了——五个文件中有一个是 PhP 文件,里面是攻击代码,居然直接以 .php 结尾被传进代码旁边的子目录了。泰经典辣,甚至没有用 GPT4,直接给 portal.php 上传文件的代码加一个文件结尾检查就过了(虽然如果是现实中真的遇到这种情况的话肯定要检测文件内容的)\n\n## 后二道题 - Swag Shop\n\n上一道题因为是 PhP,改完代码直接 `compose up --build -d` 重新跑容器也只要几秒。但是这两道题是用 Go 写的,而 Go 是需要编译的语言,所以发现的第一件事情是 `docker build` 居然要两分钟 (╯’ – ‘)╯︵ ┻━┻\n\n磨刀不误砍柴工,先把本地 Go 环境和依赖装上,把 SSL cert 挪到该放的地方,带缓存的编译重跑就只需要不到一秒了。\n\n\n\n### Attack 1\n\n第一道题非常非常简单,跑起来之后看 HTTP 访问日志马上就看到了一条野生 SQL 语句 👀 原来要修的是 SQL 注入。看看代码,main 里面定义了这个 `/shop/items/:item` 节点的函数是 DescribeItem(),把整个函数拷给 GPT4 重写拿分()\n\n
GPT4 不知道今天帮了我多少忙
\n\n### Attack 2\n\n第二道题我觉得是这五道题里面最难的,因为攻击方法并不明显。整个日志看起来都非常正常,我为了让日志看起来更整洁还隐藏了签名验证的部分,日志里实现的操作都是用户正常使用会用到的,管理员创建了几个商品,删了两个商品,用户读了一次商品列表,然后买了一件,感觉没有哪里不对。\n\n
非常正常的日志
\n\n看了超级超级久还没发现问题,但是把签名打出来发现了不同请求的签名长度不一样,所以猜猜可能是签名验证的问题就去检查了一下签名验证的代码,然后发现了这堆鬼东西:\n\n
他们自己实现了一个 ASN 验证,后面是五百行的我都看不懂的纯正密码学
\n\n不懂就不要随便自己实现加密算法啊啊啊 (╯’ – ‘)╯︵ ┻━┻\n\n密码学真的有太多我看不懂的理论数学,所以我也看不出他们的实现有没有 Bug,但是总之先试试让 GPT4 用标准库重写一遍 VerifyASN 吧... 重写完重跑一遍居然就真的就过了 🌚\n\n## 总结\n\n总之五道 Defense 题全都解出来啦,然后看时间不够快赶不上 One Among Us 的手工活动就赶快走了。感觉很开心!这是我参加的第一个有 Defense 题型的 CTF,感觉是和 Web 题完全反过来的题型。Defense 少见可能是因为这种题比较难封沙盒吧,不过第一次知道原来像我这样的平凡全栈技能也能在 CTF 上起到作用。\n\n原本登记了这次比赛只是因为 UofTCTF 他们组缺人,去之前还觉得自己一年没打过 CTF 了说不定一道题都做不出来呢,结果发现并没有全都忘掉也很开心。居然比同组的那些 UofTCTF 活跃队员分还高一些(不过也是因为 Defense 题更简单啦)总之虽然已经退坑了但是偶尔打打 CTF 还是很好玩的!"}, - {"id": 8, "title": "开源打击琴!第二天", "subtitle": "绝赞设计中 ⭐️", "tags": ["open-keyprec"], "file": "content/posts/2023-03-15 OKP Day 2.md", "date": "2023-03-15T00:00:00", "url_name": "2023-03-15-OKP-Day-2", "content": "#open-keyprec 开源打击琴的第二天\n\n今天在设计琴键布局呢,决定了做五个八度的马林巴琴布局,从 C2 到 C7 一共 61 个琴键。为了不用手动复制 60 遍写了脚本自动生成琴键!FreeCAD 可以用 py 写脚本真是省了不知道多少时间哇(虽然学 API 可能用了更久hhh)。原本是按照 78-194mm 等比例分布琴键长度,但是觉得看起来太规整了,改成用三点的方式找到了一个抛物曲线计算长度,效果好棒!\n\n
生成的 61 个琴键模型,高度是条抛物线
\n\n然后算下来打印时间大概要 91.5h,如果 24h 无间断打印的话要 3.8 天... 今天发现 Cura 的一个实验性功能可以让多个模型在同一个平台上顺序打印,很灵车但是好想试试,如果可以的话睡觉的时候也能让打印机工作了(打印机加油!\n\n真正打印的时候才发现这个打印机有好多问题,果然不应该相信半价全新... 首先是自动调平不工作,而且因为这款 \"Smart\" 打印机的受众是富家小孩,设计师去掉了需要耐心的手动调平旋钮。研究了一下发现是固件逻辑每次回零都会把调平 Mesh 关掉,也就是说自动调平完全没有用到。解决方案就是在 GCode 开始段回零之后加一句 `M420 S1` 重新启用调平... 创想啊你完全不测试你的代码么 (╯’ – ‘)╯︵ ┻━┻\n\n
自动调平 Mesh 可视化(好歪!)
\n\n然后看到印床底下有一颗孤零零的螺丝 ;-;;; 估计要拆下整个 y 轴才能取出来,好麻烦啊,不过有一点点小风险也没关系?\n\n
卡在床下面的螺丝
\n\n今天下午和聊聊去拼装模型爱好者的店买了喷漆罐,打算喷成 V7530BCF 那样的金属黑色。给 PLA 喷漆也很讲究呢,需要先喷 Primer,喷漆,再喷保护层,还要一个通风柜... 原本想在厕所开上换气喷,但是看到成分里含有机溶剂,只能等天暖在外面喷了呜呜。\n\n晚上复用器芯片到了,因为 D1 ESP32 控制板只有六个模拟输入,用来接 61 个琴键肯定不够,所以就改成了用四个 16 输入的复用器去读四个输入啦。去焊了四片芯片上的 96 个引脚。开始焊之前觉得 96 个引脚好多好可怕,但是熟练之后发现其实可以很快的,焊最后一个芯片的 24 根引脚只花了两分钟,离成为一个合格的工程师更近了!零件还缺 60 个 1MΩ 电阻和 60 个二极管和一些转接头就收集齐了!"}, - {"id": 7, "title": "Snowy World", "subtitle": "一个 telnet 协议的 ASCII 动画", "file": "content/posts/2023-03-09 Telnet Game.md", "tags": [], "date": "2023-03-09T00:00:00", "url_name": "2023-03-09-Telnet-Game", "content": "\n\n写了一个 telnet 协议的 ascii 动画!(花了一整天又没什么用,但是好好玩ww\n\n用指令 `telnet hydev.org` 连接哦。记得用一个好用一点的终端,比如 kitty / iTerm2\n\n
用 cool-retro-term 登录 ptt.cc 论坛的 telnet
\n\n昨天和鱼塔闲聊,从某紫底绿字网页聊到复古终端又聊到 telnet 论坛。这是我第一次见到 telnet 协议的论坛哇,连进 ptt 和水木论坛转了转,完全被五颜六色的字符画和各种小彩蛋吸引住了 qwq 决定我也写一个简单 ascii 动画放进我的小小角落...\n\n...然后就这样花掉了一整天 🌚\n\n刚开始用 python 两个小时写好了 telnet 监听、雪花、字符画、移动,简简单单地一层一层字符打上去,但是这样会让图层闪来闪去。然后改成了存 framebuffer 2d 矩阵,先把不同图层叠到缓存里再统一渲成一层命令行能懂的控制符,但是 py 矩阵遍历真的好慢好慢,用上 numpy 也依然非常慢,渲染一帧要 42ms。好像这个问题并没有解... 用 numba JIT 把遍历函数编译成二进制也只优化到了 16ms。无奈啊,可能方便的语言就是跑不快,借这个契机开始学 rust 了!\n\n
Python 渲染日志,一圈需要 45ms
\n\nrust 确实好不方便,因为不能有全局变量,用 struct + impl 强行模拟了 OOP 的对象,把全局全都写在 struct Main 里面 🌚。但是有时候又不能当作对象,遇到了比如可变指针借用的问题,把常量和变量分开存解决了,还有生命周期什么的,总之是好多写完了也没太学懂的概念。昨天折腾到凌晨五点 rua 完了,没想到同一个 2d 数组遍历只是用 rust 重写就只占用 0.12ms 了哇,350 倍啊 350 倍!\n(╯’ – ‘)╯︵ ┻━┻\n\n~~就此立 flag,以后新坑绝对不会再碰 python 了~~。明明同样是 O(n * m) 的代码居然会差这么多... 现实中优化算法常量也很重要呢\n\n
Rust 可变 &self 指针借用的报错
\n\n接下来想要把写完的命令行程序接到 telnet 协议上,可是 rust 没有做好的 telnet 服务器库,怎么办呢?先是试着用 tokio 手搓一个协议库,发现没办法读未缓存的原始键盘事件,去 SO 问了。之后尝试调用 c 的 libtelnet 库,跑起来到处报 SIGSEGV 呜呜呜。最后还是直接用 py 的代码开子进程做了一个中继,收到客户端的输入转发给 rust,收到 rust 的输出再转发给客户端... 意外地效果还不错。\n\n写完装进 docker 里面部署上去啦。花了一整天,但是学到了 rust,动画的效果也不错,总之很开心。写着写着有点想用这个框架写一个小游戏... 但是不太会游戏设计呢,再想想。"}, + {"id": 9, "title": "CyberSci 2023 CTF 网安比赛 Writeup", "subtitle": "你是来打网安还是修 Bug 的?🌚", "tags": ["ctf"], "file": "content/posts/2023-11-18 CyberSci Canada Writeup.md", "date": "2023-11-18T00:00:00", "url_name": "2023-11-18-CyberSci-Canada-Writeup", "content": "我解的五道题都是 Defense 分类的,Defense 规则是修好一个服务器端让攻击方的 PoC 脚本失效就能拿分(这不是我维护服务器日常做的事情吗 ;-;\n\n前三道题「CFP」是一套 PhP + Nginx 写的用来上传作业文档的服务器,后两道题「Swag Shop」是一套 Go GIN 写的购物服务器,全都跑在 docker compose 容器里(然而这两个语言我都没用过呜呜呜)\n\n知道问题的时候修一个 bug 很容易,但是 PoC 机并不会告诉你 bug 在哪里,所以解题的第一步是去查 HTTP log 找到被攻击的方法。\n\n## 前三道题 - Call for Presentations\n\n### Attack 1\n\n前三道题的部署结构我真的太熟悉了,因为我自己的所有服务器都是 Nginx + Docker,直接 `tail -f /var/log/nginx/access.log` 读出所有的请求,整理出一个攻击从开始到结束的所有请求,再 `cat /tmp/nginx-req-body/{n}/` 来读出每个请求内容。看一下请求过程如下:\n\n1. 注册一个帐号\n2. 登录这个帐号\n3. 换一个不同的密码登录这个帐号还登进去了??\n\n啊所以难道给我的这套代码登录甚至没有验证密码的吗 (╯’ – ‘)╯︵ ┻━┻\n\n
欣赏一下屎山代码
\n\n看看源代码 lib.php 确实数据库密码验证逻辑写得乱七八糟,数据库直接 string concat,密码甚至没 hash... 好直接让 GPT4 重写了一遍登录和注册这两个函数,然后 PoC 就失效了,拿分拿分 🌚\n\n
GPT4 帮我修好了!
\n\n(不过我至今没弄懂 PhP 要怎样把 log 打到能看到的地方... 打比赛的时候试了几个不同的方法都看不到 log 就算了算了直接把 curl hydev.org/say 写进去了,发到 /say 的东西会转发到我的 Telegram 上hhhh\n\n### Attack 2\n\n第一个好简单。第二个攻击的请求乍一看好像没什么问题,但是仔细看看就会发现 PoC 机注册的帐号的名字和请求提交的 JWT Token 名字不一样然后还莫名过签证验证了... 为什么呢?\n\n
第二个攻击的 Log
\n\n看一眼代码确实,签名居然不是密码学签名,而是直接把请求 JWT 里面的东西 hash 了一遍,验证签名和 hash 相等???🫠 这种客户端能生成的东西还算签名吗?算了交给 GPT4 去改,果然改完就过了。\n\n### Attack 3\n\n第三个攻击感觉是最简单的,看日志内容发现用户上传了五个不同的文件,但是看请求内容那一步就马上发现不对劲了——五个文件中有一个是 PhP 文件,里面是攻击代码,居然直接以 .php 结尾被传进代码旁边的子目录了。泰经典辣,甚至没有用 GPT4,直接给 portal.php 上传文件的代码加一个文件结尾检查就过了(虽然如果是现实中真的遇到这种情况的话肯定要检测文件内容的)\n\n## 后二道题 - Swag Shop\n\n上一道题因为是 PhP,改完代码直接 `compose up --build -d` 重新跑容器也只要几秒。但是这两道题是用 Go 写的,而 Go 是需要编译的语言,所以发现的第一件事情是 `docker build` 居然要两分钟 (╯’ – ‘)╯︵ ┻━┻\n\n磨刀不误砍柴工,先把本地 Go 环境和依赖装上,把 SSL cert 挪到该放的地方,带缓存的编译重跑就只需要不到一秒了。\n\n\n\n### Attack 1\n\n第一道题非常非常简单,跑起来之后看 HTTP 访问日志马上就看到了一条野生 SQL 语句 👀 原来要修的是 SQL 注入。看看代码,main 里面定义了这个 `/shop/items/:item` 节点的函数是 DescribeItem(),把整个函数拷给 GPT4 重写拿分()\n\n
GPT4 不知道今天帮了我多少忙
\n\n### Attack 2\n\n第二道题我觉得是这五道题里面最难的,因为攻击方法并不明显。整个日志看起来都非常正常,我为了让日志看起来更整洁还隐藏了签名验证的部分,日志里实现的操作都是用户正常使用会用到的,管理员创建了几个商品,删了两个商品,用户读了一次商品列表,然后买了一件,感觉没有哪里不对。\n\n
非常正常的日志
\n\n看了超级超级久还没发现问题,但是把签名打出来发现了不同请求的签名长度不一样,所以猜猜可能是签名验证的问题就去检查了一下签名验证的代码,然后发现了这堆鬼东西:\n\n
他们自己实现了一个 ASN 验证,后面是五百行的我都看不懂的纯正密码学
\n\n不懂就不要随便自己实现加密算法啊啊啊 (╯’ – ‘)╯︵ ┻━┻\n\n密码学真的有太多我看不懂的理论数学,所以我也看不出他们的实现有没有 Bug,但是总之先试试让 GPT4 用标准库重写一遍 VerifyASN 吧... 重写完重跑一遍居然就真的就过了 🌚\n\n## 总结\n\n总之五道 Defense 题全都解出来啦,然后看时间不够快赶不上 One Among Us 的手工活动就赶快走了。感觉很开心!这是我参加的第一个有 Defense 题型的 CTF,感觉是和 Web 题完全反过来的题型。Defense 少见可能是因为这种题比较难封沙盒吧,不过第一次知道原来像我这样的平凡全栈技能也能在 CTF 上起到作用。\n\n原本登记了这次比赛只是因为 UofTCTF 他们组缺人,去之前还觉得自己一年没打过 CTF 了说不定一道题都做不出来呢,结果发现并没有全都忘掉也很开心。居然比同组的那些 UofTCTF 活跃队员分还高一些(不过也是因为 Defense 题更简单啦)总之虽然已经退坑了但是偶尔打打 CTF 还是很好玩的!"}, + {"id": 8, "title": "开源打击琴!第二天", "subtitle": "绝赞设计中 ⭐️", "tags": ["open-keyprec"], "file": "content/posts/2023-03-15 OKP Day 2.md", "date": "2023-03-15T00:00:00", "url_name": "2023-03-15-OKP-Day-2", "content": "#open-keyprec 开源打击琴的第二天\n\n今天在设计琴键布局呢,决定了做五个八度的马林巴琴布局,从 C2 到 C7 一共 61 个琴键。为了不用手动复制 60 遍写了脚本自动生成琴键!FreeCAD 可以用 py 写脚本真是省了不知道多少时间哇(虽然学 API 可能用了更久hhh)。原本是按照 78-194mm 等比例分布琴键长度,但是觉得看起来太规整了,改成用三点的方式找到了一个抛物曲线计算长度,效果好棒!\n\n
生成的 61 个琴键模型,高度是条抛物线
\n\n然后算下来打印时间大概要 91.5h,如果 24h 无间断打印的话要 3.8 天... 今天发现 Cura 的一个实验性功能可以让多个模型在同一个平台上顺序打印,很灵车但是好想试试,如果可以的话睡觉的时候也能让打印机工作了(打印机加油!\n\n真正打印的时候才发现这个打印机有好多问题,果然不应该相信半价全新... 首先是自动调平不工作,而且因为这款 \"Smart\" 打印机的受众是富家小孩,设计师去掉了需要耐心的手动调平旋钮。研究了一下发现是固件逻辑每次回零都会把调平 Mesh 关掉,也就是说自动调平完全没有用到。解决方案就是在 GCode 开始段回零之后加一句 `M420 S1` 重新启用调平... 创想啊你完全不测试你的代码么 (╯’ – ‘)╯︵ ┻━┻\n\n
自动调平 Mesh 可视化(好歪!)
\n\n然后看到印床底下有一颗孤零零的螺丝 ;-;;; 估计要拆下整个 y 轴才能取出来,好麻烦啊,不过有一点点小风险也没关系?\n\n
卡在床下面的螺丝
\n\n今天下午和聊聊去拼装模型爱好者的店买了喷漆罐,打算喷成 V7530BCF 那样的金属黑色。给 PLA 喷漆也很讲究呢,需要先喷 Primer,喷漆,再喷保护层,还要一个通风柜... 原本想在厕所开上换气喷,但是看到成分里含有机溶剂,只能等天暖在外面喷了呜呜。\n\n晚上复用器芯片到了,因为 D1 ESP32 控制板只有六个模拟输入,用来接 61 个琴键肯定不够,所以就改成了用四个 16 输入的复用器去读四个输入啦。去焊了四片芯片上的 96 个引脚。开始焊之前觉得 96 个引脚好多好可怕,但是熟练之后发现其实可以很快的,焊最后一个芯片的 24 根引脚只花了两分钟,离成为一个合格的工程师更近了!零件还缺 60 个 1MΩ 电阻和 60 个二极管和一些转接头就收集齐了!"}, + {"id": 7, "title": "Snowy World", "subtitle": "一个 telnet 协议的 ASCII 动画", "file": "content/posts/2023-03-09 Telnet Game.md", "tags": [], "date": "2023-03-09T00:00:00", "url_name": "2023-03-09-Telnet-Game", "content": "\n\n写了一个 telnet 协议的 ascii 动画!(花了一整天又没什么用,但是好好玩ww\n\n用指令 `telnet hydev.org` 连接哦。记得用一个好用一点的终端,比如 kitty / iTerm2\n\n
用 cool-retro-term 登录 ptt.cc 论坛的 telnet
\n\n昨天和鱼塔闲聊,从某紫底绿字网页聊到复古终端又聊到 telnet 论坛。这是我第一次见到 telnet 协议的论坛哇,连进 ptt 和水木论坛转了转,完全被五颜六色的字符画和各种小彩蛋吸引住了 qwq 决定我也写一个简单 ascii 动画放进我的小小角落...\n\n...然后就这样花掉了一整天 🌚\n\n刚开始用 python 两个小时写好了 telnet 监听、雪花、字符画、移动,简简单单地一层一层字符打上去,但是这样会让图层闪来闪去。然后改成了存 framebuffer 2d 矩阵,先把不同图层叠到缓存里再统一渲成一层命令行能懂的控制符,但是 py 矩阵遍历真的好慢好慢,用上 numpy 也依然非常慢,渲染一帧要 42ms。好像这个问题并没有解... 用 numba JIT 把遍历函数编译成二进制也只优化到了 16ms。无奈啊,可能方便的语言就是跑不快,借这个契机开始学 rust 了!\n\n
Python 渲染日志,一圈需要 45ms
\n\nrust 确实好不方便,因为不能有全局变量,用 struct + impl 强行模拟了 OOP 的对象,把全局全都写在 struct Main 里面 🌚。但是有时候又不能当作对象,遇到了比如可变指针借用的问题,把常量和变量分开存解决了,还有生命周期什么的,总之是好多写完了也没太学懂的概念。昨天折腾到凌晨五点 rua 完了,没想到同一个 2d 数组遍历只是用 rust 重写就只占用 0.12ms 了哇,350 倍啊 350 倍!\n(╯’ – ‘)╯︵ ┻━┻\n\n~~就此立 flag,以后新坑绝对不会再碰 python 了~~。明明同样是 O(n * m) 的代码居然会差这么多... 现实中优化算法常量也很重要呢\n\n
Rust 可变 &self 指针借用的报错
\n\n接下来想要把写完的命令行程序接到 telnet 协议上,可是 rust 没有做好的 telnet 服务器库,怎么办呢?先是试着用 tokio 手搓一个协议库,发现没办法读未缓存的原始键盘事件,去 SO 问了。之后尝试调用 c 的 libtelnet 库,跑起来到处报 SIGSEGV 呜呜呜。最后还是直接用 py 的代码开子进程做了一个中继,收到客户端的输入转发给 rust,收到 rust 的输出再转发给客户端... 意外地效果还不错。\n\n写完装进 docker 里面部署上去啦。花了一整天,但是学到了 rust,动画的效果也不错,总之很开心。写着写着有点想用这个框架写一个小游戏... 但是不太会游戏设计呢,再想想。"}, {"id": 6, "title": "用校园网搭建服务器!", "subtitle": "在宿舍折腾网络的一篇记录w", "tags": ["技术"], "category": "技术", "file": "content/posts/2022-01-30 Router.md", "date": "2022-01-30T00:00:00", "url_name": "2022-01-30-Router", "content": "欢迎欢迎!我是 UofT 的大一新生,这是我在宿舍折腾网络的一篇记录w\n\n## 1. 搭建 FRP 实现内网穿透\n \n\n\n## 2. OpenWRT 中继学校 WPA-EAP 网络实现远程重启\n\n搭建好内网穿透之后又遇到了新的问题——因为台式机服务器装的黑苹果配置不是很稳定,它有时候会整个屏幕绿掉,必须强制重启才行,应该是 kernel panic 吧。我不在宿舍的时候回宿舍重启又太麻烦了,如果可以远程重启...\n\n想起来之前摸鱼的时候看到向日葵有做过远程重启的设备,所以就去查了下,结果发现就只是一个智能插座,在主板上配置好插电自动开机就好啦。但是这又有一个问题——宿舍里所有的网络,无论是 UofT Wifi 还是 eduroam 还是有线以太网,都需要 WPA/WPA2/WPA3-Enterprise EAP PEAP MSCHAPv2 用户名+密码验证... 可是智能插座只支持简单的 WPA-PSK 密码验证。所以就需要一个可以连上外网、又可以开 WPA-PSK WiFi 的无线路由器了。\n\n刚开始,我想过几个不同的方案:\n\n### a. 用手机连 Wifi 开热点(失败)\n\n之前无意间发现了我的 Mi Mix2S (Android 11 EvolutionX) 可以边连 Wifi 边开热点,不知道是怎样实现的。所以我想,如果用旧的华为 Mate8 这样一边连着学校的 PEAP 一边开热点就可以了。但是开机之后,我发现 Mate8 的原生系统 Android 8 EMUI 8.0 并不支持同时连 Wifi 开热点。我听说用 VPN Hotspot 可以实现无线中继,下载试了下却发现没有 Root 就不能改 SSID 和密码,每次开的 SSID 和密码都是随机的。所以花了超级多精力解锁 BootLoader、刷 Magisk、然后发现 Root 之后也不能改无线中继的 SSID 和密码... 改完之后重开中继的 SSID 还是 DIRECT-{随机}-HUAWEI, 密码还是八位随机字符。不过还是试了下用智能插座连这个无限中继,只能赌无线中继不会重启、不会关机、不会被电源管理杀掉... \n\n结果是,在台式死机之前智能插座就先下线了,回宿舍看了一眼发现手机不知道为什么重启进 Recovery 了。失败失败(\n\n### b. 用手机连数据卡开热点(太贵了)\n\n然后想到如果可以再买一张手机卡只用来开热点就解决了嘛,但是发现这边不像国内那样 ¥10/mo 就能买一张卡,这边最便宜的流量卡要 CA$15/mo,换算出来要 ¥75/mo 了,够买一个路由器了(\n\n### c. 用路由器中继\n\n然后就是现在的解决方案啦,用路由器中继学校的 PEAP。首先要做的是买一个路由器,可是这边新的路由器也真的很贵,亚马逊上最便宜的 TP-Link AC750 要 $35 = ¥175... 所以去二手市场逛了逛,很幸运的看到了附近有人 $10 出路由器,一个 Netis WF2780 和一个小米路由 R4。\n\n首先试了 WF2780,但是它好像没接好 WAN 就完全不能用的样子,SYS 灯一直在闪,网线连上电脑也没办法获取到 IP,手动分配 IP 到 192.168.1.2 也进不去管理页面。可能是坏了吧,也可能这个路由器本来就是这样?不懂,下一个(\n\n然后试了 R4,可是用小米官方的固件,无限桥接模式并不能连上 PEAP 验证的 UofT Wifi 或者 eduroam,有线桥接模式把 WAN 口接上也提示识别错误。所以只能试试 OpenWRT 啦。\n\n### 1. 给小米路由 R4 刷 OpenWRT\n\n这里我跟了 https://www.wyr.me/post/619 这个教程,很轻松地就刷好了!\n\n在电脑上要做的事情:\n\n1. 网线连上路由器,登录管理后台(我是 http://192.168.31.1)\n2. 复制管理后台登录之后 URL 里面的 stok 参数\n3. 执行以下指令,输入路由器的 IP 和刚才复制的 stok\n\n```sh\ngit clone https://github.com/acecilia/OpenWRTInvasion\ncd OpenWRTInvasion\npip3 install -r requirements.txt\npython3 remote_command_execution_vulnerability.py\n```\n\n然后就有 ssh 啦!接下来用了这个固件:https://github.com/ioiotor/mir4-ss,下载 [openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin](https://github.com/ioiotor/mir4-ss/releases/download/V19.07.4/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin) 和 [openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin](https://github.com/ioiotor/mir4-ss/releases/download/V19.07.4/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin)\n\n4. 在电脑上执行以下指令:\n\n```sh\nmkdir temp\ncd temp\nwget https://github.com/ioiotor/mir4-ss/releases/download/V19.07.4/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin\nwget https://github.com/ioiotor/mir4-ss/releases/download/V19.07.4/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin\npython3 -m http.server\n```\n\n5. 登录进 SSH Shell 之后在路由器上执行指令:\n\n```sh\ncd /tmp\nwget http://{电脑 IP 地址}/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin\nwget http://{电脑 IP 地址}/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin\nmtd write openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin kernel1\nmtd write openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin rootfs0\nnvram set flag_try_sys1_failed=1\nnvram commit\nreboot\n```\n\n然后就好啦,重启之后就是 OpenWRT 了(虽然默认没有开 WLAN,所以只能网线连到路由器)\n\n### 2. OpenWRT 连接到 PEAP 网络\n\n登录上管理页面,改完管理密码之后,我试了直接把 wlan0 改成 client mode 去连学校的网,但是发现这里也只支持密码验证的 WPA-PSK 而不支持用户名+密码的 WPA-EAP。然后查了一下发现只要把预装的 wpad-basic 换成完整的 wpa-cli + wpa-supplicant + hostapd 就可以了。但是还有一个问题就是我的路由器现在没有网,所以不能在线安装软件包。我的解决方案是用电脑先连上学校的 WIFI,再把电脑的网线连到路由器的 LAN 口上,然后在电脑上开桥接模式路由器就有网了!\n\n之后,ssh 进路由器,执行以下指令:\n\n```sh\nopkg update\nopkg remove wpad-basic\nopkg install wpa-cli wpa-supplicant hostapd nano\nreboot\n```\n\n等重启好之后,管理页面里面 Wireless Security 那一栏的验证方式里面就有 WPA2-EAP 了!接下来把学校的验证信息填进去,然后保存就连上啦!UofT 的配置如下:\n\n```txt\nEncryption : WPA2-EAP (strong security)\nCipher : auto\nEAP-Method : PEAP\n...\nCertificate Constraaint (Domain) : radius.wireless.utoronto.ca\n...\nAuthentication : EAP-MSCHAPv2\nIdentity : 你的 UTORid\nPassword : 你的 UTORid 密码\n```\n\n接下来把 WIFI 配置一下,让智能插座连上这个 WIFI 就好了!"}, {"id": 5, "title": "日记 - Royal Ontario Museum", "tags": ["日记"], "category": "日记", "file": "content/posts/2021-12-30 日记.md", "date": "2021-12-30T00:00:00", "url_name": "2021-12-30-日记", "content": "今天和聊聊去逛了 Royal Ontario Museum,是我这两年第一次逛博物馆。这个博物馆真的好大,从十点开馆逛到五点半闭馆只看完了不到三层,又或许是因为我们看得比较认真,每件感兴趣文物、标本旁边的介绍都略读了下。晚上腿好酸,从来没有站过这么久。\n\n在这里我也体会到了和聊聊知识量上的差距有多么恐怖,简直是肉身维基了…看到中国韩国的文物,聊聊看到材料和风格就猜到了文物的制作朝代、年份、位置,留下我在旁边偷偷查各个朝代都在哪些年。给我讲了好多,比如释迦牟尼虽然有十大弟子,摆在旁边的通常是阿难和大迦叶;比如在化学合成颜料之前,制作颜料通常需要找到特定颜色的自然材料,甚至有用木乃伊尸体磨成的棕色颜料绘出的名画;又比如华昇最早在中国发明的活字印刷并没有欧洲古腾堡的印刷术便利实用。生物知识也是,好多次被聊聊吐槽我到底翘了多少节生物课…多亏聊聊我今天刚知道海豚也是鲸目、鲸要升到水面呼吸、翼龙并不是鸟…更丢人的就省略了(x\n\n我们之间五年的年龄差真的好可怕,也许这是我永远没办法赶上的。这几天还发现学计算机的聊聊懂的心理知识可能比心理专业的我还多,汉语英语日语法语都比我厉害,玩游戏也好厉害…聊聊这么优秀的真的让我好自卑。不过也没关系,我也有绝对自信的领域,我也有聊聊没有的知识…吧。\n\n不管怎样,今天学到了好多!希望我能记住。不过以前或许学过这些,但是我长短期记忆都真的好差…短期比如我经常会走进一个房间就忘了进来做什么;长期比如之前母上给我看小学去一个沙漠旅游的照片,但是我完全不记得去过那里,看着照片也只想起了好像有这回事,没办法唤起情节记忆。所以其实写日记还有另一个目的——希望写下这些文字的过程能让这段记忆深深刻在记忆中。\n\n晚上我们去吃了烤肉,在餐厅拿号之后要等一个小时才有位置。等消息的时候又去逛了一次 Game Stop,我终于下定决心入手了一直想要买的 NS!是 Wii 之后我的第二个任天堂主机!(虽然说快 2022 了还原价买 2017 的主机听起来很蠢,但是能借聊聊的卡带一起联机就值了ww)聊聊还给我买了马里奥奥德赛的卡带!本来还以为自己不是很爱玩游戏的,结果凌晨醒来开箱之后就一下子沉迷玩了四个小时。\n\n烤肉很好吃!今生第一次吃烤肉,上生肉自己动手烤也是好神奇的体验。然后发现,比起照顾自己我们都更喜欢照顾对方的样子,会看到聊聊烤完把肉肉夹给我,我烤完再把肉肉夹给她ww\n\n记得今天睡觉之前和书聊天,书说像我之前那样太在意别人不在意自己也不太好,对此我回复说聊聊会在意我的。这样互相照顾好开心!"}, {"id": 4, "title": "日记 - 和聊聊相遇", "tags": ["日记"], "category": "日记", "file": "content/posts/2021-12-28 日记.md", "date": "2021-12-28T00:00:00", "url_name": "2021-12-28-日记", "content": "突然有一种认真把经历的事情记录下来的冲动,那就从今天开始吧w\n\n今天去和聊聊看了西区故事,是一个罗密欧与朱丽叶为原型的歌舞剧。故事的男女主在敌对的帮派,模糊的归属感让他们可以独立思考、走出对帮派的无脑跟随,也是这个共同点使它们一次相遇便相爱。当然和罗密欧与朱丽叶一样,结局无比沉痛。好久没有看过情绪这么沉重又细腻的故事了,上一个这样的故事或许是利兹与青鸟,或许是朝花夕誓,又或许是凝冰剑斩的某部视觉小说。这些故事真的好美——是期望和绝望的华尔兹,甜蜜中穿插着刺痛…\n\n昨天 K(前任)和我说了好多话,ta在上一段感情里和我一样是依恋的那一方,同样喜欢着一个也许不是那么喜欢自己的人。「你不要我我就没有别的东西了」——原来ta也有过把一个人看作自己的一切的经历。只是那个人更狠,直接把ta拉黑删除…所以ta讨厌浪漫、讨厌甜腻的话语、以及像ta前任对待ta一样地对待我,也许都是出于自我保护吧——不想再因为浪漫受伤,也不想让我走过同样的经历。\n\n这样看来,也许我永远也不会长大呢。和前前任子兰经历过一次这样痛苦的分别之后,我依然期待着浪漫,遇到 K 依然为ta付出了我的全部,对下一个喜欢的人也一定不会变。\n\nK 的聊天记录里ta和前任分开的时候朋友和ta说:“我太现实了,你看到的是之后的美好结局,我看到的是当你真正知道那个结局没法实现的时候你有多伤心。我想很可能是错的,但是我没法否定这个结果。”也许是这件事让 K 在亲密关系里变得现实,我知道ta父母有意见、我们能力差很远、目标也很不同,现在意识到我们只能分开也真的很伤心 。但这难道不是个悖论嘛?因为有可能失败就不去尝试的话,就把失败从可能变成了必然。我更喜欢知道一个愿望很难实现仍然付出全部去追求的理想主义。\n\n又或者,说不定我在享受浪漫的痛苦呢?\n\n(留坑)\n\n看完电影和聊聊去逛优衣库,和她一起挑了点春天的女装。她给我挑了一顶很合适的帽子!还好大方地帮我结帐了…聊聊真的对我太好了,以后一定要回报给她ww\n\n在优衣库那里还遇到了一位好像是跨男的亚裔路人,好心地走上来问咱是不是跨。虽然在这边第一次偶遇跨性别亚裔还是好新奇,但是即使是被跨鉴跨也真的好受打击... 不过之后ta问我们是不是一对,看我们像恋人又不是的样子就疯狂 ship 我们,还给了好多祝福什么的。然后!挥手道别之后聊聊顺势用西区故事里面超可爱的台词和我告白了!!以下是我今天疯狂想记下来的事情展开ww\n\n(和路人挥手道别之后) \n:所以我们是一对嘛? \n:是吧(捂脸) \n:「quiero estar contigo para siempre」 \n(然后牵住我的手) \n\n(哇啊啊啊啊啊真是太棒了!!!谢谢你,聊聊!还有不知名的英雄路人!我的心要跳出去了ww)\n\n这边优衣库店员也超级好心,聊聊虽然那天的打扮不是很过,但是带着裙子去试衣间店员也什么都没问,加拿大真好。聊聊买了两件很合适的毛衣、好厚的黑色半身裙、打底裤、还有给我买的帽子w\n\n接下来去吃了饭,因为到处都排很长队或者没开,所以就去了一家没吃过的越南河粉店,边聊边吃了好久。可惜聊聊似乎不是很喜欢吃碳水,更喜欢吃肉肉,所以把肉肉夹给她了!决定了下次吃烤肉w"},