CSAW CTF Qualification Round 2020 Writeup

この大会は2020/9/12 5:00(JST)~2020/9/14 5:00(JST)に開催されました。
今回もチームで参戦。結果は1305点で1214チーム中110位でした。
自分で解けた問題をWriteupとして書いておきます。

sanity (sanity 5)

Discordに入ると、#ruleチャネルのトピックにフラグが書いてあった。

flag{w3lc0m3_t0_csaw2020}

widthless (web 50)

$ wget http://web.chal.csaw.io:5018/
--2020-09-12 08:52:19--  http://web.chal.csaw.io:5018/
web.chal.csaw.io (web.chal.csaw.io) をDNSに問いあわせています... 216.165.2.41
web.chal.csaw.io (web.chal.csaw.io)|216.165.2.41|:5018 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 5858 (5.7K) [text/html]
`index.html' に保存中

index.html          100%[==================>]   5.72K  --.-KB/s    時間 0s    

2020-09-12 08:52:24 (95.0 MB/s) - `index.html' へ保存完了 [5858/5858]

htmlの終了タグより後ろにゼロ幅スペースがある。5種類あるので、小さい順に0~4を割り当て、7バイトごとに5進数としてデコードする。

with open('index.html', 'rb') as f:
    data = f.read()[0x1553:]

data = data.replace('\xe2\x80\x8b', '0')
data = data.replace('\xe2\x80\x8c', '1')
data = data.replace('\xe2\x80\x8d', '2')
data = data.replace('\xe2\x80\x8e', '3')
data = data.replace('\xe2\x80\x8f', '4')

msg = ''
for i in range(0, len(data), 7):
    msg += chr(int(data[i:i+7], 5))

flag = eval(msg).decode('base64')
print flag

デコード結果は以下の通り。

alm0st_2_3z

これでsignupすると、以下が表示された。

/ahsdiufghawuflkaekdhjfaldshjfvbalerhjwfvblasdnjfbldf/<pwd>
$ wget http://web.chal.csaw.io:5018/ahsdiufghawuflkaekdhjfaldshjfvbalerhjwfvblasdnjfbldf/alm0st_2_3z
--2020-09-12 09:37:44--  http://web.chal.csaw.io:5018/ahsdiufghawuflkaekdhjfaldshjfvbalerhjwfvblasdnjfbldf/alm0st_2_3z
web.chal.csaw.io (web.chal.csaw.io) をDNSに問いあわせています... 216.165.2.41
web.chal.csaw.io (web.chal.csaw.io)|216.165.2.41|:5018 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 8182 (8.0K) [text/html]
`alm0st_2_3z' に保存中

alm0st_2_3z         100%[==================>]   7.99K  --.-KB/s    時間 0s    

2020-09-12 09:37:49 (386 MB/s) - `alm0st_2_3z' へ保存完了 [8182/8182]

またゼロ幅スペースが入っている。5種類あるので、再び小さい順に0~4を割り当て、7バイトごとに5進数としてデコードする。

with open('alm0st_2_3z', 'rb') as f:
    data = f.read()

msg = ''
for i in range(len(data) - 2):
    if data[i:i+2] == '\xe2\x80':
        msg += data[i:i+3]

msg = msg.replace('\xe2\x80\x8b', '0')
msg = msg.replace('\xe2\x80\x8c', '1')
msg = msg.replace('\xe2\x80\x8d', '2')
msg = msg.replace('\xe2\x80\x8e', '3')
msg = msg.replace('\xe2\x80\x8f', '4')

flag = ''
for i in range(0, len(msg), 7):
    flag += chr(int(msg[i:i+7], 5))

flag = flag.decode('hex')
print flag

デコード結果は以下の通り。

u_unh1d_m3

これでsignupすると、以下が表示された。

/19s2uirdjsxbh1iwudgxnjxcbwaiquew3gdi/<pwd1>/<pwd2>
$ curl http://web.chal.csaw.io:5018/19s2uirdjsxbh1iwudgxnjxcbwaiquew3gdi/alm0st_2_3z/u_unh1d_m3
flag{gu3ss_u_f0und_m3}
flag{gu3ss_u_f0und_m3}

Perfect Secrecy (crypto 50)

2つの画像の各ピクセルでXORをとる。

from PIL import Image

img1 = Image.open('image1.png').convert('RGB')
img2 = Image.open('image2.png').convert('RGB')
w, h = img1.size

output_img = Image.new('RGB', (w, h), (255, 255, 255))

for y in range(h):
    for x in range(w):
        r1, g1, b1 = img1.getpixel((x, y))
        r2, g2, b2 = img2.getpixel((x, y))
        output_img.putpixel((x, y), (r1 ^ r2, g1 ^ g2, b1 ^ b2))

output_img.save('flag.png')

f:id:satou-y:20200922083033p:plain
base64文字列が現れるので、この文字列をデコードする。

enc = 'ZmxhZ3swbjNfdDFtM19QQGQhfQ=='

flag = enc.decode('base64')
print flag
flag{0n3_t1m3_P@d!}

modus_operandi (crypto 100)

