TGCTF 2025

比赛地址:TGCTF2025

比赛时间:12 Apr 2025 09:00 CST - 13 Apr 2025 21:00 CST

复现的题目用🔁标注

Misc

where it is(osint)

Challenge

小明骑着机车在路上驰骋的时候给我拍了一张照片,说找得到他在哪里就请我吃海鲜,你能把他揪出来吗?(flag 形式为 TGCTF {右上角轨道到站的站名})

where it is

解题思路

TGCTF2025-1

截取图片的关键部分识图

TGCTF2025-2

在谷歌地图搜索对应位置

TGCTF2025-3

1
TGCTF{港墘站}

next is the end

Challenge

没有人知道那一天 J1nghong 被看到了什么东西,人们只知道从那以后再也没有人能手动的点开看到他任何一个文件夹里的宝藏(请提交形式为 flag {} 的最终答案)

Solution

TGCTF2025-4

文件夹套娃,用 VSCode 打开这个文件夹直接秒了

1
flag{so_great!}

你的运气是好是坏?

Challenge

好運來 祝你好運來 好運帶來了喜和愛 好運來 我們好運來 迎著好運興旺發達通四海 疊個千紙鶴 再系個紅飄帶 願善良的人們天天好運來 你勤勞生活美 你健康春常在 你一生的忙碌為了笑逐顏開 打個中國結 請春風剪個彩 願祖國的日月年年好運來 你鳳舞太平年 你龍騰新時代 你幸福的家園迎來百花盛開 好運來 祝你好運來 好運帶來了喜和愛 好運來 我們好運來 迎著好運興旺發達通四海 疊個千紙鶴 再系個紅飄帶 願善良的人們天天好運來 你勤勞生活美 你健康春常在 你一生的忙碌為了笑逐顏開 打個中國結 請春風剪個彩 願祖國的日月年年好運來 你鳳舞太平年 你龍騰新時代 你幸福的家園迎來百花盛開 好運來 祝你好運來 好運帶來了喜和愛 好運來 我們好運來 迎著好運興旺發達通四海 好運來 祝你好運來 好運帶來了喜和愛 好運來 我們好運來 迎著好運興旺發達通四海 好運來 祝你好運來 好運帶來了喜和愛 好運來 我們好運來 迎著好運興旺發達通四海 通四海 好運來 flag 为 TGCTF

Solution

TGCTF2025-5

TGCTF2025-6

猜测依据如上

1
TGCTF{114514}

🔁这是啥 o_o

Challenge

最近某人突然喜欢上了 ai 绘画的产物,这简直不可饶恕!但是他为了让别人也有机会欣赏,居然夹带私货把 " 鬼图 “放进了题目里(请提交形式为 TGCTF {} 的最终答案)

有一天我们会接受ai吗

Solution

分解帧得到 30 张图片

在最后 9 张图片的左上角发现了不知道是什么码的碎片

TGCTF2025-7

写一个脚本读取这 9 张图片,截取每张图片的左上角 38*38 的部分,然后再按名字顺序把这九张正方形的图片拼接起来

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
from PIL import Image
import os

# 输入路径和输出路径
input_dir = "Zhe_Shi_Sha_o_o/gifframe"
output_path = "Zhe_Shi_Sha_o_o/output_image.png"

# 裁剪尺寸
crop_size = (38, 38)

# 图片编号范围
image_numbers = range(22, 31) # 22 到 30

# 读取并裁剪图片
cropped_images = []
for num in image_numbers:
file_name = f"{num}.png"
file_path = os.path.join(input_dir, file_name)

# 裁剪
with Image.open(file_path) as img:
cropped_img = img.crop((0, 0, crop_size[0], crop_size[1]))
cropped_images.append(cropped_img)

# 创建一个新的空白图片,用于拼接
new_image_size = (crop_size[0] * 3, crop_size[1] * 3)
new_image = Image.new("RGBA", new_image_size)

# 将裁剪后的图片拼接到新图片中
for i, img in enumerate(cropped_images):
row = i // 3 # 计算行号
col = i % 3 # 计算列号
new_image.paste(img, (col * crop_size[0], row * crop_size[1]))

