この大会は2023/1/21 0:00(JST)~2023/1/22 2:00(JST)に開催されました。
今回もチームで参戦。結果は3975点で848チーム中5位でした。
自分で解けた問題をWriteupとして書いておきます。
KnightCTF Discord Server (Basics 25)
Discordに入り、#announcementsチャネルのメッセージを見ると、以下のように書いてある。
01001011 01000011 01010100 01000110 01111011 01110111 00110011 01001100 01100011 00110000 01001101 00110011 01011111 01010100 00110000 01011111 01001011 01101110 01101001 01100111 01101000 01110100 01000011 01010100 01000110 01111101
ASCIIコードの2進数表記と推測できるので、デコードする。
#!/usr/bin/env python3 codes= '01001011 01000011 01010100 01000110 01111011 01110111 00110011 01001100 01100011 00110000 01001101 00110011 01011111 01010100 00110000 01011111 01001011 01101110 01101001 01100111 01101000 01110100 01000011 01010100 01000110 01111101' codes = codes.split(' ') flag = '' for code in codes: flag += chr(int(code, 2)) print(flag)
KCTF{w3Lc0M3_T0_KnightCTF}
Dirt (Misc 50)
解凍すると、ディレクトリパスが以下のようになっている。
challenge\}\s\r\3\d\l\0\f\_\3\d\1\5\n\1\_\s\r\3\d\l\0\f\{\F\T\C\K
階層の深いディレクトリ名からつなげると、フラグになる。
KCTF{f0ld3rs_1n51d3_f0ld3rs}
Logger (Misc 100)
アクセスログを日時でソートする。
: 2023-01-03 15:46:20.382679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /K - 39950 2023-01-03 15:46:20.385679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /C - 6142 2023-01-03 15:46:20.388679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /T - 48333 2023-01-03 15:46:20.391679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /F - 16796 2023-01-03 15:46:20.394679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /{ - 45424 2023-01-03 15:46:20.397679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /w - 57044 2023-01-03 15:46:20.400679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /r - 56376 2023-01-03 15:46:20.403679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /1 - 34061 2023-01-03 15:46:20.406679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /n - 18217 2023-01-03 15:46:20.409679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /k - 13820 2023-01-03 15:46:20.412679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /l - 3610 2023-01-03 15:46:20.415679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /3 - 43593 2023-01-03 15:46:20.418679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /_ - 46224 2023-01-03 15:46:20.421679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /1 - 49001 2023-01-03 15:46:20.424679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /n - 5135 2023-01-03 15:46:20.427679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /_ - 42868 2023-01-03 15:46:20.430679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /7 - 51928 2023-01-03 15:46:20.433679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /1 - 42167 2023-01-03 15:46:20.436679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /m - 9672 2023-01-03 15:46:20.439679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /3 - 13974 2023-01-03 15:46:20.442679 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - GET /} - 5898
ソート後のアクセスログの最後の方のアクセス先の"/"の後の文字を並べると、フラグになった。
KCTF{wr1nkl3_1n_71m3}
GET Me (Web/API 25)
$ curl http://167.99.8.90:9009/ {"success":false,"message":"Sorry ! You can't GET it :P"}
POSTメソッドでアクセスしてみる。
$ curl http://167.99.8.90:9009/ -X POST {"success":false,"message":"You should send me a url !"}
urlパラメータが必要のようだ。
$ curl http://167.99.8.90:9009/ -d 'url=a' {"success":false,"message":"Looking for flag ? Visit https:\/\/hackenproof.com\/user\/security"}
https://hackenproof.com/でアカウントを作成して、https://hackenproof.com/user/securityにアクセスすると、フラグが書かれていた。
KCTF{H4ck3nPr00f3d_bY_Kn16h75qu4d}
Hello (Networking 300)
dnsでフィルタリングし、問合せしているドメインの*.knoghtctf.comの*部分を連結するとbase64文字列になりそう。
#!/usr/bin/env python3 from scapy.all import * from base64 import * packets = rdpcap('find-me.pcapng') b64 = '' for p in packets: if not p.haslayer(ICMP) and p.haslayer(DNS) and p[IP].dst == '8.8.8.8': b64 += p[DNSQR].qname.decode()[0] flag = b64decode(b64).decode() print(flag)
base64デコードした結果、以下になった。
UPBL{o1_mr3a_en0_hk3_i0h}
Vigenere暗号と推測して、https://www.dcode.fr/vigenere-cipherで復号する。KCTFで始まることから、鍵はKNIGHTと推測できる。
KCTF{h1_th3n_wh0_ar3_y0u}
Go Deep! (Forensics 400)
$ binwalk sea.jpg DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 JPEG image data, JFIF standard 1.01 9247167 0x8D19BF Zip archive data, at least v2.0 to extract, compressed size: 61520, uncompressed size: 61777, name: deep 9308807 0x8E0A87 End of Zip archive, footer length: 22
jpgの後ろにzipがくっついているので、切り出す。
$ foremost sea.jpg Processing: sea.jpg |foundat=deep4}8���Umj�.���Z�����E[����6Q�i��ڻjT"bo!�V��ޱc���{��x�މ�}�=���9���L�,ܡy��Ջ;T�^���s�.��2R�;w�D�?���x��|~9�p��枽���;e0 <�����㥉ם;t������sg핺����vY�C�a�nӴ��%o܅�M̯���O���GB^��^Z��q྆��eIy�0J���$����e!|���&���/�Cz���i��RhvO�{+�;� [���}@3��~Տ��J ;��S� ���G����������SI��w�x��{�KG���Zandd��H4��ɵ�o�F��������!������̭���r����?'�����!A�1�;Y�Z������K^�\����<��97װS��4�r�-�����ڞ�������A�x/��m�rkR�[� ��&�X���J��8�� &��q�������`3�riA���{/P��&�k|x���s|X_��|��i�����Y�9�̥m<�h ��r�*�E��ha�H *|
切り出したzipを解凍すると、deepファイルが展開される。deepファイルの先頭10バイトはjpgのヘッダ部になっているが、他はpng形式になっている。バイナリエディタで先頭10バイトを以下のように修正する。
修正前:ff d8 ff e0 00 10 4a 46 49 46 修正後:89 50 4e 47 0d 0a 1a 0a 00 00
pngの高さが異なるようなので、CRCが合うように高さを変える。
#!/usr/bin/env python3 import struct import binascii with open('deep.png', 'rb') as f: data = f.read() head = data[:12] tail = data[29:] for h in range(265, 1024): height = struct.pack('>I', h) ihdr = data[12:20] + height + data[24:29] crc = struct.pack('!I', binascii.crc32(ihdr)) if crc == data[29:33]: out = head + ihdr + tail with open('deep_fix.png', 'wb') as f: f.write(out) break
最終的に修正した画像の左下にフラグが書いてあった。
KCTF{g0_d33p_d0wn}
Factorie (Cryptography 50)
nを素因数分解するだけの問題。factordbで素因数分解する。
n = 39434538531451803895327 * 55131777675015246472249
KCTF{39434538531451803895327_55131777675015246472249}
Vaulter (Cryptography 100)
暗号処理の概要は以下の通り。
・byte_data = [] ・file_name: 第1引数 ・num: 1以上1024以下のランダム整数 ・byte_data: file_nameのファイルの内容のバイナリデータ ・bdh: byte_dataの16進数表記 ・out = [] ・bdhの各文字eachについて以下を実行 ・outにeachのASCIIコードとnumのXORを追加 ・concat: outの各数値を文字にし、結合 ・concatをoutput.encに書き込み
ブルートフォースでXORして16進数になるようにし、復号する。
#!/usr/bin/env python3 import string def is_hexdigits(s): for c in s: if c not in string.hexdigits[:16]: return False return True with open('vaulter-output.enc.txt', 'r') as f: enc = f.read() for num in range(1, 1024): try: dec = b'' for i in range(len(enc)): dec += bytes([ord(enc[i]) ^ num]) bdh = dec.decode() except: continue if is_hexdigits(bdh): break with open('flag.docx', 'wb') as f: f.write(bytes.fromhex(bdh))
復号したら、docxファイルになるので、開いてみると、一番下にフラグが書いてあった。
KCTF{w3lc0m3_70_3ncryp710n_w0rLD}
I Love Pi (Cryptography 100)
暗号処理の概要は以下の通り。
・lengths: 10個の未知の要素を持つ配列 ・flag: 長さ39のフラグ ・s = 0 ・encoded_flag = "" ・lengthsの各要素lについて以下を実行 ・seg = flag[s:s+l] ・segの長さだけ以下を実行 ・seg: segをbase64エンコード ・s += l ・encoded_flag += seg ・encoded_flagを出力
base64の切れ目を確認しながら、復号する。
#!/usr/bin/env python3 import base64 dic = {} for i in range(1, 17): s = 'a' * i for _ in range(i): s = base64.b64encode(s.encode()).decode() dic[len(s)] = i with open('encoded_flag.txt', 'r') as f: enc = f.read() #### guessing #### base64_lengths = [12, 4, 24, 4, 32, 144, 8, 44, 32, 12] #### output #### flag = b'' index = 0 for i in range(len(base64_lengths)): l = base64_lengths[i] seg = enc[index:index + l] for _ in range(dic[l]): seg = base64.b64decode(seg) flag += seg index += l flag = flag.decode() print(flag)
KCTF{4_P1_4_D4Y_K33P5_7H3_H4CK3r5_4W4Y}
Jamal (Cryptography 125)
暗号処理の概要は以下の通り。
・seed(0) ・flag: フラグ ・x: 2以上9999999以下のランダム整数 ・p = get_prime(43) ・p = 2**42以上2**43以下のランダム整数 ・pが素数の場合にpを返却 ・g = get_prime(43) ・gとpが同じ間以下を実行 ・g = get_prime(43) ・gがpより大きい場合 ・g, p = p, g ・y = pow(g, x, p) ・flagの各文字chについて以下を実行 ・k = 2以上9999以下のランダム整数 ・c1, c2 = encrypt(ch, g, p, y, k) ・c1, c2をflag.encに書き込み ・pをkey.pubに書き込み
seedでランダム値はわかっているので、逆算してフラグを求める。
#!/usr/bin/env python3 from random import randint, seed def is_prime(n): if n == 2 or n == 3: return True if n % 2 == 0 or n < 2: return False for i in range(3, int(n**0.5)+1, 2): if n % i == 0: return False return True def get_prime(n): while True: p = randint(2**(n-1), 2**n) if is_prime(p): return p seed(0) x = randint(2, 9999999) p = get_prime(43) g = get_prime(43) while g == p: g = get_prime(43) if g > p: g, p = p, g y = pow(g, x, p) with open('jamal-key.pub', 'r') as f: p_file = int(f.read().split(' ')[-1]) assert p_file == p with open('jamal-flag.enc.txt', 'r') as f: lines = f.read().splitlines() flag = '' for line in lines: c1 = int(line.split(',')[0]) c2 = int(line.split(',')[1]) k = randint(2, 9999) assert pow(g, k, p) == c1 ch = (c2 * pow(pow(y, k, p), -1, p)) % p flag += chr(ch) print(flag)
KCTF{h4v3_y0u_h34rd_0f_3l64m4l?}
Encode Mania (Cryptography 150)
暗号処理の概要は以下の通り。
・flag: フラグ(kctf{************}) ・encrypted_flag = flag.encode('utf-8') ・12回以下を繰り返し実行 ・option: 0以上3以下のランダム整数 ・encrypted_flag = encrypt(encrypted_flag, option) ・optionが0の場合、base64エンコード ・optionが1の場合、base32エンコード ・optionが2の場合、base16エンコード ・optionが3の場合、base85エンコード ・encode_mania.txtにencrypted_flagを書き込み
1回ずつbase64、base32、base16、base85デコードを試して確認しながらデコードする。
#!/usr/bin/env python3 import base64 with open('encode_mania.txt', 'r') as f: flag = f.read() print('[+]', flag) #### 1st decryption #### flag = base64.b32decode(flag) print('[+]', flag.decode()) #### 2nd decryption #### flag = base64.b16decode(flag) print('[+]', flag.decode()) #### 3rd decryption #### flag = base64.b64decode(flag) print('[+]', flag.decode()) #### 4th decryption #### flag = base64.b85decode(flag) print('[+]', flag.decode()) #### 5th decryption #### flag = base64.b16decode(flag) print('[+]', flag.decode()) #### 6th decryption #### flag = base64.b16decode(flag) print('[+]', flag.decode()) #### 7th decryption #### flag = base64.b32decode(flag) print('[+]', flag.decode()) #### 8th decryption #### flag = base64.b64decode(flag) print('[+]', flag.decode()) #### 9th decryption #### flag = base64.b85decode(flag) print('[+]', flag.decode()) #### 10th decryption #### flag = base64.b64decode(flag) print('[+]', flag.decode()) #### 11th decryption #### flag = base64.b16decode(flag) print('[+]', flag.decode()) #### 12th decryption #### flag = base64.b85decode(flag) print('[+]', flag.decode())
実行結果は以下の通り。
[+] GUZDGMRUIQ3TENJYGMYTOMBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRXIEZTSNRRGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG4ZTERRVHE3EENRUGZATKOBTGM3TQNRZGUZDGMRUIUZTMNCCGMYTMOBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRTGEZTSNRRGUZDGMRUIU3DONCEGQ3DOMBUHA2TSNZZG42DMNRVG42TKNRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJQGMYTOMBUHA2TSMZRGM4TGOBVHEZTANRUGZATMNJWHE3TINJZGUZDGMRUIU3DMNRWGQ3TKNRUHA2TSNZZG4ZTERRVIE2DKNRUGZATKOBTGM3TQNSCGUZDGMRUIUZTMNCCGMYTOMBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRXIEZTSNJZGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSMZRGM4TGOBVHE2TKNRUGZATIQRXIEZTSNRRGUZDGMRUIQ3TENJYGMYTMQZUHA2TSNZZG42DMNRVG42TKNRUGZATIQRTGEZTSNRZGUZDGMRUIQ3TENJQGMZDKNRUHA2TSMZRGM4TGOBVHEZTANRUGZATKOBTGM3TQNSBGUZDGMRUIU3DMNRWGQ3DOMBUHA2TSNZZG42DMNRVHE2TKNRUGZATIQRTGEZTSNRRGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG4ZTERRVG43EENRUGZATKOBTGM3TQNSDGUZDGMRUIU3DMNRWGQ3DMQZUHA2TSMZRGM4TGOBVHE2TKNRUGZATKOBTGM3TQNRYGUZDGMRUIU3DMNRWGQ3TMNBUHA2TSNZZG42DMNRVHEZTANRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJYGMZDIRJUHA2TSNZZG4ZTERRVHEZTANRUGZATIQRXIEZTSNRRGUZDGMRUIU3DMNRWGQ3TIRJUHA2TSMZTGZDDOMRVG42DKNRUGZATKOBTGM3TQNSDGUZDGMRUIQ3TENJQGMZDKMRUHA2TSMZRGM4TGOBVG43EENRUGZATKOBTGM3TQNSDGUZDGMRUIQ3TENJQGMZDIRJUHA2TSNZZG4ZTERRVG42DKNRUGZATMNJWHE3TINKBGUZDGMRUIQ3TENJQGMYTOMBUHA2TSNZZG4ZTERRVIE2DKNRUGZATIQRTGEZTSNSBGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG42DMNRVHEZTANRUGZATIQRXIEZTSNSCGUZDGMRUIU3DMNRWGQ3TINRUHA2TSMZTGZDDOMRVG42DKNRUGZATIQRXIEZTSNRYGUZDGMRUIU3DMNRWGQ3DMOBUHA2TSNZZG42DMNRVG43EENRUGZATKOBTGM3TQNSCGUZDGMRUIQ3TENJQGMYTOMBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRXIEZTSNRZGUZDGMRUIU3DMNRWGQ3DOMBUHA2TSMZRGM4TGOBVHE2TKNRUGZATKOBTGM3TQNRZGUZDGMRUIQ3TENJQGMZDKMRUHA2TSNZZG4ZTERRVHEZTANRUGZATIQRTGEZTSNKBGUZDGMRUIQ3TENJQGMZDIRJUHA2TSNZZG4ZTERRVG43EENRUGZATKOBTGM3TQNSBGUZDGMRUIU3DMNRWGQ3TINRUHA2TSMZRGM4TGOBVHEZTANRUGZATIQRXIEZTSNSCGUZDGMRUIQ3TENJQGMZDIRJUHA2TSNZZG42DMNRVHEZTANRUGZATIQRXIEZTSNRZGUZDGMRUIU3DMNRWGQ3TKNRUHA2TSMZRGM4TGOBVIE2DKNRUGZATKOBTGM3TQNRYGUZDGMRUIQ3TENJQGMYTOMBUHA2TSNZZG42DMNRVG42TKNRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJYGMYTMQZUHA2TSMZRGM4TGOBVIE2DKNRUGZATKOBTGM3TQNKBGUZDGMRUIU3DMNRWGQ3TIQJUHA2TSMZRGM4TGOBVG43EENRUGZATKOBTGM3TQNSCGUZDGMRUIQ3TENJYGMYTOMBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRXIEZTSNRYGUZDGMRUIU3DMNRWGQ3TKNRUHA2TSNZZG4ZTERRVIE3EENRUGZATKOBTGM3TQNRYGUZDGMRUIQ3TENJQGMYTOMBUHA2TSMZRGM4TGOBVHE3EENRUGZATIQRXIEZTSNSEGUZDGMRUIU3DONCEGQ3DOMBUHA2TSNZZG4ZTERRVHE2TKNRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJQGMYTOMBUHA2TSMZRGM4TGOBVHEZTANRUGZATKOBTGM3TQNRYGUZDGMRUIU3DMNRWGQ3TIRJUHA2TSNZZG4ZTERRVIE2DKNRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJYGMZDINRUHA2TSMZRGM4TGOBVIE2TKNRUGZATIQRXIEZTSNRRGUZDGMRUIQ3TENJYGMZDIQJUHA2TSNZZG42DMNRVG43EENRUGZATIQRXIEZTSNSCGUZDGMRUIQ3TENJQGMZDKQJUHA2TSMZTGZDDOMRVHE2TKNRUGZATIQRXIEZTSNSEGUZDGMRUIQ3TENJQGMZDIRJUHA2TSMZRGM4TGOBVG42TKNRUGZATIQRTGEZTSNSBGUZDGMRUIQ3TENJQGMYTMQZUHA2TSMZRGM4TGOBVHEZTANRUGZATIQRTGEZTSNRRGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG4ZTERRVG43EENRUGZATKOBTGM3TQNSCGUZDGMRUIQ3TENJQGMZDIQJUHA2TSMZRGM4TGOBVG43EENRUGZATKOBTGM3TQNRYGUZDGMRUIU3DMNRWGQ3DMQZUHA2TSNZZG42DMNRVHEZTANRUGZATKOBTGM3TQNRRGUZDGMRUIU3DMNRWGQ3TKNRUHA2TSNZZG4ZTERRVHEZTANRUGZATIQRXIEZTSNRRGUZDGMRUIU3DMNRWGQ3TKNRUHA2TSMZRGM4TGOBVHE2TKNRUGZATKOBTGM3TQNSEGUZDGMRUIQ3TENJYGMZDINRUHA2TSNZZG42DMNRVG42TKNRUGZATIQRXIEZTSNRZGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG42DMNRVG43EENRUGZATIQRTGEZTSNRZGUZDGMRUIQ3TENJYGMYTOMBUHA2TSNZZG4ZTERRVG43EENRUGZATIQRTGEZTSNKBGUZDGMRUIQ3TENJQGMZDIRJUHA2TSNZZG42DMNRVG43EENRUGZATKOBTGM3TQNSDGUZDGMRUIU3DMNRWGQ3TIRJUHA2TSMZTGZDDOMRVG43EENRUGZATMNJWHE3TINKBGUZDGMRUIQ3TENJYGMZDINRUHA2TSNZZG42DMNRVG43EENRUGZATKOBTGM3TQNSCGUZDGMRUIQ3TENJQGMZDINRUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRTGEZTSNRZGUZDGMRUIUZTMNCCGMYTMQZUHA2TSNZZG4ZTERRVG43EENRUGZATKOBTGM3TQNSFGUZDGMRUIQ3TENJYGMZDIRJUHA2TSNZZG42DMNRVHEZTANRUGZATKOBTGM3TQNSBGUZDGMRUIQ3TENJQGMZDIRJUHA2TSNZZG4ZTERRVG42DKNRUGZATKOBTGM3TQNSBGUZDGMRUIQ3TENJQGMYTMQZUHA2TSMZRGM4TGOBVHE3EENRUGZATIQRXIEZTSNSEGUZDGMRUIQ3TENJYGMYTMQZUHA2TSMZRGM4TGOBVHE3EENRUGZATKOBTGM3TQNSDGUZDGMRUIQ3TENJYGMYTOMBUHA2TSNZZG42DMNRVHE3EENRUGZATIQRTGEZTSNRRGUZDGMRUIQ3TENJQGMYTOMBUHA2TSNZZG42DMNRVG42TKNRUGZATIQRTGEZTSNKBGUZDGMRUIQ3TENJYGMZDIQJUHA2TSNZZG4ZTERRVIE2DKNRUGZATMNJWHE3TINJZGUZDGMRUIUZTMNCCGMYTMQZUHA2TSMZTGZDDOMRVG42TKNRUGZATMNJWHE3TINJZGUZDGMRUIQ3TENJYGMYTOMBUHA2TSMZRGM4TGOBVIE2DKNRUGZATIQRXIEZTSNRRGUZDGMRUIU3DMNRWGQ3TKMRUHA2TSNZZG4ZTERRVHE3EENRUGZATKOBTGM3TQNRRGUZDGMRUIU3DMNRWGQ3TINRUHA2TSMZRGM4TGOBVG42DKNRUGZATIQRXIEZTSNSEGUZDGMRUIU3DONCEGQ3DOMBUHA2TSNZZG4ZTERRVG42TKNRUGZATIQRXIEZTSNSBGUZDGMRUIQ3TENJQGMYTMOBUHA2TSMZRGM4TGOBVHEZTANRUGZATIQRXIEZTSNKBGUZDGMRUIU3DMNRWGQ3TIQJUHA2TSNZZG4ZTERRVIE3EENRUGZATIQRTGEZTSNKBGUZDGMRUIUZTMNCCGMYTMOBUHA2TSNZZG4ZTERRVHE3EENRUGZATMNJWHE3TINRRGUZDGMRUIU3DMNRWGQ3DMQZUHA2TSNZZG42DMNRVG42TKNRUGZATMNJWHE3TINRYGUZDGMRUIQ3TENJQGMZDKNRUHA2TSMZRGM4TGOBVHEZTANRUGZATMNJWIE3TQNRYGUZDGMRUIUZTMNJQGQ3TINRUHA2TSMZTGZDDGOBVHE2TKNRUGZATMNJWIE3TQNRYGUZDGMRUIUZTMNJQGQ3TINRUHA2TSMZTGZDDGOBVHE2TCM2EGNCA==== [+] 52324D7258317048593139385A45646A4B7A396152324E66664752485979732F596B646A5833786952324E364B316848593139385A45646A4B31396152324E674D467048597974665755646A4B7A396A52324D7250317048593139385930646A6569745952324E66664756485979732F5A45646A5833786B52324E364B317048593139385A45646A4B7A395952324E6666475248593139385955646A4B7A396152324D7258316C48597974665755646A4B31396952324D7250325648593139385930646A5833786A52324E6666467048597974665955646A4B31396152324E66664752485979732F576B646A5833786C52324E6666466C48593139385955646A5833786852324E6666476448597974665930646A4B7A396A52324D7258324E485979732F5930646A4B7A396152324E6666474E4859336F725745646A5833786C52324D725032524859313938576B646A5833786C52324D7250324E485979732F5745646A6569745A52324D72503170485979732F5A45646A4B31396A52324E6666475248597974665930646A4B7A396B52324E666647464859336F725745646A4B7A396852324E666646684859797466576B646A5833786B52324D7250317048593139385A45646A4B7A396952324E6666467048593139385955646A5833786952324D72503252485979732F5930646A4B31395A52324D7250324E485979732F576B646A5833786A52324E6666474648593139385930646A4B7A396B52324D7250324E48597974665930646A4B7A396952324E6666475648593139385A45646A5833786852324D7250317048597974665755646A4B7A396A52324D7258316C48593139385A45646A5833785A52324E6666474A4859313938576B646A5833786B52324D7258317048593139385A45646A4B7A396852324E66664756485979732F5A6B646A5833786852324D725031704859313938596B646A4B7A396D52324E674D4670485979732F5955646A4B7A396A52324D7250317048593139385930646A5833786852324E6666474E485979732F5A45646A4B7A396A52324D7258324648593139385A55646A4B7A396152324D7258324A4859797466576B646A4B7A396B52324D7250325A4859336F725955646A4B7A396D52324D7250324E48593139385755646A4B31396A52324D7250316C48593139385930646A4B31396152324E66664752485979732F576B646A5833786B52324D7250324A4859313938576B646A5833786852324E6666466C48597974665930646A5833786152324E66664756485979732F5930646A4B7A396152324E6666475648593139385955646A5833786D52324D7258324648597974665755646A4B7A396952324E666647524859797466576B646A4B31396952324D72583170485979732F576B646A4B31395A52324D7250324E4859797466576B646A5833786C52324E6666474E4859336F72576B646A6569745A52324D725832464859797466576B646A5833786B52324D7250324648593139385A45646A4B31396952324E364B316C485979732F576B646A5833786E52324D7258324E48597974665930646A5833786A52324D7250324E485979732F5745646A5833786A52324D7250316C4859313938596B646A4B7A396D52324D7258316C4859313938596B646A5833786C52324D725831704859797466596B646A4B31396152324D7250317048597974665755646A4B31395A52324D7258324A485979732F5A45646A6569745952324E364B316C4859336F725755646A6569745952324D7258317048593139385A45646A4B7A396152324E66664752485979732F596B646A5833786152324E6666474648593139385745646A4B7A396D52324E674D4670485979732F5755646A4B7A396A52324D7250316848593139385930646A4B7A395A52324E6666474A485979732F5A6B646A4B31395A52324E364B3168485979732F596B646A6569746152324E6666466C48597974665755646A6569746852324D7250325648593139385930646A656A786852324E365047464859336F385955646A656A786852324E365047464859336F3859513D3D [+] R2MrX1pHY198ZEdjKz9aR2NffGRHYys/YkdjX3xiR2N6K1hHY198ZEdjK19aR2NgMFpHYytfWUdjKz9jR2MrP1pHY198Y0djeitYR2NffGVHYys/ZEdjX3xkR2N6K1pHY198ZEdjKz9YR2NffGRHY198YUdjKz9aR2MrX1lHYytfWUdjK19iR2MrP2VHY198Y0djX3xjR2NffFpHYytfYUdjK19aR2NffGRHYys/WkdjX3xlR2NffFlHY198YUdjX3xhR2NffGdHYytfY0djKz9jR2MrX2NHYys/Y0djKz9aR2NffGNHY3orWEdjX3xlR2MrP2RHY198WkdjX3xlR2MrP2NHYys/WEdjeitZR2MrP1pHYys/ZEdjK19jR2NffGRHYytfY0djKz9kR2NffGFHY3orWEdjKz9hR2NffFhHYytfWkdjX3xkR2MrP1pHY198ZEdjKz9iR2NffFpHY198YUdjX3xiR2MrP2RHYys/Y0djK19ZR2MrP2NHYys/WkdjX3xjR2NffGFHY198Y0djKz9kR2MrP2NHYytfY0djKz9iR2NffGVHY198ZEdjX3xhR2MrP1pHYytfWUdjKz9jR2MrX1lHY198ZEdjX3xZR2NffGJHY198WkdjX3xkR2MrX1pHY198ZEdjKz9hR2NffGVHYys/ZkdjX3xhR2MrP1pHY198YkdjKz9mR2NgMFpHYys/YUdjKz9jR2MrP1pHY198Y0djX3xhR2NffGNHYys/ZEdjKz9jR2MrX2FHY198ZUdjKz9aR2MrX2JHYytfWkdjKz9kR2MrP2ZHY3orYUdjKz9mR2MrP2NHY198WUdjK19jR2MrP1lHY198Y0djK19aR2NffGRHYys/WkdjX3xkR2MrP2JHY198WkdjX3xhR2NffFlHYytfY0djX3xaR2NffGVHYys/Y0djKz9aR2NffGVHY198YUdjX3xmR2MrX2FHYytfWUdjKz9iR2NffGRHYytfWkdjK19iR2MrX1pHYys/WkdjK19ZR2MrP2NHYytfWkdjX3xlR2NffGNHY3orWkdjeitZR2MrX2FHYytfWkdjX3xkR2MrP2FHY198ZEdjK19iR2N6K1lHYys/WkdjX3xnR2MrX2NHYytfY0djX3xjR2MrP2NHYys/WEdjX3xjR2MrP1lHY198YkdjKz9mR2MrX1lHY198YkdjX3xlR2MrX1pHYytfYkdjK19aR2MrP1pHYytfWUdjK19ZR2MrX2JHYys/ZEdjeitYR2N6K1lHY3orWUdjeitYR2MrX1pHY198ZEdjKz9aR2NffGRHYys/YkdjX3xaR2NffGFHY198WEdjKz9mR2NgMFpHYys/WUdjKz9jR2MrP1hHY198Y0djKz9ZR2NffGJHYys/ZkdjK19ZR2N6K1hHYys/YkdjeitaR2NffFlHYytfWUdjeithR2MrP2VHY198Y0djejxhR2N6PGFHY3o8YUdjejxhR2N6PGFHY3o8YQ== [+] Gc+_ZGc_|dGc+?ZGc_|dGc+?bGc_|bGcz+XGc_|dGc+_ZGc`0ZGc+_YGc+?cGc+?ZGc_|cGcz+XGc_|eGc+?dGc_|dGcz+ZGc_|dGc+?XGc_|dGc_|aGc+?ZGc+_YGc+_YGc+_bGc+?eGc_|cGc_|cGc_|ZGc+_aGc+_ZGc_|dGc+?ZGc_|eGc_|YGc_|aGc_|aGc_|gGc+_cGc+?cGc+_cGc+?cGc+?ZGc_|cGcz+XGc_|eGc+?dGc_|ZGc_|eGc+?cGc+?XGcz+YGc+?ZGc+?dGc+_cGc_|dGc+_cGc+?dGc_|aGcz+XGc+?aGc_|XGc+_ZGc_|dGc+?ZGc_|dGc+?bGc_|ZGc_|aGc_|bGc+?dGc+?cGc+_YGc+?cGc+?ZGc_|cGc_|aGc_|cGc+?dGc+?cGc+_cGc+?bGc_|eGc_|dGc_|aGc+?ZGc+_YGc+?cGc+_YGc_|dGc_|YGc_|bGc_|ZGc_|dGc+_ZGc_|dGc+?aGc_|eGc+?fGc_|aGc+?ZGc_|bGc+?fGc`0ZGc+?aGc+?cGc+?ZGc_|cGc_|aGc_|cGc+?dGc+?cGc+_aGc_|eGc+?ZGc+_bGc+_ZGc+?dGc+?fGcz+aGc+?fGc+?cGc_|YGc+_cGc+?YGc_|cGc+_ZGc_|dGc+?ZGc_|dGc+?bGc_|ZGc_|aGc_|YGc+_cGc_|ZGc_|eGc+?cGc+?ZGc_|eGc_|aGc_|fGc+_aGc+_YGc+?bGc_|dGc+_ZGc+_bGc+_ZGc+?ZGc+_YGc+?cGc+_ZGc_|eGc_|cGcz+ZGcz+YGc+_aGc+_ZGc_|dGc+?aGc_|dGc+_bGcz+YGc+?ZGc_|gGc+_cGc+_cGc_|cGc+?cGc+?XGc_|cGc+?YGc_|bGc+?fGc+_YGc_|bGc_|eGc+_ZGc+_bGc+_ZGc+?ZGc+_YGc+_YGc+_bGc+?dGcz+XGcz+YGcz+YGcz+XGc+_ZGc_|dGc+?ZGc_|dGc+?bGc_|ZGc_|aGc_|XGc+?fGc`0ZGc+?YGc+?cGc+?XGc_|cGc+?YGc_|bGc+?fGc+_YGcz+XGc+?bGcz+ZGc_|YGc+_YGcz+aGc+?eGc_|cGcz<aGcz<aGcz<aGcz<aGcz<aGcz<a [+] 34423536343335363435353433323536344235413441343634333535333235373437353633343536343135363533343334413441344434383535353535323443344235363433353735313533353335393445343634453436343335353332353734373532353734363431333334333437344535363445343735333332343435303442353634333536343535323533353434373436344134363433353535333535343734363445343535373536353334333441343634413536353135343532353634423536343435373439353334333534343935413434343634333535353335353437343634433537343334443442343734393335343934363531344534323535344235363433353634353532353335313445353235373436343335373533353834433441343535363442344434423433344134363442353735353334333334433442353634343536344433333433353934453445353534363431353534323534343934413534353734423444344234333441344134443437333233333333333234423536343335363435353235333530343935413432343634313535343235343439344133323435333435313441333534383535334433443344334433443344 [+] 4B564356455432564B5A4A464355325747563456415653434A4A4D485555524C4B564357515353594E464E464355325747525746413343474E564E47533244504B5643564552535447464A464355535547464E45575653434A464A56515452564B56445749534354495A44464355535547464C57434D4B4749354946514E42554B564356455253514E525746435753584C4A45564B4D4B434A464B575534334C4B5644564D3343594E4E554641554254494A54574B4D4B434A4A4D47323333324B56435645525350495A424641554254494A324534514A3548553D3D3D3D3D3D [+] KVCVET2VKZJFCU2WGV4VAVSCJJMHUURLKVCWQSSYNFNFCU2WGRWFA3CGNVNGS2DPKVCVERSTGFJFCUSUGFNEWVSCJFJVQTRVKVDWISCTIZDFCUSUGFLWCMKGI5IFQNBUKVCVERSQNRWFCWSXLJEVKMKCJFKWU43LKVDVM3CYNNUFAUBTIJTWKMKCJJMG2332KVCVERSPIZBFAUBTIJ2E4QJ5HU====== [+] UEROUVRQSV5yPVBJXzR+UEhJXiZQSV4lPlFmZihoUERFS1RQRT1ZKVBISXN5UGdHSFFQRT1Wa1FGPX44UERFPllQZWZIU1BIUjskUGVlXkhPP3Bge1BJXmozUERFOFBPP3BtNA== [+] PDNQTPI^r=PI_4~PHI^&PI^%>Qff(hPDEKTPE=Y)PHIsyPgGHQPE=VkQF=~8PDE>YPefHSPHR;$Pee^HO?p`{PI^j3PDE8PO?pm4 [+] NEY0NzM4NzY2NjY0NzQ1RjIzNDY1NTZGNjQ2OTQzNTY2QzNCNDkyODU3NkU1ODM0MzY0NzJENDU1MzNC [+] 4F4738766664745F2346556F646943566C3B4928576E583436472D45533B [+] OG8vfdt_#FUodiCVl;I(WnX46G-ES; [+] KCTF{dfs_0r_b4u7e_f04c3}
KCTF{dfs_0r_b4u7e_f04c3}
Toddler RSA (Cryptography 300)
暗号処理の概要は以下の通り。
・flag1: フラグの前半 ・flag2: フラグの後半 ・p, q: 512ビット素数 ・n = p * q ・e = 0x10001 ・phi = (p - 1) * (q - 1) ・m = flag1を数値化したもの ・ct = pow(m, e, n) ・primes = [p, q] ・98回以下繰り返し ・primesに512ビット素数を追加 ・primesをシャッフル ・primes2 = [] ・以下繰り返し ・primes2の長さが16の場合、繰り返し終了 ・p: 128ビット素数 ・pがprimes2になければ、primes2にpを追加 ・以下繰り返し ・n2 = 1 ・primes2の各数値pについて以下を実行 ・r: 0以上1以下のランダム整数 ・rが1の場合、n2 *= p ・n2のビット長が1024より大きい場合、繰り返し終了 ・m2 = flag2を数値化したもの ・ct2 = pow(m2, e, n2) ・infos.txtに以下の形式で書き込み [ct] [ct2] [primes[0]] [primes[1]] [primes[2]] ... [primes2[0]] [primes2[1]] [primes2[2]] ...
flag1の暗号化に使われているp, qは不明なので、primes1の素数のペアをブルートフォースして復号する。
flag2の暗号化に使われている素数はその積が1024bitを超えたときのものなので、それを使ってブルートフォースして復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * import itertools def is_printable(s): for c in s: if c < 32 or c > 126: return False return True e = 0x10001 with open('infos.txt', 'r') as f: params = f.read().splitlines() ct = int(params[0]) ct2 = int(params[1]) primes = [int(p) for p in params[2].split(' ')[:-1]] primes2 = [int(p) for p in params[3].split(' ')[:-1]] for pq in itertools.combinations(primes, 2): p = pq[0] q = pq[1] phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(ct, d, p * q) flag1 = long_to_bytes(m) if flag1.startswith(b'KCTF{'): break found = False for i in range(1, 17): for ps in itertools.combinations(primes2, i): n = 1 for p in ps: n *= p if n.bit_length() > 1024: phi = 1 for p in ps: phi *= p - 1 d = inverse(e, phi) m2 = pow(ct2, d, n) flag2 = long_to_bytes(m2) if flag2.endswith(b'}') and is_printable(flag2): found = True break if found: break flag = (flag1 + flag2).decode() print(flag)
KCTF{rsa_and_only_rsa_ftw}