Attack All Around

今やCTFと競プロばかりだが、トビタテ生のアメリカ留学やTOEFL奮闘記

wormcon 2021 writeup

cryptoしか解いてないけど上位でした

Result

f:id:partender810:20210830154331p:plain
result


Writeup

githubに掲載できないみたいなので、問題ファイルなど直書きします。

RoboXOR 50pt


Rick got a robot named "XORius" as a gift by his parents which activates with a key, in user manual it was written - "we suggest you to use your name is X factor for ROBO ^_^" so Rick followed the user manual, his bot was working fine and now started saying
"2506110631060d103c5a15582036045b3c075734640015580d10531e0d1c134a2f"
But now Rick has fear of his parents and he wants your help to understand his ROBO

xorでしょう。keyを使い回ししていると仮定して、flagのフォーマットである"wormcon{"で各バイトをxorしてみるとkeyの長さが4でグルグル回していました。


enc = "2506110631060d103c5a15582036045b3c075734640015580d10531e0d1c134a2f"
key = []
k = "wormcon{"
for i in range(0,4*2,2):
    key.append(int(enc[i:i+2],16)^ord(k[i//2]))
print(key) # [82, 105, 99, 107]
flag = ""
for i in range(0,len(enc),2):
    flag += chr(int(enc[i:i+2],16)^key[(i//2)%4])
print(flag)


wormcon{n3v3r_g0nn4_6iv3_y0u_up!}



Exclusive 100pt


SO EXCLUSIVE. MUCH ELITE. SUCH WOW.
ファイル:chall.py, out.txt

#chall.py

#!/usr/bin/env python3
import os

def splitit(n):
    return (n >> 4), (n & 0xF)

def encrypt(n, key1, key2):
    m, l = splitit(n)
    e = ((m ^ key1) << 4) | (l ^ key2)
    return e

FLAG = open('flag.txt').read().lstrip('wormcon{').rstrip('}')
alpha = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'

assert all(x in alpha for x in FLAG)

otp = int(os.urandom(1).hex(), 16)
otpm, otpl = splitit(otp)

print(f"{otp = }")
cipher = []

for i,ch in enumerate(FLAG):
    if i % 2 == 0:
        enc = encrypt(ord(ch), otpm, otpl)
    else:
        enc = encrypt(ord(ch), otpl, otpm)
    cipher.append(enc)

cipher = bytes(cipher).hex()
print(f'{cipher = }')

open('out.txt','w').write(f'cipher = {cipher}')

# ---out.txt---
# cipher = a1adabc2b7acbbffb5ae86fee8edb1aeabc2e8a886a986f5e9f0eac2bbefeaeaeaf986fee8edb1aeab 


splitit関数は、8bit値を上位4bit下位4bitに分けて返してくれます。また、encrypt関数はnをsplititで4bitに分け、前半をkey1後半をkey2でxorし、前者を上位4bit後者を下位4bitとする8bit値が返り値となります。

key1, key2はotp変数に依存し、1byteなのでbrute forceします。逆関数を作り、復元した結果が変数alphaだけで構成されているかを判別すればOKです。


def splitit(n):
    return (n >> 4), (n & 0xF)

cipher = "a1adabc2b7acbbffb5ae86fee8edb1aeabc2e8a886a986f5e9f0eac2bbefeaeaeaf986fee8edb1aeab"
alpha = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'

for otp in range(256):
    flag = ""
    otpm, otpl = splitit(otp)
    for i in range(0,len(cipher),2):
        if (i//2)%2 == 0:
            m = int(cipher[i],16)^otpm
            l = int(cipher[i+1],16)^otpl
        else:
            m = int(cipher[i],16)^otpl
            l = int(cipher[i+1],16)^otpm
        flag += chr(m*16+l)
    if all(x in alpha for x in flag):
        print("wormcon{"+flag+"}")


wormcon{x0r_n1bbl3_c1ph3r_15_4_h0m3_br3w3d_c1ph3r}



Fake Encryption 331pt


Key sizes: 56 bits Block sizes: 64 bits Rounds: 16 Designers: IBM
And you dare to say it's weak???
ファイル:chall.py, flag.png.enc, ff_error.png, ff_error.png.enc

# chall.py
#!/usr/bin/env python3
from Crypto.Cipher import DES
import random


def splitn(text, size):
    return [text[i:i+size] for i in range(0,len(text),size)]

def encrypt(m, key):
    cipher = DES.new(key, DES.MODE_ECB)
    return cipher.encrypt(m)


flag = open('flag.png','rb').read()
ff = splitn(flag, 8)

assert len(flag) % 8 == 0, len(flag)

key = random.randbytes(8)
enc_flag = encrypt(flag, key)

random.seed(ff[0])
random.shuffle(ff)

ff = b''.join(ff)
enc_ff = encrypt(ff, key)

open('flag.png.enc', 'wb').write(enc_flag)
open('ff_error.png', 'wb').write(ff)
open('ff_error.png.enc', 'wb').write(enc_ff)


まず、DESは使いません。変数ffをシャッフルする際のseedがff[0]としている点に注目します。変数ffはflag.pngのバイナリデータを8byteずつ分けた値が格納されています。シャッフル後のffが与えられていますが、8byte毎の並びは変わりません。なのでその8byte毎でseedとする総当たりをします。

次にseedを取った後ですが、ffの長さと同じ配列を用意します。値はindexと同じにします。これをシャッフルします。例えば、値0がindex14に移動していたらシャッフル後のffのindex14は元々index0にあったということになります。png画像なので、index0が正しいpngフォーマットになっているかを判別し、あとはシャッフルした配列結果を基に復元します。

画像を開いてみるとflagが書いてありました。


import random
f = open("ff_error.png","rb").read()
print(f)
#tmp = [i for i in range(len(f)//8)]
print(len(f))
for i in range(0,len(f),8):
    tmp = [i for i in range(len(f)//8)]
    random.seed(f[i:i+8])
    assert tmp[5] == 5
    random.shuffle(tmp)
    #print(tmp)
    #print(str(i)+" : ",end="")
    #for j in range(4):
    for k in range(len(tmp)):
        if tmp[k] == 0:
            if f[8*k:8*k+8] == b'\x89PNG\r\n\x1a\n':
                print("find")
                dat = b""
                for idx in range(len(f)//8):
                    for j in range(len(tmp)):
                        if tmp[j] == idx:
                            dat += f[8*j:8*j+8]
                open('flag.png', 'wb').write(dat)
    

f:id:partender810:20210829215015p:plain
flag.png


wormcon{ECB_lacks_diffiusion}



Invisible Cipher 419pt


Note: The Language used as plaintext is English.
YOU CAN'T GET THE FLAG IF YOU CAN'T SEE THE CIPHER
ファイル:chall.py, flag.enc

#chall.py
#!/usr/bin/env python3

def encrypt(pt, PTALPHA, CTALPHA):
    ct = ''
    for ch in pt:
        i = PTALPHA.index(ch)
        ct += CTALPHA[i]
    return ct


PTALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '
CTALPHA = open('CTALPHA.txt').read().strip()
FLAG = open('flag.txt').read().strip()

assert len(CTALPHA) == len(PTALPHA)
assert all(x in PTALPHA for x in FLAG)

enc_flag = encrypt(FLAG, PTALPHA, CTALPHA)

with open('flag.enc','w') as f:
    f.write(enc_flag)
    print('DONE')
ぃ〷〴ぁ〴おう〰あお〾〽〲〴お〰お〺〸〽〶お〾〵おあ〲〾ぃ〻〰〽〳おう〷〾あ〴お〽〰〼〴おう〰あおぁ〾〱〴ぁぃお〱ぁい〲〴お〷〴お〷〰〳お〽〴〴〳おぃ〾お〱〴お〱〾ぃ〷お〱ぁ〰ぅ〴お〰〽〳おう〸あ〴お〵〾ぁおぃ〷〴おぃ〸〼〴あお〸〽おう〷〸〲〷お〷〴お〻〸ぅ〴〳おう〴ぁ〴おう〸〻〳お〰〽〳おぁい〳〴おぃ〷〴お〺〸〽〶お〾〵お〴〽〶〻〰〽〳おう〰あお〰ぃおう〰ぁおう〸ぃ〷お〷〸〼お〰〽〳お〷〰〳お〻〴〳お〰お〶ぁ〴〰ぃお〰ぁ〼えお〸〽ぃ〾おあ〲〾ぃ〻〰〽〳おぃ〾お〳ぁ〸ぅ〴お〷〸〼お〾いぃお〾〵おぃ〷〴お〻〰〽〳お〱〰ぃぃ〻〴お〰〵ぃ〴ぁお〱〰ぃぃ〻〴お〷〰〳お〱〴〴〽お〵〾い〶〷ぃおあ〸ぇおぃ〸〼〴あお〷〰〳お〱ぁい〲〴お〻〴〳お〷〸あお〱ぁ〰ぅ〴お〻〸ぃぃ〻〴お〰ぁ〼えお〰〶〰〸〽あぃお〷〸あお〵〾〴あお〰〽〳おあ〸ぇおぃ〸〼〴あお〷〰〳お〷〸あお〼〴〽お〱〴〴〽お〱〴〰ぃ〴〽お〰〽〳お〳ぁ〸ぅ〴〽お〸〽ぃ〾お〵〻〸〶〷ぃお〰ぃお〻〰あぃお〷〸あお〰ぁ〼えおう〰あおあ〲〰ぃぃ〴ぁ〴〳お〰〽〳お〷〴おう〰あお〵〾ぁ〲〴〳おぃ〾お〷〸〳〴お〷〸〼あ〴〻〵お〸〽おぃ〷〴おう〾〾〳あお〰〽〳お〸〽お〻〾〽〴〻えお〿〻〰〲〴あお〰〼〾〽〶おぃ〷〴お〼〾い〽ぃ〰〸〽あお〾〽 〴おぁ〰〸〽えお〳〰えお〱ぁい〲〴お〻〰えお〾〽おぃ〷〴お〶ぁ〾い〽〳おい〽〳〴ぁお〰おぁい〳〴おあ〷〴〳お〻〸あぃ〴〽〸〽〶おぃ〾おぃ〷〴お〿〰ぃぃ〴ぁお〾〵おぃ〷〴お〳ぁ〾〿あお〾〽おぃ〷〴おぁ〾〾〵お〰〱〾ぅ〴お〷〸〼お〷〴おう〰あおぃ〸ぁ〴〳お〰〽〳おあ〸〲〺お〰ぃお〷〴〰ぁぃお〰〽〳おぁ〴〰〳えおぃ〾お〶〸ぅ〴おい〿お〰〻〻お〷〾〿〴お〸ぃおあ〴〴〼〴〳おぃ〾お〷〸〼おぃ〷〰ぃおぃ〷〴ぁ〴おう〰あお〽〾おいあ〴お〵〾ぁお〷〸〼おぃ〾おぃぁえおぃ〾お〳〾お〰〽えぃ〷〸〽〶お〼〾ぁ〴お〰あお〷〴お〻〰えおぃ〷〸〽〺〸〽〶お〷〴おあ〰うお〰おあ〿〸〳〴ぁお〾ぅ〴ぁお〷〸あお〷〴〰〳お〼〰〺〸〽 〶おぁ〴〰〳えおぃ〾おう〴〰ぅ〴お〷〴ぁおう〴〱お〷〴おう〰ぃ〲〷〴〳お〷〴ぁお〰あおあ〷〴おぃ〾〸〻〴〳おあ〻〾う〻えお〰〽〳おう〸ぃ〷お〶ぁ〴〰ぃお〲〰ぁ〴おあ〸ぇおぃ〸〼〴あおあ〷〴おぃぁ〸〴〳おぃ〾おぃ〷ぁ〾うお〷〴ぁお〵ぁ〰〸〻おぃ〷ぁ〴〰〳お〵ぁ〾〼お〾〽〴お〱〴〰〼おぃ〾お〰〽〾ぃ〷〴ぁお〰〽〳おあ〸ぇおぃ〸〼〴あお〸ぃお〵〴〻〻おあ〷〾ぁぃお〿〾〾ぁおぃ〷〸〽〶おあ〰〸〳お〱ぁい〲〴おえ〾いおぃ〾〾お〺〽〾うおう〷〰ぃお〸ぃお〸あおぃ〾お〵〰〸〻お〱いぃおぃ〷 〴おあ〿〸〳〴ぁお〳〸〳お〽〾ぃお〻〾あ〴お〷〾〿〴おう〸ぃ〷おぃ〷〴おあ〸ぇぃ〷お〵〰〸〻いぁ〴おう〸ぃ〷おあぃ〸〻〻お〼〾ぁ〴お〲〰ぁ〴おあ〷〴お〼〰〳〴おぁ〴〰〳えおぃ〾おぃぁえお〵〾ぁおぃ〷〴おあ〴ぅ〴〽ぃ〷おぃ〸〼〴お〱ぁい〲〴お〰〻〼〾あぃお〵〾ぁ〶〾ぃお〷〸あお〾う〽おぃぁ〾い〱〻〴あお〰あお〷〴おう〰ぃ〲〷〴〳お〷〴ぁおあう〸〽〶お〷〴ぁあ〴〻〵お〾いぃおい〿〾〽おぃ〷〴おあ〻〴〽〳〴ぁお〻〸〽〴おう〾い〻〳おあ〷〴お〵〰〸〻お〰〶〰〸〽お〽〾おぃ〷〴おぃ〷ぁ〴 〰〳おう〰あお〲〰ぁぁ〸〴〳おあ〰〵〴〻えおぃ〾おぃ〷〴お〱〴〰〼お〰〽〳お〵〰あぃ〴〽〴〳おぃ〷〴ぁ〴お〸おぃ〾〾おう〸〻〻おぃぁえお〰おあ〴ぅ〴〽ぃ〷おぃ〸〼〴お〲ぁ〸〴〳お〱ぁい〲〴お〷〴お〰ぁ〾あ〴お〰〽〳お〲〰〻〻〴〳お〷〸あお〼〴〽おぃ〾〶〴ぃ〷〴ぁお〷〴おぃ〾〻〳おぃ〷〴〼お〾〵お〷〸あお〿〻〰〽あお〰〽〳おあ〴〽ぃおぃ〷〴〼お〾いぃおう〸ぃ〷 お〼〴ああ〰〶〴あお〾〵お〲〷〴〴ぁおぃ〾お〷〸あお〳〸あ〷〴〰ぁぃ〴〽〴〳お〿〴〾〿〻〴おあ〾〾〽おぃ〷〴ぁ〴おう〰あお〰〽お〰ぁ〼えお〾〵お〱ぁ〰ぅ〴おあ〲〾ぃ〲〷〼〴〽お〰ぁ〾い〽〳お〷〸〼お〰〽〾ぃ〷〴ぁお〱〰ぃぃ〻〴おう〰あお〵〾い〶〷ぃお〰〽〳おぃ〷〴お〺〸〽〶お〾〵お〴〽〶〻〰〽〳おう〰あお〶〻〰〳おぃ〾お〶〾お〱〰〲〺お〸〽ぃ〾お〷〸あお〾う〽お〲〾い〽ぃぁえお〸お〷〰ぅ〴お〷〴〰ぁ〳お〸ぃおあ〰〸〳おぃ〷〰ぃお〰〵ぃ〴ぁおぃ〷〰ぃお〳〰えお〽〾お〾〽〴お〱えおぃ〷〴お〽〰〼〴お〾〵お〱ぁい〲〴おう〾い〻〳お〴ぅ〴ぁお〷いぁぃお〰おあ〿〸〳〴ぁおぃ〷〴お〻〴ああ〾〽おう〷〸〲〷お ぃ〷〴お〻〸ぃぃ〻〴お〲ぁ〴〰ぃいぁ〴お〷〰〳おぃ〰い〶〷ぃおぃ〷〴お〺〸〽〶おう〰あお〽〴ぅ〴ぁお〵〾ぁ〶〾ぃぃ〴〽お〷〴おぃ〾〻〳おいあおぃ〷〴お〵〻〰〶おう〰あお〲〰ぁ〴〵い〻お〵ぁ〴぀い〴〽〲えお〰〽〰〻えあ〸あお〱ぁ〴〰〺あおあい 〱あぃ〸ぃいぃ〸〾〽お〲〸〿〷〴ぁお〷〴お〰〻あ〾おあい〶〶〴あぃあおぃ〷〴おいあ〴ぁおぃ〾お〹〾〸〽おぃ〷〴おう〾ぁ〳 あおう〸ぃ〷おい〽〳〴ぁあ〲〾ぁ〴お〰〽〳お〿いぃおぃ〷〴おぁ〴あい〻ぃお〸〽おぃ〷〴お〵〻〰〶おうぁ〰〿〿〴ぁお〱〴〵〾 ぁ〴おあい〱〼〸ああ〸〾〽


まず1文字ずつordして値を確認します。

[12355, 12343, 12340, 12353, 12340, 12362, 12358, 12336, 12354, 12362, 12350, 12349, 12338, 12340, 12362, 12336, 12362, 12346, 12344, 12349, 12342, 12362, 12350, 12341, 12362, 12354, 12338, 12350, 12355, 12347, 12336, 12349, 12339, 12362, 12358, 12343, 12350, 12354, 12340, 12362, 12349, 12336, 12348, 12340, 12362, 12358, 12336, 12354, 12362, 12353, 12350, 12337, 12340, 12353, 12355, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12343, 12340, 12362, 12343, 12336, 12339, 12362, 12349, 12340, 12340, 12339, 12362, 12355, 12350, 12362, 12337, 12340, 12362, 12337, 12350, 12355, 12343, 12362, 12337, 12353, 12336, 12357, 12340, 12362, 12336, 12349, 12339, 12362, 12358, 12344, 12354, 12340, 12362, 12341, 12350, 12353, 12362, 12355, 12343, 12340, 12362, 12355, 12344, 12348, 12340, 12354, 12362, 12344, 12349, 12362, 12358, 12343, 12344, 12338, 12343, 12362, 12343, 12340, 12362, 12347, 12344, 12357, 12340, 12339, 12362, 12358, 12340, 12353, 12340, 12362, 12358, 12344, 12347, 12339, 12362, 12336, 12349, 12339, 12362, 12353, 12356, 12339, 12340, 12362, 12355, 12343, 12340, 12362, 12346, 12344, 12349, 12342, 12362, 12350, 12341, 12362, 12340, 12349, 12342, 12347, 12336, 12349, 12339, 12362, 12358, 12336, 12354, 12362, 12336, 12355, 12362, 12358, 12336, 12353, 12362, 12358, 12344, 12355, 12343, 12362, 12343, 12344, 12348, 12362, 12336, 12349, 12339, 12362, 12343, 12336, 12339, 12362, 12347, 12340, 12339, 12362, 12336, 12362, 12342, 12353, 12340, 12336, 12355, 12362, 12336, 12353, 12348, 12360, 12362, 12344, 12349, 12355, 12350, 12362, 12354, 12338, 12350, 12355, 12347, 12336, 12349, 12339, 12362, 12355, 12350, 12362, 12339, 12353, 12344, 12357, 12340, 12362, 12343, 12344, 12348, 12362, 12350, 12356, 12355, 12362, 12350, 12341, 12362, 12355, 12343, 12340, 12362, 12347, 12336, 12349, 12339, 12362, 12337, 12336, 12355, 12355, 12347, 12340, 12362, 12336, 12341, 12355, 12340, 12353, 12362, 12337, 12336, 12355, 12355, 12347, 12340, 12362, 12343, 12336, 12339, 12362, 12337, 12340, 12340, 12349, 12362, 12341, 12350, 12356, 12342, 12343, 12355, 12362, 12354, 12344, 12359, 12362, 12355, 12344, 12348, 12340, 12354, 12362, 12343, 12336, 12339, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12347, 12340, 12339, 12362, 12343, 12344, 12354, 12362, 12337, 12353, 12336, 12357, 12340, 12362, 12347, 12344, 12355, 12355, 12347, 12340, 12362, 12336, 12353, 12348, 12360, 12362, 12336, 12342, 12336, 12344, 12349, 12354, 12355, 12362, 12343, 12344, 12354, 12362, 12341, 12350, 12340, 12354, 12362, 12336, 12349, 12339, 12362, 12354, 12344, 12359, 12362, 12355, 12344, 12348, 12340, 12354, 12362, 12343, 12336, 12339, 12362, 12343, 12344, 12354, 12362, 12348, 12340, 12349, 12362, 12337, 12340, 12340, 12349, 12362, 12337, 12340, 12336, 12355, 12340, 12349, 12362, 12336, 12349, 12339, 12362, 12339, 12353, 12344, 12357, 12340, 12349, 12362, 12344, 12349, 12355, 12350, 12362, 12341, 12347, 12344, 12342, 12343, 12355, 12362, 12336, 12355, 12362, 12347, 12336, 12354, 12355, 12362, 12343, 12344, 12354, 12362, 12336, 12353, 12348, 12360, 12362, 12358, 12336, 12354, 12362, 12354, 12338, 12336, 12355, 12355, 12340, 12353, 12340, 12339, 12362, 12336, 12349, 12339, 12362, 12343, 12340, 12362, 12358, 12336, 12354, 12362, 12341, 12350, 12353, 12338, 12340, 12339, 12362, 12355, 12350, 12362, 12343, 12344, 12339, 12340, 12362, 12343, 12344, 12348, 12354, 12340, 12347, 12341, 12362, 12344, 12349, 12362, 12355, 12343, 12340, 12362, 12358, 12350, 12350, 12339, 12354, 12362, 12336, 12349, 12339, 12362, 12344, 12349, 12362, 12347, 12350, 12349, 12340, 12347, 12360, 12362, 12351, 12347, 12336, 12338, 12340, 12354, 12362, 12336, 12348, 12350, 12349, 12342, 12362, 12355, 12343, 12340, 12362, 12348, 12350, 12356, 12349, 12355, 12336, 12344, 12349, 12354, 12362, 12350, 12349, 12340, 12362, 12353, 12336, 12344, 12349, 12360, 12362, 12339, 12336, 12360, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12347, 12336, 12360, 12362, 12350, 12349, 12362, 12355, 12343, 12340, 12362, 12342, 12353, 12350, 12356, 12349, 12339, 12362, 12356, 12349, 12339, 12340, 12353, 12362, 12336, 12362, 12353, 12356, 12339, 12340, 12362, 12354, 12343, 12340, 12339, 12362, 12347, 12344, 12354, 12355, 12340, 12349, 12344, 12349, 12342, 12362, 12355, 12350, 12362, 12355, 12343, 12340, 12362, 12351, 12336, 12355, 12355, 12340, 12353, 12362, 12350, 12341, 12362, 12355, 12343, 12340, 12362, 12339, 12353, 12350, 12351, 12354, 12362, 12350, 12349, 12362, 12355, 12343, 12340, 12362, 12353, 12350, 12350, 12341, 12362, 12336, 12337, 12350, 12357, 12340, 12362, 12343, 12344, 12348, 12362, 12343, 12340, 12362, 12358, 12336, 12354, 12362, 12355, 12344, 12353, 12340, 12339, 12362, 12336, 12349, 12339, 12362, 12354, 12344, 12338, 12346, 12362, 12336, 12355, 12362, 12343, 12340, 12336, 12353, 12355, 12362, 12336, 12349, 12339, 12362, 12353, 12340, 12336, 12339, 12360, 12362, 12355, 12350, 12362, 12342, 12344, 12357, 12340, 12362, 12356, 12351, 12362, 12336, 12347, 12347, 12362, 12343, 12350, 12351, 12340, 12362, 12344, 12355, 12362, 12354, 12340, 12340, 12348, 12340, 12339, 12362, 12355, 12350, 12362, 12343, 12344, 12348, 12362, 12355, 12343, 12336, 12355, 12362, 12355, 12343, 12340, 12353, 12340, 12362, 12358, 12336, 12354, 12362, 12349, 12350, 12362, 12356, 12354, 12340, 12362, 12341, 12350, 12353, 12362, 12343, 12344, 12348, 12362, 12355, 12350, 12362, 12355, 12353, 12360, 12362, 12355, 12350, 12362, 12339, 12350, 12362, 12336, 12349, 12360, 12355, 12343, 12344, 12349, 12342, 12362, 12348, 12350, 12353, 12340, 12362, 12336, 12354, 12362, 12343, 12340, 12362, 12347, 12336, 12360, 12362, 12355, 12343, 12344, 12349, 12346, 12344, 12349, 12342, 12362, 12343, 12340, 12362, 12354, 12336, 12358, 12362, 12336, 12362, 12354, 12351, 12344, 12339, 12340, 12353, 12362, 12350, 12357, 12340, 12353, 12362, 12343, 12344, 12354, 12362, 12343, 12340, 12336, 12339, 12362, 12348, 12336, 12346, 12344, 12349, 12342, 12362, 12353, 12340, 12336, 12339, 12360, 12362, 12355, 12350, 12362, 12358, 12340, 12336, 12357, 12340, 12362, 12343, 12340, 12353, 12362, 12358, 12340, 12337, 12362, 12343, 12340, 12362, 12358, 12336, 12355, 12338, 12343, 12340, 12339, 12362, 12343, 12340, 12353, 12362, 12336, 12354, 12362, 12354, 12343, 12340, 12362, 12355, 12350, 12344, 12347, 12340, 12339, 12362, 12354, 12347, 12350, 12358, 12347, 12360, 12362, 12336, 12349, 12339, 12362, 12358, 12344, 12355, 12343, 12362, 12342, 12353, 12340, 12336, 12355, 12362, 12338, 12336, 12353, 12340, 12362, 12354, 12344, 12359, 12362, 12355, 12344, 12348, 12340, 12354, 12362, 12354, 12343, 12340, 12362, 12355, 12353, 12344, 12340, 12339, 12362, 12355, 12350, 12362, 12355, 12343, 12353, 12350, 12358, 12362, 12343, 12340, 12353, 12362, 12341, 12353, 12336, 12344, 12347, 12362, 12355, 12343, 12353, 12340, 12336, 12339, 12362, 12341, 12353, 12350, 12348, 12362, 12350, 12349, 12340, 12362, 12337, 12340, 12336, 12348, 12362, 12355, 12350, 12362, 12336, 12349, 12350, 12355, 12343, 12340, 12353, 12362, 12336, 12349, 12339, 12362, 12354, 12344, 12359, 12362, 12355, 12344, 12348, 12340, 12354, 12362, 12344, 12355, 12362, 12341, 12340, 12347, 12347, 12362, 12354, 12343, 12350, 12353, 12355, 12362, 12351, 12350, 12350, 12353, 12362, 12355, 12343, 12344, 12349, 12342, 12362, 12354, 12336, 12344, 12339, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12360, 12350, 12356, 12362, 12355, 12350, 12350, 12362, 12346, 12349, 12350, 12358, 12362, 12358, 12343, 12336, 12355, 12362, 12344, 12355, 12362, 12344, 12354, 12362, 12355, 12350, 12362, 12341, 12336, 12344, 12347, 12362, 12337, 12356, 12355, 12362, 12355, 12343, 12340, 12362, 12354, 12351, 12344, 12339, 12340, 12353, 12362, 12339, 12344, 12339, 12362, 12349, 12350, 12355, 12362, 12347, 12350, 12354, 12340, 12362, 12343, 12350, 12351, 12340, 12362, 12358, 12344, 12355, 12343, 12362, 12355, 12343, 12340, 12362, 12354, 12344, 12359, 12355, 12343, 12362, 12341, 12336, 12344, 12347, 12356, 12353, 12340, 12362, 12358, 12344, 12355, 12343, 12362, 12354, 12355, 12344, 12347, 12347, 12362, 12348, 12350, 12353, 12340, 12362, 12338, 12336, 12353, 12340, 12362, 12354, 12343, 12340, 12362, 12348, 12336, 12339, 12340, 12362, 12353, 12340, 12336, 12339, 12360, 12362, 12355, 12350, 12362, 12355, 12353, 12360, 12362, 12341, 12350, 12353, 12362, 12355, 12343, 12340, 12362, 12354, 12340, 12357, 12340, 12349, 12355, 12343, 12362, 12355, 12344, 12348, 12340, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12336, 12347, 12348, 12350, 12354, 12355, 12362, 12341, 12350, 12353, 12342, 12350, 12355, 12362, 12343, 12344, 12354, 12362, 12350, 12358, 12349, 12362, 12355, 12353, 12350, 12356, 12337, 12347, 12340, 12354, 12362, 12336, 12354, 12362, 12343, 12340, 12362, 12358, 12336, 12355, 12338, 12343, 12340, 12339, 12362, 12343, 12340, 12353, 12362, 12354, 12358, 12344, 12349, 12342, 12362, 12343, 12340, 12353, 12354, 12340, 12347, 12341, 12362, 12350, 12356, 12355, 12362, 12356, 12351, 12350, 12349, 12362, 12355, 12343, 12340, 12362, 12354, 12347, 12340, 12349, 12339, 12340, 12353, 12362, 12347, 12344, 12349, 12340, 12362, 12358, 12350, 12356, 12347, 12339, 12362, 12354, 12343, 12340, 12362, 12341, 12336, 12344, 12347, 12362, 12336, 12342, 12336, 12344, 12349, 12362, 12349, 12350, 12362, 12355, 12343, 12340, 12362, 12355, 12343, 12353, 12340, 12336, 12339, 12362, 12358, 12336, 12354, 12362, 12338, 12336, 12353, 12353, 12344, 12340, 12339, 12362, 12354, 12336, 12341, 12340, 12347, 12360, 12362, 12355, 12350, 12362, 12355, 12343, 12340, 12362, 12337, 12340, 12336, 12348, 12362, 12336, 12349, 12339, 12362, 12341, 12336, 12354, 12355, 12340, 12349, 12340, 12339, 12362, 12355, 12343, 12340, 12353, 12340, 12362, 12344, 12362, 12355, 12350, 12350, 12362, 12358, 12344, 12347, 12347, 12362, 12355, 12353, 12360, 12362, 12336, 12362, 12354, 12340, 12357, 12340, 12349, 12355, 12343, 12362, 12355, 12344, 12348, 12340, 12362, 12338, 12353, 12344, 12340, 12339, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12343, 12340, 12362, 12336, 12353, 12350, 12354, 12340, 12362, 12336, 12349, 12339, 12362, 12338, 12336, 12347, 12347, 12340, 12339, 12362, 12343, 12344, 12354, 12362, 12348, 12340, 12349, 12362, 12355, 12350, 12342, 12340, 12355, 12343, 12340, 12353, 12362, 12343, 12340, 12362, 12355, 12350, 12347, 12339, 12362, 12355, 12343, 12340, 12348, 12362, 12350, 12341, 12362, 12343, 12344, 12354, 12362, 12351, 12347, 12336, 12349, 12354, 12362, 12336, 12349, 12339, 12362, 12354, 12340, 12349, 12355, 12362, 12355, 12343, 12340, 12348, 12362, 12350, 12356, 12355, 12362, 12358, 12344, 12355, 12343, 12362, 12348, 12340, 12354, 12354, 12336, 12342, 12340, 12354, 12362, 12350, 12341, 12362, 12338, 12343, 12340, 12340, 12353, 12362, 12355, 12350, 12362, 12343, 12344, 12354, 12362, 12339, 12344, 12354, 12343, 12340, 12336, 12353, 12355, 12340, 12349, 12340, 12339, 12362, 12351, 12340, 12350, 12351, 12347, 12340, 12362, 12354, 12350, 12350, 12349, 12362, 12355, 12343, 12340, 12353, 12340, 12362, 12358, 12336, 12354, 12362, 12336, 12349, 12362, 12336, 12353, 12348, 12360, 12362, 12350, 12341, 12362, 12337, 12353, 12336, 12357, 12340, 12362, 12354, 12338, 12350, 12355, 12338, 12343, 12348, 12340, 12349, 12362, 12336, 12353, 12350, 12356, 12349, 12339, 12362, 12343, 12344, 12348, 12362, 12336, 12349, 12350, 12355, 12343, 12340, 12353, 12362, 12337, 12336, 12355, 12355, 12347, 12340, 12362, 12358, 12336, 12354, 12362, 12341, 12350, 12356, 12342, 12343, 12355, 12362, 12336, 12349, 12339, 12362, 12355, 12343, 12340, 12362, 12346, 12344, 12349, 12342, 12362, 12350, 12341, 12362, 12340, 12349, 12342, 12347, 12336, 12349, 12339, 12362, 12358, 12336, 12354, 12362, 12342, 12347, 12336, 12339, 12362, 12355, 12350, 12362, 12342, 12350, 12362, 12337, 12336, 12338, 12346, 12362, 12344, 12349, 12355, 12350, 12362, 12343, 12344, 12354, 12362, 12350, 12358, 12349, 12362, 12338, 12350, 12356, 12349, 12355, 12353, 12360, 12362, 12344, 12362, 12343, 12336, 12357, 12340, 12362, 12343, 12340, 12336, 12353, 12339, 12362, 12344, 12355, 12362, 12354, 12336, 12344, 12339, 12362, 12355, 12343, 12336, 12355, 12362, 12336, 12341, 12355, 12340, 12353, 12362, 12355, 12343, 12336, 12355, 12362, 12339, 12336, 12360, 12362, 12349, 12350, 12362, 12350, 12349, 12340, 12362, 12337, 12360, 12362, 12355, 12343, 12340, 12362, 12349, 12336, 12348, 12340, 12362, 12350, 12341, 12362, 12337, 12353, 12356, 12338, 12340, 12362, 12358, 12350, 12356, 12347, 12339, 12362, 12340, 12357, 12340, 12353, 12362, 12343, 12356, 12353, 12355, 12362, 12336, 12362, 12354, 12351, 12344, 12339, 12340, 12353, 12362, 12355, 12343, 12340, 12362, 12347, 12340, 12354, 12354, 12350, 12349, 12362, 12358, 12343, 12344, 12338, 12343, 12362, 12355, 12343, 12340, 12362, 12347, 12344, 12355, 12355, 12347, 12340, 12362, 12338, 12353, 12340, 12336, 12355, 12356, 12353, 12340, 12362, 12343, 12336, 12339, 12362, 12355, 12336, 12356, 12342, 12343, 12355, 12362, 12355, 12343, 12340, 12362, 12346, 12344, 12349, 12342, 12362, 12358, 12336, 12354, 12362, 12349, 12340, 12357, 12340, 12353, 12362, 12341, 12350, 12353, 12342, 12350, 12355, 12355, 12340, 12349, 12362, 12343, 12340, 12362, 12355, 12350, 12347, 12339, 12362, 12356, 12354, 12362, 12355, 12343, 12340, 12362, 12341, 12347, 12336, 12342, 12362, 12358, 12336, 12354, 12362, 12338, 12336, 12353, 12340, 12341, 12356, 12347, 12362, 12341, 12353, 12340, 12352, 12356, 12340, 12349, 12338, 12360, 12362, 12336, 12349, 12336, 12347, 12360, 12354, 12344, 12354, 12362, 12337, 12353, 12340, 12336, 12346, 12354, 12362, 12354, 12356, 12337, 12354, 12355, 12344, 12355, 12356, 12355, 12344, 12350, 12349, 12362, 12338, 12344, 12351, 12343, 12340, 12353, 12362, 12343, 12340, 12362, 12336, 12347, 12354, 12350, 12362, 12354, 12356, 12342, 12342, 12340, 12354, 12355, 12354, 12362, 12355, 12343, 12340, 12362, 12356, 12354, 12340, 12353, 12362, 12355, 12350, 12362, 12345, 12350, 12344, 12349, 12362, 12355, 12343, 12340, 12362, 12358, 12350, 12353, 12339, 12354, 12362, 12358, 12344, 12355, 12343, 12362, 12356, 12349, 12339, 12340, 12353, 12354, 12338, 12350, 12353, 12340, 12362, 12336, 12349, 12339, 12362, 12351, 12356, 12355, 12362, 12355, 12343, 12340, 12362, 12353, 12340, 12354, 12356, 12347, 12355, 12362, 12344, 12349, 12362, 12355, 12343, 12340, 12362, 12341, 12347, 12336, 12342, 12362, 12358, 12353, 12336, 12351, 12351, 12340, 12353, 12362, 12337, 12340, 12341, 12350, 12353, 12340, 12362, 12354, 12356, 12337, 12348, 12344, 12354, 12354, 12344, 12350, 12349]


これは換字式暗号ですね。この数値のどれかが空白となり、それ以外はテキトーなアルファベットを当てはめます。数値が同じなら同じアルファベットになるようにします。

全ての数値に対して空白にしたとき、明らかに長すぎる単語が出てきたものは無視します。


ABCDC EFG HIJC F KLIM HN GJHAOFIP


最初が"THERE ARE"ぽいです(違うけど)。これをquipquipに投げて完了です。


THERE WAS ONCE A KING OF SCOTLAND WHOSE NAME WAS ROBERT BRUCE HE HAD NEED TO BE BOTH BRAVE AND WISE FOR THE TIMES IN WHICH HE LIVED WERE WILD AND RUDE THE KING OF ENGLAND WAS AT WAR WITH HIM AND HAD LED A GREAT ARMY INTO SCOTLAND TO DRIVE HIM OUT OF THE LAND BATTLE AFTER BATTLE HAD BEEN FOUGHT SIX TIMES HAD BRUCE LED HIS BRAVE LITTLE ARMY AGAINST HIS FOES AND SIX TIMES HAD HIS MEN BEEN BEATEN AND DRIVEN INTO FLIGHT AT LAST HIS ARMY WAS SCATTERED AND HE WAS FORCED TO HIDE HIMSELF IN THE WOODS AND IN LONELY PLACES AMONG THE MOUNTAINS ONE RAINY DAY BRUCE LAY ON THE GROUND UNDER A RUDE SHED LISTENING TO THE PATTER OF THE DROPS ON THE ROOF ABOVE HIM HE WAS TIRED AND SICK AT HEART AND READY TO GIVE UP ALL HOPE IT SEEMED TO HIM THAT THERE WAS NO USE FOR HIM TO TRY TO DO ANYTHING MORE AS HE LAY THINKING HE SAW A SPIDER OVER HIS HEAD MAKING READY TO WEAVE HER WEB HE WATCHED HER AS SHE TOILED SLOWLY AND WITH GREAT CARE SIX TIMES SHE TRIED TO THROW HER FRAIL THREAD FROM ONE BEAM TO ANOTHER AND SIX TIMES IT FELL SHORT POOR THING SAID BRUCE YOU TOO KNOW WHAT IT IS TO FAIL BUT THE SPIDER DID NOT LOSE HOPE WITH THE SIXTH FAILURE WITH STILL MORE CARE SHE MADE READY TO TRY FOR THE SEVENTH TIME BRUCE ALMOST FORGOT HIS OWN TROUBLES AS HE WATCHED HER SWING HERSELF OUT UPON THE SLENDER LINE WOULD SHE FAIL AGAIN NO THE THREAD WAS CARRIED SAFELY TO THE BEAM AND FASTENED THERE I TOO WILL TRY A SEVENTH TIME CRIED BRUCE HE AROSE AND CALLED HIS MEN TOGETHER HE TOLD THEM OF HIS PLANS AND SENT THEM OUT WITH MESSAGES OF CHEER TO HIS DISHEARTENED PEOPLE SOON THERE WAS AN ARMY OF BRAVE SCOTCHMEN AROUND HIM ANOTHER BATTLE WAS FOUGHT AND THE KING OF ENGLAND WAS GLAD TO GO BACK INTO HIS OWN COUNTRY I HAVE HEARD IT SAID THAT AFTER THAT DAY NO ONE BY THE NAME OF BRUCE WOULD EVER HURT A SPIDER THE LESSON WHICH THE LITTLE CREATURE HAD TAUGHT THE KING WAS NEVER FORGOTTEN HE TOLD US THE FLAG WAS CAREFUL FREQUENCY ANALYSIS BREAKS SUBSTITUTION CIPHER HE ALSO SUGGESTS THE USER TO JOIN THE WORDS WITH UNDERSCORE AND PUT THE RESULT IN THE FLAG WRAPPER BEFORE SUBMISSION


Heritage History | Fifty Famous Stories Retold by James Baldwin

これですね。


HE TOLD US THE FLAG WAS CAREFUL FREQUENCY ANALYSIS BREAKS SUBSTITUTION CIPHER HE ALSO SUGGESTS THE USER TO JOIN THE WORDS WITH UNDERSCORE AND PUT THE RESULT IN THE FLAG WRAPPER BEFORE SUBMISSION


とあるのですが、flagが分からない…。この文章のタイトルかと思ったら違いました。結局これでした。


wormcon{CAREFUL_FREQUENCY_ANALYSIS_BREAKS_SUBSTITUTION_CIPHER}



Rem, Shinobu, Asuna 475pt


I thought RSA means Rem, Shinobu and Asuna!!!
ファイル:chall.py, out.txt

#!/usr/bin/env python3
from Crypto.Util.number import *

FLAG = open('flag.txt', 'rb').read()

bits = 512
e = 65537
p = getPrime(bits)
q = getPrime(bits)
n = p*q
phi = (p-1)*(q-1)
d = inverse(e, phi)
hint = 2*d*(p-1337)

m = bytes_to_long(FLAG)
c = pow(m, e, n)

print(f"n = {hex(n)}")
print(f"e = {hex(e)}")
print(f"c = {hex(c)}")
print(f"hint = {hex(hint)}")

# ---out.txt ---
# n = 0xced9347557a5d6f88e3a506517ad051aff9c1a2ee8a1ac27f3dd74c58ac1c5bc2e2ba7ae2aba617497c5204d3933d9a941cf9af61d8308d760cad984567fa725f35510f6944dce3306687b49138c1eda555cd1f1a0c5fbf10b47ca0aa2afca13083a02f59281a2087d8b277fa43ad187dbc84d37f276c997b9ed456c1601256d
# e = 0x10001
# c = 0xd5d4bc7f461ab02dddb1c3d911bfeee35837a787b02f09d45f5c29e122d784bf5ee97e1ace3a320130fb8747c40292a8503613b674280ab7b64163e9a2ab8a39dfba55d2032d67f1d3fe6389881f8c4145c5b7eb8d83caaa6ebebad021f668a83434d7d48a249f5e8e23828b1aa9402c8b88eab9c48e035a9997bdcc4b48479
# hint = 0x7acdc2f1c0acd1fb471f7804a984b962206babbbc8aba1c6a06757b1a10ba3941e5d9d5a1f19b8d9ed9facb48f8f0beda5366ed62c77303a5749e96f1cb820fd0d4d4e7ac1fc15207ae36f9a5aa0fdd9240605277d5ba51dee5075186fbea7340a5b2d09d82e025485ecedd7c505265e81c57db7ce72e722c0179f71669413c54fced2b3663b2171e38554d00e876c67b5d221bea6b1c7345fe1ae024ffdd72afd12f79522ac96932f6505d9ce8e7abad89182bcb7911b6a1dc7054c7a42b304


紆余曲折ありましたが、結果としては以下のa, bを求めることです。

a = k(p-1) + b (k : 整数)

適当な整数xを持ってきます。ここで、xa - xb = 0 mod p となり、左辺はpの倍数となります。フェルマーの小定理 (xp-1 = 1 mod p) を使えばこのように変形できます。

xa = xk(p-1) + b = xk(p-1) × xb mod p


では、a,bを求めていきます。

hint = 2*d*(p-1337)
e*hint = 2*e*d*(p-1337)

e*d = k(p-1)(q-1)+1 (k : 整数)より
e*hint = 2*(k(p-1)(q-1)+1)*(p-1337) )= 2k(p-1)(q-1)(p-1337)+2(p-1337)
= 2k(p-1)(q-1)(p-1337)+2(p-1)-2672

ゆえに、a = e*hint, b = -2672 が分かりました。xe*hint - x-2672 はpの倍数となります。nとgcdとれば素因数分解できます。


from Crypto.Util.number import *
import math,random
n = (中略)
e = (中略)
c = (中略)
hint = (中略)
m = random.randrange(n)
c1 = pow(m,e*hint,n)
c2 = pow(m,1336*2,n)
c2 = inverse(c2,n)
print(c1)
print(c2)
p = math.gcd(c1-c2,n)
q = n//p
phi = (p-1)*(q-1)
d = inverse(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))


wormcon{RSA_And_Fermat's_Little_Theorem!?}



Sir Oracle 484pt


"I am Sir Oracle,. And when I ope my lips, let no dog bark!"
nc 34.83.246.93 8000
ファイル:server.py

# server.py
#!/usr/bin/env python3
from Crypto.Util.number import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Hash import SHA256
import os


bits = 256
bs = AES.block_size
FLAG = open('flag.txt').read()

menu = """
+-------------------------+
|                         |
|        M E N U          |   
|                         |
| [1] DH Parameters       |
| [2] View PublicKeys     |
| [3] Encrypt Flag        |
| [4] Generate PublicKey  |
|                         |
+-------------------------+
"""

def encrypt(m, key):
    key = SHA256.new(str(key).encode()).digest()[:bs]
    iv = os.urandom(bs)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    enc = cipher.encrypt(pad(m.encode(), 16))
    return (enc.hex(), iv.hex())

def gen_pubkey(g, p, privkey):
    l = privkey.bit_length()
    m = int(input("Enter some random integer > "))
    new_privkey = privkey ^ m
    new_pubkey = pow(g, new_privkey, p)
    return new_pubkey

if __name__ == '__main__':
    g = 2
    p = getPrime(bits)

    # Rick Astley
    a = getRandomRange(1, p-1)
    R = pow(g,a,p)

    # Kermit the Frog
    b = getRandomRange(1, p-1)
    K = pow(g,b,p)

    s = pow(R,b,p)
    enc_flag, iv = encrypt(FLAG, s)

    # test
    with open('priv.txt','w') as f:
        f.write('a='+str(a)+'\n')
        f.write('b='+str(b))

    print(menu)
    l = p.bit_length() + 4
    
    try:
        for _ in range(l):
            ch = input("Choice ? ").strip().lower()

            if ch == '1':
                print("[DH parameters]")
                print(f"{g = }")
                print(f"{p = }\n")
            
            elif ch == '2':
                print("[Rick's PublicKey]")
                print(f"{R = }\n")
                print("[Kermit's PublicKey]")
                print(f"{K = }\n")
            
            elif ch == '3':
                print("[ENC FLAG]")
                print(f"{enc_flag = }\n")
                print("[IV]")
                print(f"{iv = }\n")

            elif ch == '4':
                npk = gen_pubkey(g, p, b)
                print("[Kermit's New PublicKey]")
                print(f"{npk = }\n")
            else:
                print(f":( Invalid Choice !!!")
                break
    except Exception as e:
        print(e)
        exit()

R = pow(g,a,p), K = pow(g,b,p) が渡され、s = pow(R,b,p) を求めたいという状態です。また、任意の整数mについて npk = pow(g,bm,p)を教えてくれます。

mを2のべき乗とすることで、mのbit数番目のbのbitが分かります。例えばm = 1を送った時、bの最下位ビットが0ならbm=b+1となりnpk = K*2 mod p となります。反対にbの最下位ビットが1ならbm=b-1となりnpk = K/2 mod p となります。渡されたnpkとKを比較してbの最下位ビットを特定します。

同様に、m = 2を送った時を考えます。

bの下位2ビット目が0 → npk = K*4 mod p
bの下位2ビット目が1 → npk = K/4 mod p

これを255回繰り返して、bが特定できました。

from Crypto.Util.number import *
from functools import reduce
from operator import mul
from itertools import combinations
import sys
import socket, struct, telnetlib
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Hash import SHA256

# --- common funcs ---
def sock(remoteip, remoteport):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((remoteip, remoteport))
    return s, s.makefile('rw')

def read_until(f, delim='\n'):
    data = ''
    while not data.endswith(delim):
        data += f.read(1)
    return data

    
#HOSTはIPアドレスでも可
HOST, PORT = "34.83.246.93", 8000
s, f = sock(HOST, PORT)
for _ in range(12): print(read_until(f))

#--DH parameter--
read_until(f,"? ")
s.send(b"1\n")
read_until(f)
g = int(read_until(f).split()[-1])
p = int(read_until(f).split()[-1])
read_until(f)

#--Pubkey--
read_until(f,"? ")
s.send(b"2\n")
read_until(f)
R = int(read_until(f).split()[-1])
read_until(f)
print(read_until(f))
K = int(read_until(f).split()[-1])
print("K =",K)
read_until(f)

#--enc flag--

read_until(f,"? ")
s.send(b"3\n")
read_until(f)
enc = read_until(f).split()[-1][1:-1]
read_until(f)
read_until(f)
iv = read_until(f).split()[-1][1:-1]
read_until(f)

#--calc b--
b = ""
for i in range(255):
    read_until(f,"? ")
    s.send(b"4\n")
    read_until(f,"> ")
    s.send(str(int("1"+"0"*i,2)).encode()+b"\n")
    read_until(f)
    npk = int(read_until(f).split()[-1])
    read_until(f)
    if npk == (K*pow(2,int("1"+"0"*i,2),p))%p: b = "0" + b
    elif npk == (K*pow(inverse(2,p),int("1"+"0"*i,2),p))%p: b = "1" + b
    else: print("Not Found")
    print(len(b),b)
print("p =",p)
print("b =",b)
print("iv =",iv)
print("enc =",enc)
print("R =",R)
b = int(b,2)
s = pow(R,b,p)
key = SHA256.new(str(s).encode()).digest()[:16]
iv = long_to_bytes(int(iv,16))
cipher = AES.new(key, AES.MODE_CBC, iv)
flag = cipher.decrypt(long_to_bytes(int(enc,16)))
print(flag)


wormcon{00p5!_n0_m45k_n0_FL4G}