Hexion CTF 2020 Online Writeup

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

About (Misc)

Aboutのページにフラグサンプルとしてフラグが書いてあった。

hexCTF{mu5t_b3_7he_eas1est_fl4g_y0u_g0t}

Mirage (Misc)

キーボードで入力した文字と異なる表示がされる。下記の上段の文字を入力したら、下段のように表示された。

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./_HLYUaPkr6:;<=>?@wcevoyGz1TJ{VDMQ39iquC7WXN[\]^I`dBFS4f}jZE5gRsAKOplm20xt8hb|n~

以下の問題の文字列を置換する。

j4teqybvAskIE2S}4IdIc_M5IB8IHmlIF_0Ypn
C = '!"#$%&\'()*+,-./_HLYUaPkr6:;<=>?@wcevoyGz1TJ{VDMQ39iquC7WXN[\]^I`dBFS4f}jZE5gRsAKOplm20xt8hb|n~'
P = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
Q = 'j4teqybvAskIE2S}4IdIc_M5IB8IHmlIF_0Ypn'
print ''.join(P[C.index(q)] for q in Q)
hexCTF{Don7_judge_a_B0Ok_by_1ts_c0v3r}

X0R (Crypto)

フラグがhexCTF{から始まることを前提に、XOR鍵の長さが8~16の場合でどうなるかを見ていく。
長さは9バイトとわかるので、それを前提にフラグとなる条件を調整し、候補を選出し、英語として正しそうなものをフラグとする。

from string import ascii_letters, lowercase

def str_xor(s1, s2):
    return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2))

def check_flag(s):
    for c in s[7:-1]:
        if c not in lowercase + '_':
            return False
    return True

with open('flag.enc', 'rb') as f:
    enc = f.read()

flag_head = 'hexCTF{'
key1 = str_xor(flag_head, enc)

# search key length
for length in range(8, 17):
    print '[+] length =', length
    pt = ''
    for i in range(0, len(enc), length):
        pt += str_xor(enc[i:i+len(flag_head)], key1)
        pt += '?' * (length - len(flag_head))
    pt = pt[:len(enc)]
    print '[-] pt =', pt

# key length = 9
for key2 in ascii_letters:
    for key3 in ascii_letters:
        key = key1 + key2 + key3
        key = key * (len(enc) / len(key) + 1)
        flag = str_xor(enc, key)
        if check_flag(flag):
            print flag

実行結果は以下の通り。