$ nc crypto.chal.csaw.io 5001
Hello! For each plaintext you enter, find out if the block cipher used is ECB or CBC. Enter "ECB" or "CBC" to get the flag!
Enter plaintext: 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Ciphertext is:  930fe486c86922be9674464cc33045f9930fe486c86922be9674464cc33045f9930fe486c86922be9674464cc33045f9f677cb3f81a5c63832e1464fd50d9e1b
ECB or CBC? 
ECB
Enter plaintext: 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Ciphertext is:  42ad00dca61d8908d960c39e1e50e3e2b4dd99c15dbc8490b3e7a31b78bf3b1168b8dcdcf40ad2825b24ab97bf5847f887b9c8a379abcfb15edb4203acf0a20d
ECB or CBC? 
CBC
Enter plaintext:

AESのようなブロック暗号でモードを答えていく問題のようだ。
ECBの場合、ブロック単位で同じ平文は同じ暗号文になることを利用する。16バイト分"\x10"*16を指定すれば、パディングも同じになるので、条件を満たす。
これで答えていくが、177ラウンドあたりで止まる。176個答えたら、フラグが表示されるのかと思ったが、そうではなかった。
ECBの場合は0, CBCの場合は1にして順に結合して、デコードしてみる。

import socket

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('crypto.chal.csaw.io', 5001))

data = recvuntil(s, '\n').rstrip()
print data

