关于我送毕业祝福贺卡不写人话这件事

最后更新于 2021-06-25 5,861 次阅读


背景

起因是在为我们学校高三毕业生写毕业贺卡时,给他们写了“迷题”一样的东西上去。反正结果就是我也不知道有没有人猜出来,因为貌似没人看得懂。反正就水篇文章探讨一下,毕竟这些题目还是对于高中生来说有点难度的(指 CTF)。

题目一

MTc2MjJCRjA6MUU2MQ==

出题人:Akira

考察要点

  • Base64 编解码的掌握
  • IP 地址的进制转换
  • 网页 Debug 基础

这份是我自己编的,如果对网络基础知识了解的人可以算是非常简单的了,创意方面我也在 Nazo Game 中获取了不少灵感,不过这里并没有借鉴他们的创意。

Base64 解码

看到这段字符后面的两个等号可能最先想到的就是经过 Base64 转换的字符,那么应该如何区分?

  • Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法,包括大小写字母 A-Za-z,数字 0-9 ,两个可打印符号 +, /(两个可打印符号在不同的系统中而不同)和用作后缀用途的等号 = 来表示。
  • Base64 编码要求把 3 个 8 位字节(3*8=24)转化为 4 个 6 位的字节(4*6=24),之后在 6 位的前面补两个 0,形成 8 位一个字节的形式。 如果剩下的字符不足 3 个字节,则用 0 填充,输出字符使用 =,因此编码后输出的文本末尾可能会出现 1 或 2 个 =
  • 为了保证所输出的编码位可读字符,Base64 制定了一个编码表,以便进行统一转换。编码表的大小为 2^6=64,这也是 Base64名称的由来。
索引对应字符索引对应字符索引对应字符索引对应字符
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62+
12M29d46u63/
13N30e47v
14O31f48w
15P32g49x
16Q33h50y
Base64 转换表

依据这些对 Base64 的介绍,我们可以写一个正则表达式来匹配 Base64 编码 ^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$

那么我们要把这段经过 Base64 编码后的可打印字符解码就可以这样反向推导:

Base64 解码
Base64 编码 M T c 2 以此类推
索引 12 19 28 54
二进制位 0 0 1 1 0 0 0 1 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0
ASCII 编码 49 55 54
文本 1 7 6

因为最后会多出 2 个字节用 = 代替,所以编码前的字节数不能被 3 整除,余数为 2,即最后剩余两个八位(待补足)字节(2 个 byte),而最后一个 6 位的 Base64 字节块有四位是 0 值。

Base64 解码
Base64 编码 M Q = =
索引 12 16
二进制位(补0) 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ASCII 编码 49
文本 1

或者你可以通过在线的 Base64 编解码程序直接转换出来。

最后得到的结果为 17622BF0:1E61

十六进制转 IP 地址

先看这种格式,其实是一个十六进制数的 IP 地址+ 端口,用正则表达式来 Match 可以这么写:^[0-9a-fA-F]{1,3}$ 为了防止有人爆破此 IP 我还是选择不明说答案(迫真保命)

那么我们只需要把它转换成十进制就可以得到答案,接着你能通过答案去进入一个网页。

在网页中找到彩蛋

在浏览器中打开上面解出来的 IP:Port 后我们发现这是貌似是一个空白页面,只有标题写着 "What are you looking for?"。遇到这种情况,以多年网上冲浪经验的你应该会想到查看 Elements 或是用 Console 查看或使用调试内容等,算是我们前端 Debug 的通用手段。

这里也是如此,打开 Console 就能看到输出的调试信息,Elements 也能查到。这样你就成功找到了 EGG 了!

题目二

这道题是基于 LCTF2018 的一道比赛题目出的,此题大部分难点在于数据包分析,我们来看看。

OSU

h77p5://1ch1n053.h0n4m1.c1u8/f1135/05u.pc4p

CTF!

出题人:Akira & LCTF2018

考察要点

  • Leet Speak
  • 数据包的分析掌握
  • exp 脚本运用

1337 Speak

1337 (Leet) Speak,又称黑客语。简单来说就是把原本的字符写成形状相似的其它字符,通常将拉丁字母转变成数字或是特殊符号等。例如标题中字母 l 写成数字 1,字母 e 写成 数字 3(相似于大写的 E),字母 t 写成数字 7。将单字写成同音的字母或数字也属于 Leet,但这道题目中不会涉及。

转换后转换前
7t
5s
1i & l
0o
3e
8b
4a
本题中 Leet 的对应转换

那么通过对原先单词的猜测可以翻译为网址:https://ichinose.honami.club/files/osu.pcap

对数据包分析

进入上面解出来的 URL 会下载一个 .pcap 的文件,这是由 Wireshark 创建的数据文件

