2024/08/03(~48h)に行われた海外のCTF大会にチームで出場しました。(Team Name: FCS_Zunndamons, User Name: HydrangeA)(順位: 121/575)
今回、cryptoメインで解答に挑戦しました. Crypto1問を解答できたため、その解答の軌跡を残せればと思います.
何かの参考になれば幸いです。
AES is very robust, but let's quadruple its power!
dist.zip
dist内のファイルは以下の通りです.
4ES.py
output.txt
AES暗号(ブロック暗号)を用いてFlagを暗号化しているようです. AES暗号の秘密鍵は、変数charsを基に3文字分のランダムなバイト列(w,x,y,z)を4つ生成し、そのバイト列をすべて加算したものをsha256でハッシュしてdigestした値となっています。
AES暗号はブロック暗号であるため、共通鍵暗号となります。つまり暗号化に使われた鍵と同じものを推測できれば正しく復号することが可能になります。そのためまずは秘密鍵を求められるかに焦点を置くことが望ましいと考え、話を進めます。
秘密鍵の構成はsha256(w+x+y+z).digestであるため、構成要素w,x,y,zが分かれば求められます。w,x,y,zはbytes(choices(chars, k=L))であるため、charsに含まれる文字列から重複ありでL文字選んだものが与えられます。今回はL=3であるため、通りの文字列が考えられます。ここで、この組み合わせ数で総当たりできるかどうか考えてみます。
w,x,y,zそれぞれが2744通りの組み合わせをとりうるため、を全探索できれば解けます。ただし、コンテスト中に解き切ることは困難です。
唐突ですが、与えられた情報pt, ctがflagのAES暗号化に一切かかわっていないことにお気づきでしょうか(この情報を基に解けと言わんばかりの情報っぽい)。一度について見ていきましょう。
とある平文ptに対してAES暗号を4回適応した結果が暗号文ctとなっています。その暗号化に使われる秘密鍵はw,x,y,zをそれぞれsha256でハッシュした値k1,k2,k3,k4となっています。
この暗号化に関しても、w,x,y,zの組み合わせを総当たりすれば解けそうで、先ほど導出した通りを解く必要があるように感じます。
わざわざ濁しているので、結論を言うと工夫すれば総当たりの回数を減らすことができます。ではどうするか。
今回pt, ctが与えられており、AES暗号(ないし共通鍵暗号)の特徴から、同じ秘密鍵を用いれば元の平文に復号することが可能です(より具体的にはAES暗号内のdecrypt関数を動かします)。そのため、ptをk1,k2で暗号化した値と、ctをk4,k3で復号した値が合致することになります。この考えにより、それぞれの組み合わせ数は通りとなり、総当たり回数が大幅に削減されます。
この方針を採用した解答の手順は以下となります。
以上により、問題を解くことが出来ます。
補足1: 半分全列挙というアルゴリズム(テクニック?)があります。ぜひ検索してみてください。
crew{m1tm_at74cK_1s_g0lD_4nd_py7h0n_i5_sl0w!!}
この大会以前にも何度か海外のCTF大会に参加していましたが、ことごとく惨敗してwriteupすらかけない状態が続いていました。特にRSAの問題が来るとめったに解けない。2番目に解かれていたCryptoの問題もRSA。今回も解けず。対してブロック暗号の正答率は割と高い。アルゴリズムに物言わせて数学ができないという悲しい現実。次こそはRSAの問題を解きたい!と強く思いました。
最後まで読んでいただきありがとうございました。