b_flag = ''
for i in range(176):
    print 'Round %d' % (i+1)
    data = recvuntil(s, '\n').rstrip()
    print data
    pt = '\x10' * 16
    s.sendall(pt + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
    ct = data.split(' ')[-1]
    if ct[:32] == ct[32:64]:
        mode = 'ECB'
        b_flag += '0'
    else:
        mode = 'CBC'
        b_flag += '1'
    data = recvuntil(s, '\n').rstrip()
    print data
    print mode
    s.sendall(mode + '\n')

flag = ''
for i in range(0, len(b_flag), 8):
    flag += chr(int(b_flag[i:i+8], 2))
print flag

実行結果は以下の通り。

Hello! For each plaintext you enter, find out if the block cipher used is ECB or CBC. Enter "ECB" or "CBC" to get the flag!
Round 1
Enter plaintext:
Ciphertext is:  11ec4ae466ec7533ee0abd8e9eaf4e2e11ec4ae466ec7533ee0abd8e9eaf4e2e
ECB or CBC?
ECB
Round 2
Enter plaintext:
Ciphertext is:  c867accc1e82d639e8123a60e68eec4c7acd1c8d45309790d604033ea2fec7c4
ECB or CBC?
CBC
Round 3
Enter plaintext:
Ciphertext is:  b8824345f74c05d0b09572db5d5b030ca19ce24e35258d89e124469b8cb0aa41
ECB or CBC?
CBC
                :
Round 176
Enter plaintext:
Ciphertext is:  e3a3680c714ba1dc89fc3dfeb4d166b0e0295ea092b93a498c61fe31909f54b3
ECB or CBC?
CBC
flag{ECB_re@lly_sUck$}
flag{ECB_re@lly_sUck$}

authy (crypto 150)

$ curl crypto.chal.csaw.io:5003 
This is a secure and private note-taking app sponsored by your favorite Nation-State.
For citizens' convenience, we offer to encrypt your notes with OUR own password! How awesome is that?
Just give us the ID that we generate for you, and we'll happily decrypt it back for you!

Unfortunately we have prohibited the use of frontend design in our intranet, so the only way you can interact with it is our API.

/new

    DESCRIPTION:
        Adds a new note and uses our Super Secure Cryptography to encrypt it.

    POST PARAMS:
        :author: your full government-issued legal name
        :note: the message body you want to include. We won't read it :)

    RETURN PARAMS:
        :id: an ID protected by password  that you can use to retrieve and decrypt the note.
        :integrity: make sure you give this to validate your ID, Fraud is a high-level offense!


/view
    DESCRIPTION:
        View and decrypt the contents of a note stored on our government-sponsored servers.

    POST PARAMS:
        :id: an ID that you can use to retrieve and decrypt the note.
        :integrity: make sure you give this to validate your ID, Fraud is a high-level offense!

    RETURN PARAMS:
        :message: the original unadultered message you stored on our service.

$ curl crypto.chal.csaw.io:5003/new -d 'author=a&note=n'
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47

$ echo YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz | base64 -d
admin=False&access_sensitive=False&author=a&note=n&entrynum=783

サーバの処理概要は以下の通り。

■new()
・パラメータチェック
 ・authorキー、noteキーがあること
 ・adminキー、access_sensitiveキーがないこと
・指定したパラメータに以下を追加
 {"admin": "False", "access_sensitive": "False" }
・さらに以下を追加
 {"entrynum": 783}
・infostr: すべてのkeyとvalの関係を&で結合
・identifier: infostrをbase64エンコードする。
・以下を表示
 ・id: identifier
 ・integrity: SECRET + infostrのsha1

■view()
・パラメータチェック
 ・idキー、integrityキーがあること
・identifier: idデータをbase64デコードする。
・checksum: integrityデータ
・note_dict: identifierのパラメータを辞書化する。
・encode: idデータをbase64デコードしたデータ
・gen_checksum: SECRET + encodeのsha1
・checksumがgen_checksumと一致していなければ、エラー
・entrynumが0以上10以下の場合
 ・adminデータがTrueまたは"True"になっていなければ、エラー
 ・access_sensitiveデータがTrueまたは"True"になっていなければ、エラー
 ・entrynumが7の場合、フラグが表示される。
・entrynumが0以上10以下でない場合
 ・authorデータ、noteデータを表示する。

SECRET + admin=False&access_sensitive=False&author=a&note=n&entrynum=783 --(sha1)--> 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47

Hash Length Extension Attackで攻撃できそう。この際エンコードに気を付けてデータの送信を行う。

#!/usr/bin/env python3
import requests
import hashpumpy
import base64
from binascii import hexlify

url = 'http://crypto.chal.csaw.io:5003/'
add_data = '&admin=True&access_sensitive=True&entrynum=7'

author0  = 'a'
author = author0

sec_len = 1
while True:
    payload = {'author': author, 'note': 'n'}
    r = requests.post(url + 'new', data=payload)
    ret = r.text.rstrip()
    print(ret)

    id = ret.split(' ')[-1].split(':')[0]
    integrity = ret.split(' ')[-1].split(':')[1]
    print('[+] id =', id)
    print('[+] integrity =', integrity)

    org_data = base64.b64decode(id)
    print('[+] original data =', org_data)

    print('[+] SECRET length =', sec_len)
    h, d = hashpumpy.hashpump(integrity, org_data, add_data, sec_len)
    print(d)
    new_id = base64.b64encode(d.decode('ISO-8859-1').encode('unicode-escape'))
    payload = {'id': new_id, 'integrity': h}

    try:
        identifier = base64.b64decode(new_id).decode()
        params = identifier.replace('&', ' ').split(" ")
        note_dict = { param.split("=")[0]: param.split("=")[1]  for param in params }

        r = requests.post(url + 'view', data=payload)
        print(payload)
        ret = r.text
        if '>:(' not in ret:
            print(ret)
            break

        author = author0
        sec_len += 1

    except:
        author += 'a'

実行結果は以下の通り。

Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 1
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAyXHgwMCZhZG1pbj1UcnVlJmFjY2Vzc19zZW5zaXRpdmU9VHJ1ZSZlbnRyeW51bT03', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 2
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x08&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDJceDA4JmFkbWluPVRydWUmYWNjZXNzX3NlbnNpdGl2ZT1UcnVlJmVudHJ5bnVtPTc=', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 3
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x10&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMlx4MTAmYWRtaW49VHJ1ZSZhY2Nlc3Nfc2Vuc2l0aXZlPVRydWUmZW50cnludW09Nw==', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 4
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x18&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAyXHgxOCZhZG1pbj1UcnVlJmFjY2Vzc19zZW5zaXRpdmU9VHJ1ZSZlbnRyeW51bT03', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 5
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02 &admin=True&access_sensitive=True&entrynum=7'
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YWEmbm90ZT1uJmVudHJ5bnVtPTc4Mw==:9d916c54db33d0016db9716b7e34c4697709a535
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YWEmbm90ZT1uJmVudHJ5bnVtPTc4Mw==
[+] integrity = 9d916c54db33d0016db9716b7e34c4697709a535
[+] original data = b'admin=False&access_sensitive=False&author=aa&note=n&entrynum=783'
[+] SECRET length = 5
b'admin=False&access_sensitive=False&author=aa&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02(&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YWEmbm90ZT1uJmVudHJ5bnVtPTc4M1x4ODBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDIoJmFkbWluPVRydWUmYWNjZXNzX3NlbnNpdGl2ZT1UcnVlJmVudHJ5bnVtPTc=', 'integrity': '50ab5a9497c696808aad9bbecc1a1c7ab5f764b2'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 6
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02(&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMigmYWRtaW49VHJ1ZSZhY2Nlc3Nfc2Vuc2l0aXZlPVRydWUmZW50cnludW09Nw==', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 7
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAyMCZhZG1pbj1UcnVlJmFjY2Vzc19zZW5zaXRpdmU9VHJ1ZSZlbnRyeW51bT03', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 8
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x028&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDI4JmFkbWluPVRydWUmYWNjZXNzX3NlbnNpdGl2ZT1UcnVlJmVudHJ5bnVtPTc=', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 9
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02@&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMkAmYWRtaW49VHJ1ZSZhY2Nlc3Nfc2Vuc2l0aXZlPVRydWUmZW50cnludW09Nw==', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 10
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02H&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAySCZhZG1pbj1UcnVlJmFjY2Vzc19zZW5zaXRpdmU9VHJ1ZSZlbnRyeW51bT03', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 11
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02P&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDJQJmFkbWluPVRydWUmYWNjZXNzX3NlbnNpdGl2ZT1UcnVlJmVudHJ5bnVtPTc=', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 12
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02X&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMlgmYWRtaW49VHJ1ZSZhY2Nlc3Nfc2Vuc2l0aXZlPVRydWUmZW50cnludW09Nw==', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}
Successfully added YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz:0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] id = YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09Nzgz
[+] integrity = 0c7bcfd171c9c7a3ffa06de0c1f16d29067a4b47
[+] original data = b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783'
[+] SECRET length = 13
b'admin=False&access_sensitive=False&author=a&note=n&entrynum=783\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02`&admin=True&access_sensitive=True&entrynum=7'
{'id': b'YWRtaW49RmFsc2UmYWNjZXNzX3NlbnNpdGl2ZT1GYWxzZSZhdXRob3I9YSZub3RlPW4mZW50cnludW09NzgzXHg4MFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAyYCZhZG1pbj1UcnVlJmFjY2Vzc19zZW5zaXRpdmU9VHJ1ZSZlbnRyeW51bT03', 'integrity': '57da35fdda9993546e53c8a41784d98372392a34'}

Author: admin
Note: You disobeyed our rules, but here's the note: flag{h4ck_th3_h4sh}
flag{h4ck_th3_h4sh}

adversarial (crypto 200)

AES CTRモードでカウンタのサイクルが同じなので、各ブロックの平文と暗号文のXORは同じになる。
https://github.com/Jwomers/many-time-pad-attack/blob/master/attack.pyを使って、解読する。

#!/usr/bin/env python 
import string
import collections
import sets

# XORs two string
def strxor(a, b):     # xor two strings (trims the longer input)
    return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)])

