2014/12/06 09:00 JSTから2014/12/07 17:00 JSTに行われたSECCON 2014オンライン予選に参加しました。今回は一人で参加してみました。
それでは挑戦した問題について書いていきます。


解けた問題

Welcome to SECCON (Start 100)

いわゆる練習問題。何も考えずに提示されたフラッグテキストを入力するだけ。
フラッグテキスト: SECCON{20141206}

Easy Cipher (Crypto 100)

謎の数値列が渡されるのでそれを解読。

87 101 108 1100011 0157 6d 0145 040 116 0157 100000 0164 104 1100101 32 0123 69 67 0103 1001111 1001110 040 062 060 49 064 100000 0157 110 6c 0151 1101110 101 040 0103 1010100 70 101110 0124 1101000 101 100000 1010011 1000101 67 0103 4f 4e 100000 105 1110011 040 116 1101000 0145 040 1100010 0151 103 103 0145 1110011 0164 100000 1101000 0141 99 6b 1100101 0162 32 0143 111 1101110 1110100 101 0163 0164 040 0151 0156 040 74 0141 1110000 1100001 0156 056 4f 0157 0160 115 44 040 0171 1101111 117 100000 1110111 0141 0156 1110100 32 0164 6f 32 6b 1101110 1101111 1110111 100000 0164 1101000 0145 040 0146 6c 97 1100111 2c 100000 0144 111 110 100111 116 100000 1111001 6f 117 63 0110 1100101 0162 0145 100000 1111001 111 117 100000 97 114 0145 46 1010011 0105 0103 67 79 1001110 123 87 110011 110001 67 110000 1001101 32 55 060 100000 110111 0110 110011 32 53 51 0103 0103 060 0116 040 5a 0117 73 0101 7d 1001000 0141 1110110 1100101 100000 102 0165 0156 33

これが渡される数値列。正体は2進数、8進数、10進数、16進数で表されたASCIIコード。10進数なのか16進数なのか判別しづらいものはあるものの愚直に文字コードとにらめっこしながら解読してフラッグテキストを入手。
フラッグテキスト: SECCON{W31C0M 70 7H3 53CC0N ZOIA}

Shuffle (Binary 100)

実行するたびに出力結果の変わる実行ファイルが与えらえる。デコンパイラにかけるとmain部分にシャッフルされる前のデータ列が存在していたのでそれを取り出してフラッグテキストとして入力。
フラッグテキスト: SECCON{Welcome to the SECCON 2014 CTF!}

Reverse it (Binary 100)

謎のバイナリファイルが与えられる。見たところタイトル通りにデータ列が逆転されたJPEGファイルのようで、各データが上位4bitと下位4bitが逆転されており、さらにデータ列の並びも逆転しているので再逆転して画像ファイルに復号。画像ファイルを開くとさらに左右反転されていたので読みやすいよう左右反転してフラッグテキスト入手。
フラッグテキスト: SECCON{6in_tex7}

QR (Easy) (QR 200)

Easyという割には苦しめられた問題。QRコードの断片が焼きこまれたホットケーキの画像が渡される。しかし、左半分は食べられているので残った右半分から内容を復元しなければならない。基本的に右側にデータ部があるので、まずは右上のマーカーをもとにQRのマスクパターンを予測し、左側部分のマーカーを補ったうえでQRリーダーソフトに噛ましてフラッグテキストを入手。

復元したQR 復元したQR

フラッグテキスト: SECCON{PSwIQ9d9GjKTdD8H}

SECCON Wars: The Flag Awakens (QR 300)

ある動画へのリンクが与えられる。動画の内容はSECCONの説明をSTAR WARS風に行っている動画で、中盤あたりからQRコードが流れてくるもSECCONのロゴが邪魔をしてまともに読み取れない状況。動画ファイルをダウンロードし、ffmpegで静止画として書き出したのちにRalphaでQRコードが表示されている部分のみにトリミングし、ImageMagickで連結してQR部分を抽出。これをQRリーダーに入力してフラッグテキストを入手。

QRコード QRコード

フラッグテキスト: SECCON{M4Y 7H3 F0RC3 83 W17H U}

Get the key.txt (Forensics 100)

バイナリファイルが渡される。おそらくファイルシステムの一部でバイナリエディタで眺めると複数のディレクトリエントリと大量のダミーフラッグテキストが存在していた。目的となるkey.txtのエントリが最後尾にあったため、おそらく最後にあるフラッグテキストが本物だろうという推測で入力すると正解だった。
フラッグテキスト: SECCON{@]NL7n+-s75FrET]vU=7Z}

Choose the number (Programming 100)

あるサーバへのホストとポート番号を渡される。Telnetでアクセスすると数列とその中での最大値か最小値を問われる。回答すると次の問題が出題される。手動でも解けなくはないがプログラムを書いて自動で解かせた。時間の都合上非常に適当なコードになっている。

NumSearch.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import java.io.*;
import java.net.Socket;
 