玩过 CTF 的人会知道,CTF 旨在夺旗(Capture the Flag)。我们需要从这个数据包中找出 FLAG,以下是其中一种解题思路。这里要感谢 @TundraWork 在 Github 上贡献的题目源代码,让我们看看他们团队写的这篇 Writeup 原文地址


你会玩osu!么?

题目描述: 你从未玩过的船新音游, osu.ppy.sh 了解一下

题目给了一个 USB 流量包,首先我们用 Wireshark 打开看一下:

我们发现有多个设备的流量,而且整个捕获持续了很长时间,看来需要详细分析一下。

其中我们发现一个汇报为 G102 Prodigy Gaming Mouse 的罗技鼠标,但过滤后发现此设备的回报数据很少,没有什么价值。另外还发现一个汇报为 CTL-472 的设备,搜索一下发现是 Wacom 的数位板设备,是一个绝对坐标指针设备,而且它的汇报是等时间间隔(固定回报率)的。猜测可能是通过这个设备的移动轨迹提供信息。

二话不说上 tshark 过滤一下数据格式。

分析一下这个设备的数据,发现类似于如下格式:

02:e1:76:2b:e5:13:54:02:1a:00

其中第 3 和第 5 个 byte 变化幅度较小,第 2 和第 4 个 byte 变化幅度较大,可以猜测出是数位板的 x y 坐标,分别 2 个 byte ,小端。

02:e1:x(76:2b):y(e5:13):54:02:1a:00

同时我们还知道数位板设备是可以汇报笔接触板子的压力大小的,分析数据我们可以发现倒数第 3 个 byte 是压力:

02:e1:x(76:2b):y(e5:13):54:pressure(02):1a:00

同时我们可以查到,这个设备是可以在笔一定距离悬空时仍然检测到笔位置的,那么我们可以大胆猜测笔触板后的移动轨迹里藏着信息。经过分析后找到一个合适的 pressure 阈值,给 CTL-472 设备移动轨迹画图。

The "Easier" Way

如果你有足够的耐心,还是可以找到数位板画 flag 的那一段时间的,只需要过滤出这段时间的数据,按照上面所说根据 pressure 画图,就可以得到比较清楚的结果,直接交题走人。

下面给出 whitzard 的脚本:

import turtle as t

t.screensize(2400, 2400)
t.setup(1.0, 1.0, 0, 0)
keys = open('usbdata.txt')
i=0
for line in keys:
	i+=1
	if len(line) == 30 and i>3000:
		a0 = int(line[6:8], 16)
		a1 = int(line[9:11], 16)
		x = a0+a1*256
		b0 = int(line[12:14], 16)
		b1 = int(line[15:17], 16)
		y = b0+b1*256
		press = int(line[21:23], 16)
		if x!=0 and y!=0:
			t.setpos(x/20-500,-y/20)
			if press > 2:
				t.pendown()
			else:
				t.penup()

The "Harder" Way

但画出来发现无用的线条太多了,我们是不是漏掉了什么过滤条件?

既然题目让我们了解一下这个船新音游,那我们就了解一下,打开 osu.ppy.sh ,点击导航栏 help 进入 wiki ,首先看一下默认游戏模式玩法: https://osu.ppy.sh/help/wiki/Game_Modes/osu!

粗略翻了一下,大意就是用一个指针设备控制移动,z x 两个按键控制点击。不过在稍下面我们发现了一个有趣的东西:

意思是我们可以在游戏中按下 c 键的同时移动光标画画?

因垂丝汀,我们回头看一下完整的 pcap 包,发现这样一个设备:

这个设备在 1.8.0 汇报状态, 1.8.1 进行数据通信,分析通信数据我们可以很容易看出这是一个典型的 USB HID Keyboard 。我们拿出所有 1.8.1 的数据,它们都是 8 byte 的,根据 USB UID spec :

同时我们查表(链接)得到游戏默认三个按键的对应 keycode :

Z: 1D X: 1B C: 06

那么我们只需要扫描第 2-7 byte 的值,找到任何一个 byte 值为 06 的数据包表示此时按下 C ,同时后续第一个没有任何 byte 值为 06 的数据包表示此时松开 C 。过滤出所有按下 C 的时间段内的来自 1.7.1 的数据,再画出数据所表示的点,即可得到清晰的 flag 图像。

至于 exp 脚本?这道题没有一个队伍使用此思路解题,所以留个课后练习,请大家自己动手尝试一下吧~


总结

第一题是是个人出的一个小彩蛋,并没有绕太多弯,只是做个小解密游戏给大家当热身了。第二题要求掌握的要点还是比较苛刻的,如果你曾玩过 OSU! 这款游戏就会相对好理解。本人还是水平有限,毕竟顾及到非专业人士,出的水平还很逊,与 CTF 比赛的题目相比还是自愧不如。

如果您对这这次的文章还算满意或是有其它意见,欢迎在评论区探讨。

Views: 48