# 10 unknown ciphertexts (in hex format), all encrpyted with the same key
c1 = '''
2us8eN+xyfX3m+ouq+Rp51ruXKXYbKCbe5GjrddBHVm0vhKd2KMXMjFWQVclCmNnsGuEhFSOoFRo
0hIKHGZrrCS/BRITjW7DJ5L+c0C6Dhu6yBNSnWDpf7sYMknxcaZ+FSwg0nVVNxlNZsfqpd9NOg7F
OGsysrh8EIGXZiovI6mLWo9FobtcCDbRZXT7Op5rz7hFynKLtFLIx1GTt4CUrKw6J/tpjTZ9mv/w
bBjD5Iwd060oTwfZd4NVg+GdDqyz1PA=
'''.decode('base64').encode('hex')
c2 = '''
w+YyIN+r1brrm/li+7YB5Ey6XbjYbKCbfIej69lAEReh+weex/E7NX1GVEcuWGwyt37Ijk7AjlRt
2RlTSDJ0pTHrUQMZiiuHNdy/NUG2BFH/zR5diiWwcqtMJk36P/V4Hi87lztFfwxRI571sYtGd0CE
Im5hsbwwGoadIXk+LuCLXoZUp7U=
'''.decode('base64').encode('hex')
c3 = '''
2es4LJm027Kll/h4tPBH6hX/XaubJfjcYpTm5pMPLBGj+xWdhuR+PWIVDhZkGj52oWuL3wrS/hUp
nVBfPC555COnRAxckT2aZsi4dx3uB1b5j0wB0CGwPeMYBUD6cbN/ESdslyYYf0xfJIa0tZ5Na1fX
dWth6/B8JYeWZj8mJ+KLR5Qa769ID2+MIHzrKtowm6kJnn/OjF/Ok0WWtYbY5axpYKFug31slvDn
OV2Br4g=
'''.decode('base64').encode('hex')
c4 = '''
wOYuf56/3/W9yLNxpeoB3Ei9TOqVcLydOpKj64YZQEr39VOlgvAqdHxKXVFjH2Nn/DzQ3AzO5yBs
wwlfBSNvtySsQEtEznaTd9L+QUCsFhf32ghAiCf1MPYOaRuuf/VHFTM43jhHLAtYIdul6MkWaFHL
bF4ktal8HIqANTgtI6WTGN8T/rUOOTLOMT3lf55xw69Mk2rY4ASanQOusZKMrLI2M+ZphiB9y6e8
Oludtr0Mxb0oQBuKfY1HlOHHSvXpi/A=
'''.decode('base64').encode('hex')
c5 = '''
xKM8Yd+s0rClv/kh/K1V7U66FuqxNaycPpSyrtoPDBGj+z6Qk/E3LD8PZwJqGXAi5GiNilPAsBVg
xBQRD2Z6qzfrXAQJ1m75KYn+fUSpBxf33hVKyTHldb1MOEfxIvVyHiRsij1NKh9RZsrttd9eKQ+G
KXky5rU9As+SKi0vNODPDp5PuukODjjTNn7hdZhxzK1awH7OoVjek1GfuYCR4v86Mudtlyo+kvPo
cErb44QI2OcoaAyeYcAAgq6SGe213P5s3JnNJc1kSHnEoWR7bY4u1Tk0w4uqB4E7zR500Ig+M/mz
qTYUVCbAd8ghJVAxA2aKOZ302gtYn1elVRO7ljUCQfo5WdZtdsimmTN1LcLfB0ZAgLxUIeABA+xG
ChOBG/Q3az9GqUn6s13t8i24ySz+xCl2fDLqZjCanEVWNtIx1D1Fvm3Mt7+45yoANA7lHqnYsS/Y
wWqSJswOJmVBuLJprfZ33mPGLsf0FXNzaho9cBYioFIQEzUUyQ==
'''.decode('base64').encode('hex')
c6 = '''
zPcpbZyzmrTx3u8j46oPqHi9XeqMfarOOpGiudtcC1n17F3I1bZpdCAfABAySzBn9TPb1hPS/0cp
nV07B2ZyqzHrVw4MlDeAMpP+YU22ERf32ghAiCf1Pu55JVz+Mr4zETRsmjRVMVYZE83g8ItGPkCE
KG4zo64vUdzEaGB4c7KLH9cO/asdW3eMfC6xNN86kegEkxaB+FnExwOIsZGU9f8nL7V8iSwu0/zh
ehnS8YxH
'''.decode('base64').encode('hex')
c7 = '''
xeIrad+h1aClm/0n5uRJ6UnuWeqcZ6qPNtWIrtEDWA2uugfRnuwrdGZKXEciC2lnt3+aih2Xpgcp
whgeBHk8ky2qUUsVnm7ZKYn+YkCtBxfv0RpRhSWwZKEYJkn0NPV1Ai8h3iFKPgwZIszgsZIReyiK
Oyo2qagwFc+KKSxqLevEWcdUp/4OCT7bI3j6f4Nhx+hL1iaZvVLFk1eSscGc/royLbV/jjcxl72k
aATXtp0B0+l6SB+VLptPg62bQw==
'''.decode('base64').encode('hex')
c8 = '''
2us0b5f42KfskOwxtLFSqEy6GKaZZrvOL5rmv9ZKWBSpthafk6MxMjFbXFd2ECpns2KNnViJqVR9
2BhfDjNyoCSmQAUImSKAIJC/YgW2ERfv0w9ahCHkdaJBcU3nIad2AzMpmnkCPhZdZsrttd9vNQ+I
LWY45q85B4qSKjwuZuTYDoVPu/MODzLaLHPmc4NlgqlH13KLtlOFk3eSsZOdrL4hJbV8lip9l/7r
exmdtr0B0+lsQhGLLphP0biQCb/6yLdmzc2MJ9tySXiX9XI0bMY8nAY3loynBsQo0A41yoR3M/m9
qCVVTymPbYArLlASBXzEYNTM3k4WlEzkB3Cgl3YOXP0uF85kaZCmgj59JdTfHEhWmbxGJ7IGH6kX
MheGHfQgKT9fpxCytErt5yu5yTX+lyk+aXf9fD3Ulk0CY509yWgWo2nW/rW56Q==
'''.decode('base64').encode('hex')
c9 = '''
wOYuf56/3/Wzyrtwp+oB3Ei9TOqVcLydOpKj64gbSEv19VOlgvAqdHxKXVFjH2Nn8j7Y3Q7O5yBs
wwlfBSNvtySsQEtKzH6SddL+QUCsFhf32ghAiCf1MPgMYRqsf/VHFTM43jhHLAtYIdul5sseaVPL
bF4ktal8HIqANTgtI6WdGtcS/LUOOTLOMT3lf55xw69Mk2Ta6AWYnQOusZKMrLI2M+ZphiB9xaW0
O1mdtr0Mxb0oQBuKfY1HlOHJSP3oifA=
'''.decode('base64').encode('hex')
c10 = '''
2O07Y42sz7vkiu4u7egB5kLuV6SdNayPNdWkrp5bFxWi+wSZhvd+IHlKDm9jDHQuvCqBnBPAnht8
kBUeHiM8sCrrVg4Z2CfUZpqxZwWmDULozB5fj26wRKZRIgj2IvVqHzU+3jlDLAwZJdbkvpxLdUCk
Kn4ktP0oGYaAank+LuDZS8dJvLtAAnfJMG/mc4NlgqpI0DnA+G7ExgOOtYqdrKs7JbVqjTA40+Ht
ZQaftp0B0+l7WRGLd8xFn6WMUO2j1ash0tjHLp5mXSve7z1td9srnDc9h96lDYBp3A9514lkdqqr
rDJAXjaFcYA9JwVoG3LEOtTs2QtUlU/iECax1nYuXP18Q8NqasTyhj48M8KbXllcnvAeaOsdAuxE
CxeLT/Q2JUhEplS/o1Ss6CHxySD/030fLCTwfS7UgERXOponzGgBtmnFt6SiomcTLEzpGKnYqyXV
yCOPLIVdYQ==
'''.decode('base64').encode('hex')
c11 = '''
2es4LLK5zqfshqsr5+RO5EmrSuqMfa6Ae4ypvp5EFhax9VO4x/MsMXdKXAJhF3MpsGOGiB2GtRtk
kAkXDWZ5qSC5Qg4SmyuAKZr+eku6Ql70yx5UmyH8MK9WPkX+PawzBC9sij1Hfx1UI8zitZFNPkCK
Kio1rrh8H4qLMnVqL+uLWY9JrPMODjbOID38coRxgqFakyaGvRfY2luOvMGO6a0gKfpmzw==
'''.decode('base64').encode('hex')
c12 = '''
2es4LLK5zqfshqsr5+RAqF63S76deOPOFZCp5Z57EBiy+wCIlPc7OTFGXQJtDXRnoWSNgkTO5zZ8
xF0IACNy5DykUEwOnW7JKI+3cUDzQk71yltfhi/7MK9KPl3xNfkzBygtinVGMFhAKculo5pLZECn
OXkoqLgvAs+eIzdmZvHOT4RIquldQXfRJGrxf59xjuhK0iCevVnf1lGJ+sGs5LpzNvB6mGUwmv/g
ekrc8Mkd3qwoXRuWfoBF0baaXKyo3/5118DFJdkzWWSX8nxifYB5/iAsw4uqF40lnh1wnoh9P6qo
rDZHXmCQZs80JBVoDWHPbofs30da0EKrBTGmjHYYVagoX8N1L5f/nS95LIvfH0dR0uhaKeZSGq1c
GgXSG/U9aD9EvUL6tFao6zzzyRj+wn0+bSH9Mi2b2V5Mfpc6yDwEvWiZt72ltDNBIkirBbWdsC+Z
3WaHM4xLb3ATtOEno+4kwybTItv0DHMgfF90dwo3oEIBFT4EyXht/gmmKqUH3+nqpNuKZVNuNm0/
luqszUFULuho1emuvPoXHjM1RbVfpVbaag4owD/KTWORtWfxEmGyOVHTj9dPiFPpIhIao69KuE/b
ryCTW6dp5XkAB64E3PSsQzufz49kHITrz4hNkXPn
'''.decode('base64').encode('hex')
c13 = '''
2es4LJm027Kll/h4tPBH6hX/XaubJfjcYpTm5pMPLBGj+xWdhuR+PWIVDhZkGj52oWuL3wrS/hUp
nVBfPC555COnRAxckT2aZsi4dx3uB1b5j0wB0CGwPeMYBUD6cbN/ESdslyYYf0xfJIa0tZ5Na1fX
dWth6/B8JYeWZj8mJ+KLR5Qa769ID2+MIHzrKtowm6kJnn/OjF/Ok0WWtYbY5axpYKFug31slvDn
OV2Br4g=
'''.decode('base64').encode('hex')
c14 = '''
3uYzeJa91KGljvkt87ZA5V7gGJ6QcLbOOJSo69NADhzmsh3Rhu06dH5aWgJtHiYmqnPInFKGswNo
whhfGzJ1qCnrTQoOnGPXL467cQWrDRfu1x5am2Djab1MNEWxcYF7ETRskzBDMQsZMtbkpN9PNRmK
Im9hsbh8GY6FIzdtMqXeQJdMuvxJCDOdLG6oaoJ2x6Zd2jOCtE6L0k3alYad4qt9YNxmkiw5lrHw
YQ+T24gdxKBwAV6NZolZ0aCNGe2/zLtz3NbCLp5yQ2+X9XVxYY44zjB4jZHkDIoskEpC28x6cvy5
5CBBSTaJdcUgaBIxTHvDKp320QtQgkzmVSS8nTtbE+olF9B0YYrvgDw8J9WQEwlBmvlfZLIQArgX
Cx6XFr05d3oLvFi/8V+s8iC2jCTh0i8lInfMejyN2UpQf9IvzikXt2Xb8PCrqytBOUbuUbmXrDjK
gSOcK4VXb3ATtOEho/Zg2C3VZsO4FDx0dl90aQE+vxtGBTMJhDAM/QjnKbdJ0qHkttuNYlltc35t
nLj/zgBJJe82kP7t8ewXUD56XKMTp0rAaBAo0DWaQGyDtSnxXS66cELTntdImUXwaQ==
'''.decode('base64').encode('hex')
c15 = '''
1+oyYt+T36z2xKt6tOkBzg3jGIvYOO+/e9jm+p4CWCPm9lOjx65+DjECDmAiVSYd5CfIvR3N5yYp
nV0tRmZOoTWuRB9G2HaAa9yYNQj/Ixe3nyoTxGChMOMYCwiycYczXWAW3ngCHVgUZuSl/d98e03F
Hips5o9yUb2WNjwrMr+LFscN790OQHf8ZTCoS80vgvkJnnK0+BqL4QPX9LvYof8RYLgou2Vw08Ok
JErhtsRJ5A==
'''.decode('base64').encode('hex')
c16 = '''
xKMqY5H/zvXpl+5i4KsB8UK7FOq2cKDAe7CwrsxWWAqvtRSdgqMzNX8PQVAiD2kqpWTImFWP5xxo
w10MHClzoGW/TQ4Vim7HNJOre0HzQlLs2glKhi71MLlQPgj3MKYzFi85mT1WfxlXZt/itZFaewiE
Pyolr7g4X8+xMy1qMe3OXIIAu/NLFHfVJGvtOotjy6RM137OoVjek1STuI3Y/6owI/BthWs=
'''.decode('base64').encode('hex')
c17 = '''
3e84bYy9lPXEjasLtLNA+w29WbORe6jCe4aurp5cDAyruR+Ug6MrJH5BDkMiC2krsX6BgFPAsBxs
whgdEWZyoSS5SRJcwXeFZpO4NUSzDhfu2ghHyTPlcqRdMlzscbRwEyU8ijBGfwxRI571opBJKQGI
bGsy5rEzH4jTJypqMu3OV8dXqulLTTDUM3jmOowiwaBG2jGL9BfOxUaU9IierKs7JewoliAvlrHr
ZwbKtoge17ttDRGfLphIkLXfH6W1071khdjYa98zQ27W8zBhds020iY7ipGxEMQl2xxw0sIyROK1
qDYUTyiJcIAlJgM/CWGKKIH21V9fn03uEXz0kSJXROkvF81jeY3pmyhwOIeZC0dRk/FXJuYTG6BO
XxCeDuo9YTMLvFivohiu9CC8nSj/0H0iZDK4fS2cnFlVc4EtlisKvXjH9rSjpDMOP1erAqSLty/U
xGDIIo5BInANqOE9pPtwkSrUZs6xHmgga1Q3agEkp1ICUjYJgDBYsBnuNaEI0qzr4o+WaBZwb385
lqf/yxVOJfF8nq3H7u4XEnsuXb9ApQXdbhZ8hCjfTniGtW2lRma5OVXJhZBOkE2xZwhe6rdH+Vrb
tiGYTfV3+GxAB6ELm+m2ACeVjJRzF9D5w4kBnCeqBO3JU6j9ocU/AMmaB0XjMTd13Lh24kzDnOHn
MxBHhxTfYe2ki35XEOMP9WYpYBrhcn8S0EYi7uY8Jh6vploUBDM3XGyeNMdkK3YVB+EUPWs1lSuq
i0UMuFyqUoxik35l0T2H4KTD2C/hDuIA12nyEFjhfi1EztvK+shdVSd+wL7bLv0DDB1hy/N1w5PT
QGtE444gnmRwvhQrZ6vUCSspwQ6FNfIASiAvTs3GWV3ei5By/6GY5s0QTC8Vh9djHGVIPXAgqJ67
wOlVgyFR4CWpoDp+yZYfB8vUCsG07kUUVQ==
'''.decode('base64').encode('hex')
c18 = '''
xKQrad+r37Dr3uostKVG7UO6GLqNe6yGe4GuudFaHxHmulOSiO09JnRbSwJ1GWor6iqlilPArxV/
1V0aBTZorSCvBQ4SjCfSI9y9eUyvERf7y1tHgSX9MK9WNQj3OKEzHi84ljxMOFhbM8qlsZZcdUC8
KX5hsrU5GJ3TNS04I+vMWo8ArvVKTSPVIHT6Op5yx61NkzOcvRfYx0qWuMGa7aw2JLVhj2U80+br
ewbXtp0B170oRA3ZbJlJnbXfE6P6yKttwMqCa/x2TmrC8ng0d8h5yD05l9LkF4wsx0pi14B+M+S5
sjZGGyKFI8E3aAM8HnzEKdT3xAtXgwPtFCOg2DcEE/EzQoJiboqmjD4y
'''.decode('base64').encode('hex')
c19 = '''
yPU4foas0rzrmas2/KVVqEWvS+qZNa2LPJyopddBH1muugDRhu1+MX9LAAJLWHUioSqch1jAohpt
kB4QBS9yo2vrbEsPnSuAMpS7NUG+EFz02ghAyTPgYqtZNUHxNvszOWA/mzACOx1YMtar/tEOOg6B
bHMus/09A4rTJzUmZvHDT5MAvO9PAzPOZXTmOoVr0ehe0ivA
'''.decode('base64').encode('hex')
c20 = '''
2eYueN+136b2n+wntPURvRT8FuqscLyae5ijuM1OHxzm6kPE3rFwdEVKXVYiFWM0t2uPih3R90Ew
glNfPCNvsGWmQBgPmSnFZs3uIBztTBfO2ghHyS31Y71ZNk2/YOUmSXJi3gFHLAwZK9v2o55JPkDU
fD949PN8JYqAMnknI/bYT4BF76oeWG6Paz3cf552gqVMwCGPv1KLghPP7dPWrIs2M+EojCAugPDj
bEqCptxQhOcoeRuKesxNlLKMHaq/mu8xkICeZQ==
'''.decode('base64').encode('hex')
c21 = '''
zPB9dZCtmrThm/o39bBE5FTuSL+MOe+aM5Dmu8xAGhWjtlOYlKM9PH5GTUcsWEQysCqfih2BqwZs
0RkGSC1yqzLrUgMdjG7ZKYn+dFe6QlD11hVUyTT/MKpXfQj7Prs0BGA7m2oCHhRLI9/hqd9newOE
Iioyo7h8BYeWZjoiJ+zFDpVFrvhaBDjTfz38cogiwaBM3juNuVuLw1Gft5SK/7AhM7V8iSQp0+Lt
bgTS+skd3qwoQhCKa5gAnqffHaP637Nu0dDDJZIzSW7E6Hp6fcp5zyU9gJeiCoco0gZsnph9M+Wq
oSFDUyWMboAoJxchDzPLIJC4xE5Xg0zlW3CVlnYSXucoXs1vL5Dujy88KNTfH0VHl/1WMbIQG6VZ
Gx+cCL0hamoLvF/6pVCopja0hDH90n03YjO4fTuCkERXadI8yT0RuzaV5Liv5y4SbUnkGLOf4z7W
jWeBJsBPIXVBpaksvv8k2DCSKM2gEHVueRotbRFnr1YIUj8PxyxDsB7yKLRJz72r4rORfVMtNkU5
06OsghVVJb1rxeTs6OwLTT40QblSrAXBcxppynreTWGAo2DqXCL8akzWn5tIkE74KApF76ICrVOe
+zuZV/V96TUDQegU1OmqQyiCip5iFoP6jI8ZimKnDPfSC+HoutV6WceBVQD3IDN4yals+AuUifLj
PxRWnVY=
'''.decode('base64').encode('hex')

