この大会は2021/9/8 19:30(JST)~2021/9/10 13:30(JST)に開催されました。
今回もチームで参戦。結果は2805点で496チーム中41位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome (Welcome)
Slackに入り、#generalチャネルのメッセージを見ると、Slackbotがひたすらフラグを送信している。
TMUCTF{W3lc0m3_70_7muc7f_2021_7h15_15_4_U}
Warmup (Welcome)
2つの画像の色が異なる場合は黒、同じ場合は白にして画像にしてみると、フラグが現れた。
from PIL import Image img1 = Image.open('ciphered_message.png').convert('RGB') img2 = Image.open('secret.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)) if r1 == r2 and g1 == g2 and b1 == b2: output_img.putpixel((x, y), (0, 0, 0)) else: output_img.putpixel((x, y), (255, 255, 255)) output_img.save('flag.png')
TMUCTF{W3_h0p3_y0u_3nj0y_7h15_c0mp371710n_4nd_7h4nk_y0u!}
Warmup (Pwn)
Ghidraでデコンパイルする。
undefined8 main(void) { char local_58 [76]; int local_c; setbuf(stdout,(char *)0x0); setbuf(stdin,(char *)0x0); setbuf(stderr,(char *)0x0); tmulogo(); puts("Welcome to TMUCTF 2021! Let us know your name: "); local_c = 0; gets(local_58); puts("Thanks!\n"); if (local_c != 0) { system("cat flag.txt"); } return 0; }
BOFで長い文字列を指定すればよい。80バイト入力してみる。
$ nc 194.5.207.56 7000 ================================================================= = ____ _ _ ____ ____ ____ ____ ____ ____ __ = = |_ _\|\/\ || \ | __\|_ _\| _\ | \| || \ / | = = || | \||_|\| \__ || | _\ '-'_/| \ |'-'_/ /_ | = = |/ |/v\/|___/|___/ |/ |/ |___]|___||___] \| = = = ================================================================= Welcome to TMUCTF 2021! Let us know your name: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Thanks! TMUCTF{n0w_y0u_4r3_w4rm3d_up}
TMUCTF{n0w_y0u_4r3_w4rm3d_up}
UnBIOSed (Reversing)
$ python pyinstxtractor.py Unbiosed.exe [*] Processing Unbiosed.exe [*] Pyinstaller version: 2.1+ [*] Python version: 37 [*] Length of package: 18531925 bytes [*] Found 44 files in CArchive [*] Beginning extraction...please standby [!] Warning: The script is running in a different python version than the one used to build the executable Run this script in Python37 to prevent extraction errors(if any) during unmarshalling [!] Unmarshalling FAILED. Cannot extract PYZ-00.pyz. Extracting remaining files. [*] Successfully extracted pyinstaller archive: Unbiosed.exe You can now use a python decompiler on the pyc files within the extracted directory
Unbiosed.exe_extracted\Unbiosedを編集し、ヘッダを付けpycにする。ヘッダは以下を16バイト付けた。
3e 0d 0d 0a 00 00 00 00 00 00 00 00 00 00 00 00
pycをデコンパイルする。
$ uncompyle6 Unbiosed.pyc # uncompyle6 version 3.7.4 # Python bytecode 3.7 (3390) # Decompiled from: Python 3.6.9 (default, Jan 26 2021, 15:33:00) # [GCC 8.4.0] # Embedded file name: Unbiosed.py import numpy as np, random a = np.empty([10, 10]) b = np.empty([10, 10]) c = np.dot(a, b) if random.uniform(0, 5) <= 2: print('The Bios is Corrupted!') exit() d = input('Please Enter the Recovery Key:') e = list(d) g = 0 h = [84, 77, 85, 67, 84, 70, 123, 77, 52, 121, 95, 52, 108, 108, 95, 89, 48, 117, 114, 95, 68, 51, 99, 49, 53, 49, 48, 110, 53, 95, 98, 51, 95, 85, 110, 98, 49, 48, 53, 51, 100, 33, 125] for f in range(len(h)): if ord(e[f]) != h[f]: g = g + 1 if g > 0: print('Your Bios Data Cannot be Recovered with This Key.') exit() print("Congratulations! You Have The Flag, But I'll Print it Out Again For You:") print(d) # okay decompiling Unbiosed.pyc
hのコードを文字にすればよい。
h = [84, 77, 85, 67, 84, 70, 123, 77, 52, 121, 95, 52, 108, 108, 95, 89, 48, 117, 114, 95, 68, 51, 99, 49, 53, 49, 48, 110, 53, 95, 98, 51, 95, 85, 110, 98, 49, 48, 53, 51, 100, 33, 125] flag = ''.join([chr(c) for c in h]) print flag
TMUCTF{M4y_4ll_Y0ur_D3c1510n5_b3_Unb1053d!}
Login (Web)
http://185.235.41.189/robots.txtにアクセスすると、コードが書かれている。
if (isset($_GET["password"])) { if (hash("md5", $_GET["password"]) == $_GET["password"]) { echo "<h1>Here is the flag:</h1>" . $flag; } else { echo "Try harder!"; } }
md5が0e[数字]になる0eから始まる文字列を指定すればよい。調べると例えば0e215962017が該当するらしいので、入力するとフラグが表示された。
TMUCTF{D0_y0u_kn0w_7h3_d1ff3r3nc3_b37w33n_L0053_c0mp4r150n_4nd_57r1c7_c0mp4r150n_1n_PHP!?}
Tri (Crypto)
問題の暗号は以下の通り。
kqiaprcvsbmwynzjghxudftleo+ dk+hjpegrhomfgjozzshxqcojnkcozsrfgbnjviubevbuxrrpzdfkjmd+vrwiegqh+ocydjoinlpehrgdnjcvbdacsodjelhvxjmsfzqedvfdbulsoxctne+cagjiovlwlphergkw
いろいろ調べてみたら、Trifid cipherというのがある。https://cryptii.com/pipes/trifid-cipherでデコードしてみる。GROUP SIZEが3の時に以下のように復号できる。
didyouforgetthatthreeismyfavoritenumberlibrxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr ↓ did you forget that three is my favorite number librxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr
以下の部分をシーザー暗号としてシフトする。
librxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr
https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。
Rotation 3: ifyoujumpoverthefencesproperlyipromisetogiveyoutheflaglipsaytsgttcascihraelasneetnintasscerwirisho ↓ if you jump over the fences properly i promise to give you the flag lipsaytsgttcascihraelasneetnintasscerwirisho
今度はRail Fence Cipherっぽい。https://www.geocachingtoolbox.com/index.php?lang=en&page=railFenceCipherで復号する。
レール数:3、オフセット:3で復号できた。
classicciphersarealwaysinterestingisntthatso
TMUCTF{classicciphersarealwaysinterestingisntthatso}
Common Factor (Crypto)
暗号の処理概要は以下の通り。
・e = 65537 ・primes: 5個の2048bit素数 ・n: primesの要素の積 ・nを出力 ・x1 = primes[1] ** 2 ・x2 = primes[2] ** 2 ・x3 = primes[1] * primes[2] ・y1 = x1 * primes[2] + x2 * primes[1] ・y2 = x2 * (primes[3] + 1) - 1 ・y3 = x3 * (primes[3] + 1) - 1 ・x2 + x3 + y1を出力 ・y2 + y3を出力 ・pow(flag, e, n)を出力
式を変形してみる。
x2 + x3 + y1 = primes[2] ** 2 + primes[1] * primes[2] + primes[1] ** 2 * primes[2] + primes[2] ** 2 * primes[1] = primes[2] ** 2 * (primes[1] + 1) + primes[1] * primes[2] * (primes[1] + 1) = primes[2] * (primes[1] + primes[2]) * (primes[1] + 1) y2 + y3 = x2 * (primes[3] + 1) - 1 + x3 * (primes[3] + 1) - 1 = primes[2] ** 2 * (primes[3] + 1) + primes[1] * primes[2] * (primes[3] + 1) - 2 = primes[2] * (primes[1] + primes[2]) * (primes[3] + 1) - 2
y2 + y3 + 2 と n のGCDはprimes[2]。次に1つ目の式からprimes[1]がわかる。さらに2つ目の式からprimes[3]がわかる。
pow(flag, e, n) = c →pow(flag, e, primes[1]*primes[2]*primes[3]) = c % primes[1]*primes[2]*primes[3]
modulusをprimes[1]*primes[2]*primes[3]にして、復号する。
from Crypto.Util.number import * from sympy import * e = 65537 with open('output.txt', 'r') as f: n = int(f.readline().rstrip()) k1 = int(f.readline().rstrip()) k2 = int(f.readline().rstrip()) c = int(f.readline().rstrip()) p2 = GCD(k1, n) p1 = symbols('p1') eq = Eq(p2 * (p1 + p2) * (p1 + 1), k1) ps = solve(eq) for p in ps: if p > 0: p1 = p break p3 = symbols('p3') eq = Eq(p2 * (p1 + p2) * (p3 + 1) - 2, k2) ps = solve(eq) p3 = ps[0] phi = (p1 - 1) * (p2 - 1) * (p3 - 1) d = inverse(e, phi) m = pow(c % (p1 * p2 * p3), d, (p1 * p2 * p3)) flag = long_to_bytes(m) print flag
TMUCTF{Y35!!!__M4Y_N0t_4lW4y5_N33d_4ll_p21M3_f4c70R5}
435! (Crypto)
keyと暗号の一部がマスクされている。ブロックごとに考える。
平文 CBC (Cipher Bloc ker Chaining) is an advanced for m of block ciphe r encryptionHHHH HHHHHHPPPPPPPPPP 暗号 9**********b4381646*****01****** **************8b9***0485******** **********************0**ab3a*cc 5e**********18a********5383e7f** ************1b3*******9f43fd6634 1f3ef3fab2bbfc838b9ef71867c3bcbb
暗号の最後のブロックとパディングがわかっているので、条件を満たすkeyをブルートフォースで求める。あとは後ろのブロックから順に復号していき、ivを求める。これがフラグになる。
#!/usr/bin/python3 import itertools import binascii import hashlib from Crypto.Cipher import AES from Crypto.Util.strxor import strxor def pad(message): padding = bytes((key_len - len(message) % key_len) * chr(key_len - len(message) % key_len), encoding='utf-8') return message + padding chars = '' for code in range(32, 127): chars += chr(code) ct5 = binascii.unhexlify('1f3ef3fab2bbfc838b9ef71867c3bcbb') ct4_tail = binascii.unhexlify('9f43fd6634') for c in itertools.product(chars, repeat=3): key = (c[0] + 'XhN2' + c[1] +'8d%8Slp3' + c[2] + 'v').encode() key_len = len(key) h = hashlib.sha256(key).hexdigest() hidden = binascii.unhexlify(h)[:10] message = b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption' + hidden pt5 = pad(message)[-16:] aes = AES.new(key, AES.MODE_ECB) pt = aes.decrypt(ct5) if strxor(pt[-5:], b'\x0a' * 5) == ct4_tail: break print('[+] key =', key) h = hashlib.sha256(key).hexdigest() hidden = binascii.unhexlify(h)[:10] message = b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption' + hidden message = pad(message) pts = [message[i:i+16] for i in range(0, len(message), 16)] ct = ct5 for i in range(5, -1, -1): aes = AES.new(key, AES.MODE_ECB) pt = aes.decrypt(ct) ct = strxor(pt, pts[i]) print('[+] ct_part =', binascii.hexlify(ct)) flag = 'TMUCTF{%s}' % ct.decode() print('[*] flag =', flag)
実行結果は以下の通り。
[+] key = b'0XhN2!8d%8Slp3Ov' [+] ct_part = b'9c1a9d16795c1b334d6ec49f43fd6634' [+] ct_part = b'5e5969dcdb9b18ac33993785383e7f32' [+] ct_part = b'959349e93481869c836d900dcab3a6cc' [+] ct_part = b'8bc67a00c0e5198b9d0304858953eb83' [+] ct_part = b'9f4ac903118b43816462b35101a7b6fe' [+] ct_part = b'5930555f4433437259503733445f3137' [*] flag = TMUCTF{Y0U_D3CrYP73D_17}
TMUCTF{Y0U_D3CrYP73D_17}
Strangely (Crypto)
https://wiremask.eu/tools/xor-cracker/でクラックする。key「f3 d9 01 ae 93 bb 25」でrarファイルにようになったが、keyの7バイト目がことなるようなので、調整する。
with open('file', 'rb') as f: enc = f.read() rar_head = 'Rar!\x1a\x07\x00' key = [] for i in range(len(rar_head)): key.append(ord(enc[i]) ^ ord(rar_head[i])) dec = '' for i in range(len(enc)): dec += chr(ord(enc[i]) ^ key[i%len(key)]) with open('flag.rar', 'wb') as f: f.write(dec)
rarファイルの情報を見る。
$ 7z l -slt flag.rar 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI) Scanning the drive for archives: 1 file, 1559 bytes (2 KiB) Listing archive: flag.rar -- Path = flag.rar Type = Rar Physical Size = 1559 Solid = - Blocks = 23 Multivolume = - Volumes = 1 ---------- Path = 5.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:29:40 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = D4F15C54 Host OS = Win32 Method = m3:17 Version = 29 Path = 6.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:29:51 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 6224C494 Host OS = Win32 Method = m3:17 Version = 29 Path = 7.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:30:03 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = B79C496B Host OS = Win32 Method = m3:17 Version = 29 Path = 8.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:30:17 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 0DEB7416 Host OS = Win32 Method = m3:17 Version = 29 Path = 9.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:30:31 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = B1441D53 Host OS = Win32 Method = m3:17 Version = 29 Path = 10.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:30:41 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = A55CEB27 Host OS = Win32 Method = m3:17 Version = 29 Path = 11.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:30:56 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 05C3ACC9 Host OS = Win32 Method = m3:17 Version = 29 Path = 12.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:31:09 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 3DA99B67 Host OS = Win32 Method = m3:17 Version = 29 Path = 13.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:31:21 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 3F4D936A Host OS = Win32 Method = m3:17 Version = 29 Path = 14.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:31:35 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 138AA87B Host OS = Win32 Method = m3:17 Version = 29 Path = 15.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:31:45 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = A538E0A1 Host OS = Win32 Method = m3:17 Version = 29 Path = 16.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:31:55 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = B9DF8C6B Host OS = Win32 Method = m3:17 Version = 29 Path = 17.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:32:05 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 01CE8D5D Host OS = Win32 Method = m3:17 Version = 29 Path = 18.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:32:16 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 814B8BED Host OS = Win32 Method = m3:17 Version = 29 Path = 19.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:32:28 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 717F3F79 Host OS = Win32 Method = m3:17 Version = 29 Path = 20.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:32:40 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 5C011BC9 Host OS = Win32 Method = m3:17 Version = 29 Path = 21.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:32:50 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = A48DBAA5 Host OS = Win32 Method = m3:17 Version = 29 Path = 22.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-20 10:20:48 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = E64AF817 Host OS = Win32 Method = m3:17 Version = 29 Path = 23.txt Folder = - Size = 1 Packed Size = 16 Modified = 2021-01-20 10:20:59 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = FCB6E20C Host OS = Win32 Method = m3:17 Version = 29 Path = 1.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:28:43 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 3570E041 Host OS = Win32 Method = m3:17 Version = 29 Path = 2.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:28:57 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 654AB3A9 Host OS = Win32 Method = m3:17 Version = 29 Path = 3.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:29:09 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 5B22215B Host OS = Win32 Method = m3:17 Version = 29 Path = 4.txt Folder = - Size = 4 Packed Size = 16 Modified = 2021-01-19 13:29:27 Created = Accessed = Attributes = A Encrypted = + Solid = - Commented = - Split Before = - Split After = - CRC = 0E0D89E9 Host OS = Win32 Method = m3:17 Version = 29
1.txt~22.txtまでのsizeは4、23.txtのsizeは1なので、総当たりでCRCが一致する文字列を見つける。
import binascii import itertools crcs = [0x3570E041, 0x654AB3A9, 0x5B22215B, 0x0E0D89E9, 0xD4F15C54, 0x6224C494, 0xB79C496B, 0x0DEB7416, 0xB1441D53, 0xA55CEB27, 0x05C3ACC9, 0x3DA99B67, 0x3F4D936A, 0x138AA87B, 0xA538E0A1, 0xB9DF8C6B, 0x01CE8D5D, 0x814B8BED, 0x717F3F79, 0x5C011BC9, 0xA48DBAA5, 0xE64AF817, 0xFCB6E20C] chars = '' for c in range(32, 127): chars += chr(c) flag = '' for i in range(len(crcs)): found = False if i == 22: r = 1 else: r = 4 for c in itertools.product(chars, repeat=r): text = ''.join(c) if (binascii.crc32(text) & 0xffffffff) == crcs[i]: found = True flag += text print '[+] flag =', flag break if found == False: print 'Error' break print '[*] flag =', flag
実行結果は以下の通り。
[+] flag = TMUC [+] flag = TMUCTF{7 [+] flag = TMUCTF{7h3r3 [+] flag = TMUCTF{7h3r3_w45 [+] flag = TMUCTF{7h3r3_w45_n0_ [+] flag = TMUCTF{7h3r3_w45_n0_n33d [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_ [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru7 [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0 [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_ [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_ [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455 [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0 [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_ [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcu [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473 [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:) [+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)} [*] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)}
TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)}
Broken RSA (Crypto)
暗号処理の概要は以下の通り。
・pads = [b'\x04', b'\x02', b'\x00', b'\x01', b'\x03'] ・i, j: 0~4の組み合わせ ・pads[0] + b'TMUCTF' + pads[4] ・pads[1] + b'TMUCTF' + pads[3] ・pads[2] + b'TMUCTF' + pads[2] ・pads[3] + b'TMUCTF' + pads[1] ・pads[4] + b'TMUCTF' + pads[0] ・pads[0] * 2 + b'TMUCTF' + pads[4] * 2 ・pads[1] * 2 + b'TMUCTF' + pads[3] * 2 ・pads[2] * 2 + b'TMUCTF' + pads[2] * 2 ・pads[3] * 2 + b'TMUCTF' + pads[1] * 2 ・pads[4] * 2 + b'TMUCTF' + pads[0] * 2 : ・それぞれのpow(bytes_to_long(msg), e, n)を出力 ・最後にpow(bytes_to_long(secret_msg), e, n)を出力
以下を比べてみる。
・pads[2] + b'TMUCTF' + pads[2] = b'TMUCTF\x00' ・pads[2] * 2 + b'TMUCTF' + pads[2] * 2 = b'TMUCTF\x00\x00' ・pads[2] * 3 + b'TMUCTF' + pads[2] * 3 = b'TMUCTF\x00\x00\x00'
1つ目の数の256倍が2つ目の数になり、2つ目の数の256倍が3つ目の数になる。このことから暗号化データは以下のようになることを使って、nを導き出す。
(A * 256**e) % n = B (B * 256**e) % n = C
(A * 256**e - B) と (B * 256**256 - C)のGCDがnと考えられる。算出すると、nは以下の値になる。
n = 178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381
これを素因数分解する。
$ python -m primefac 178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381 178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381: 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087 17168409475383972628504778240855911978985929543286350892069246008372473042523567037011013249871547777584631416739758322856251015798698301831765580955300650407835153601378654173742292554894502681735405620391535895647045866153891745460976487617315465562496499358894287054034024692381191210822762212034588017308516989613261306910988892855362427544142343518767108593353834256519607664876369541892324877459094093260657539475432861721224124049660249386714464357030183841589410520002623236416489710292432265593266725745973870777993186048812530526551997744644388584507538634448903227467825441758880828727826547230875410498763
素因数分解できたので、それを使ってsecret_msgを復号する。
from Crypto.Util.number import * e = 65537 with open('output.txt', 'r') as f: encs = map(int, f.read().split('\n')) diff = [] for i in range(4): diff.append(encs[i*5+2] * 256**e - encs[(i+1)*5+2]) n = diff[0] for i in range(1, 4): n = GCD(n, diff[i]) p = 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087 q = 17168409475383972628504778240855911978985929543286350892069246008372473042523567037011013249871547777584631416739758322856251015798698301831765580955300650407835153601378654173742292554894502681735405620391535895647045866153891745460976487617315465562496499358894287054034024692381191210822762212034588017308516989613261306910988892855362427544142343518767108593353834256519607664876369541892324877459094093260657539475432861721224124049660249386714464357030183841589410520002623236416489710292432265593266725745973870777993186048812530526551997744644388584507538634448903227467825441758880828727826547230875410498763 assert n == p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(encs[25], d, n) flag = long_to_bytes(m) print flag
復号結果は以下の通り。
Public key cryptography. RSA was first publicly described in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman of the Massachusetts Institute of Technology. TMUCTF{Ju57_4n07h3r_R54_ch4ll3n63!_C0u1d_y0u_50lv3_17?!?}
TMUCTF{Ju57_4n07h3r_R54_ch4ll3n63!_C0u1d_y0u_50lv3_17?!?}