明石高専Bチームとして出て、結果は6位でした。 CTFは大会に二回だけ参加したことがあるだけで、セキュコンへの参加も初めてでしたが、ググったらなんとかなりました。 完全に競プロ系の問題を解く枠として参加するつもりだったんですけど、競プロの問題一切でなくて泣きました。
- 問題一覧
- Binary 20回もやれば、暗号と認めてやっても良いだろう
- Binary 復号せよ
- Forensics お茶をさぐれ
- Forensics 最後に消したファイル
- Misc 拡張されたIPv6
- Misc ツートントン
- Network 名前を解決したい!
- Web JWT
- おわりに
問題一覧
Bianry Crypto Forensics Misc Network Web
以下、解いたり考察して解いてもらった問題について解法を書いていきます。
Binary 20回もやれば、暗号と認めてやっても良いだろう
BASE64decodeを20回してやるとFLAGがでてくる。 CyberChefというサイトがオススメ。
Binary 復号せよ
暗号器のexeと出力結果の文字列が与えられる。
とありあえずJetBrains社のツールである「dotPeek」をインストールしてexeを読み込む。
すると、入力に対してAES暗号化して、BASE64で出力しているとわかる。(JetBrains様は素晴らしいです) なので、出力をBASE64デコードして、AES復号したら入力がわかる。
AES暗号化に使用しているパラメータが特に隠されたり他のファイルに書いてあったりもなく、1ファイルに書いてあるので、そのまま使えばよい。
FLAGはCTFKIT{Enjoy_KOSEN_SECCON_2019}
Forensics お茶をさぐれ
apkファイルが与えられる。apkファイルは調べたらただのzipらしいので解凍する。なんか色々でてくる。classes.dex
というファイルが実際のプログラムの塊らしいので、これをdex2jar
というツールを使ってjarファイルに変換する。jarファイルはこれもzipらしいので解凍する。色々でてくるが、com.android
やcom.androidx
みたいなフォルダはどうせライブラリなので無視する。プログラム本体(classファイル)をJetBrains社製のIDE、Intellij IDEA
を用いて開くと、javaファイルにデコンパイルされる。
フラグを出力する部分があるが、めんどくさそうな計算をして文字列を組み立てているのがわかる。 なので出力と計算の部分だけ切り取って実際に実行してみると、フラグがでる。
実際に実行したコード
public class Main { public static void main(String[] args) { Main a = new Main(); a.doIt(); } public void doIt() { StringBuilder var4 = new StringBuilder(); var4.append(this.f()); var4.append(this.l()); var4.append(this.o()); var4.append(this.g()); var4.append(this.g2()); var4.append(this.e()); var4.append(this.h()); var4.append(this.i()); var4.append(this.j()); var4.append(this.k()); var4.append(this.l2()); var4.append(this.n()); var4.append(this.o2()); String var8 = var4.toString(); StringBuilder var9 = new StringBuilder(); var9.append("CTFKIT{"); var9.append(this.nyaho(var8)); var9.append("}"); System.out.println(var9.toString()); } public String nyaho(String var1) { char[] var5 = new char[var1.length()]; for (int var4 = 0; var4 < var1.length(); ++var4) { char var3 = var1.charAt(var4); char var2; if (var3 >= 'a' && var3 <= 'm') { var2 = (char) (var3 + 13); } else if (var3 >= 'A' && var3 <= 'M') { var2 = (char) (var3 + 13); } else if (var3 >= 'n' && var3 <= 'z') { var2 = (char) (var3 - 13); } else { var2 = var3; if (var3 >= 'N') { var2 = var3; if (var3 <= 'Z') { var2 = (char) (var3 - 13); } } } var5[var4] = var2; } return String.valueOf(var5); } public String e() { return "v"; } public String f() { return "h"; } public String g() { return "f"; } public String g2() { return "u"; } public String h() { return "a"; } public String i() { return "b"; } public String j() { return "_"; } public String k() { return "g"; } public String l() { return "e"; } public String l2() { return "r"; } public String n() { return "n"; } public String o() { return "r"; } public String o2() { return "_"; } }
CTFKIT{ureshino_tea_}
Forensics 最後に消したファイル
ファイルは.7z
で与えられるのでとりあえず解凍する。
でてきたやつのfileコマンドの出力が、DOS/MBR boot sector...
みたいな感じになる。
binwalkをすると、RSAのprivate-keyが存在していることがわかる。
hexdumpして無理やり取得。
そのあと、ディスクイメージはzipらしいと知り、さらに解凍するとflag/mullin.encrypted
が見つかる。
これをopensslコマンドを叩き、さっきのprivate keyを使用して復号した。
cat ./flag/mullin.encrypted | openssl rsautl -decrypt -inkey private-key.pem
CTFKIT{Pandemonium_Mont_Blanc}
Misc 拡張されたIPv6
ググったら、RFC8135だとわかる。
FLAGはCTFKIT{RFC8135}
Misc ツートントン
モールス信号になってる白黒の画像ファイルが与えられる。 左から右、上から下に見ていき、連続した黒2つがトン、5つでツー、白は3つ以上空いたら文字の区切りという法則が見たらわかる。
チームのメンバーに、pythonで適当に書いてもらって.
, -
, の3文字にしてから、適当なサイトでモールス複合をしたらでてきた。
復号に使ったサイト https://morse.ariafloat.com/en/
Network 名前を解決したい!
https://futuregadget-9.tech/ にアクセスできない、設定を間違えたのか..?みたいな問題文。
問題のタイトルからDNSやろってなる。
とりあえずnslookup
, dig
, whois
を叩いていく。
nslookup
ででました。http://153.126.212.45/
にアクセスすると、CTFKIT{naki_nureshi_megami_no_kikan}
って書いてある。
Web JWT
Cookieを見ると、なにやら怪しいやつがある。それが認証に使われていることがわかる。
Cookieの値
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJpYXQiOjE1NzIwNTE2MDN9.D60_GbWe_xLD3QEMs9_IbvTcVTgFz4Uv6kGIbcLqWo2CNmDk8_lwFGqb74_J4T6bXMqUvuHJyflBYrAbwpmp7h_zRwyDV-VQCg0X5p3AlStjSeSkaq6vsitkJ18_Zbgw02iHerCP68tNJtArguqwAFEeAa0dX1-Y01nJ0ZvCnA9rS3Yj77U61Kpde4nIpvSImg_3sx5c8QUQ4JKVXBS3e_UNd7NodZQ7XBkUbk8p6DreqpRNda9TJNtlDEOr-E-6QcoLJWZCxn2VUqWDQjGlSpWCjdvsihtlbytR1fyd9KXOO1uezQWBFWCI54E1dPeC-gkxxMAxRHNn8r30nAEXdw
Base64デコードしたら、色々でてくるのでググると、Json Web Tokenという技術らしいので調べる。
header, payload, signatureの3つになってるっぽい。
とりあえず、渡しているjsonデータ(payload)の
{ "user": "guest", "iat": 1572051603 }
を
{ "user": "admin", "iat": 1572051603 }
にして送信したら良さそうかなー?となる。
じゃあ改ざん検知を欺瞞するためにどうするかというと、脆弱性があるらしい。
このサイトが非常に有益だった。
header部分で検証に使用するアルゴリズムを{"typ":"JWT","alg":"RS256"}
から、{"typ":"JWT","alg":"HS256"}
に変えて、最後のsignatureを頑張ってつくればいいとわかる。
脆弱性があるやつは、signatureの暗号化に使う鍵を、サーバーの証明書の鍵と同じにしているらしい。公開鍵なのでとりあえず手に入れて、それをwikiに従ってBase64エンコードなり色々して、Cookieを組み上げていく。 最後にCookie書き換えてリロードしたらでてくる。
CTFKIT{old_jwt_library_is_unsecure}
後でせやなってなったが、JWTを実装してるライブラリを使ったらもっと簡単に書けた(なんで自分で全部実装したんだろう...)。
おわりに
読んでいただきありがとうございました!来年もでたいな