ciphers = [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15,
    c16, c17, c18, c19, c20, c21]
# The target ciphertext we want to crack
target_cipher = c17

# To store the final key
final_key = [None]*800
# To store the positions we know are broken
known_key_positions = set()

# For each ciphertext
for current_index, ciphertext in enumerate(ciphers):

        counter = collections.Counter()
        # for each other ciphertext
        for index, ciphertext2 in enumerate(ciphers):
                if current_index != index: # don't xor a ciphertext with itself
                        for indexOfChar, char in enumerate(strxor(ciphertext.decode('hex'), ciphertext2.decode('hex'))): # Xor the two ciphertexts
                                # If a character in the xored result is a alphanumeric character, it means there was probably a space character in one of the plaintexts (we don't know which one)
                                if char in string.printable and char.isalpha(): counter[indexOfChar] += 1 # Increment the counter at this index
        knownSpaceIndexes = []

        # Loop through all positions where a space character was possible in the current_index cipher
        for ind, val in counter.items():
                # If a space was found at least 7 times at this index out of the 9 possible XORS, then the space character was likely from the current_index cipher!
                if val >= 7: knownSpaceIndexes.append(ind)
        #print knownSpaceIndexes # Shows all the positions where we now know the key!

        # Now Xor the current_index with spaces, and at the knownSpaceIndexes positions we get the key back!
        xor_with_spaces = strxor(ciphertext.decode('hex'),' '*800)
        for index in knownSpaceIndexes:
                # Store the key's value at the correct position
                final_key[index] = xor_with_spaces[index].encode('hex')
                # Record that we known the key at this position
                known_key_positions.add(index)

