【愚公系列】2022年02月 攻防世界-进阶题-MISC-83(qr-easy)

举报
愚公搬代码 发表于 2022/02/14 14:45:56 2022/02/14
【摘要】 一、Keyes_secret题目链接:https://adworld.xctf.org.cn/task/task_list?type=misc&number=1&grade=1&page=5 二、答题步骤 1.下载附件得到一张图片:首先,我们需要基于上图的干净图像。此二维码的大小为 29x29,版本V的大小为N × N,N = 17 + 4V,所以这是版本 3。 2.二维码格式信息该区域表...

一、Keyes_secret

题目链接:https://adworld.xctf.org.cn/task/task_list?type=misc&number=1&grade=1&page=5
在这里插入图片描述

二、答题步骤

1.下载附件

得到一张图片:
在这里插入图片描述
首先,我们需要基于上图的干净图像。
在这里插入图片描述
此二维码的大小为 29x29,版本V的大小为N × N,N = 17 + 4V,所以这是版本 3。

2.二维码格式信息

该区域表示二维码的格式信息。实际上,格式信息是 15 位长,区域有最后 8 位。
在这里插入图片描述
搜索所有格式信息字符串的列表,我们可以发现类型信息位是001001110111110.所以这个二维码有ECC级别H和掩码模式1。

所有格式信息字符串的列表:

ECC 级别 蒙版图案 类型信息位
L 0 111011111000100
L 1 111001011110011
L 2 111110110101010
L 3 111100010011101
L 4 110011000101111
L 5 110001100011000
L 6 110110001000001
L 7 110100101110110
M 0 101010000010010
M 1 101000100100101
M 2 101111001111100
M 3 101101101001011
M 4 100010111111001
M 5 100000011001110
M 6 100111110010111
M 7 100101010100000
Q 0 011010101011111
Q 1 011000001101000
Q 2 011111100110001
Q 3 011101000000110
Q 4 010010010110100
Q 5 010000110000011
Q 6 010111011011010
Q 7 010101111101101
H 0 001011010001001
H 1 001001110111110
H 2 001110011100111
H 3 001100111010000
H 4 000011101100010
H 5 000001001010101
H 6 000110100001100
H 7 000100000111011

1 号掩码有公式(row) mod 2 == 0。注意行号是从0开始的,所以我们要切换坐标为0,2,4,…,28的行的位。

掩码号 如果下面的公式对于给定的行/列坐标为真,则切换该坐标处的位
0 (行 + 列) mod 2 == 0
1 (行) mod 2 == 0
2 (列) mod 3 == 0
3 (行 + 列) mod 3 == 0
4 (楼(行 / 2)+ 楼(列 / 3)) mod 2 == 0
5 ((行 * 列) mod 2) + ((行 * 列) mod 3) == 0
6 ( ((行 * 列) mod 2) + ((行 * 列) mod 3) ) mod 2 == 0
7 ( ((行 + 列) mod 2) + ((行 * 列) mod 3) ) mod 2 == 0

在这里插入图片描述

所以4行2列一组,原始的 D1-D26 是:

D1  = 0b11101100
D14 = 0b10000010
D2  = 0b11111000
D15 = 0b10010101
D3  = 0b00110110
D16 = 0b00111101
D4  = 0b01110110
D17 = 0b01100010
D5  = 0b00100010
D18 = 0b11101001
D6  = 0b11110001
D19 = 0b10100001
D7  = 0b00110111
D20 = 0b11100101
D8  = 0b01010010
D21 = 0b11010101
D9  = 0b00010111
D22 = 0b00101101
D10 = 0b11011110
D23 = 0b10010111
D11 = 0b01000100
D24 = 0b10001011
D12 = 0b01010100
D25 = 0b01111000
D13 = 0b11001101
D26 = 0b11000110

(行) mod 2 == 0 掩码之后

D1  = 0b00100000
D14 = 0b01001110
D2  = 0b00110100
D15 = 0b01011001
D3  = 0b11111010
D16 = 0b00001110
D4  = 0b01000101
D17 = 0b01010001
D5  = 0b00010001
D18 = 0b11011010
D6  = 0b00111101
D19 = 0b10010010
D7  = 0b00000100
D20 = 0b11010101
D8  = 0b10011110
D21 = 0b00011001
D9  = 0b11010100
D22 = 0b00010001
D10 = 0b00010100
D23 = 0b00001110
D11 = 0b11011101
D24 = 0b00010010
D12 = 0b11010010
D25 = 0b00011111
D13 = 0b01010100
D26 = 0b01000000

3.数据解码

解码有模式指示符:

0001:数字模式(每 310 位)
0010:字母数字模式(每 2 个字符 11 位)
0100:字节模式(每个字符 8 位)
1000:汉字模式(每个字符 13 位)
0111: ECI 模式

字符计数指示符跟在模式指示符之后。

版本 1-9
数字模式:10 位
字母数字模式:9位
字节模式:8位
汉字模式:8位
版本 1026
数字模式:12位
字母数字模式:11 位
字节模式:16位
汉字模式:10位
版本 2740
数字模式:14位
字母数字模式:13 位
字节模式:16位
汉字模式:12

4.Ruby脚本

data = '00100000' \
       '00110100' \
       '11111010' \
       '01000101' \
       '00010001' \
       '00111101' \
       '00000100' \
       '10011110' \
       '11010100' \
       '00010100' \
       '11011101' \
       '11010010' \
       '01010100' \
       '01001110' \
       '01011001' \
       '00001110' \
       '01010001' \
       '11011010' \
       '10010010' \
       '11010101' \
       '00011001' \
       '00010001' \
       '00001110' \
       '00010010' \
       '00011111' \
       '01000000'
alphanumeric = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'.chars

def read(str, size)
  str.slice!(0, size)
end

def kanji(num)
  if num >= 0x1740
    (0xC140 + num / 0xC0 * 0x100 + num % 0xC0)
      .chr(Encoding::Shift_JIS).encode(Encoding::UTF_8)
  else
    (0x8140 + num / 0xC0 * 0x100 + num % 0xC0)
      .chr(Encoding::Shift_JIS).encode(Encoding::UTF_8)
  end
end

loop do
  case mode = read(data, 4)
  when '0010' # Alphanumeric
    count = read(data, 9).to_i(2)
    (count / 2).times do
      chunk = read(data, 11).to_i(2)
      print alphanumeric[chunk / 45] + alphanumeric[chunk % 45]
    end
    print alphanumeric[read(data, 11).to_i(2)] if count.odd?
  when '0100' # Byte
    count = read(data, 8).to_i(2)
    count.times do
      print read(data, 8).to_i(2).chr
    end
  when '1000' # Kanji
    count = read(data, 8).to_i(2)
    count.times do
      print kanji(read(data, 13).to_i(2))
    end
  when '0000' # Terminate
    break
  else
    fail "Unhandled mode #{mode}"
  end
end

使用 Ruby 运行上述代码来获得falg:SECCON{PSwIQ9d9GjKTdD8H}

总结

  1. 二维码
  2. ruby
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。