# 保存拼接后的图片
new_image.save(output_path)
print(f"拼接完成,结果已保存到 {output_path}")

TGCTF2025-8

拼接得到的是一个汉信码,找了一个在线网站扫描在线汉信码识别

TGCTF2025-9

得到结果 time is your fortune ,efficiency is your life

这提醒我们要关注时间,联想到 gif 的帧间隔隐写

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
from PIL import Image, ImageSequence

def decode_message_from_gif(gif_path, time_scale_factor=1):

img = Image.open(gif_path)

durations = []

print("Extracting frame durations:")
for i, frame in enumerate(ImageSequence.Iterator(img)):
duration = frame.info.get('duration') # 获取当前帧的时间间隔
if duration is None:
print(f"Warning: Frame {i + 1} has no duration information. Skipping...")
continue

scaled_duration = int(duration / time_scale_factor) # 缩放时间间隔
durations.append(scaled_duration)
print(f"Frame {i + 1}: Original Duration = {duration}, Scaled Duration = {scaled_duration}")

print("\nFull Scaled Durations:", durations)

# 尝试将时间间隔值直接转换为字符
try:
message = ''.join(chr(d) for d in durations if 32 <= d <= 126) # 过滤可打印字符
print("\nDecoded Message (ASCII):", message)
except ValueError as e:
print(f"Error decoding durations: {e}")
message = "Decoding failed. Check the durations manually."

return message


# 从GIF中解码消息
gif_path = "Zhe_Shi_Sha_o_o/有一天我们会接受ai吗.gif"
decoded_message = decode_message_from_gif(gif_path,10)
print("\nFinal Decoded Message:", decoded_message)

运行得到 flag

1
TGCTF{You_caught_up_with_time!}

🔁TeamGipsy&ctfer

Challenge

通过网盘分享的文件:TeamGipsy&ctfer (1).zip

链接: https://pan.baidu.com/s/1ssrn654ByHi0oiQRV5k7DA?pwd=GAME

提取码: GAME

解压密码为 66cffa039811fb39

Solution

TGCTF2025-10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 1  passwd hznuctfer
2 reboot
3 pass
4 passwd hznuctfer
5 reboot
6 sudo apt update
7 sudo apt install docker.io
8 clear
9 docker -v
10 docker run -d --name TeamGipsyctf1 -e MYSQL_ROOT_PASSWORD=password_is_me mysql
11 docker exec -it TeamGipsy1 bash
12 docker exec -it TeamGipsyctf1 bash
13 docker run -d --name TeamGipsyctf2 -e MYSQL_ROOT_PASSWORD=password_is_me mysql
14 docker exec -it TeamGipsy2 bash
15 docker exec -it TeamGipsyctf2 bash
16 docker -l
17 docker ps
18 docker stop TeamGipsyctf1
19 docker stop TeamGipsyctf2
20 docker ps
21 exit
22 history
23 history > mimi.txt

发现这里启动了两个 MySQL 容器然后又关了,于是去 /var/lib/docker/volumes/ 看看卷存了些啥

经过一番搜索得知 TeamGipsy 文件夹下的两个 .ibd 是 InnoDB 存储引擎用来存储表数据和索引的物理文件,也就是说数据都存在这里面

然后再找个解析工具,发现了 ddcw/ibd2sql

经尝试, flag 藏在 1783d31445c82f27a817f947a32249bd2f15738dbb9906685aea05a339df20ba\_data\TeamGipsy\TG.ibd 下,运行命令 python main.py .\1783d31445c82f27a817f947a32249bd2f15738dbb9906685aea05a339df20ba\_data\TeamGipsy\TG.ibd --sql --ddl 解析,返回如下

1
2
3
4
5
6
CREATE TABLE IF NOT EXISTS `TeamGipsy`.`TG`(
`id` int NOT NULL AUTO_INCREMENT,
`flaghere` varchar(255) NULL,
PRIMARY KEY (`id` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
INSERT INTO `TeamGipsy`.`TG` VALUES (1, 'HZNUCTF{0H!_YOu_are_really_the_TeamGipsy_ctfer}');
1
HZNUCTF{0H!_YOu_are_really_the_TeamGipsy_ctfer}