# Construct a hex key from the currently known key, adding in '00' hex chars where we do not know (to make a complete hex string)
final_key_hex = ''.join([val if val is not None else '00' for val in final_key])
# Xor the currently known key with the target cipher
output = strxor(target_cipher.decode('hex'),final_key_hex.decode('hex'))
# Print the output, printing a * if that character is not known yet
print ''.join([char if index in known_key_positions else '*' for index, char in enumerate(output)])

'''
Manual step
'''
# From the output this prints, we can manually complete the target plaintext from:
# The secuet-mes*age*is: Wh** usi|g **str*am cipher, nev***use th* k*y *ore than onc*
# to:
# The secret message is: When using a stream cipher, never use the key more than once

# We then confirm this is correct by producing the key from this, and decrpyting all the other messages to ensure they make grammatical sense
#target_plaintext = "The secret message is: When using a stream cipher, never use the key more than once"
target_plaintext = "Please. As I was saying, she stumbled upon a solution whereby nearly 99% of all test subjects accepted the program as long as they were given a choice, even if they were only a"
print target_plaintext
key = strxor(target_cipher.decode('hex'),target_plaintext)
for cipher in ciphers:
        print strxor(cipher.decode('hex'),key)

途中までだが、復号結果は以下の通り。

*kea<b. sqa#$f9so,ibgxh~h r2tu(/lp} 6ponc$.so9{t>na;}|3!;yknearly  9| ~f5(~lgyest sdbg$otso/dze'1zd the 4|ogr",0ajebo`g ashtr+yr2$115({lenha  ho(*&  e&u{9{hstfey ye&e ocl8lans|  of that choi*e a*****e*r*******c*****l**e******l**this*****er***n**ion*** ****as*o**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Please. As I was saying, she stumbled upon a solution whereby nearly 99% of all test subjects accepted the program as long as they were given a choice, even if they were only a
What is real? How do you define real? If you're talking about what you can feel, what you can smell, what you can taste and see, then real is simply electrical signals interpre
Neo, sooner or later you're going to realize, just as I did, that there's a difference between knowing the path, and walking the path.
The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a
Message 86831. Test message 86831. Test message 86831. Test message 86831. Test message 86831. Test message 86831. Test message 86831. Test message 86831. Test message 86831. T
I am the Architect. I created the Matrix. I have been waiting for you. You have many questions and though the process has altered your consciousness, you remain irrevocably hum
Attack at dawn. Use the address 37.9257 10.2036 1939.283 - Do not reply to this message. Attack at dawn. Use the address 37.9257 10.2036 1939.283 - Do not reply to this message
Have you ever had a dream Neo, that you were so sure was real? What if you were unable to wake from that dream? How would you know the difference between the dream world, and t
Which brings us at last to the moment of truth, wherein the fundamental flaw is ultimately expressed, and the Anomaly revealed as both beginning and end. There are two doors. T
Message 64023. Test message 64023. Test message 64023. Test message 64023. Test message 64023. Test message 64023. Test message 64023. Test message 64023. Test message 64023. T
Unfortunately, no one can be told what the Matrix is. You have to see it for yourself. This is your last chance. After this, there is no turning back. You take the blue pill, t
The Matrix is older than you know. I prefer counting from the emergence of one integral anomaly to the emergence of the next, in which case this is the sixth version.
The Matrix is a system, Neo. That system is our enemy. But when you're inside, you look around, what do you see? Business men, teachers, lawyers, carpenters. The very minds of 
The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a -- The flag is: 4fb81eac0729a
Sentient programs. They can move in and out of any software still hard-wired to their system. That means that anyone we haven't unplugged is potentially an Agent. Inside the Ma
Zion Keys: 8 - F - A - Q - 1 - Z - R - Z - B - Z - R - R - R. Repeat: 8 - F - A - Q - 1 - Z - R - Z - B - Z - R - R - R. Repeat: 8 - F - A - Q - 1 - Z - R - Z - B - Z - R - R -
I won't lie to you, Neo. Every single man or woman who has stood their ground, everyone who has fought an agent has died. But where they have failed, you will succeed.
Please. As I was saying, she stumbled upon a solution whereby nearly 99% of all test subjects accepted the program as long as they were given a choice, even if they were only a
I've seen an agent punch through a concrete wall. Men have emptied entire clips at them and hit nothing but air. Yet their strength and their speed are still based in a world t
Everything that has a beginning has an end. I see the end coming. I see the darkness spreading. I see death... and you are all that stands in his way.
Test message 10592. Test message 10592. Test message 10592. Test message 10592. Test message 10592. Test message 10592. Test message 10592. Test message 10592. Test message 105
As you adequately put, the problem is choice. But we already know what you are going to do, don't we? Already I can see the chain reaction: the chemical precursors that signal 

"The flag is: 4fb81eac0729a"とのことなので、nc接続で"4fb81eac0729a"を投入する。

$ nc crypto.chal.csaw.io 5000
Hello Morpheus. Back from the mission so quickly? I see.
Well what flags have you discovered? See, if I like what you have, I'll be willing to trade with you...

> 4fb81eac0729a

flag{m1ss1on_acc00mpl11shheedd!!}
flag{m1ss1on_acc00mpl11shheedd!!}