この大会は2019/10/9 7:00(JST)~2019/10/14 7:00(JST)に開催されました。
今回もチームで参戦。結果は4131点の満点で584チーム中29位でした。
自分で解けた問題をWriteupとして書いておきます。
History lesson in malware (Trivia 10)
ここで言っているマルウェアはStuxnetのこと。https://techtarget.itmedia.co.jp/tt/news/1705/09/news03.htmlなどに載っている。
{cve-2010-2568}
Making OPC UA secure (Trivia 10)
OPC UAとUA Securityのご紹介の資料からSecurityモードがわかる。
https://www.jpcert.or.jp/ics/2011/20110210-fujii-sama.pdf
{none-sign-signandencrypt}
Using an OPC UA service (Trivia 10)
OPC UAとUA Securityのご紹介の資料からサービスがわかる。
https://www.jpcert.or.jp/ics/2011/20110210-fujii-sama.pdf
暗号化するのはSecureチャネルのサービス。
{securechannel}
Insider attack 1 (Secret 1)
このジャンルの問題を解くのを了承するだけ。
{ok}
Industrial sightseeing tour 1 (OSINT 100)
写真に"KOH-I-NOOR HARDTMUTH"と書いてあるのが見える。文房具店らしい。その場所を調べる。
Ceske Budejovice
{CeskeBudejovice}
Access the device! (OSINT 200)
見えている文字(ETH, MRX)で検索すると、MRX3 LTE という製品が見つかる。"MRX3 LTE" default password で検索すると、マニュアルが見つかる。
http://www.insys-icom.cz/bausteine.net/f/10803/QIG_en_INSYS_MRX_LTE_190125.pdf?fd=0
これにデフォルトのユーザ名、パスワードが書いてある。
{insys-icom}
The pasted leak (Forensics 700)
https://pastebin.com/6U36KmG0にアクセスすると、以下の内容がpasteされている。
traciduke:3a7a5871998e43741d09571f779f18d9 uwilliams:f67793a860600a2e73f7cb58ed3c9f25 diazrhonda:21fd63743deefd2380305ba5dc3932a0 chendana:472eccb32d0d9419903587934b2fc68a melaniecarr:516373b9c689d6dd28c62e245c58c035 thompsonsheri:7ad71e2f104c6e670888bbf59ada4d15 dennis40:466df7524db6a9270135162d7df1bbb3 nfrye:b1201c10488c081de2a423390514a8d3 torresmaria:d39a6996e054f90a507a812e8cb88067 nfrederick:4316dee282545d285ff2d4e0fa777698
https://hashkiller.co.uk/Cracker/MD5でクラックする。
3a7a5871998e43741d09571f779f18d9 [No Match] f67793a860600a2e73f7cb58ed3c9f25 [No Match] 21fd63743deefd2380305ba5dc3932a0 [No Match] 472eccb32d0d9419903587934b2fc68a [No Match] 516373b9c689d6dd28c62e245c58c035 [No Match] 7ad71e2f104c6e670888bbf59ada4d15 [No Match] 466df7524db6a9270135162d7df1bbb3 MD5 pa$$2019 b1201c10488c081de2a423390514a8d3 [No Match] d39a6996e054f90a507a812e8cb88067 [No Match] 4316dee282545d285ff2d4e0fa777698 [No Match]
KeePassで添付のkdbxを開き、Master Passwordとしてpa$$2019を指定する。パスワードが通り、内容を見ることができた。
important-noteを見ると、URLが書いてある。
https://0bin.net/paste/8OroFXcfz9P-+uN9#UJiJ2F7SsuvS3zgxzI00vw8rehyoPT0+CdShZmgN8L6
ここにアクセスすると、フラグが書いてあった。
{n3v3r_r3cycl3_y0ur_53cr37_p455w0rd5}
Schlamperei (Crypto 200)
setup_customerID_9721.zipはパスワードがかかっているが、"9721"で解凍できた。
展開されたファイル群の中にsessionkey_2fishecb.txt.gpgがあるので、復号してみる。
まず71062c43B022BE72_public-key.txtは秘密鍵なので、インポートする。
$ gpg --import 71062c43B022BE72_public-key.txt gpg: 鍵B022BE72: 公開鍵"MYF4N74571CM4CH1N3C0rP (MFMC)"をインポートしました gpg: 鍵B022BE72: 秘密鍵をインポートしました gpg: 鍵B022BE72:"MYF4N74571CM4CH1N3C0rP (MFMC)"変更なし gpg: 処理数の合計: 2 gpg: インポート: 1 (RSA: 1) gpg: 変更なし: 1 gpg: 秘密鍵の読み込み: 1 gpg: 秘密鍵のインポート: 1 $ gpg --output sessionkey_2fishecb.txt --decrypt sessionkey_2fishecb.txt.gpg 次のユーザの秘密鍵のロックを解除するには パスフレーズがいります:"MYF4N74571CM4CH1N3C0rP (MFMC)" 2048ビットRSA鍵, ID B022BE72作成日付は2019-09-15 gpg: 無効なパスフレーズです。再入力してください ...
パスフレーズが必要のようだ。
README.txtを見ると以下の文がある。
NOTE: The old default encryption password 'VMC' has been replaced since 09/2018. Please use the new one.
VMCというパスワードが変わったとのこと。'MFMC'になったと考えられる。
$ gpg --output sessionkey_2fishecb.txt --decrypt sessionkey_2fishecb.txt.gpg 次のユーザの秘密鍵のロックを解除するには パスフレーズがいります:"MYF4N74571CM4CH1N3C0rP (MFMC)" 2048ビットRSA鍵, ID B022BE72作成日付は2019-09-15 gpg: 2048-ビットRSA鍵, ID B022BE72, 日付2019-09-15に暗号化されました "MYF4N74571CM4CH1N3C0rP (MFMC)"
パスフレーズに"MFMC"を指定すると、復号できた。
$ cat sessionkey_2fishecb.txt A0 C9 18 74 33 F2 2C 00 83 2B 1E 99 22 10 1A 6A
ファイル名からTwofish暗号(ECBモード)の鍵と考えられる。message.txtの内容をこの鍵で復号する。
from twofish import Twofish with open('message.txt', 'r') as f: ct = f.read().replace(' ', '').decode('hex') with open('sessionkey_2fishecb.txt', 'r') as f: key = f.read().replace(' ', '').decode('hex') T = Twofish(key) pt = '' for i in range(0, len(ct), 16): pt += T.decrypt(ct[i:i+16]) print pt
復号結果は以下の通り。
If you reveal your secrets to the wind, you should not blame the wind for revealing them to the trees. {silence_is_golden}
{silence_is_golden}
Enhanced PLC Encryption Standard (Crypto 600)
とりあえずどんな暗号処理をしているか日本語に直訳。
1.すべてのPLCが共有シークレットパスワードを取得します。 これは非常に長いため、誰もそれをブルートフォースできません。 2.2つのデバイスが通信したい場合、1つ(A)が他のデバイス(B)に固有のチャレンジを送信します。 3.Bはチャレンジを取得し、チャレンジのパスワードの各文字をハッシュします: response = hash(char + challenge) 4.セキュリティのため、ここではSHA-256を使用します(安全でないMD5またはSHA-1は使用しません!)。 また、各文字を個別にハッシュするため、攻撃者が応答を記録した場合に完全なパスワードが 漏洩することはありません。 5.BはAに多くの応答を送り返します。Aはパスワードの長さとパスワード自体を知っています。 したがって、応答がない場合、または応答が多すぎる場合、Aは接続を終了できます。 6.Aはハッシュ(char +チャレンジ)も実行し、すべての応答を比較します。 不一致がある場合、Aは接続を終了します。 7.すべての応答が一致すると、AとBは共有秘密パスワードをキーとして使用して通信を開始します。 ここでは、PLCが軍事グレードのAESをサポートしていないため、CBCモードで3DESを使用しています。
ハッシュにする際、1文字+チャレンジコードに対して行っているのでブルートフォースで割り出すことができる。これで秘密鍵がわかり、3DES-CBC、IVは\x00*8で暗号化しているので、復号できる。
import hashlib from Crypto.Cipher import DES3 def unpad(s): return s[:-ord(s[-1])] challenge = 'VkcV29UKCGbfuZyqea7uKbZ9' h = [ '5daaa90b563017184bb8dc277f63f02366a59519113b9ac87ba6fd46f93dc1ff', '01b4e096bcb756f176beaa2ebbb99ef144dc3fb0bc2d27e5fe63a5601e3abace', 'db00873b16b99e32c6c67672ea52df6769cf7801ebb3dbf168f5b2e0f2ecc3bf', '146797c2afa9e1a2ad2ff8f05de647702949923f9a5dc12b26452b2c520c3340', '67dacf84cce58a6bf283d62354ad05052fe42808b59866dfb30137a08b4ff12d', 'c13dcb97dccf5e3942324409202a103eb9f007866f247ebea48e2a67cbbcd07f', 'd72a057ba7fddd03cae3d3f7d75f865fb1c2ddbe8ef65afc0ce8fbc0fc4122cb', '6eddcbed70839add89ed38c3068ffe6780f7b86f0bc7276e2d7e06f47ea2e05a', '146797c2afa9e1a2ad2ff8f05de647702949923f9a5dc12b26452b2c520c3340', 'd72a057ba7fddd03cae3d3f7d75f865fb1c2ddbe8ef65afc0ce8fbc0fc4122cb', 'db00873b16b99e32c6c67672ea52df6769cf7801ebb3dbf168f5b2e0f2ecc3bf', '4c1b4d5c926c4160b19effa23c93710f3086866a74aca5dad801fd81118d8d68', '67dacf84cce58a6bf283d62354ad05052fe42808b59866dfb30137a08b4ff12d', '4d4ac18fd35d3707fc3671d372bbe494691b01611632359c7d39b7becbfc1184', '4d4ac18fd35d3707fc3671d372bbe494691b01611632359c7d39b7becbfc1184', '571aef6ff2d25a7a32c3a9fc3b1c06d874979f082b5e90b0c30a01203885a2b0', 'fdc984b4a8fec04fcb9faacf99f9dbfd0fbef0a33906c3fa89d9fb0b63947a0e', '146797c2afa9e1a2ad2ff8f05de647702949923f9a5dc12b26452b2c520c3340', '588917d1f04bbc53aed45c6db061092dde79af4c5fc3f01e96eab2e86b30e581', 'a122c3b77eaf01341cc0c7da6e45e7ff9ff57f97a4c9542ad7e96a0f28499029', 'fdc984b4a8fec04fcb9faacf99f9dbfd0fbef0a33906c3fa89d9fb0b63947a0e', '8419e8ddded5e57e71db42841f865f9fd751ec3b8e0395ba36818b52a015e47e', 'af621e444935d03bc563e24982ad25d19c3ca4f52341232c978f7e63c809a27e', '572c394ed63437090aec71c806d92a2a10d5e3651eb30a91d1573ba3d37f4ad9' ] password = '' for i in range(24): for code in range(32, 127): text = chr(code) + challenge if hashlib.sha256(text).hexdigest() == h[i]: password += chr(code) break print 'password =', password IV = '0' * 8 ct1 = '24066241b2c524457a58196640197307469c18fd71bb6de304501a8d50981e25' cipher = DES3.new(password, DES3.MODE_CBC, IV) pt1 = unpad(cipher.decrypt(ct1.decode('hex'))) print pt1 ct2 = '07d89c21b9dd1eb81e26d52398da02a3d000ba82f9198b2b3311cb1cda901418' cipher = DES3.new(password, DES3.MODE_CBC, IV) pt2 = unpad(cipher.decrypt(ct2.decode('hex'))) print pt2
実行結果は以下の通り。
password = ultras3cr3tpa$$w0rd2019! EPES HANDSHAKE SUCCESSFUL {never-roll-your-own-crypto}
{never-roll-your-own-crypto}