0xgame2025_Misc_Teching

我是0xGame2025的部分Misc的出题人,下面是针对misc方向的授课文案,希望能帮助刚踏上ctf路上的学弟学妹们快速入门

0xgame2025所有题目归档可以点击下面按钮跳转

0xGame2025Week1赛题归档

Week1

Sign_in

题目只给我们一串编码,遇到这类题,就把它复制到cyberchef这类自动化解密工具(我们经常管它叫赛博厨子)中,工具会帮我们检测出编码类型

ps:我们在飞书上有准备cyberchef的离线版本,下载解压后点击那个html文件就能用

这里希望学弟学妹们能看到一种陌生的编码就进行简单的学习,万变不离其宗,只要掌握其中几种编码原理,其他的编码方式也就能快速上手了

简单说说工具的使用,请注意,如果这里output右侧出现魔法棒,就说明,工具已经检测出字符串的可能编码方式,点击即可

需要注意,该工具也有可能误判,如果说解密出来的东西不可读或者是别的错误情况,请及时的选择其他法子

image-20250924174928073

Recipe中出现From base64,同时output也大变样,形式上很像我们要提交的flag

image-20250924175758659这里先讲解清楚Base64编码原理

base64编码原理

Base64编码是使用范围特别广的一种编码方式,不管是图片,文字,音频等各类文件,都可以通过base64编码处理,便携发送到网上进行传输

正常的Base64编码用到的字符集是(A-Z, a-z, 0-9, +, /)共64个字符,但是注意,‘A’在字符集的索引值是0,’/'的索引值是63,中间的就按照顺序进行递增

编码原理如下,先将传输的信息转换成二进制,然后这里的二进制串都是8位的,接下来8位变6位,3个字母拆4组,接着6位二进制变十进制,然后按照十进制在Base64字符集中进行索引,上面说的3个字母拆4组,如果说拆的时候不够拆了,要用0填充,但是全是0的那组下面转换索引值后,用=号填充

下面是将明文flag转换成base64编码的原理示意图

pic_20250924184003_0

这里有个小结论,遇到Zmxh别迟疑,说不定就是flag的base64编码呢?

还有昂,这里我一直说的是编码而不是加密,所以注意一个小细节,以后不要说base64加密

凯撒密码原理

接下来拿到很像flag的字符串

1
2
0hQkwo{Govm0wo_d0_0hQ4w3_2y25_@xn_r@mu_Pyb_peX}
0xGame{xxx} #这一行给你们比对的

