QR Puzzles from SECCON CTF
上周末的 SECCON CTF, 有几个 QR 码的题..
Problem 1¶
http://www.youtube.com/watch?v=omobhuutrE4
这个视频里, 中间最下方有一个滚动的被挡住的 QR 二维码.
先抽帧. 二维码是 37x37 的, 因此我挑了一个 fps=6.8, 使得二维码滚过去的时间差不多为 37 帧.
|
图中的文字部分是扭曲的, 因此标出一个 perspective 变换, 将文字部分扭正:
|
然后将每幅图的最后一行拼起来, resize 成方形再做二值化, 得到二维码:
噪声较大, 但是使用一个足够好的扫码软件是能够扫出来的 (反正微信扫不出来).
后来想到, 由于总是要 resize 成方形, 所以抽帧频率其实是不太重要的, 再抽的密一些可能还可以减少噪声. 甚至 perspective 可能也不需要做..
Problem 2¶
题中的二维码严重缺失, 找了找 QR Code 的 specification 发现 codeword 的 layout:
可以看到, 对于 29x29 的二维码, 所有的 data codewords 在图中都是完好的, format 部分有一点, 也足够恢复出 format 信息. (format 有效值只有 5 位, 其余为冗余编码).
即使将 Fixed Patterns 部分补全, 也无法用常用软件恢复, 因为软件的工作原理都是在假设每个点都有可能错误的情形下, 利用 error correction codewords 进行纠正, 这也是 qr 码的设计初衷. 而题目提供的信息是 "保证正确的点 + 缺失的点", 由于缺失过多, 又无法向软件提供 "保证正确" 这一信息, 因而无法恢复, 需要研究 qr 编码方式.
为了便于识别, qr 码需要避免出现大片的连续黑白区域, 因此在将数据及 EC 编码结束后, 会对其尝试应用一些全局的 mask, 挑一个效果最好的 mask.
从 format 中可以得到本题的 mask 为 001, 因此对 data 部分异或一次 mask, 就可得到真实的二进制数据, 再按照 layout 图中标出的阅读顺序, 将 26x8 个 bit 解析出来:
|
qr 码编码分为若干 segment, 每一个 segment 包含 4bit 的类型标识 (数字 / 数字字母 / byte 等),segment 长度, 及数据. 在 ISO/IEC 18004:2006 标准手册中找到具体的规则, 即可将以上数据解码为答案.
Problem 3¶
此题只提供了 EC 部分, qr 码使用的是 Reed-Solomon Error Correction.
比赛时看不下去数论, 就利用一些尝试性的东西乱搞, 最终把答案的前 11 个字符弄出来了, 后面就弄不动了.
以后有空看了 reed-solomon 再解决它吧..