[+] length = 8
[-] pt = hexCTF{?xN|ECXe?GAFI~uY?tvIuv^y?eWbrS^H?CJ
[+] length = 9
[-] pt = hexCTF{??percali??agilist??expiali??cious}
[+] length = 10
[-] pt = hexCTF{???[kTAU`G???NB~jDAn???yoByukc???CJ
[+] length = 11
[-] pt = hexCTF{????UMvuYN????YDSX^lF????i{EsgAe??
[+] length = 12
[-] pt = hexCTF{?????soBywva?????tvIuv^y?????cious}
[+] length = 13
[-] pt = hexCTF{??????Q[NWOhY??????n[aGIXe??????e}S
[+] length = 14
[-] pt = hexCTF{???????eW`oQPN???????Fi^AU`E???????
[+] length = 15
[-] pt = hexCTF{????????iyXqiG|????????yoByukc?????
[+] length = 16
[-] pt = hexCTF{?????????GAFI~uY?????????eWbrS^H???
hexCTF{yspercaliltagilistceexpialinicious}
hexCTF{yppercalilwagilistcfexpialinjcious}
hexCTF{yqpercalilvagilistcgexpialinkcious}
hexCTF{ywpercalilpagilistcaexpialinmcious}
hexCTF{ytpercalilsagilistcbexpialinncious}
hexCTF{yupercalilragilistccexpialinocious}
hexCTF{ybpercalileagilistctexpialinxcious}
hexCTF{ycpercalildagilistcuexpialinycious}
hexCTF{pspercalietagilistjeexpialigicious}
hexCTF{pppercaliewagilistjfexpialigjcious}
hexCTF{pqpercalievagilistjgexpialigkcious}
hexCTF{pwpercaliepagilistjaexpialigmcious}
hexCTF{ptpercaliesagilistjbexpialigncious}
hexCTF{pupercalieragilistjcexpialigocious}
hexCTF{pbpercalieeagilistjtexpialigxcious}
hexCTF{pcpercaliedagilistjuexpialigycious}
hexCTF{qspercalidtagilistkeexpialificious}
hexCTF{qppercalidwagilistkfexpialifjcious}
hexCTF{qqpercalidvagilistkgexpialifkcious}
hexCTF{qwpercalidpagilistkaexpialifmcious}
hexCTF{qtpercalidsagilistkbexpialifncious}
hexCTF{qupercalidragilistkcexpialifocious}
hexCTF{qbpercalideagilistktexpialifxcious}
hexCTF{qcpercaliddagilistkuexpialifycious}
hexCTF{rspercaligtagilistheexpialieicious}
hexCTF{rppercaligwagilisthfexpialiejcious}
hexCTF{rqpercaligvagilisthgexpialiekcious}
hexCTF{rwpercaligpagilisthaexpialiemcious}
hexCTF{rtpercaligsagilisthbexpialiencious}
hexCTF{rupercaligragilisthcexpialieocious}
hexCTF{rbpercaligeagilisthtexpialiexcious}
hexCTF{rcpercaligdagilisthuexpialieycious}
hexCTF{sspercaliftagilistieexpialidicious}
hexCTF{sppercalifwagilistifexpialidjcious}
hexCTF{sqpercalifvagilistigexpialidkcious}
hexCTF{swpercalifpagilistiaexpialidmcious}
hexCTF{stpercalifsagilistibexpialidncious}
hexCTF{supercalifragilisticexpialidocious}★
hexCTF{sbpercalifeagilistitexpialidxcious}
hexCTF{scpercalifdagilistiuexpialidycious}
hexCTF{tspercaliatagilistneexpialicicious}
hexCTF{tppercaliawagilistnfexpialicjcious}
hexCTF{tqpercaliavagilistngexpialickcious}
hexCTF{twpercaliapagilistnaexpialicmcious}
hexCTF{ttpercaliasagilistnbexpialicncious}
hexCTF{tupercaliaragilistncexpialicocious}
hexCTF{tbpercaliaeagilistntexpialicxcious}
hexCTF{tcpercaliadagilistnuexpialicycious}
hexCTF{vspercalictagilistleexpialiaicious}
hexCTF{vppercalicwagilistlfexpialiajcious}
hexCTF{vqpercalicvagilistlgexpialiakcious}
hexCTF{vwpercalicpagilistlaexpialiamcious}
hexCTF{vtpercalicsagilistlbexpialiancious}
hexCTF{vupercalicragilistlcexpialiaocious}
hexCTF{vbpercaliceagilistltexpialiaxcious}
hexCTF{vcpercalicdagilistluexpialiaycious}
hexCTF{mspercalixtagilistweexpializicious}
hexCTF{mppercalixwagilistwfexpializjcious}
hexCTF{mqpercalixvagilistwgexpializkcious}
hexCTF{mwpercalixpagilistwaexpializmcious}
hexCTF{mtpercalixsagilistwbexpializncious}
hexCTF{mupercalixragilistwcexpializocious}
hexCTF{mbpercalixeagilistwtexpializxcious}
hexCTF{mcpercalixdagilistwuexpializycious}
hexCTF{ospercaliztagilistueexpialixicious}
hexCTF{oppercalizwagilistufexpialixjcious}
hexCTF{oqpercalizvagilistugexpialixkcious}
hexCTF{owpercalizpagilistuaexpialixmcious}
hexCTF{otpercalizsagilistubexpialixncious}
hexCTF{oupercalizragilistucexpialixocious}
hexCTF{obpercalizeagilistutexpialixxcious}
hexCTF{ocpercalizdagilistuuexpialixycious}
hexCTF{bspercaliwtagilistxeexpialiuicious}
hexCTF{bppercaliwwagilistxfexpialiujcious}
hexCTF{bqpercaliwvagilistxgexpialiukcious}
hexCTF{bwpercaliwpagilistxaexpialiumcious}
hexCTF{btpercaliwsagilistxbexpialiuncious}
hexCTF{bupercaliwragilistxcexpialiuocious}
hexCTF{bbpercaliweagilistxtexpialiuxcious}
hexCTF{bcpercaliwdagilistxuexpialiuycious}
hexCTF{supercalifragilisticexpialidocious}

Really Smart Acronym (Crypto)

$ nc challenges1.hexionteam.com 5000
Flag: 40902781606846802311586977934385133859679496512492096420620208230340785724799511854915812621329891174603752082591090114879982308678393016550792557551755944535065368379532516199878005697308029412891805036536924535485251928513122638267815921487344262397073082951313563783819849236208541334095533962169606262251
One encrypt:
m =>

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

・flagの暗号化の数値を表示
・数値を指定→暗号化数値を表示
・一定回数入力した値を復号し、LSBを表示する。

RSA.generateで鍵を生成しているので、e = 65537。一回暗号化を試すときに-1を指定したら、その暗号化したものに1を足せばnになる。以上を元にLSB decryption oracle attackで復号する。

from fractions import Fraction
from Crypto.Util.number import *
import socket

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

def lsb_oracle(s, cipher):
    data = recvuntil(s, '> ')
    print data + str(cipher)
    s.sendall(str(cipher) + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data

    return int(data)

e = 65537

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('challenges1.hexionteam.com', 5000))

data = recvuntil(s, '\n').rstrip()
print data
c = int(data.split(': ')[1])

data = recvuntil(s, '=> ')
print data + '-1'
s.sendall('-1\n')
data = recvuntil(s, '\n').rstrip()
print data
n = int(data) + 1

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

bounds = [0, Fraction(n)]

i = 0
m = 0
while True:
    print 'Round %d' % (i+1)
    i += 1

    c2 = (c * pow(2, e, n)) % n
    lsb = lsb_oracle(s, c2)
    if lsb == 1:
        bounds[0] = sum(bounds)/2
    else:
        bounds[1] = sum(bounds)/2
    diff = bounds[1] - bounds[0]
    diff = diff.numerator / diff.denominator
    print diff
    if diff == 0:
        m = bounds[1].numerator / bounds[1].denominator
        break
    c = c2

flag = long_to_bytes(m)
print flag

実行結果は以下の通り。

                :
Round 1024
> 64111759478737749461970575969099358768030180256792438675788727048664806426381430637081426645207554609594634348321656289100558189664666699433256030068379321200966898432834018500934679581920735388564362032423919596274534842205529337751336479191375349647150136831941754113972204012803574425353888003203818701316
1
0
hexCTF{n1c3_r5a_tr1ck5_m4t3}
hexCTF{n1c3_r5a_tr1ck5_m4t3}

Survey (Survey)

アンケートに答えたら、フラグが表示された。

hexCTF{thank_you_for_your_time}