刷题数量足够多的话,能快速认识到,这个是凯撒密码这类的简单移位替换密码(仔细观察的话,会发现首字母的数字没变,符号没变,基本上就能往这里猜测了

加密原理就是将明文中的每个字母按照字母表顺序向后(或向前)移动固定的位置,得到密文。

加解密公式

  • 加密密文字母 = (明文字母位置 + 偏移量) mod 26
  • 解密明文字母 = (密文字母位置 - 偏移量 + 26) mod 26

所以说只要知道密文字母还有shift(偏移量)就能快速锁定明文字母

需要注意的地方如下:

凯撒密码进行替换的时候,应该先检测明文是大写还是小写

大写字母范围:A(65)到Z(90)

小写字母范围:a(97)到z(122)

由于这里的凯撒偏移指定在对应的大小写字母表中,所以我们的范围只有0-25的索引值,就是说,如果明文是大写,我们应该减去65,用得到的结果进行偏移,然后进行26取余确保结果依然在字母表中,然后再+65回到大写字母中,小写字母的解密操作是同样的原理

不过问题来了,我们这里并不知道shift,好在索引值为0-25,就26个选项,可以选择爆破,最坏的结果就是爆破到第26次,理论依据就是我上面说的,加上shift后,我们会对结果进行26取余,让最终得到的偏移值不会超过26

这里还是建议自己手搓凯撒爆破解密脚本

什么?!你代码也写不好?女孩子请找我,我来教你写;男孩子也可以来找我,我可以考虑给你梆梆一拳

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def exp(str,shift):
result=""
for char in str:
if char.isupper():
result+=chr((ord(char)-65-shift)%26+65)
elif char.islower():
result+=chr((ord(char)-97-shift)%26+97)
else:
result+=char

return result
def solver(str):
for i in range(26):
a=exp(str,i)
if a.startswith("0xGame"):
print(a)
break

if __name__=="__main__":
solver("0hQkwo{Govm0wo_d0_0hQ4w3_2y25_@xn_r@mu_Pyb_peX}")
#0xGame{Welc0me_t0_0xG4m3_2o25_@nd_h@ck_For_fuN}

公众号原稿

首先要知道一些前置知识

.docx文件的本质就是zip压缩包,与此类似的可读的文档(压缩包)格式有.xlsx和.pptx

这是微软从office 2007开始引入的新的默认格式,遵循一个名为“开放打包约定”(Open Packaging Conventions,简称OPC)。

在这个约定下,我们可以将一个.docx文件看成“披着Word外衣的ZIP压缩包”

关于约定格式上的细节,大家可以自己研究下,只需要知道,下次遇到这类题后,可以尝试将后缀名改成zip,解压看看有没有什么特殊的文件在里面

1
2
3
4
5
6
7
8
9
10
11
12
13
[Content_Types].xml
_rels/
docProps/
app.xml
core.xml
word/
document.xml <-- 这里存放文档的主要文字内容
styles.xml <-- 这里存放样式信息
media/
image1.png <-- 你插入的图片就在这里
theme/
_rels/
...

一般来说,解压**.docx**文件后,它的文件目录如上

本题中,你们解压后会在docProps/目录下看到gift.xml,而这就是我为你们准备的flag

2025-09-24-22-16-18-image

ez_shell

注意:本题是SSH容器连接题目

本题是一道帮助新生接触Linux命令的引导题,其他佬可以跳过下面的引导部分,需要提交的flag组成如下:

  • whoami命令的结果
  • pwd命令的结果
  • 当前路径下的文件夹名(除去上级路径和当前路径符号
  • 该文件夹下面的flag1.txt文件内容
  • /root下的flag2.txt文件内容

上述结果需要用’_'连接,然后用0xGame{}包裹,最终flag样例:0xGame{who_pwd_xxx_xxx_xxx}

会用到的信息:

  • ssh连接:hacker/h@cker_it
  • root用户:root/Y0u_@re_root

如何如何👀?

是第一次接触shell吗,解决不了的话,我来教你,这里有个Linux命令大全,先放这,猜你不会仔细看,好好看看我下面的引导步骤吧,敲黑板昂!!!

如何?

引导

也许我有没说明白的点,可以随时找我,或者自行研究解决

遇到这样的tcp容器题目,需开启容器,会得到类似这样的内容nc1.ctfplus.cn 34857

前面部分可以是IP地址也可以是域名,后面的数字是端口号,注意,中间是空开的,和http的’:'连接有所差异

常见的tcp服务是使用netcat这样的工具进行nc连接的,但是题目描述中,说到了,这个是ssh容器题目,而且给出了连接账密,需要我们通过ssh进行远程连接


  • step1 进入shell

在终端中输入:

1
ssh hacker@nc1.ctfplus.cn -p 34857

tips:powershell,cmd,linux终端等都可以滴

一般来说,ssh服务是用默认端口22连接的,就是说在平时连接靶机的时候可以不用-p指定端口,而这里是由于docker容器进行了端口转发才需要我们指定对应的端口号进行连接

上面看不懂问题不大,需要清楚一点,连接ssh需要指定靶机上有远程连接权限的用户,比方说本题中,只有hacker用户能ssh连接,root不可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ssh hacker@nc1.ctfplus.cn -p 34857
The authenticity of host '[nc1.ctfplus.cn]:34857 ([103.85.86.154]:34857)' can't be established.
ED25519 key fingerprint is SHA256:heNboAPQQACbtUAWuJK45JXDMmx2YFFmYkGyVhd17e0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[nc1.ctfplus.cn]:34857' (ED25519) to the list of known hosts.
hacker@nc1.ctfplus.cn's password:
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <https://wiki.alpinelinux.org/>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

dep-428f3ef5-705a-4364-a5ee-e59fc8e1fc00-5d4c55ff4b-gpflw:~$

回车运行命令后会出现一大段安全验证的信息,不用管,大致意思是说本电脑第一次连接该服务器,主机列表中找不到对应的身份记录,然后输出了服务器的公钥指纹,用来验证服务器身份的,这个时候,我们需要输入yes来同意连接,然后服务器公钥会保存在本地~/.ssh/known_hosts文件中,下次连接的时候就不会触发警告

接下来是输入密码h@cker_it,这里你们会不会因为看不到输入的内容误以为机器出问题了?O(∩_∩)O

这是Linux系统出于安全考虑的设计,为了防止旁观者在我们输入密码时看到任何视觉反馈(包括星号、圆点等)但是我们的每一次输入都是被正常记录的,所以一定要注意不要打错字哦,复制进去也是可以的(这个设计熟悉就好,几乎所有Linux系统都是这样的,就好比手机某网站的登录页面,输入密码全用"·"进行替代

登录后看到类似hostname:~$ 的字样,就表示我们登录成功,那么恭喜你第一次进入shell成功了🥳🥳🥳

  • step2 开始答题

所有Linux的基础命令都一样的,详细介绍还是请看我上面放置的网页链接,下面仅仅讲述题目中要用到的命令,也是我们经常用的

whoami

很显然,是who am i(我是谁),用途是显示当前用户名

1
2
yolo@yolo:~$ whoami
yolo
pwd

print working directory,功能是显示当前工作目录的绝对路径

1
2
yolo@yolo:~$ pwd
/home/yolo
ls

真是最最常用的命令,用途是列出当前路径下的文件及其属性信息,但是经常要结合参数使用

1
2
3
4
5
6
yolo@yolo:~$ ls
yolo@yolo:~$ ls -la
total 12
drwxr-xr-x 3 yolo yolo 4096 Sep 26 17:58 .
drwxr-xr-x 11 yolo yolo 4096 Sep 26 17:56 ..
drwxr-xr-x 2 yolo yolo 4096 Sep 26 17:58 .secret

第一个ls会单纯列出正常无隐藏的文件名或文件夹名,在Linux中,像.xxx这样的,名字前面是’.'的文件或文件夹会被系统默认隐藏,需要使用-a显示所有文件,包括隐藏的;-l会列出文件的属性,包括文件类型、权限、编辑时间、所有者等等

这里的.代表的是当前目录,是一种相对路径,…代表的是上一级路径,前面的drwxr-xr-x交给你们自己研究

pwd

本命令可以改变当前路径,和我们在Windows桌面双点某文件夹进去看里面的内容的操作类似

1
2
3
4
5
yolo@yolo:~$ pwd
/home/yolo
yolo@yolo:~$ cd .secret
yolo@yolo:~/.secret$ pwd
/home/yolo/.secret
cat

本命令可以读取指定文件的内容,正常来说,推荐用cat读取那些小点的,纯文本的文件,比方说flag.txt这样的,其他情况下,有其他命令可以用,比如more,less等等,自个研究昂

1
2
3
4
yolo@yolo:~/Desktop/.secret$ ls
flag1.txt
yolo@yolo:~/Desktop/.secret$ cat flag1.txt
congratulation!
su root

Linux对于权限的概念很严格(当然Windows同样,只是不常见

一些文件或路径,需要高权限乃至root用户才能进入,这个时候,我们需要使用su xxx指定切换用户,同样需要使用登录密码

1
2
3
4
5
6
7
yolo@yolo:~/.secret$ cd /root
-bash: cd: /root: Permission denied
yolo@yolo:~/.secret$ su root
Password:
root@yolo:/.secret# cd /root
root@yolo:~# pwd
/root

这里我给用户同样设置了不用密码的sudo权限,允许用户yolo不输入密码的情况下直接执行root权限命令

1
2
3
4
5
6
7
8
yolo@yolo:~/.secret$ id
uid=1000(yolo) gid=1000(yolo) groups=1000(yolo)
yolo@yolo:~/.secret$ sudo su
root@yolo:/home/yolo/.secret# id
uid=0(root) gid=0(root) groups=0(root)
root@yolo:/home/yolo/.secret# cd /root
root@yolo:~# cat flag2.txt
hacker!
  • step3 合成flag
1
0xGame{yolo_/home/yolo_.secret_congratulation!_hacker!}

我猜真有人把上面的flag交上去了吧,梆梆锤你呢,自个做一遍,熟悉下,然后这里学长给出建议,一定要多用,越学到后面,我们的命令行工具使用的就越多,而且,在终端上操作没有一种黑客体验感吗?多cool!

cool

Zootopia

这个题的考点很基础,是png图片的LSB隐写,下面就简单说说lsb的隐写原理,如果对其他png隐写方法感兴趣,可以看看这篇博客

嗯,没错,是我写的

lsb原理

首先有个大概的理解,在png图片中,一个像素点在文件数据中存储的大小是三个字节,比较常见的模式是按照rgb进行存储的(模式有很多种,但是rgb确实是最常见,其他的模式对应的隐写原理和下面的一样

rgb三个颜色通道的范围都是[0-255] 别记岔了!!!

1
2
3
4
5
几个常见的颜色
红色:(255,0,0)
绿色:(0,255,0)
蓝色:(0,0,255)
白色:(255,255,255)

然后在文件内部,数据是按照8位二进制进行存储的,比方说某个像素点的值是(111,222,225),那么在存储中,对应的值是(01101111,11011110,11100001)

然后这里,我们定义每个8位二进制的最后一位为LSB (Least Significant Bit,最低有效位)

所谓的lsb隐写就是对每个二进制的最低有效位进行编辑,使用01二进制进行隐写信息,可以藏文件,也可以藏字符串,同样,颜色通道的选择也很多样性,可以仅仅对R通道进行隐写,也可以选择两个以上…

在lsb的原理基础上,颜色通道隐写还能拓展到其他的通道中,也就出现了MSB (Most Significant Bit,最高有效位)或者其他混乱通道隐写(组合起来很多,不过原理都是一样的

编者补充:lsb隐写相对msb而言,有个显著的优势,那就是对整个画面影响不大,或者说我们肉眼几乎看不清隐写前后的差异

解密LSB

解决方式很多,由于lsb的提取稍微麻烦点,我们这里就不细说脚本怎么搓(写提取脚本老麻烦了呢

推荐的解密工具有Stegsolve,Zsteg

stegsolve

前者是有可视化界面的提取通道隐写的工具,同样也有对单个颜色通道提取查看图片的功能,还有xor等等操作,目前来看,我感觉这个最好用

image-20251001160837872

先导入图片(你把png图片给拉进去也没问题

Analyse->Data Extract->勾选Red,Green,Blue三个通道的最后一位->选中LSB First(虽说感觉没用)->Preview

通过上述操作,我们能看到文件最前面隐藏了flag,但是在当前情况下,直接复制,会顺带把左边的十六进制数据复制到,建议把preview上面的Include Hex Dump In Preview取消勾选,重新Preview下,就好复制flag了(复制出来的结果中间有空格,自行删减就好

zsteg

后者是命令行工具,可以帮我们检测多个颜色通道可能有的隐写信息,提取也很好提

正常来说,直接zsteg xxx.png可以显示大部分可读的颜色通道隐写的部分内容,然后一些情况下,我们可能会发现稍大文件被隐写进去,这时候我们需要使用**-E xxx<通道组合>** 来完整提取隐写数据到文件中

image-20251001161738864
1
0xGame{W1_Need_t0_t@k3_a_break}

ezshell_PLUS

本题是ezshell的进阶,就是看看大家的自学能力如何,下面我给出我的步骤

image-20251001163833641
1
sha256sum files/* | grep -i "021832def36ccd081b38d8fd51b534d70826b5df4423ce2c15386797ab08bef8"

我猜测这里让你们感觉新奇吧,就是用了个管道符,让前一步的输出作为后一步的输入

然后用到了sha256sum,grep命令,这些也很常见,分别是计算哈希和查找

然后这里有个”*“,它被叫做通配符,可以匹配任意字符

学长只能说,多见多学多用,命令行用熟悉,会对后面的学习帮助很大

Do not enter

本题考察了dd镜像挂载与分析

我们首先用file命令查看镜像的基本结构

1
2
file do_not_enter.dd
do_not_enter.dd: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x10,0,1), end-CHS (0x28f,3,32), startsector 2048, 81920 sectors; partition 2 : ID=0x83, start-CHS (0x2a0,0,1), end-CHS (0x3ff,3,32), startsector 86016, 81920 sectors; partition 3 : ID=0xf, start-CHS (0x3ff,3,32), end-CHS (0x3ff,3,32), startsector 169984, 178176 sectors

从输出可以看出,do_not_enter.dd是一个MBR(主引导记录)格式的磁盘镜像,包含一个引导扇区和三个分区

  • 分区1和2是Linux原生分区(类型0x83)
  • 分区3是扩展分区(类型0x0f),通常用于容纳更多逻辑分区

上面看不懂问题不大,反正和下面的解题过程没多少关系,做多了,就会有更深的体会(●’◡’●)

💡 小知识:MBR 是一种较老但广泛支持的分区方案,现代系统更多使用 GPT,但大多数 Linux 工具(如 fdiskmountlosetup 等)依然能很好地处理 MBR 镜像。
如果你还不熟悉“引导扇区”“分区表”这些概念,没关系!你可以简单把它理解为:这个 .dd 文件就像是把一整块硬盘“拍了张快照”保存下来了。我们要做的,就是用合适的工具把这个“虚拟硬盘”挂载到系统里,像打开普通文件夹一样去查看里面的内容。

做法

第一步:创建循环设备映射

1
sudo losetup -fP do_not_enter.dd

命令解释:

  • losetup:linux下的循环设备管理工具,能将文件虚拟成块,换句话说,就是把一个dd文件转换成机器磁盘可以读的格式
  • -f:自动查找第一个可用的loop设备
  • -P:关键参数!让内核在关联后重新扫描分区表,自动创建分区设备节点
  • 作用:将DD镜像文件虚拟成一个”硬盘“,系统会识别出其中的分区结构

第二步:验证设备映射状态

1
sudo losetup -a

命令解释:

  • -a:显示所有活跃的loop设备状态

第三步:识别分区结构与标签

1
lsblk -f /dev/loop0 #后面的/dev/loop0是通过第二步得到的

命令解释:

  • lsblk:列出块设备信息的专业工具
  • -f:显示文件系统信息,包括分区标签
  • 我的考点其实就是这里,就像题目说的那样,我们应该选中那个do_not_enter的标签

第四步:挂载目标分区

1
2
mkdir -p /mnt/test
sudo mount /dev/loop0p2 /mnt/test

命令解释:

  • mount:标准的文件系统挂载命令
  • /dev/loop0p2:我们要挂载的分区设备 #这里的参数是通过第三步得到的
  • /mnt/test:我们设置的挂载点目录
  • 底层原理:将分区中的ext4文件系统挂载到目录树,使文件可访问

第五步:搜索flag内容

1
sudo grep -r "0xGame" /mnt/test

命令解释:

  • grep:强大的文本搜索工具
  • -r:递归搜索,遍历目录下的所有文件
  • “0xGame”:flag头

第六步:清理

1
2
3
sudo umount /mnt/test
sudo losetup -d /dev/loop0
sudo rmdir /mnt/test

本题还有其他工具能快速挂载,比如说kpartx

然后关于blkid,也能用它来读取那个分区的标签,在某些情况下,它可以和lsblk换着用

特性 blkid lsblk
主要功能 读取文件系统的元数据和属性 显示块设备的拓扑结构和关系
数据来源 读取文件系统的超级块(superblock) 查询内核的块设备信息(sysfs)
输出视角 文件系统视角 设备拓扑视角
信息类型 文件系统特定属性(UUID, LABEL, TYPE) 设备层次关系(父子、大小、挂载点)
使用场景 按属性识别和挂载文件系统 理解磁盘分区结构和布局

然后下面是我给出的参考步骤,可以看出在正确步骤下,我们只能找到一个完完整整的flag的,fake flag真的一点也没为难大家的(盲猜有人说我胡乱塞东西,哈哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
~$ sudo losetup -fP do_not_enter.dd
~$ sudo losetup -a
/dev/loop0: [2096]:536444 (/home/yolo/Desktop/timu/0xGame_challenge/do_not_enter.dd)
~$ lsblk -f /dev/loop0
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0
├─loop0p1 ext4 1.0 UserShare 5a6be8f0-43f9-4020-a729-510d6d57e95b
├─loop0p2 ext4 1.0 Do_not_enter 643298ec-2a07-4681-9555-addf90de8ae1
├─loop0p3
├─loop0p5 ext4 1.0 WebServer f965eed6-3de2-4533-8e06-2c816f9e4574
└─loop0p6 ext4 1.0 SysLogs 650ce632-c57e-41c6-8a3b-c6bf3d4e2193
~$ sudo mount /dev/loop0p2 /mnt/test
~$ sudo grep -r "0xGame" /mnt/test
/mnt/test/syslog:0xGame{WoW_y0u_fouNd_1t?_114514}
~$ sudo umount /mnt/test
~$ sudo losetup -d /dev/loop0
~$ sudo rmdir /mnt/test
image-20251002010301159

一些其他工具(Windows,本意还是让大家掌握dd镜像挂载方式,但是赖我,没有给大家说清楚,应该关注分区标签,为各位师傅解题时候造成困扰感到抱歉

  • AXIOM
image-20251009225550160
  • DiskGenius
image-20251009225621434
  • R-Studio
image-20251009225641928

学长碎碎念

关于本题,我设置了180个fake flag,目的就是希望新生们采取专业工具科学地进行分析,而不是使用strings暴力手撕,然后在Windows这边,有人用axiom能读出标签名,我测试过autopsy,发现不能显示分区标签,而且一些选手和我聊过,他们用火眼、取证大师等等著名一把梭取证工具也没能解决出来(可见我出的题还蛮好 ,其实是希望学弟学妹们在后面的学习中,会遇到越来越多的一把梭脚本或者说是妙妙小工具,我并不排斥使用的,但是!我希望你们能掌握对应的原理并亲手用自己的"笨"方法解决出一两道后再选择是否使用所谓的“一把梭”,不然,没了好用的神奇小工具,你还能做出什么呢?

在我看来,一把梭工具应该被用在重要赛事抢血上,而不是简单小比赛上冲榜用的

接下来关于AI,这个是近年来最热门的东西,有了ai,对你们入门ctf的帮助会非常非常大,不用觉得啥事都问ai会不好意思,因为我也最开始啥也不懂,这样过来的。所以还是很鼓励大家学习新知识的时候,先自己研究,卡住的话询问ai解决方案,接下来才是找圈子内厉害的师傅(一定要整理并描述清楚自己遇到的问题,不然对他们来说,帮你解惑的难度会上一个档次,haha

然后每次从ai那里拿到解决方案,希望你们能从中学习到一些,而不是无脑的ai说啥你干啥,不然下次遇到类似的问题,我们再问一遍AI?这也就带出了我下面给大家的忠告:一定合理使用AI,趁着AI在旁边,我们多通过它学习一些新知识,等我们用不了的情况下,也不会手足无措(想象这样一个情景,如果说你啥事只会问ai,那么你所做的事情是不是任何人都能替代?是不是说你失去了ai,会一点竞争力都没有?


0xgame2025_Misc_Teching
https://yo1o.top/2025/10/11/0xgame2025teching/
作者
Yolo
发布于
2025年10月11日
许可协议