この大会は2017/2/3 19:00(JST)~2017/2/6 19:00(JST)に開催されました。
今回もチームで参戦。結果は2040点で1029チーム中63位でした。
自分で解けた問題をWriteupとして書いておきます。
CR1: Ultracoded (Cryotography 50)
ONE, ZEROのスペース区切りの文字列。0,1に置き換え、2進数のASCIIコードとして文字に変換する。さらにBase64文字列になるので、デコードする。
with open('zero_one', 'r') as f: data = f.read() data = data.replace('\n', '').split(' ') b_data = '' for i in range(len(data)): if data[i] == 'ZERO': b_data += '0' else: b_data += '1' b64_data = '' for i in range(0, len(b_data), 8): code = int(b_data[i:i+8], 2) b64_data += chr(code) print b64_data.decode('base64')
すると、モールス信号が出てきた。
.- .-.. . -..- -.-. - ..-. - .... .---- ..... --- .---- ... --- ..... ..- .--. ...-- .-. --- ..... . -.-. .-. ...-- - --- - -..- -
Onlineツールで復号する。
ALEXCTFTH15O1SO5UP3RO5ECR3TOTXT
"O"を"_"に変換する。
ALEXCTFTH15_1S_5UP3R_5ECR3T_TXT
{ }を付ける。
ALEXCTF{TH15_1S_5UP3R_5ECR3T_TXT}
CR3: What is this encryption (Cryotography 150)
eが非常に大きいRSA暗号の復号問題。Wiener's Attackの一部を流用し、復号する。
def egcd(a, b): x,y, u,v = 0,1, 1,0 while a != 0: q, r = b//a, b%a m, n = x-u*q, y-v*q b,a, x,y, u,v = a,r, u,v, m,n gcd = b return gcd, x, y def decrypt(p, q, e, c): n = p * q phi = (p - 1) * (q - 1) gcd, a, b = egcd(e, phi) d = a pt = pow(c, d, n) return hex(pt)[2:-1].decode('hex') p = 0xa6055ec186de51800ddd6fcbf0192384ff42d707a55f57af4fcfb0d1dc7bd97055e8275cd4b78ec63c5d592f567c66393a061324aa2e6a8d8fc2a910cbee1ed9 q = 0xfa0f9463ea0a93b929c099320d31c277e0b0dbc65b189ed76124f5a1218f5d91fd0102a4c8de11f28be5e4d0ae91ab319f4537e97ed74bc663e972a4a9119307 e = 0x6d1fdab4ce3217b3fc32c9ed480a31d067fd57d93a9ab52b472dc393ab7852fbcb11abbebfd6aaae8032db1316dc22d3f7c3d631e24df13ef23d3b381a1c3e04abcc745d402ee3a031ac2718fae63b240837b4f657f29ca4702da9af22a3a019d68904a969ddb01bcf941df70af042f4fae5cbeb9c2151b324f387e525094c41 c = 0x7fe1a4f743675d1987d25d38111fae0f78bbea6852cba5beda47db76d119a3efe24cb04b9449f53becd43b0b46e269826a983f832abb53b7a7e24a43ad15378344ed5c20f51e268186d24c76050c1e73647523bd5f91d9b6ad3e86bbf9126588b1dee21e6997372e36c3e74284734748891829665086e0dc523ed23c386bb520 plaintext = decrypt(p, q, e, c) print plaintext
ALEXCTF{RS4_I5_E55ENT1AL_T0_D0_BY_H4ND}
CR4: Poor RSA (Cryotography 200)
公開鍵と暗号化データをBASE64エンコードしたファイルが与えられている。
flag.b64をBASE64デコードしたファイルをflag.encとする。
公開鍵の内容を見てみる。
$ openssl rsa -pubin -text < key.pub Public-Key: (399 bit) Modulus: 52:a9:9e:24:9e:e7:cf:3c:0c:bf:96:3a:00:96:61: 77:2b:c9:cd:f6:e1:e3:fb:fc:6e:44:a0:7a:5e:0f: 89:44:57:a9:f8:1c:3a:e1:32:ac:56:83:d3:5b:28: ba:5c:32:42:43 Exponent: 65537 (0x10001) writing RSA key -----BEGIN PUBLIC KEY----- ME0wDQYJKoZIhvcNAQEBBQADPAAwOQIyUqmeJJ7nzzwMv5Y6AJZhdyvJzfbh4/v8 bkSgel4PiURXqfgcOuEyrFaD01soulwyQkMCAwEAAQ== -----END PUBLIC KEY-----
次のnの値をfactordbで素因数分解する。
n = 0x52a99e249ee7cf3c0cbf963a009661772bc9cdf6e1e3fbfc6e44a07a5e0f894457a9f81c3ae132ac5683d35b28ba5c324243 (= 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019)
この結果は以下のp, qの値となる。
p = 863653476616376575308866344984576466644942572246900013156919 q = 965445304326998194798282228842484732438457170595999523426901
この結果から秘密鍵を作成する。
$ rsatool.py -f PEM -o key.pri -p 863653476616376575308866344984576466644942572246900013156919 -q 965445304326998194798282228842484732438457170595999523426901 Using (p, q) to initialise RSA instance n = 52a99e249ee7cf3c0cbf963a009661772bc9cdf6e1e3fbfc6e44a07a5e0f894457a9f81c3ae132ac 5683d35b28ba5c324243 e = 65537 (0x10001) d = 33ad09ca06f50f9e90b1acae71f390d6b92f1d6d3b6614ff871181c4df08da4c5f5012457a643094 05eaecd6341e43027931 p = 899683060c76b9c0de581a69e0ea9d91bed1071beb1d924a37 q = 99cde74aedee87adffdd684cbc478e759870b4f20692f65255 Saving PEM as key.pri
秘密鍵を使って、暗号データを復号する。
$ openssl rsautl -decrypt -inkey key.pri < flag.enc ALEXCTF{SMALL_PRIMES_ARE_BAD}
ALEXCTF{SMALL_PRIMES_ARE_BAD}
SC1: Math bot (Scripting 100)
計算問題を解いていくだけ。
#!/usr/bin/env python import socket import re pattern = 'Question (.+) :\n(.+)' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('195.154.53.62', 1337)) for i in range(1000): data = s.recv(1024) print data m = re.search(pattern, data) formula = m.group(2) formula = formula.replace('=', '') ans = str(eval(formula)) + '\n' print ans s.sendall(ans) data = s.recv(1024) print data
500回正解すると、フラグが表示された。
ALEXCTF{1_4M_l33t_b0t}
SC2: Cutie cat (Scripting 150)
画像のステガノグラフィの問題。いろいろ試したみたが、なかなかうまくいかなかった。PythonのSteganographyライブラリを使ったら、簡単にフラグを抽出できた。
from steganography.steganography import Steganography secret_text = Steganography.decode('cat_with_secrets.png') print secret_text
ALEXCTF{CATS_HIDE_SECRETS_DONT_THEY}
TR1: Hello there (Trivia 10)
freenodeで#alexctfに入る。
: 19:14 *topic : Alexandria University student held capture the flag event ctf.oddcoder.com ALEXCTF{W3_w15h_y0u_g00d_luck}
ALEXCTF{W3_w15h_y0u_g00d_luck}