SECCON 2013 北海道大会 writeup

チームdodododoで参加してきました。メンバーは@akiym, @lmt_swallow, @goldcard, @ayako119の4人です。
僕は全く解けなかったのですが、@goldcardさんのおかげで優勝できました。ありがとうございます。

f:id:akiym:20131204003412p:plain

チームメンバーによるwriteup

出身地チャート (エラーコードを探せ!)

アンケートのようなウェブアプリ。しかし、これはダミーだろうと見た。エラーコードというのは、HTTPのステータスコードのことだと思う。

  • 403
    • .htaccessや.htpasswordにアクセスする
    • nrm044____________
    • (アプリ側に対して不正なリクエストを送ると403が返ってくるが、アプリはダミーなので。)
  • 404
    • 適当にアクセスするだけ
    • ______kfou6s______
  • 405

flag: nrm044kfou6sf0nor6

デコードせよ

@ayako119さんのwriteupの補足。
このQRコードは少し特殊で、読み込めないQRコードリーダーもあるので注意。しかし、スマートフォンで十数枚のQRコードを読むのは少し大変である。さらにQRコードが100個くらいになってくると人力では無理なので、後出しジャンケンになってしまうが、スマートな解法を考えてみた。
(なぜこんなことをするかというと、ASIS CTF Writeup PPC/Code&Code - nk0t's diaryを思い出したため)

QRコードの読み込みにはzxingというライブラリが便利で、さらにコマンドラインツールもついてくる。今回はこれを使う。また、QRコードはアニメーションGIFになっているためそれを分解する必要がある。実は意外にも簡単で、2ステップで済む。

% convert +adjoin qrmono.gif qr.png
% zxing qr-{0..15}.png | base64 -D | base64 -D
USAGI NO UNAJI
UWAGI NO URAJI
UNAGI NO UMAMI
UNAGI NO GENKI
THE FLAG IS UNAGINOJUMONTAISOU

ちなみに、妨害コンテンツとして「うなぎのじゅもん体操」が流れていたが、踊る余裕はなかった。

以下、解けなかった問題

パスワードを答えなさい

binaryの問題。競技中はまったくバイナリが読めなかった。。ということで、さっき読んでみたら、割と簡単だった。これはもったいない。

use strict;
use warnings;

my @a1 = (0xde, 0xed, 0xbe, 0xef);
my @a2 = (0xba, 0xdc, 0xab, 0x1e, 0xc0, 0xed);

my @b1 = qw(
    C6 01 0F 2F 87 26 94 CF  80 18 43 C0 B3 92 E7 A4
    39 72 0B 85 23 95 B9 E2  1D 69 70 EC 2A 34 FA 4B
    4D F0 42 F7 4A 00 C9 36  5A 8E 05 0D AE D2 A3 66
    98 DB B4 6E 9A 08 3E EE  96 81 55 06 AC F9 6B 88
    24 F4 E8 63 7D DF 89 F3  A5 8D 90 74 97 FD AA 99
    B1 83 59 F5 D6 9D 7E 5B  8A E3 6C 6F 67 82 78 7F
    B7 3A B0 5D D0 76 DA 44  29 5E C3 3F DC BB 75 A6
    58 65 A1 2B E1 A0 79 7C  77 B6 14 CE A8 4F 52 31
    0A 9B 35 F1 A2 60 27 84  4C 86 9F 93 19 1C FB 8F
    28 8B FC CC CA F8 46 EA  EF AF 10 D9 56 7B B8 E9
    1B 0E C5 71 BF 3B E4 04  2D 09 53 02 2C DE 62 11
    D8 51 48 57 07 25 12 9C  8C FF 7A 1E A7 FE E6 BE
    B5 03 17 3C E5 AB BC CB  1F C4 68 C2 30 54 BA 22
    B2 CD 6D 49 6A AD A9 0C  DD D7 BD 37 C7 F2 ED 38
    40 13 16 61 33 73 4E 1A  5C 41 2E 15 C8 91 EB 3D
    45 E0 F6 50 C1 D1 9E 32  D5 47 D3 5F 64 D4 21 20
);
@b1 = map { hex } @b1;
my @b2 = qw(
    73 B5 C4 BC 6C E0 FB 15  1F 26 06 E1 04 7B 3B 3E
    08 F9 84 9E 5A DF 34 8C  3D 8A 47 D9 64 E9 F3 F1
    13 69 D2 50 C1 1A B3 AF  30 39 83 74 C9 70 18 95
    61 CD 4F 49 16 E3 6F 24  D8 0A 1E C8 C5 4E A8 BA
    46 0C FF C7 1D 85 3F E6  0F 19 C3 0D D7 A9 C6 5E
    2B B0 62 D4 EA BD 76 97  71 8F 31 A4 4D 92 4C 7D
    7C 4B EE 72 9A EB 17 53  FD 0B AB 2A 88 BE 99 54
    D1 68 11 8E B9 2E A2 EF  91 E2 5B D3 AE 42 D6 CC
    03 32 9C 87 DE 20 AD 9B  9F DA 7A 59 A5 58 B4 43
    A1 EC 56 12 DD F4 67 2C  0E 23 7E 6B B6 4A 3A 25
    F2 3C 81 51 41 78 60 01  98 FE 5F 27 1B 44 89 2D
    A3 21 79 AC A6 82 9D FC  F6 C0 B2 00 8B 29 6E E5
    35 ED D5 55 09 8D 75 F8  E7 77 F0 F5 E4 38 BF B8
    48 A0 28 33 65 45 02 36  22 CA F7 CE 7F 1C 66 CB
    05 80 93 DC 63 10 07 B7  D0 B1 14 E8 CF 6A 37 2F
    A7 94 AA 57 40 BB 6D 90  86 52 5D FA 96 DB C2 5C
);
@b2 = map { hex } @b2;

my @password = (0x9a, 0x2b, 0x88, 0x0f, 0x12, 0x62, 0x28, 0x60, 0x86, 0x3c, 0x13, 0xa2);

for my $i (0 .. scalar(@password) - 1) {
    my $d = find_index($password[$i], @b2);
    $d ^= $a2[$i % 6];
    my $c = find_index($d, @b1);
    $c ^= $a1[$i % 4];
    print chr $c;
}
print "\n";

sub find_index {
    my ($c, @xs) = @_;
    my $i = 0;
    while ($i < scalar @xs) {
        if ($c == $xs[$i]) {
            return $i;
        }
        $i++;
    }
}

flag: sUbstItUtIOn

パスワードを得よ

OSイメージの中のaというプログラムを解析し、パスワードを得よ。

@potetisenseiによると、ただa.hrbをndisasmして読むだけでいいらしい。
hrbファイルがどのような構造になっているかは以下を参考にした。offset +0x36からコード領域みたいだ。
1.NASK環境からの解脱 - Project_Rena_( unofficial plan : shoko ) - Seesaa Wiki(ウィキ)

00000053  6A50              push byte +0x50
00000055  E89800            call 0xf0
00000058  0000              add [bx+si],al
0000005A  6A61              push byte +0x61
0000005C  E89100            call 0xf0
0000005F  0000              add [bx+si],al
00000061  6A73              push byte +0x73
00000063  E88A00            call 0xf0
00000066  0000              add [bx+si],al
00000068  6A73              push byte +0x73
0000006A  E88300            call 0xf0
0000006D  0000              add [bx+si],al
0000006F  6A77              push byte +0x77
00000071  E87C00            call 0xf0
00000074  0000              add [bx+si],al
00000076  6A6F              push byte +0x6f
00000078  E87500            call 0xf0
0000007B  0000              add [bx+si],al
0000007D  6A72              push byte +0x72
0000007F  E86E00            call 0xf0
00000082  0000              add [bx+si],al
00000084  6A64              push byte +0x64
00000086  E86700            call 0xf0
00000089  0000              add [bx+si],al
0000008B  83C420            add sp,byte +0x20
0000008E  6A3A              push byte +0x3a
00000090  E85D00            call 0xf0
00000093  0000              add [bx+si],al
00000095  6A20              push byte +0x20
00000097  E85600            call 0xf0
0000009A  0000              add [bx+si],al
0000009C  6A48              push byte +0x48
0000009E  E84F00            call 0xf0
000000A1  0000              add [bx+si],al
000000A3  6A61              push byte +0x61
000000A5  E84800            call 0xf0
000000A8  0000              add [bx+si],al
000000AA  6A52              push byte +0x52
000000AC  E84100            call 0xf0
000000AF  0000              add [bx+si],al
000000B1  6A49              push byte +0x49
000000B3  E83A00            call 0xf0
000000B6  0000              add [bx+si],al
000000B8  6A62              push byte +0x62
000000BA  E83300            call 0xf0
000000BD  0000              add [bx+si],al
000000BF  6A4F              push byte +0x4f
000000C1  E82C00            call 0xf0
000000C4  0000              add [bx+si],al
000000C6  83C420            add sp,byte +0x20
000000C9  6A74              push byte +0x74
000000CB  E82200            call 0xf0
000000CE  0000              add [bx+si],al
000000D0  6A65              push byte +0x65
000000D2  E81B00            call 0xf0
000000D5  0000              add [bx+si],al
000000D7  6A4F              push byte +0x4f
000000D9  E81400            call 0xf0
000000DC  0000              add [bx+si],al
000000DE  6A53              push byte +0x53
000000E0  E80D00            call 0xf0
000000E3  0000              add [bx+si],al
000000E5  E81400            call 0xfc
000000E8  0000              add [bx+si],al

そのままだった。"Password: HaRIbOteOS"になる。

flag: HaRIbOteOS

Are you Smart?#01

04C4E4C454B4C44450
E2323265B5D6DC35CF

考えたけど、よくわからなかった。競技中はxorを取ってみたりと考えてみたがうまくいかない。結局どのチームも解けなかった。出題者によると数分で作成した問題なので簡単らしい。しかし、残念ながらSmartになれなかった。
ふと思いついて文字列同士でorを取ってみたところ"u6s6w6w5w5F6Gw75wv"と出てきた。何か関係がある…?

追記:

@shiracamusさんからTwitterにて『「0E 0F コード」でググったらそれっぽいのが…』とのこと(コメントにも)。ありがとうございます。
縦読みして、EBCDIC縦読みは考えていたが、EBCDICだとは気づかなかった。

echo -en "\x0E\x42\xC3\x42\xE3\x42\xC6\x45\x5B\x45\xBD\x46\xCD\x4C\x43\x45\x5C\x0F" | iconv --from-code=IBM930 --to-code=UTF-8
CTF大会開催中

flag: CTF大会開催中


それでは全国でお会いしましょう。