Skip to content

Latest commit

 

History

History
96 lines (65 loc) · 5.47 KB

File metadata and controls

96 lines (65 loc) · 5.47 KB

ThrRip's Hackergame 2024 Write-ups

先说点废话

第一次打 CTF,也是第一次玩 Hackergame。不是学计算机的,不是理科生,也不是工科生,所以有技术含量的题目就全部跳过了💦(也就是为什么只写了「无法获得的秘密」的题解)。题目最终完成度如下:

题目完成度

无法获得的秘密

在 2024 年,只需要一个浏览器就可以做到:

于是作为 web 开发者,我真的就只用了一个浏览器。用非常短的 shell 脚本(所以不需要自动输入的工具)为 secret 分块并显示为黑白块,用 JavaScript 读取并还原为二进制位,并且过程是实时的(下面解释了如何同步发送端和接收端)。

发送端

首先在新标签页中打开 VNC 控制台,然后把远端主机的屏幕分辨率调整为 1920x1200,以获得最多的有效像素。

在新标签页中打开 VNC 控制台

调整远端主机的屏幕分辨率

打开终端。可以用 Ctrl+- 缩小字符以进一步提高数据密度。用以下命令确认终端的行列数量。

tput cols
tput lines

找到小于 $(tput cols) 的最大的 8 的倍数,作为数据显示区域的宽。用 $(($(tput lines) - 1)) 作为数据显示区域的高(留一行用于显示当前传输的块的编号)。把这两个数填入 encode.sh 中的 _vw_vh 变量,然后运行。当然也可以不保存为脚本文件,直接输入每一行命令并运行。

其中,用 splitsecret 分成文件名为 secret.000secret.001、……的块。

split -a 3 -b $(($_vw * $_vh / 8)) -d secret secret.

然后用 basenc 把每块转为用 01 表示的二进制位,用 sed0 替换为空格,把 1 替换为 ,转换后保存为 secret.000.txtsecret.001.txt 等文件。

for c in secret.*; do basenc --base2msbf -w $_vw $c | sed -E 's/0/ /g; s/1/█/g' > $c.txt; done

使用 send.sh 在一个绝对的时间点开始发送(显示),并按设置的固定间隔切换到下一块。在接收端也使用同样的设置,就可以实时发送和接收。

# The second in the current minute to start
_s=$1
# Interval (seconds) between chunks
_i=$2

[ $_s -gt $((10#$(date +%S))) ] && sleep $(($_s - $((10#$(date +%S))) - 1)).$((1000 - 10#$(date +%N | head -c 3)))

for c in secret.*.txt; do clear; cat $c; echo -n $c; sleep $_i; done

接收端

Tip

如果你想亲自运行接收端程序进行尝试,请使用:

cd unobtainable-secret/decode
pnpm i --frozen-lockfile
pnpm run build
pnpm run preview

如果需要编辑代码后在浏览器中实时更新,可以使用 pnpm run dev。需要注意 unobtainable-secret/decode/ 目录下的所有文件均使用 Mozilla Public License version 2.0(MPL 2.0)许可,不同于此存储库主要使用的知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议,详见本文的许可部分。

有一个很酷的 UI。

接收端界面

controls 区域输入必填的设置后,即可 Start capture。解析出的内容会以每块一个 Uint8Array 显示在 output 区域。点击 Save 可以把这些内容保存为二进制文件。

Tip

因为该传输方式没有纠错机制,建议使用 (Optional) Stop after reading ... bytes 设置,每 50 或 100 个块停止读取并保存一次,检查这些块的校验和。

在远端主机合并指定区间的块并计算 SHA-256:

# 第 1 至 50 块(000 至 049)
for c in secret.{000..049}; do cat $c >> secret.000..049; sha256sum secret.000..049; rm -f secret.000..049; done

Note

根据我的测试,Chromium 的 Canvas API 性能非常低。接收端读取每一块的时刻,是在每块显示间隔之间的中间点,这样能确保网络抖动带来的影响变得最小。在 Firefox 中可以把间隔(Read and decode every ...ms 以及 send.sh$_i)设置为 1 秒,但是在 Chromium 中必须设置为至少 4 秒,否则无法在指定时间内处理完每块的内容。

许可

本仓库 /players/ThrRip/unobtainable-secret/decode/ 目录下的所有文件基于 Mozilla Public License version 2.0(MPL 2.0)许可发布。