naoppyの日記

自分が欲しいなと思った記事を書きます。

KOSEN セキュリティコンテスト2019 write-up

明石高専Bチームとして出て、結果は6位でした。 CTFは大会に二回だけ参加したことがあるだけで、セキュコンへの参加も初めてでしたが、ググったらなんとかなりました。 完全に競プロ系の問題を解く枠として参加するつもりだったんですけど、競プロの問題一切でなくて泣きました。

f:id:naoppy_ac:20191026183202p:plain

問題一覧

Bianry f:id:naoppy_ac:20191026183940p:plain Crypto f:id:naoppy_ac:20191026184013p:plain Forensics f:id:naoppy_ac:20191026184042p:plain Misc f:id:naoppy_ac:20191026184124p:plain Network f:id:naoppy_ac:20191026184253p:plain Web f:id:naoppy_ac:20191026184326p:plain

以下、解いたり考察して解いてもらった問題について解法を書いていきます。

Binary 20回もやれば、暗号と認めてやっても良いだろう

BASE64decodeを20回してやるとFLAGがでてくる。 CyberChefというサイトがオススメ。

Binary 復号せよ

暗号器のexeと出力結果の文字列が与えられる。

とありあえずJetBrains社のツールである「dotPeek」をインストールしてexeを読み込む。

www.jetbrains.com

すると、入力に対してAES暗号化して、BASE64で出力しているとわかる。(JetBrains様は素晴らしいです) なので、出力をBASE64デコードして、AES復号したら入力がわかる。

f:id:naoppy_ac:20191028124914p:plain

AES暗号化に使用しているパラメータが特に隠されたり他のファイルに書いてあったりもなく、1ファイルに書いてあるので、そのまま使えばよい。

f:id:naoppy_ac:20191026190853p:plain

FLAGはCTFKIT{Enjoy_KOSEN_SECCON_2019}

Forensics お茶をさぐれ

apkファイルが与えられる。apkファイルは調べたらただのzipらしいので解凍する。なんか色々でてくる。classes.dexというファイルが実際のプログラムの塊らしいので、これをdex2jarというツールを使ってjarファイルに変換する。jarファイルはこれもzipらしいので解凍する。色々でてくるが、com.androidcom.androidxみたいなフォルダはどうせライブラリなので無視する。プログラム本体(classファイル)をJetBrains社製のIDEIntellij 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} f:id:naoppy_ac:20191026184753p:plain

Misc ツートントン

モールス信号になってる白黒の画像ファイルが与えられる。 左から右、上から下に見ていき、連続した黒2つがトン、5つでツー、白は3つ以上空いたら文字の区切りという法則が見たらわかる。

f:id:naoppy_ac:20191028124454p:plain

チームのメンバーに、pythonで適当に書いてもらって., -, の3文字にしてから、適当なサイトでモールス複合をしたらでてきた。

復号に使ったサイト https://morse.ariafloat.com/en/

Network 名前を解決したい!

https://futuregadget-9.tech/ にアクセスできない、設定を間違えたのか..?みたいな問題文。 問題のタイトルからDNSやろってなる。 とりあえずnslookup, dig, whoisを叩いていく。

f:id:naoppy_ac:20191026205224p:plain

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という技術らしいので調べる。

f:id:naoppy_ac:20191026212154p:plain

header, payload, signatureの3つになってるっぽい。

とりあえず、渡しているjsonデータ(payload)の

{
    "user": "guest",
    "iat": 1572051603
}

{
    "user": "admin",
    "iat": 1572051603
}

にして送信したら良さそうかなー?となる。

じゃあ改ざん検知を欺瞞するためにどうするかというと、脆弱性があるらしい。

このサイトが非常に有益だった。

https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/

header部分で検証に使用するアルゴリズム{"typ":"JWT","alg":"RS256"}から、{"typ":"JWT","alg":"HS256"}に変えて、最後のsignatureを頑張ってつくればいいとわかる。

脆弱性があるやつは、signatureの暗号化に使う鍵を、サーバーの証明書の鍵と同じにしているらしい。公開鍵なのでとりあえず手に入れて、それをwikiに従ってBase64エンコードなり色々して、Cookieを組み上げていく。 最後にCookie書き換えてリロードしたらでてくる。

CTFKIT{old_jwt_library_is_unsecure}

後でせやなってなったが、JWTを実装してるライブラリを使ったらもっと簡単に書けた(なんで自分で全部実装したんだろう...)。

おわりに

読んでいただきありがとうございました!来年もでたいな