内角540°

セキュリティ。SIEMとかIPSとか統計とかクラウドとか。数学以外で。

0CTF(2017) writeup #oneTimePad

問題

I swear that the safest cryptosystem is used to encrypt the secret!
oneTimePad.zip

2ファイルを渡される。

①暗号化用のスクリプト
oneTimePad.py
②フラグを暗号化した結果ファイル
ciphertext

解く

GF(2^{256})で定義された暗号。
processから以下を読み取れる。

  • R:乱数
  • K:鍵
  • S:シード

 K_{0}=(R_{0})
 K_{1}={{(K_{0}} \bigoplus S)}^2
 K_{2}={{(K_{1}} \bigoplus S)}^2


上記から、Sとkeyを導く。

 S^2=K_{1} \bigoplus K_{2}
 K_{0}=K_{1} \bigoplus {K_{1}}^2 \bigoplus K_{2}

 K_{1}と、 K_{2}はわかっている。

 K_{1} =crypted(fake_secret1) \bigoplus fake_secret1
 K_{2} =crypted(fake_secret2) \bigoplus fake_secret2

コード

#!/usr/bin/env python
# coding=utf-8

from os import urandom

def process(m, k):
    cal = m ^ k
    res = 0
    for i in bin(cal)[2:]:
        res = res << 1;
        if (int(i)):
            res = res ^ cal

        if (res >> 256):
            res = res ^ P
    return res

def keygen(seed):
    key = str2num(urandom(32))
    while True:
        #print "key : ",key,"\nseed : ",seed
        yield key
        key = process(key, seed)

def str2num(s):
    return int(s.encode('hex'), 16)

P = 0x10000000000000000000000000000000000000000000000000000000000000425L
fake_secret1 = "I_am_not_a_secret_so_you_know_me"
fake_secret2 = "feeddeadbeefcafefeeddeadbeefcafe"

#----------------------------------------------------------------#
ctxt1 = 0xaf3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f
ctxt2 = 0x630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c
ctxt3 = 0xe913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b

key2 = ctxt2 ^ str2num(fake_secret1)
key3 = ctxt3 ^ str2num(fake_secret2)
 
cal = key3
for i in range(255):cal = process(cal, 0)

seed = cal ^ key2
process(key2, seed) == key3
cal = key2
for i in range(255):cal = process(cal, 0)
key1 = cal ^ seed
process(key1, seed) == key2

message = key1 ^ ctxt1
print "flag{"+hex(message)[2:-1].decode("hex")+"}"

フラグ

flag{t0_B3_r4ndoM_en0Ugh_1s_nec3s5arY}