public class NumSearch {
    public static void main(String[] args) throws IOException {
        Socket target = new Socket("HOSTNAME", 31337);
        BufferedReader input = new BufferedReader(new InputStreamReader(target.getInputStream()));
        BufferedWriter output = new BufferedWriter(new OutputStreamWriter(target.getOutputStream()));
        long[] nums = null;
        while(true) {
            String line1 = input.readLine();
            System.out.println(line1);
            if(line1.contains("Congratulations!")) {
                break;
            }
            StringBuffer line2 = new StringBuffer();
            char c;
            do {
                c = (char)input.read();
                line2.append(c);
            } while(c != '?');
            line2.append((char)input.read());
            System.out.print(line2);
 
            if(line1.contains(", ")) {
                String[] data = line1.split(", ");
                nums = new long[data.length];
                for(int i = 0; i < data.length; i++) {
                    nums[i] = Long.parseLong(data[i]);
                }
            }
            if(line2.toString().contains("maximum")) {
                long max = nums[0];
                for(long i: nums) {
                    if(i > max) {
                        max = i;
                    }
                }
                output.write(String.valueOf(max));
                output.flush();
                System.out.println(String.valueOf(max));
            } else if (line2.toString().contains("minimum")) {
                long min = nums[0];
                for(long i: nums) {
                    if(i < min) {
                        min = i;
                    }
                }
                output.write(String.valueOf(min));
                output.flush();
                System.out.println(String.valueOf(min));
            }
        }
        char c;
        int count = 0;
        do {
            c = (char)input.read();
            System.out.print(c);
            count++;
        } while(c != '}');
    }
}

フラッグテキスト: SECCON{Programming is so fun!}

Get the key (Network 100)

パケットキャプチャデータが渡される。内容を見るとあるFTPサーバにアクセスしている様子のダンプで、BASIC認証の部分に認証データ(user:passwordの形式でBASE64エンコードしたもの)が残っていたのでそれを利用してFTPサーバにログインしフラッグテキストを入手。
フラッグテキスト: SECCON{Basic_NW_Challenge_Done!}


解けなかった問題

Decrypt it (Easy) (Crypto 200)

暗号化用の実行ファイルと暗号化されたフラッグテキスト画像が渡される。デコンパイラにかけてみると実行時の時間をもとに乱数を生成して元データに対してビット演算をしているようだけれどうまく解読できず。

Let’s disassemble (Binary 200)

とあるサーバへのホストとポート番号を与えられる。Telnetでアクセスすると8bitな16進数が与えられて入力を求められる。おそらくこれをマシン語として解釈して内容を入力するのだろうけれどそういった分野は詳しくないのでパス。

Bleeding “Heartbleed” Test Web (Web 300)

一時期大騒ぎになったOpenSSLの脆弱性がテーマな問題。あるWebサイトが提示されており、アクセスするとHeartbleedのチェック用サイトだった。試しに脆弱性のあるサーバを用意してクエリとして与えてみるも漏れ出たメモリダンプが表示されるだけだった。あるタイミングでSQLのデータベースエラーが表示されていたのでうまくメモリ内容にSQLインジェクションを含んで攻撃すればよかったのかもしれない。

Binary Karuta (Web 500)

バイナリカルタ。100回連続で正解すればいいようだけれど詳しくない分野なのでパス。

BBQR (QR 400)

また断片のQRコードが与えられる。SECCONではQRコードを焼いたり食べたりすることが日常茶飯事なのだとか。今回は左半分だけ残っているため、データ部分はほとんど存在していない。誤り訂正レベルなどは分かるけれども、誤り訂正符号と一部データ部のみで元データを復号しなければならない。誤り訂正のロジックは詳しく知らないのでパス。

Read it (Forensics 300)

謎のバイナリファイルが渡される。シグネチャなどからおそらくWord Perfectに関連するデータであると推測したけれども、ビューアやコンバータで扱えず。

UnknownFS (Forensics 400)

謎のファイルシステムのダンプを渡される。FATのようではないかというヒントはあるけれどもGPT形式であるということ以外よくわからなかった。この問題については唯一正解者がいないらしい。

Confused analyte (Forensics 500)

マルウェアが渡される。これを解析し、フラッグテキストを入手せよという内容だけれど、仮想マシン内で解析しようとするもうまくいかず。IOC(Indicator of Compromise)という考え方を知ることができた。

The Golden Gate (Programming 400)

BASE64エンコードされたデータと電子工作で作られたエンコードボードの画像が与えられる。エンコードボードにはNANDゲートチップなどが載っており、8つの入力ボタンと8つのLEDがついていたことからエンコードさえたデータのデコーダ回路と推測されるが、電子工作はそこまで詳しくないためパス。

Get from curious “FTP” server (Network 300)

制限の強いFTPサーバからフラッグテキストを入手せよという問題。LISTコマンドなどが使えず、キーファイルを探す方法が思い浮かばなかった。


終えてみて

今回は一人でどこまでやれるか試したいと思ったので一人で参加したけれど、やはり得意でない分野を補助してもらえなかったりと一人でやることの辛さを感じた。QR系統は意外と楽しかったけれどフォレンジクス関係がボロボロなのが残念。
次回以降機会があれば再度チームでやってみたい。