KOSEN セキュリティコンテスト 2017 に参加したおはなし

はじめに

KOSENセキュリティコンテスト2017にPwnPwnPainとして参加してきました。
参加は2度目で、今年は去年とは打って変わって「Jeopardy」と「KoH(King of Hill)」形式でのCTFでした(去年はサーバーの脆弱性を潰すHardening的な形式?でした)。 レベル感は全体的には低めに感じましたが、まだまだ力及ばずな問題もありました。

とりあえず、備忘録、復習の記録ってのも兼ねて、競技時間中に解けた問題と、終わってから解けた問題のWriteupをカテゴリーごとにゆるーく書きたいと思います。

また、Writeupにて、出力や入力が極端に長い場合、...として省略させていただきます。

f:id:ush1ken:20171023000720p:plain

目次

Sample

00 _ サンプル _ 100

これはサンプル問題である。 今回出題される問題は、全て答えとなる「フラグ」が含まれている。
フラグは、必ずSCKOSEN{hoge}の形式になっている。
この問題のフラグはSCKOSEN{Let's enjoy}である。入力しろ。

Flag: SCKOSEN{Let's enjoy}

Binary

01 _ フラグを答えろ _ 100

正しいフラグを書けば正しいかどうかを判定してくれる、便利なアプリを開発した。
フラグを調べて解答せよ

a.outという実行ファイルが配布されるので、何も考えずにstringsコマンド...

$ strings a.out 
/lib64/ld-linux-x86-64.so.2
{e#yd
libc.so.6
puts
__stack_chk_fail
stdin
printf
strtok
fgets
strcmp
__libc_start_main
__gmon_start__
GLIBC_2.4
GLIBC_2.2.5
UH-`
SCKOSEN{H
h1dden_fH
1ag}

一応実行してみる。

# ./a.out    
Enter the FLAG: SCKOSEN{h1dden_f1ag}   
correct! the flag is SCKOSEN{h1dden_f1ag}

Flag: SCKOSEN{h1dden_f1ag}

02 _ ファイル名を探せ _ 100

フラグは簡単だ、ファイル名に隠した。

qというファイルが渡されるので、何も考えずにfileコマンド...

$ file q
q: POSIX tar archive (GNU)

tarファイルということなので、解凍。

$ tar xvf tmp 
x q/
x q/xNUMaohRhJu8EJTLRx0ivRfwXk3cc
x q/y2Ce56H56EVYwO7tWgOXo726O0uXp
x q/h14PySClySuaKQ6kxjLYWhq99ibhm
x q/2bTq1nVLWdgX6aypu018Yl84ubSsE
x q/VgiiZE4hEprvEWdLnsO4G8KbOHUTi
x q/G0wmRiMSrE1uArCttTbnd1wefAFad
x q/8Q0VABE4ellLGwRVQtb640YcDXCB2
x q/arRyqJbDkwFhzfSvDJEbpvlGYJy3q
x q/BNpv17Z6xGJhMatl91SZbU5MRErTa
...

なんかqっていうディレクトリにファイルがたくさん(18888個)でてくる。
ファイルの中には何も書かれていないので、とりあえずファイル名をbase64デコードしてみるも、Incorrect Paddingと言われる。
冷静になって考えたら、18888個の中にフラグがあるのでは、と思ってgrepしてみる。

$ ls q | grep SCKOSEN
SCKOSEN{ki_ha_mori_ni_kakuse}

Flag: SCKOSEN{ki_ha_mori_ni_kakuse}

03 _ ボスを倒せ _ 200

とあるゲームを見つけたのだが、ボスがあまりにも強すぎて一切倒せそうにない。
どうにか倒す方法はないだろうか?
ゲームへの接続方法: nc [hostname] [port] 例: nc www.ctfkit 8050

この問題は、チームメンバーが適当にBoFしようとしたら解けた問題。。
ちゃんとロジックを考えるために、競技終了間際に挙動をメモったので復習。

とりあえずncで接続。

$ nc score.kosensc2017.tech 40048
Input your name: AAAAA
Player's HP: 1000
Boss's HP: 12345678
Next round=>^Z

たぶん、最初の入力にBoFがあるんだろうなあ、と考えてAをいっぱい入れてみる。

$ nc score.kosensc2017.tech 40048
Input your name: AAAAAAAAAAAAAAAAAAAAAA 
Player's HP: 1094795585
Boss's HP: 16705
Next round=>^Z

お、減った。ということで、16075をpythonhex(16075)してみると見事'0x4141'という出力に。
ここで、入力したAは22個なので、1個減らせばボスのHPは0x41で65になるのでは、と思うものの65だとちょっとまだ強い()ので、スペースBoF。(なぜかecho -eで\x01とかが流し込めなかった、、)

$ nc score.kosensc2017.tech 40048
Input your name: AAAAAAAAAAAAAAAAAAAA 
Player's HP: 1094795585
Boss's HP: 32
Next round=>1

Round 1/10
    Player's Attack!
    Boss's HP: 21 (-11)
    Boss's Attack!
    Player's HP: 1094795419 (-166)
Next round=>
Round 2/10
    Player's Attack!
    Boss's HP: 12 (-9)
    Boss's Attack!
    Player's HP: 1094795244 (-175)
Next round=>1

Round 3/10
    Player's Attack!
    Boss's HP: 3 (-9)
    Boss's Attack!
    Player's HP: 1094795069 (-175)
Next round=>
Round 4/10
    Player's Attack!
    Boss's HP: 0 (-10)
    Boss's Attack!
    Player's HP: 1094794937 (-132)
You win!
Flag is SCKOSEN{buffer_over_flow!}

Flag: Flag is SCKOSEN{buffer_over_flow!}

04 _ OreNoFS _ 500

このファイルraw.dmgには、どうも独自のファイルシステムが構築されているらしい。 このファイルシステムに格納されたデータは1つ、そのデータを復元しよう。
このファイルシステムは、クラスタ単位で管理されており、1クラスタ=4096byteであることは分かっている。
また、AllocationTableというFATファイルシステムでいうFAT領域とディレクトリエントリ、データ格納領域に分けられているようだ。
また、GUID Partition Table(GPT)でフォーマットされているので、その分はクラスタの管理外である点に注意しなければならない。
ATは2byte*8192、ディレクトリエントリは32byteで下記の構造体で定義されているらしい。

 struct directory_entry {
         unsigned char magic;(1byte) 
         char filename[8];
         char extension[3];
         unsigned int size;(4byte) 
         unsigned long offset_of_cluster;(2byte) 
         char attribute[12];
         unsigned long reserved;(2byte) 
};

解けなかったので他の方のwriteupを読んで解きたい。。

Crypto

05 _ 簡単な暗号化2 _ 100

ファイルからフラグを探せ

チームメンバーが、1日目の夜に解いてくれた問題。

問題ファイルにアクセスすると、base64っぽい文字列がずらーっと並んでいたので、コピペして、pythonに流し込んでdecodeしてみる。

$ python
>> import base64
>> input = '''
NGI1MDA0MDMwMDE0MDgwODAwMDgyYzU2NGI1MzAwMDAwMDAwMDAwMDAwMDAwMDAw...
'''
>>> base64.b64decode(("".join(input.split('\n'))))
'4b5004030014080800082c564b53000000000000000000000000000b0000725f6c652f73722e6c65ad73dd92034a0c41ef...'
>>> len(base64.b64decode(("".join(input.split('\n')))))
8520

decodeしてみると、何かのファイルのバイナリっぽい何かが出てくる。
チームメンバーが解いたときリトルエンディアンうんぬん言っていたので、頑張ってリトルエンディアンにしてファイルに出力してみる。

>>> b = base64.b64decode(("".join(input.split('\n'))))
>>> packed = "".join([pack("<L",int("0x"+b[i:i+8], 16)) for i in range(0, len(b), 8)])
>>> "".join([pack("<L",int("0x"+b[i:i+8], 16)) for i in range(0, len(b), 8)])
'\x03\x04PK\x08\x08\x14\x00V,\x08\x00\x00\x00SK\x00\x00\x00\x00...'
>>> f = open("out", "wb")

出力したものをfileコマンドで調査。

$ file out
out: data

なんかうまくいっていない。。
また冷静になって考えてみると、先頭4バイトが\x03\x04PKとなっていて、なんかみたことあるなあ、、とggると、ZIPファイルのシグネチャ0x504B0304(PK\003\004)となっていた。
なるほど。ということで、2バイトでリトルエンディアン取り直すことに。

>>> "".join([pack("<H",int("0x"+b[i:i+4], 16)) for i in range(0, len(b), 4)])
'PK\x03\x04\x14\x00\x08\x08\x08\x00V,SK\x00\x00\x00\x00...'

お、今度はちゃんとZIPファイルと同じシグネチャになった。ということで、ファイルとして出力してみる。

>>> packed = "".join([pack("<H",int("0x"+b[i:i+4], 16)) for i in range(0, len(b), 4)])
>>> f = open("out", "wb")
>>> f.write(packed)

出力したファイルを調査すると、Microsoft社のWordファイルだということが分かるので開いてみる。

$ file out 
out: Microsoft Word 2007+
$ mv out.doc out.docx
$ open out.docx

f:id:ush1ken:20171022183858p:plain Flag: SCKOSEN{TEXT_BUT_NOT_PLAIN}

06 _ 解凍して解答せよ _ 100

ファイルからフラグを読み取れ!

flag.zipというファイルが渡されるので、解凍すると、flagというディレクトリの中にpngが2つ展開される。

$ unzip tmp.zip 
Archive:  tmp.zip
   creating: flag/
  inflating: flag/masks.png          
  inflating: flag/xor.png 

開いてみると、次のような画像が表示される。 f:id:ush1ken:20171022184929p:plain 画像をみると、xorしたらなんか得られそうだし、画像のファイル名もmasksとxorだし、ということで画像のxorをとってみる。

import cv2
masks = cv2.imread('./flag/masks.png')
xor = cv2.imread('./flag/xor.png')
flag = cv2.bitwise_xor(masks, xor)
cv2.imwrite('flag.png', flag)

f:id:ush1ken:20171022192038p:plain Flag: SCKOSEN{simple_visual_cryptography}

07 _ 簡単な符号化 _ 100

U0NLT1NFTntiYXNlNjRfaXNfdmVyeV9lYXN5fQ

base64デコードするだけ。

$ echo "U0NLT1NFTntiYXNlNjRfaXNfdmVyeV9lYXN5fQ" | base64 -D
SCKOSEN{base64_is_very_easy

Flag: SCKOSEN{base64_is_very_easy}

Network

15 _ 寝坊気味のコンピュータ _ 100

ここにある通信をキャプチャしたファイルがある。この中から、フラグを見つけ出せ!

problem.pcapngというファイルが渡されるのでとりあえずstringsコマンド...

$ strings problem.pcapng 
Linux 4.10.0-37-generic
Dumpcap (Wireshark) 2.2.6 (Git Rev Unknown from unknown)
wlp4s0
Linux 4.10.0-37-generic
SCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSESCKOSE
N{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wakeN{wake
_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la_on_la
n_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_an_is_a
1~_z
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}
lerm}

フラグっぽいのがみえるので手動で抽出。
ちなみに、Wake-on-LANパケットは、起動したいマシンのMACアドレスを16回繰り返したデータを含むそうです。
この問題では、フラグが6文字ずつMACアドレスとしてWoLパケットに埋め込まれているという問題でした。
Flag: SCKOSEN{wake_on_lan_is_alerm}

16 _ ログインしたいんだ! _ 100

ここにある通信をキャプチャしたファイルがある。この中から、フラグを見つけ出せ!

これもまたproblem.pcapngというファイルが渡されるのでまた何も考えずstringsコマンド...

$ strings problem.pcapng
...
GET / HTTP/1.1
Host: 172.27.132.124
Connection: keep-alive
Authorization: Basic YWRtaW46U0NLT1NFTntiYXNpY19pc191bnNlY3VyZX0=
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.102 Safari/537.36 Vivaldi/1.94.971.8
...

ざーっと眺めるとしたのほうにbase64っぽい文字列を発見。 よく見るとBasic認証をしているので、base64デコードしてみる。

$ echo "YWRtaW46U0NLT1NFTntiYXNpY19pc191bnNlY3VyZX0=" | base64 -D
admin:SCKOSEN{basic_is_unsecure}

Flag: SCKOSEN{basic_is_unsecure}

別解

f:id:ush1ken:20171022231009p:plain たぶんこっちが正攻法。
WireSharkなどのパケットキャプチャツールでproblem.pcapngを開くと、401 Unauthorizedで認証に何度も失敗しているHTTP通信が見られるので、認証に成功している(200 OKな)パケットを探す。
48パケット目に200 OKなパケットがあり、その直前のGET / HTTP/1.1なパケットを見ると、Basic認証の情報があるので、パスワードがフラグになっている。 f:id:ush1ken:20171022232423p:plain Flag: SCKOSEN{basic_is_unsecure}

17 _ ファイル送信 _ 200

これはファイルを送受信しているpcapです

file.pcapというファイルが与えられるので、とりあえずstrings...してもあまり嬉しい情報は見つからなかった。
素直にWireSharkで開くと、Lenna.pngと、lock.zipがHTTP通信で送受信されているのがわかる。
ということで、WireSharkFile -> Export Objects -> HTTP -> Save Allでファイルをエクスポート。

それぞれのfileコマンドの結果を見てみる。

$ file Lenna.png lock.zip 
Lenna.png: PNG image data, 512 x 512, 8-bit/color RGB, non-interlaced
lock.zip:  Zip archive data, at least v2.0 to extract

普通のファイルっぽいので、普通にunzipしてみる。

$ unzip lock.zip 
Archive:  lock.zip
[lock.zip] Lenna.png password: 
password incorrect--reenter: 
password incorrect--reenter: 
   skipping: Lenna.png               incorrect password
[lock.zip] flag.txt password: 
password incorrect--reenter: 
password incorrect--reenter: 
   skipping: flag.txt                incorrect password

普通にパスワードがかかっててunzipできない。
ここでみんなで数時間悩んだ。
「Lenna.pngにパスワードが隠されているのでは?」「TCPパケットにパスワードが隠されているのでは?」「BruteForceでパスワードクラックするのでは?」
結論からいえば、既知平文攻撃でした。
1日目終了後、おうちに帰って冷静になってctf zip パスワードとかでwriteupを適当にggっていたら、あ。これだ。

SECCON 2015 Online CTF Writeup

ということで、pkcrackをインストールし、早速実行。

$ zip Lenna.zip Lenna.png
$ pkcrack -C lock.zip -c Lenna.png -P Lenna.zip -p Lenna.png -d flag.zip
...
Done. Left with 90 possible Values. bestOffset is 298362.
Stage 1 completed. Starting stage 2 on Sun Oct 22 23:51:16 2017
Ta-daaaaa! key0=e15a792b, key1=591e8679, key2=9dee3dba
Probabilistic test succeeded for 175560 bytes.
Ta-daaaaa! key0=e15a792b, key1=591e8679, key2=9dee3dba
Probabilistic test succeeded for 175560 bytes.
Stage 2 completed. Starting zipdecrypt on Sun Oct 22 23:51:19 2017
Decrypting Lenna.png (155edefb6ebeec35536b5a3d)... OK!
Decrypting flag.txt (f38434531be49de337a96b0e)... OK!
$ cat flag.txt
SCKOSEN{k_p_t_a}

Flag: SCKOSEN{k_p_t_a}

おわりに

今回のKOSENセキュコンでは、圧倒的知識不足を感じました(毎回感じてる気がする)。
というのも、解きたい問題のメインテーマについてそこそこ知識が無いと解けない問題というものにどんどん直面してきてるように感じるので、もっと広く深く勉強したいです。
解けなかった問題についても、プロ各位のwriteupを見て勉強したいです。。

楽しい大会をありがとうございました!

ICTSC8に参加したおはなし

はじめに

今回は、ICTトラブルシューティングコンテスト第8回(以下、ICTSC8)に参加してきた(記事を書いてる今は真っ最中)ので、備忘録、そして戒めの記録としてこの記事を書きます。

ICTSC8にはEagleJumpというチーム名で参加させていただきました。

ちなみに、こういうWrite-Up的なものを書くのは初めてなので、ログなどの取り忘れが多いです。。

1日目

1日目終了時点では500点で8位/15位でした。
ちなみに1位のチームは1960点、2位920点、3位890点って感じでした。
1位圧倒的ですね。。2位3位もぉっょぃ。。

ちなみに1日目は1問も解けませんでした。。
チームメンバーにめちゃくちゃ自虐キツイって言われたんですが、自戒の念も含め、ですね。

伝統の国 第二のトラブル (ipv6環境構築)

1日目に解こうとした問題を2日目には完全に解けるように、ipv6の基礎を理解するためにおうちに帰って簡単に、思い出せる限りで同じ環境を構築してみました。

構成

時間が無かったので(帰宅22時スタート)、端末はMacBook Pro(MacOS Sierra)とRaspberryPi3(CentOS 7, 問題ではUbuntu)を使用して、ルーターは実機で892j(問題では1941?)を使用しました。
パケトレでもいいかなって思ったのですが、時間もなかったので(重要)、なんか途中までやって機能制限されてたら嫌だなって思って実機にしました。

問題は892jから1941にconfigそのまんま移植しちゃったてへぺろな的な感じだったので、完全には再現できていませんが、ipv6とNAT-PTの勉強も兼ねて、前日(当日)夜の悪あがきです。

ネットワーク図は以下のとおりです(ipv6のネットワーク図の書き方わからない)。。 f:id:ush1ken:20170830213546p:plain

fa0 設定

まず892jにRaspberryPi3(以下、rpi)に繋いでいるインターフェイスの設定を行いました。(ちょろいちょろい)

2分後…

Router(config-if)#ip address 192.168.140.2 255.255.255.0
% IP addresses may not be configured on L2 links FastEthernet0.

インターフェイスIPアドレスが割り振れない。。
どうやら892jでは(?)、LANポートはL2スイッチなので直では割り振れないよう。。

jianlan.hatenablog.com

ということで、VLAN。

Router(config)#vlan 10
Router(config-vlan)#exit
Router(config)#int vlan 10
Router(config-if)#
*Aug 26 14:12:14.083: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan10, changed state to down
Router(config-if)#ip address 192.168.140.1 255.255.255.0
Router(config-if)#no shutdown
Router(config-if)#exit
Router(config)#int fa0 
Router(config-if)#switchport access vlan 10
Router(config-if)#end

Vlan10の設定と、インタフェースへの割当が出来たので、つぎは疎通確認。

Router#ping 192.168.140.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.140.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms

できた。

gi0 設定

次はMacBookPro(macだとmacアドレスと分かりづらいので以下、mbp)に繋いでいるインターフェイスの設定を行いました。

Router(config)#ipv6 unicast-routing
Router(config)#int gi0
Router(config-if)#ipv6 address 2001:DB8:3002::9/64
Router(config-if)#no shutdown
Router(config-if)#end

これでmbp側のインターフェイスの設定が終わりましたので、あとは疎通確認。

Router#ping ipv6 <mbp ipv6 address>
Output Interface: GigabitEthernet0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::82C:2547:BBA2:48FA, timeout is 2 seconds:
Packet sent with a source address of <mbp ipv6 address>%GigabitEthernet0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/0/0 ms

できた。
gi0の場合はVLAN振らなくていいらしい。

NAT-PT 設定?

さあここからが勝負。
以下のサイトを参考にNAT-PTの設定を行っていきます。
changineer.info

まずはipv6 natのプレフィクスの設定と、vlan10とgi0のnatの設定。

Router(config)#ipv6 nat prefix 2017::/96
Router(config)#int vlan 10
Router(config-if)#ipv6 nat
Router(config-if)#exit
Router(config)#int gi0
Router(config-if)#ipv6 nat
Router(config-if)#exit
Router(config)#!ここのexitって要るのだろうか、、

つぎに、v4からv6への変換?とv6からv4への変換?
基本的に問題の(一部だけ)持ち帰ったconfigの通りに写経しただけなので、あんまり意味がわかっていない。。

Router(config)#ipv6 nat v4v6 source 192.168.140.1 2017::192.168.140.1
Router(config)#ipv6 nat v4v6 source 192.168.140.2 2017::192.168.140.2
Router(config)#ipv6 nat v6v4 source list v6-src pool v4-pool overload
Router(config)#ipv6 nat v6v4 pool v4-pool 192.168.130.1 192.168.130.1 prefix-length 24

そして、ipv6のルーティングプロトコルの設定?と、各インタフェースへの割当。
この辺も正直必要なのか必要でないのかよくわかっていない。。
今回、問題のconfigをなぜか一部しか持って返っていなかったのでルーティングプロトコルの設定とか何すれば良いんだろうみたいな感じでした。
そもそもNAT-PTだとルーティングプロトコルとか要らないんでしょうか。。

Router(config)#ipv6 router rip P1
Router(config-rtr)#exit
Router(config)#int fa0
Router(config-if)#exit
Router(config)#ipv6 router rip P1
Router(config-rtr)#exit
Router(config)#int vlan 10
Router(config-if)#ipv6 rip P1 enable
Router(config-if)#exit
Router(config)#int gi0
Router(config-if)#ipv6 rip P1 enable
Router(config-if)#exit

最後になんかaccess-listを作って割当。

Router(config)#ipv6 access-list nat_traffic
Router(config-ipv6-acl)#permit ipv6 any 2017::/96
Router(config-ipv6-acl)#exit
Router(config)#int vlan 10
Router(config-if)#ipv6 nat prefix 2017::/96 v4-mapped nat_traffic
Router(config-ipv6-acl)#exit

これで設定は終わり。。
ping等で疎通確認が出来て安心できたのかこの日は、ろくにログも取らずに午前3時に作業を終えました。

ログが取れた際のVlan10(rpi側インタフェース)と、gi0(mbp側インタフェース)、アクセスリストまわりのコンフィグと、"show ipv6 route connected"コマンドの結果を以下に載せます。

interface GigabitEthernet0
 no ip address
 duplex auto
 speed auto
 ipv6 address 2001:DB8:3002::9/64
 ipv6 nat
!
interface Vlan10
 ip address 192.168.140.1 255.255.255.0
 ipv6 enable
 ipv6 nat prefix 2017::/96 v4-mapped nat_traffic
 ipv6 nat
!
ip forward-protocol nd
!
no ip http server
no ip http secure-server
!
logging esm config
ipv6 nat v4v6 source 192.168.140.1 2017::C0A8:8C01
ipv6 nat v4v6 source 192.168.140.2 2017::C0A8:8C02
ipv6 nat v6v4 source list v6-src pool v4-pool overload
ipv6 nat v6v4 pool v4-pool 192.168.140.1 192.168.140.1 prefix-length 24
ipv6 nat prefix 2017::/96
!
ipv6 access-list nat_traffic
 permit ipv6 any 2017::/96
Router#show ipv6 route connected
IPv6 Routing Table - default - 4 entries
Codes: C - Connected, L - Local, S - Static, U - Per-user Static route
       B - BGP, HA - Home Agent, MR - Mobile Router, R - RIP
       D - EIGRP, EX - EIGRP external, ND - Neighbor Discovery
       O - OSPF Intra, OI - OSPF Inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
       ON1 - OSPF NSSA ext 1, ON2 - OSPF NSSA ext 2
C   2001:DB8:3002::/64 [0/0]
     via GigabitEthernet0, directly connected
C   2017::/96 [0/0]
     via NVI0, directly connected
     via Vlan10, directly connected

2日目

2日目、まあ気持ち悪い。 ねむい。 それでもこの日に1問でも解かなければ人権が無さそうだったので、頑張りました。

結果、前日(当日早朝)にやった問題再現が功を奏したか、伝統の国 第二のトラブルを無事満点(300点)で解くことができました。
ありがとうございました。

伝統の国 第二のトラブル (Write-Up的なもの)

以下、1問だけWrite-Up的なものです。
詳しい解説とかはまた時間があるときにでも、、()

問題

ちょっと見にくいですが、当日のUIも兼ねて、こんな感じでしたというご紹介。

f:id:ush1ken:20170830215457j:plain

初めて見る方は問題文の設定が意味不明すぎると思うのでちょっとうろ覚え解説。

我々、参加者は謎の世界に飛ばされたらしく、謎の世界の謎の国々でトラブルを解決するストーリーらしいです(かなりざっくり)。

問題は、環境構築でもあったとおり、ipv4ipv6の変換をnat-ptで行おうと思ったけど、config移植したらぶっ壊れたみたいなお話でした。

解答

以下に、実際の解答をほぼ原文でペーストします。

お疲れ様です。EagleJumpの***です。 問題14の回答を送らせていただきます。

この問題では、"ipv6 access-list v6-src"の設定ミスが原因で、IPv6からIPv4への変換が出来ず、疎通ができないというトラブルが発生していたと考えられました。

また、"ip cef"および"ipv6 cef"が有効になっていたため、パケットDropが発生していました。

以上のトラブルを解消すべく、以下のように設定を変更し、「1941のgi0/0ポートに繋いだIPv6アドレスのみを持つPCから192.168.140.1にping」が正しく通ることを確認いたしました。 ご確認のほど、よろしくお願いいたします。

v6-srcアクセスリストの編集

1941(config)#ipv6 access-list v6-src
1941(config-ipv6-acl)#no permit ipv6 1::/64 any 
1941(config-ipv6-acl)#permit ipv6 2001:db8:3002::/64 any
"ip cef"および"ipv6 cef"の無効化

1941(config)#no ip cef
1941(config)#no ipv6 cef
以上の修正を行った上で、「1941のgi0/0ポートに繋いだIPv6アドレスのみを持つPCから192.168.140.1にping」が通ったので、その結果を以下に示します。

$ ping6 2017::192.168.140.1
PING6(56=40+8+8 bytes) 2001:db8:3002::442b:59a3:1c29:e83f --> 2017::c0a8:8c01
16 bytes from 2017::c0a8:8c01, icmp_seq=0 hlim=254 time=1.686 ms
16 bytes from 2017::c0a8:8c01, icmp_seq=1 hlim=254 time=1.337 ms
16 bytes from 2017::c0a8:8c01, icmp_seq=2 hlim=254 time=1.580 ms
^C
--- 2017::192.168.140.1 ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 1.337/1.534/1.686/0.146 ms
解答は以上です。 採点のほど、よろしくお願いいたします。

この問題のキモは、アクセスリストの設定ミスだったようなので、アクセスリストを変更しました。
また、NAT-PT使用環境ではcef(Cisco Express Forwarding)はサポートされていないので、無効化する必要がある、という点が満点に繋がったのかなと思います。

まとめ

最終的なチームとしての結果は1310点?とかで、何位ぐらいなんでしょうね。。
もしこれを見てくださっているICTSC8運営の方いらっしゃいましたら、ランキングの公開ぜひお願いしたいです。。

次回は関西で開催されるのが決定されているそうですが、別のイベントで忙しそうなので出れるかは微妙ですが、日程が合えば予選参加したいです。

次はこのぐらいの問題は1日目の午前の1/2ぐらいでちゃちゃっと解いてみたいものです。。

セキュリティ・キャンプ 2017 のおはなし

はじめに

セキュリティ・キャンプ 2017 (以下、キャンプ)に参加させていただいたのでブログを開設することを決めました。
今回のブログでは、キャンプ中に起きた出来事や思ったこと(講義の内容については割愛)などを書いていこうと思います。
はじめて書くのでつたないブログになるかとは思いますが、優しい目で見ていただけると幸いです。
また、もし公開してはならない情報まで公開していた場合はコメントやTwitter(@o__g_)等にて教えていただけるとありがたいです。

目次

受けた講義

キャンプでは選択講義で以下の講義を受けました。
もし、この講義どうだった?とか、この講義楽しかったよね〜〜、とかってお話をして頂ける場合はコメントやTwitter(@o__g_)等で、連絡いただけると喜びます。

  • A1 PowerShellベースのマルウェアとその防御手法
  • A2 AIのデータ汚染を検知しよう
  • A3 AIのデータ汚染を検知しよう
  • A4 Androidマルウェアなアプリを機械学習で検知しよう!
  • A5 Availability Challenge ~サービスの可用性を確保せよ~
  • E6 インシデントレスポンスで攻撃者を追いかけろ
  • E7 インシデントレスポンスで攻撃者を追いかけろ

DAY1

初日。

この日は集合(受付)が12:00~12:30とのことだったので、途中で名刺入れとかお菓子とか買いながらのんびり向かおうと思っていました。 しかし、知り合いのチューターに早く来たほうがいいと言われたので、諸々を諦め会場に向かうことにしました。

会場に着きいろいろ手続きを済ませ、ホールへ案内されるとすでに8割ぐらい参加者が揃っていて、名刺交換会なるものが始まっていました。 ぼくはもともと人見知りなので、その場では多くの人とは名刺交換をすることができず、キョロキョロあたりを見回しながら、名前順に配置された4人1テーブルのメンバーと少し挨拶をしたりしました。

会場に着いて数分後、まだ12:30にもなっていないのに食事の案内が行われ、まだ来ていない人もいたため、早く来て良かった、、と思いました。 食堂では4人1テーブルという感じで、ホールでのテーブルのメンバーと一緒に食べました。 食事の内容等については、他の方のブログやTwitter“#seccamp”タグを検索すれば得られると思います(あとがき: カレーが結構辛かった)。

食事を終えると、結構時間が余っていたためホールに戻ると、また名刺交換会が始まり、そこでは勇気を出していろんな方と名刺を交換することができました。 名刺を持ってきていないという方も居て、その方は俗に言う「人権を失った」状態だったので、やっぱり持ってきて良かったと思いました。

名刺については、学校で用意していただいたものを持っていったのですが、やはり自分のSNSアカウントやハンドルネーム等が載った名刺も作って持ってきたほうが良かったなあと思いました。 ちゃんとした名刺(会社や学校のもの)とふざけた名刺(個人のSNSや趣味などを書いたもの)といった2種類の名刺を渡してくださった方や、片面に社用、裏面に私用の名刺を刷ってある方もいたので参考にさせていただきたいと思います。

その後は、ぉっょぃ方々によるお話や講義が約4時間弱続きましたが、前日深夜の事前課題ラストスパートに起因する集中もとい意識が朦朧としてしまったことだけをお伝えし、内容については割愛させていただきます。

講義が終わると、また食事の案内があり、食事を終えるとまたホールに戻ってきて、最後のグループワークのセッションに移りました。 グループワークでは、4つのテーマのうち1つのテーマを選んで議論し、最終日に発表するというものでした。 チーム分けは自分のテーブルの4人と隣のテーブルの4人を合わせた計8人でした。 ぼくはチームでリーダーを立候補しましたが、5日間通して大したことをやっていないので、グループワークについても詳細は、この記事では割愛させていただきます。

ここまでで、キャンプDAY1が終わり、それぞれ自室に帰ってゆっくり休みました。 ちなみに部屋の中はこんな感じでした。 なんか脱ぎ捨てられたシャツが写り込んでいますが気にしないでください。 f:id:ush1ken:20170822135321j:plain

DAY2

2日目の朝はとにかくつらかったです。

グループワークのお話を07:30から食堂でしよう!とチームメンバーと決めていたのですが、集まったものの、ほぼ全員が頭働いてなくて、議論のぎの字も無く、次に集まる日程のみを決めてあとは食事に集中することにしました。 それ以降の3日間は言うまでもなく、朝の会議はなくなりました。

食事のあとは08:30からすぐに専門講義が始まるので、それぞれの部屋に向いました。 2日目だけ専門講義(1コマ4時間)が3コマ入っていて、キツかったですが、楽しかったです。

ぼくは、2日目の昼食と夕食のときにIPAによる取材?が入っていたので、食事を急いで食べなければならず結構そこはつらかったです。

そしてこの日の夜は、22:00から疲れた身体にムチを打って()、朝やり損ねたグループワークの続きを行いました。 案の定、進捗はあまり良くなかったです。

その後、部屋に帰って次の日の講義の事前課題の発表資料を作ろうと思っていました。 しかし、某ズにて講師の方から「心配しないでください。寝てください。」とのお告げがありましたので、本能のままに眠りにつきました。 f:id:ush1ken:20170822153712j:plain

2日目に受けた選択講義は以下のとおりです。

  • A1 PowerShellベースのマルウェアとその防御手法
  • A2 AIのデータ汚染を検知しよう
  • A3 AIのデータ汚染を検知しよう

DAY3

3日目の朝もつらかったです。

この日も朝からご飯を食べ(当たり前のことですが当たり前ではない)、08:30から講義を受けるというスケジュールでした。 しかし、講義は楽しいので、そこまでストレスではありませんでしたが、やはり眠いものは眠いですね。

最初の講義では、前日に詰めようと思っていた出来かけの発表資料で発表したのですが、その講義の参加者の半分?ぐらいしか発表資料出来ていないって感じでびっくりしました。

最初の講義が終わって昼食を食べていたのですが、あまりにも眠すぎて、早く食べてお昼寝しようと思いましたが、微妙に時間が足らず断念しました。

夕食では、参加者、チューター、講師、その他という分類で、決められた座席に座り、講師の方やチューター、参加者との交流を行いました。

この日は、朝食、講義、昼食、講義、夕食と、ここまでは2日目と同じだったのですが、夕食のあとにBoF(85分)と企業プレゼンテーション(30分)、最後にグループワーク(80分)、と盛りだくさんな1日でした。

全てのセッションが22:00に終わって、それ以降は部屋に戻ってゆっくりTwitterを見る時間にしました。 すると、Twitterにて、4日目に受ける講義(E6,7)の事前課題一緒にやろう!というお誘いをいただいたので、終わってはいたものの、まだ不十分であると感じていたため、集合場所に向いました。 事前課題の続きは、以下写真の中央右下に小さく見えます、丸テーブルにて行いました。

今更ですが、今年の会場(クロスウェーブ府中)はとても綺麗で、こういった、簡単に話し合いができるような場所もあって、デザインもすごく素敵いい場所だなあと思いました。 f:id:ush1ken:20170822143744j:plain

3日目に受けた選択講義は以下のとおりです。

DAY4

4日目の朝もつらかったです。毎日朝はつらいですね。

この日も、2日目と3日目と同じく、講義2コマを朝昼夕食で挟むようなスケジュールで進んでいきました。

この日は、3日目のお昼に考えていたお昼寝大作戦を決行いたしました。
1コマ目の講義が終わり、すぐに食堂へむかい、1分たりとも時間を無駄にするなと言わんばかりに、食事を素早く済ませ、一緒のテーブルで食べていたキャンプ参加者に行って参ると一言を残し、自室へむかいました。
自室のドアになにかよくわからないヒモがかかっており、掃除のおばちゃんがお昼寝中に来ると嫌だなと思い、合鍵であけられないよう内鍵(U字ロック?)をかけ、閉まっていたはずのカーテンがなぜか開いていたので閉め、念入りにiPhoneでアラームを30分後にセットしました。 そして、眠いはずなのに覚醒している脳をなだめるよう、目をつぶり眠りにつこうとしました。

目をつぶって数分後、だんだん夢にも入ってきたなあというころ、いろんな人の話し声や笑い声の幻聴が大音量で聞こえてきました。
これはまずい、と思った頃にはもう遅く意識がハッキリしたころにはすでに金縛りにかかっていました。。
金縛りが解け、時計を見るとまだ10分しか経っていませんでしたので、また眠りにつき残りの20分で精一杯眠気を飛ばそうと思いました。
結局あとの20分も変な夢ばかり見て、30分間で眠気を覚ますこともなく、逆に疲れるような体験をしてしまいました。
そして疲れた顔で2コマ目の講義に向いました。

この日の夕食は、やけに豪華な感じでした。 しかし、豪華なだけに「なんか今日量少ないね」という声も聞こえてきました。が、ぼくは美味しかったので満足できました。 (食べかけですが、気にしないでください。) f:id:ush1ken:20170822151800j:plain

夕食のあとは、企業プレゼンテーションとグループワークがあり、BoFが無い代わりに21:00に解散となっていました。
しかし、グループワークのあとサプライズがあり、プレゼントがホールの外に並べてあるとのアナウンスがあり、会場がざわつきました。 班ごとに、プレゼントを見て回ると、そこには本やリュック、マイコンボード?などのいろいろなプレゼント(以下ツイート参照)がありました。

ぼくは、OS自作本とNN自作本を選びました。 他にもトラ技Jr.とInterfaceも全員がいただきました。 本当にありがたいです。 今後、この本を読んで、ネタにしたブログを書きたいと思っています。 ありがとうございました。 精一杯還元したいと思います。 f:id:ush1ken:20170822153138j:plain

そして、21:00からグループワークの続きをやろうかとも思いましたが、チームメンバーもみんな疲れているだろうしということで、21:00以降は残業はしませんでした。ホワイトですね。

4日目に受けた選択講義は以下のとおりです。

  • E6 インシデントレスポンスで攻撃者を追いかけろ
  • E7 インシデントレスポンスで攻撃者を追いかけろ

DAY5

最終日です。
「5日目の朝もつらかったです。」という文面を期待していた方もいたかとは思いますが、この日は朝食を犠牲にして睡眠を得ることで、多少のつらみを抑えることに成功しましたことをご報告いたします。
(本当はこの作成を2日目から使いたかったのですが、さすがに講義中にエネルギー切れになるのは避けたいので封印していました。)

集合のギリギリまで寝ていていつもよりほんのすこしだけ眠くないぼくは、急いでホールに向い、最後のグループワークを行いました。 最後のグループワークでは、資料作成を行いました。 みなさんやはりおつかれでしたが、その後なんとか発表資料を提出し、発表を無事(?)終えることが出来ました。。 他のメンバーもそうですが、身体を張って発表してくださったお二方には特に感謝したいと思います。

10班全ての発表を終えると、昼食を食べ、またホールに戻り、専門講義の成果報告のプレゼンを見ました。 専門講義ではこういうことやってたのか、こういう成果があったのかというようなことがわかったので良かったと思います。

そして最後に、ぉっょぃ方々のお言葉で閉会式が終わり、セキュリティキャンプは幕を閉じました。
と思いきや、それでは集合写真を撮りますのでということで1階フロントに集まり、最後に集合写真を取りました。 「圧倒的」「「「成長!!」」」

感想

出来事が長くなってしまったので、感想は簡潔に済ませたいと思います。

キャンプの感想を一言で、まとめるならば「足りない」です。 事前課題を行う事前期間、実際に講義を受ける5日間、そして事後の今日に至るまでを含め、圧倒的に時間が「足らない」と感じています。
なぜかというと、この約2,3ヶ月だけで講師,チューターの持っている知識を完全に得られることはほぼ不可能で、さらに言えば、5日間という短い期間では受ける講義の範疇の知識を全て得るというのは不可能だと思ったからです。

何が言いたいかというと、セキュリティ・キャンプに参加しただけでは、圧倒的成長することは出来ず(中には出来た方もいるかもしれません)、参加した後もモチベーションを継続して、勉強していくことが大事だなと感じました。

また、この5日間ではいろんな分野の知識を広く浅く学ぶことによって、以前に増して今後の学習の方向性が固まって、以前に増してモチベーションを維持することができるようになったと思います。

さらに、参加者、チューター、講師、運営の様々な方と知り合えたこのご縁を無駄にすることなく、今後もイベントに参加する、イベントを主催する、ことなどを通してイキリストの輪(元ネタ:A班グループワーク発表)を広げたいと思います。

セキュリティキャンプに関わってくださった全ての方に感謝して、自分なりにこの恩を少しずつ返していきたいと思います。
ありがとうございました。