この記事は setodaNote CTFのCryptoジャンルのWriteupです。
- base64 (50pts, 405solves)
- ROT13 (50pts, 390solves)
- pui_pui (80pts, 345solves)
- tkys_secret_service (120pts, 226solves)
- lets_bake (150pts, 119solves)
- vul_rsa_01 (200pts, 170solves)
- vul_rsa_02 (250pts, 139solves)
- WEARECIA (300pts, 76solves)
base64 (50pts, 405solves)
タイトルのとおり、ZmxhZ3tJdCdzX2NhbGxlZF9iYXNlNjQhfQ==
をbase64でデコードするだけ。
CybeChef使った。
FLAG
flag{It's_called_base64!}
なお、Base64は"暗号"ではないので注意。
ROT13 (50pts, 390solves)
タイトルのとおり、synt{Rira_lbh_Oehghf?}
をROT13で復号するだけ。
CyberChef使った。
FLAG
flag{Even_you_Brutus?}
pui_pui (80pts, 345solves)
以下の文字列を変換せよ。という問題。 "暗号" ではなくただのhex stringなので、ASCIIでエンコードする。
\x41\x3a\x44\x6f\x20\x79\x6f\x75\x20\x6b\x6e\x6f\x77\x20\x4d\x6f\x6c\x63\x61\x72\x3f\x0a\x0a\x42\x3a\x4f\x66\x20\x63\x6f\x75\x72\x73\x65\x21\x20\x49\x20\x6c\x6f\x76\x65\x20\x74\x68\x65\x20\x73\x63\x65\x6e\x65\x20\x77\x68\x65\x72\x65\x20\x68\x65\x20\x73\x69\x6e\x6b\x73\x20\x69\x6e\x74\x6f\x20\x74\x68\x65\x20\x62\x6c\x61\x73\x74\x20\x66\x75\x72\x6e\x61\x63\x65\x20\x77\x68\x69\x6c\x65\x20\x67\x69\x76\x69\x6e\x67\x20\x74\x68\x65\x20\x74\x68\x75\x6d\x62\x73\x20\x75\x70\x2e\x0a\x0a\x41\x3a\x2e\x2e\x2e\x20\x57\x68\x61\x74\x3f\x0a\x0a\x42\x3a\x62\x74\x77\x2c\x20\x74\x68\x65\x20\x66\x6c\x61\x67\x20\x69\x73\x20\x66\x6c\x61\x67\x7b\x48\x61\x76\x65\x5f\x79\x6f\x75\x5f\x65\x76\x65\x72\x5f\x68\x65\x61\x72\x64\x5f\x6f\x66\x5f\x48\x65\x78\x64\x75\x6d\x70\x3f\x7d\x2e\x0a
FLAG
flag{Have_you_ever_heard_of_Hexdump?}
tkys_secret_service (120pts, 226solves)
以下の文章を解読して欲しいという問題。
Gur cevgrsgbvh vp Pvhgevyyrq Hhsynmmbpbrq Vhpvezngbvh (PHV) ermbqrhg bh hvhprqreny mlmgrzm nhq vetnhbfngbvhm bm vp cnenzvahg bzcvegnhsr gv prqreny ntrhsbrm nhq snh qbersgyl bzcnsg gur nobybgl vp gur prqreny tvirehzrhg gv massrmmpayyl svhqasg bgm rmmrhgbny zbmmbvhm nhq pahsgbvhm. Gubm caoybsngbvh cevibqrm ntrhsbrm jbgu ersvzzrhqrq mrsaebgl erdaberzrhgm pve cevgrsgbht gur svhpbqrhgbnybgl vp PHV jurh gur bhpvezngbvh bm ermbqrhg bh hvhprqreny mlmgrzm nhq vetnhbfngbvhm; jurh gur hvhprqreny vetnhbfngbvh bm hvg svyyrsgbht ve znbhgnbhbht bhpvezngbvh vh orunyp vp n prqreny ntrhsl ve ambht ve vcrengbht n mlmgrz vh orunyp vp nh ntrhsl; nhq jurer gurer ner hv mcrsbpbs mnprtaneqbht erdaberzrhgm pve cevgrsgbht gur svhpbqrhgbnybgl vp Synt bm pynt{cabcab_sne_vp_zvy} PHV cermseborq ol gur naguvebfbht ynj, ertayngbvh, ve tvirehzrhgjbqr cvybsl pve gur PHV sngrtvel ybmgrq bh gur PHV Ertbmgel. Gur erdaberzrhgm nccyl gv nyy svzcvhrhgm vp hvhprqreny mlmgrzm nhq vetnhbfngbvhm gung cevsrmm, mgver, nhq/ve genhmzbg PHV, ve gung cevibqr cevgrsgbvh pve masu svzcvhrhgm. Gur mrsaebgl erdaberzrhgm ner bhgrhqrq pve amr ol prqreny ntrhsbrm bh svhgensgany irubsyrm ve vgure nterrzrhgm rmgnoybmurq orgjrrh guvmr ntrhsbrm nhq hvhprqreny vetnhbfngbvhm.
換字式暗号ぽい。 https://quipqiup.com/ に解析をおまかせすると解いてくれる。
The protection of Fontrolled Nnclassified Onformation (FNO) resident in nonfederal systems and organizations is of paramount importance to federal agencies and can directly impact the ability of the federal government to successfully conduct its essential missions and functions. This publication provides agencies with recommended security requirements for protecting the confidentiality of FNO when the information is resident in nonfederal systems and organizations; when the nonfederal organization is not collecting or maintaining information on behalf of a federal agency or using or operating a system on behalf of an agency; and where there are no specific safeguarding requirements for protecting the confidentiality of Clag is flag{puipui_car_of_mol} FNO prescribed by the authorizing law, regulation, or governmentwide policy for the FNO category listed in the FNO Registry. The requirements apply to all components of nonfederal systems and organizations that process, store, and/or transmit FNO, or that provide protection for such components. The security requirements are intended for use by federal agencies in contractual vehicles or other agreements established between those agencies and nonfederal organizations.
FLAG
flag{puipui_car_of_mol}
lets_bake (150pts, 119solves)
以下のレシピを解読して、メッセージを入手せよという問題。
Input:
NzRmNDRiMWE0Y2M2ZGNiNzc3NTMyNTcwZjk0MTE4NTMyNTcxZjE1YTE1NTJkY2M0
Recipe:
RnJvbV9CYXNlNjQoJ0EtWmEtejAtOSsvPScsdHJ1ZSkN]b2[sRnJvbV9IZXgoJ05vbmUnKQ0=]b2[sRm9yaygnJScsJ18nLGZhbHNlKQ0=]b2[sUkM0KHsnb3B0aW9uJzonVVRGOCcsJ3N0cmluZyc6J2NoZWYnfSwnTGF0aW4xJywnTGF0aW4xJyk=
タイトルや問題文的にCyberChefのレシピぽいが、CyberChefの既定のフォーマットではない。 ]b2[
で区切られたBase64された文字列のように見えたので、RnJvbV9CYXNlNjQoJ0EtWmEtejAtOSsvPScsdHJ1ZSkN
をデコードしてみたところ、以下のようなCyberChefのレシピが見えた。
- From_Base64('A-Za-z0-9+/=',true)
その後、sRnJvbV9IZXgoJ05vbmUnKQ0=
、sRm9yaygnJScsJ18nLGZhbHNlKQ0=
、sUkM0KHsnb3B0aW9uJzonVVRGOCcsJ3N0cmluZyc6J2NoZWYnfSwnTGF0aW4xJywnTGF0aW4xJyk=
も同じようにBase64デコードしてみたが、エラーが発生してうまくデコードできない。
ここでいろいろ試していたところ、3つのデコードが失敗する文字列の先頭にはすべて s
がついていることに気づく。もしかして、区切りは ]b2[s
なのでは?と思い RnJvbV9IZXgoJ05vbmUnKQ0=
、Rm9yaygnJScsJ18nLGZhbHNlKQ0=
、UkM0KHsnb3B0aW9uJzonVVRGOCcsJ3N0cmluZyc6J2NoZWYnfSwnTGF0aW4xJywnTGF0aW4xJyk=
でBase64デコードすると、以下のようなCyberChefのレシピがデコードされた。
- From_Hex('None')
- Fork('%','_',false)
- RC4({'option':'UTF8','string':'chef'},'Latin1','Latin1')
これでレシピが解読できたので、あとはCyberChefに食わせるだけ。
FLAG
flag{hello_baked_cipher}
vul_rsa_01 (200pts, 170solves)
以下の条件のRSA暗号。
- c :
39119617768257067256541748412833564043113729163757164299687579984124653789492591457335
- n:
13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257
- e:
65537
脆弱なRSA暗号と言ってすぐに思いつくのが nが素因数できるだったので、factordbで調べてみる。
すると、3058517013146002381763962882964790715736519
と 4372642466716249946441875327733923056149624303
に素因数分解できることがわかる。
あとはわかったpとqを使って平文を計算する。最近CTFでCryptoを解いてなかったが、今はRsaCtfToolという便利ツールがあるらしい。
https://github.com/Ganapati/RsaCtfTool
$ ./RsaCtfTool.py \ > -p 3058517013146002381763962882964790715736519 \ > -q 4372642466716249946441875327733923056149624303 \ > -e 65537 \ > --uncipher 39119617768257067256541748412833564043113729163757164299687579984124653789492591457335 private argument is not set, the private key will not be displayed, even if recovered. Results for /tmp/tmp8eaai5w4: Unciphered data : HEX : 0x0000000000666c61677b7765616b5f7273615f63616e5f62655f646563727970746564217d INT (big endian) : 46327402297761911070944293204953074319567693047395802794186233938451290661245 INT (little endian) : 62230274487105820292772638823612604590748807093488833479858991971752061223012822008463360 utf-8 : flag{weak_rsa_can_be_decrypted!} STR : b'\x00\x00\x00\x00\x00flag{weak_rsa_can_be_decrypted!}'
FLAG
flag{weak_rsa_can_be_decrypted!}
ちなみにRsaCtfToolにはcrackできたp,qをfactordbにsubmitする機能があるらしい。
RsaCtfToolとかいうやつ使ったことないんだけどfactordbに素数アップロードするってマジ?
— れっくす (@xrekkusu) 2021年3月21日
確かにコードを見るとsubmitする機能が実装されているが、現バージョンでは --sendtofdb
を引数につけない限りは有効にならなそうだ。
https://github.com/Ganapati/RsaCtfTool/blob/cb5281f3de402827af53f7cb875bddf1abb53bd3/lib/fdb.py#L10
vul_rsa_02 (250pts, 139solves)
以下の条件のRSA暗号
- c:
227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681
- n:
314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423
- e:
66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137
eの値が異常に大きい。eの値が大きいと相対的に秘密鍵dが小さくなるのでeとnが求められる。(Wiener's Attack)
Wiener's Attackによる解読もRsaCtfToolに実装されているので、これを使って暗号文を解読する。
$ ./RsaCtfTool.py \ > --attack wiener \ > -n 314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423 \ > -e 66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137 \ > --uncipher 227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681 private argument is not set, the private key will not be displayed, even if recovered. [*] Testing key /tmp/tmpxcahula7. [*] Performing wiener attack on /tmp/tmpxcahula7. 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 340/340 [00:00<00:00, 10971.49it/s] 26%|████████████████████████████████▎ | 88/340 [00:00<00:00, 8250.41it/s] [*] Attack success with wiener method ! Results for /tmp/tmpxcahula7: Unciphered data : HEX : 0x00026d79a6fba2741958ce82462855a96ec4dc1623133cfc341579920befc02eb7b9e0a3bbb87200666c61677b3139375f4d69636861656c5f4a5f5769656e65725f3637337d INT (big endian) : 139798168458800312619727954564053595602272620374704334322644822890230408773803390124016933159608289280352695220195070051973287657162728356081272992926853175686148989 INT (little endian) : 1845704400959999148955767357764584773879807573417556934806144078363531192151775289329637546633081241953731286516885596747340023540455177925029084293276584228646671942144 utf-16 : Ȁ祭ﮦ璢堙苎⡆쑮ᛜጣﰼᔴ鉹⻀릷ꏠ뢻r汦条ㅻ㜹䵟捩慨汥䩟坟敩敮彲㜶紳 STR : b'\x00\x02my\xa6\xfb\xa2t\x19X\xce\x82F(U\xa9n\xc4\xdc\x16#\x13<\xfc4\x15y\x92\x0b\xef\xc0.\xb7\xb9\xe0\xa3\xbb\xb8r\x00flag{197_Michael_J_Wiener_673}'
FLAG
flag{197_Michael_J_Wiener_673}
WEARECIA (300pts, 76solves)
WEARECIAは"We are CIA"かなと思い、"CIA Crypto" でググるとKryptosという暗号がヒットする。WikipediaのKryptosのページを見るとKryptosに書いてある暗号の全文が載っており、問題の冒頭の部分と一致する。
https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%B9
Wikiperidaには、キーワードがKryptos, Palimpsestのヴィジュネル暗号を用いたアルファベットの換字式暗号と書いてあったが、イメージが解読のわかなかった。
いろいろと調べてると、変換表がある以下のサイトにたどり着いた。
https://math.ucsd.edu/~crypto/Projects/KarlWang/index2.html
この表を元に以下のようなプログラムを実装し、暗号文を解読した。
#! /usr/bin/env python3 cipher = 'EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFDRCDNKFRHHMKVLLTGBMFDUTMALDUMKYQTGLWLWCM' key1 = 'KRYPTOSABCDEFGHIJLMNQUVWXZ' key2 = 'PALIMPSEST' def rolling(str , n): return str[n:len(str)] + str[:n] flag = '' for i,v in enumerate(cipher): i = i%10 table = rolling(key1,key1.find(key2[i])) flag += key1[table.find(v)] print(flag)
$ python3 kryptos.py BETWEENSUBTLESHADINGANDTHEABSENCEOFLIGHTLIESTHENUANCEOFIQLUSIONFLAGISWEARETHENATIONSFIRSTLINEOFDEFENSE
解読した文章の後半部分のメッセージが "FLAG IS WEARETHENATIONSFIRSTLINEOFDEFENSE" となっていることから、FLAGは以下のようになる。
flag{WEARETHENATIONSFIRSTLINEOFDEFENSE}