Trend Micro CTF 2018 Write-up

Trend Micro CTF 2018とは

Trend Micro CTF 2018 – Raimund Genes Cupは、 安全なデジタル社会の実現を目指す トレンドマイクロが主催する、 サイバーセキュリティに関する 第4回目の世界的な競技大会です

www.trendmicro.com

成績

自分はMisc100, Misc200を解き,300点獲得しました. f:id:satto1237:20180916161702j:plain

Write-up

Misc100

Category: Misc
Points: 100
Brave Challenger, welcome!

I will hand you the flag, just not on a silver platter. Closely analyze the file, peel it back layer by layer, examine it byte by byte and the flag will reveal itself.

Follow the rabbit hole, the flag is hiding at the end of the tunnel!

Get your hands dirty! Whip out all your tools! Use your hex editor! But also be careful my brave challenger, for it might blow up in your face.

Good Luck!

f:id:satto1237:20180916162526p:plain

アプローチ:これ系の問題はforemost + binwalk

とりあえず EATME.pdf が渡されるので strings してみると

> strings EATME.pdf | grep flag.txt
flag.txtUT

flag.txtが埋め込めれていることが分かるので, foremost してあげます.
./output/zip/00001462.zip を得ることができるのでunzipします.

> unzip 00001462.zip
Archive:  00001462.zip
Boooooom!
flbn.txt:  mismatching "local" filename (galf.txt),
         continuing with "central" filename version
  inflating: flbn.txt

しかし,微妙にunzipが失敗する(flbn.txtのせい)のでbinwalkを使います.

> binwalk -e  00001462.zip                                                                                                                                                   

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Zip archive data, at least v2.0 to extract, compressed size: 41, uncompressed size: 200, name: flag.txt
4220981       0x406835        End of Zip archive, comment: "Boooooom!"
4221083       0x40689B        Zlib compressed data, default compression
4221165       0x4068ED        Unix path: /Type/Metadata/Subtype/XML>>stream
4221317       0x406985        Unix path: /www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://p
4222198       0x406CF6        Zlib compressed data, default compression
4222644       0x406EB4        Zlib compressed data, default compression

./_00001462.zip.extracted/flag.txt を得ることできました.
flag.txtTMCTF{QWxpY2UgaW4gV29uZGVybGFuZA==}です.
因みにQWxpY2UgaW4gV29uZGVybGFuZA==base64Alice in Wonderlandです.

Misc200

Category: Misc
Points: 200
If you look at that Constellation the sky will open

Traffic Traffic Traffic...

this is really strange ...

hour 1...

hour 2...

hour 3...

where is the data!!!!!? AAAAAAAAAAA ...

lets take a look to the night and see if we can plot something....
Hint 1 REVERSE THE CASES - if you think the flag is in uppercase, try lowercase. If you think the flag is in lowercase, try uppercase.

アプローチ:pcap(ICMP)からデータ抽出+可視化

この問題ではtraffic.pcapproc.pyが渡されます.

まずtraffic.pcapに注目すると,ICMPで何かやってそうなことに気づきます(他のプロトコルTLSv1なので読めない) f:id:satto1237:20180916170607p:plain

ICMPのデータ部を確認すると座標のような値が流れていることに気づきます.
f:id:satto1237:20180916171152p:plain

データを抽出するためにwiresharkicmp.type == 8(ICMPのrequestのみ)というフィルタをかけて一旦pcapで保存します(icmp.pcap).
tsharkを使ってデータを抽出します.

> tshark -r  icmp.pcap -T fields -e data.data

34:2e:34:38:36:39:31:30:2c:33:2e:30:30:30:30:36:30
34:2e:32:30:35:34:31:30:2c:31:2e:34:34:30:30:30:30
33:2e:38:31:31:36:37:30:2c:30:2e:35:30:39:36:35:30
31:2e:30:32:37:32:39:30:2c:33:2e:30:33:38:35:38:30
32:2e:37:37:38:30:32:30:2c:30:2e:30:30:38:33:31:30
35:2e:39:37:37:30:36:30:2c:32:2e:35:32:35:32:31:30
34:2e:31:31:32:39:33:30:2c:34:2e:34:38:30:31:32:30
37:2e:30:31:31:39:37:30:2c:33:2e:30:32:37:31:37:30
36:2e:35:31:30:34:36:30:2c:32:2e:39:33:30:33:30:30
36:2e:39:39:38:36:31:30:2c:32:2e:35:32:37:38:35:30
34:2e:38:30:34:30:31:30:2c:35:2e:30:31:33:39:37:30
37:2e:30:37:33:32:34:30:2c:33:2e:35:33:37:36:31:30
33:2e:38:32:31:37:34:30:2c:30:2e:30:30:30:37:30:30
33:2e:35:36:38:31:36:30:2c:34:2e:39:39:37:30:35:30
...

ここで抽出したデータを適当なスクリプトを書いて座標データに変換します.

import codecs

fr = open('hex.txt','r')
fw = open('test_2.txt','a')
for row in fr:
    hex = ''.join(row.strip().split(':'))
    print(hex)
    text = codecs.decode(hex, 'hex_codec').decode('utf-8')
    print(text)
    fw.write(text + '\n')

fr.close()
fw.close()

多分xxd -p -rをうまく使うとワンライナーで書けると思う
のですが改行周りがめんどくさくなってスクリプト書きました.

座標データを抽出できたのでtraffic.pcapと一緒に渡されたproc.pyを確認します.

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()  # for plot styling
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
from numpy import genfromtxt

#humm, encontre este codigo en un servidor remoto
#estaba junto con el "traffic.pcap"
# que podria ser?, like some sample code 

_data2 = np.genfromtxt('test_2.txt', delimiter=',')
db = DBSCAN(eps=10000, min_samples=100000).fit(my_data2)
labels = db.labels_
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
          for each in np.linsspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):   
    class_member_mask = (labels == k)
    xy = X[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=14)
             

             
#NOTE: what you see in the sky put it format TMCTF{replace_here}
#where "replace_here" is what you see
plt.title('aaaaaaaa: %d' % n_clusters_)
plt.show()

コメントを読むとICMPから得た座標データを投げてあげると文字が浮かび上がり,それがflagになるようです.
早速実行しようとしますが,いくつかのエラーがでて実行できません(未定義の変数の使用,DBSCANのimport, DBSCANパラメータの不適切な設定).
そのため,以下のように書き直します.

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()  # for plot styling
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
from numpy import genfromtxt
from sklearn.cluster import DBSCAN

#humm, encontre este codigo en un servidor remoto
#estaba junto con el "traffic.pcap"
# que podria ser?, like some sample code

# _data2 = np.genfromtxt('test_2.txt', delimiter=',')
my_data2 = np.genfromtxt('test_2.txt', delimiter=',')
#eps=10000, min_samples=100000
db = DBSCAN().fit(my_data2)
labels = db.labels_
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
          for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
    class_member_mask = (labels == k)
    # xy = X[class_member_mask & core_samples_mask]
    xy = my_data2[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=14)



#NOTE: what you see in the sky put it format TMCTF{replace_here}
#where "replace_here" is what you see
plt.title('aaaaaaaa: %d' % n_clusters_)
plt.show()

上記のプログラムを実行すると以下のような画像を得ることができます.

f:id:satto1237:20180916174022p:plain

直感で左右反転させます.

f:id:satto1237:20180916174440p:plain

FLAG:1と読めますね.
問題文のヒントに従うと,TMCTF{flag:1}が得られます.

今回の問題とはあまり関係ないですが,DBSCANは密度ベースのクラスタリングアルゴリズムです.
以下の動画が参考になると思います.

www.youtube.com

まとめ

  • 全体的に難しくて簡単な問題しか解けなかった
  • 今回もBinary問題から逃げてしまった
  • Analysis-offensive100で変な音をずっと再生してたら具合悪くなった上に結局解けなかった
  • 0完は回避できたので良かった(CBCTFの悲劇を繰り返さずにすんだ)

CyberRebeatCTF2018 Write-up

CyberRebeatCTFとは

ennach.sakura.ne.jp

CyberRebeatは、サークルE.N.Nachが制作したノベルゲームのタイトルです。 この作品はサイバーセキュリティや、ハッカー、CTFなどを題材としており、 その題材の珍しさや高いクオリティが評価され、日本国内で各種の賞を受賞しました。 本イベントは当該作品の英語版がSteamにてリリースされたことを記念して、より多くの方にCTFを楽しんでいただこうと企画されました。

成績

1人で参加してこんな感じでした.
32位/177チーム(参加人数:270人)

f:id:satto1237:20180909160550p:plain

f:id:satto1237:20180909210959p:plain

[Exercise]

Exercise

CRCTF{CyberRebeatCTF}

CRCTF{CyberRebeatCTF} を提出するだけです.

[Crypto]

Rotation

P4P6S{9RN4RUNPXR45}

アプローチ:rot13 -> 換字式暗号
問題文的にrot13だと思ったのでrot13してみるとC4C6F{9EA4EHACKE45}になります.
次に数字は換字式暗号っぽいなと思ったので4 -> R, 6 -> T, 9 -> W, 5 -> S に変換します.
最終的にflagCRCTF{WEAREHACKERS}になります.

[Misc]

Readme

Readme.

f:id:satto1237:20180909162549j:plain

アプローチ:Electroharmonixを頑張って読む
image.jpgを見るとElectroharmonixというフォントを使ったものだと分かるので下記のサイトの変換表?を見ながらflagを読み解きます.
最終的なflagCRCTF{YOUCANPLAYCYBERREBEATINBOTHLANGUAGES}です.

www.dafont.com

[Programming]

Calculation

nc 59.106.212.75 8080

アプローチ:Pythonで自動化
nc 59.106.212.75 8080をすると四則演算が降ってくるタイプので問題です.
手でやるのはめちゃくちゃしんどいのでPythonで自動化します.
20問解くとflagがでます.
CRCTF{She calls herself a human calculator}

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(('59.106.212.75', 8080))

def read():
    res = s.recv(4096).decode('utf-8')
    # print(res)
    return res

for i in range(100):
    print('count: {}'.format(i))
    res = read()
    problem = res.split('\n')[0]
    print(problem)
    if res == '\ufeff':
        continue
    ans = str(eval(problem))
    s.send(ans.encode('utf-8')+b'\n')
    print(ans)

Prime Factor

Answer the maximum prime factor.
nc 59.106.212.75 8081
example:
Question:120
Answer:5 (Prime Factors: 2, 3, 5)

アプローチ:そこそこ速い素因数分解アルゴリズムを使う
基本的な流れはCalculation と同じですが,弱い(遅い)素因数分解アルゴリズムを使うと計算が終わらないので注意する必要があります.
自分はsympyというPythonのライブラリを使いました.
25問解くとflagがでます.
CRCTF{I'm a calculating type by nature.}
Number Theory — SymPy 1.2 documentation

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from sympy import factorint
from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(('59.106.212.75', 8081))

def read():
    res = s.recv(4096).decode('utf-8')
    # print(res)
    return res


for i in range(100):
    print('count: {}'.format(i))
    res = read()
    print(res)
    if res == '\ufeff':
        continue
    number = res.split('\n')[0]
    print(number)
    prime_dict = factorint(int(number))
    ans = str(max(prime_dict.keys()))
    print(ans)
    s.send(ans.encode('utf-8')+b'\n')

Visual Novels

nc 59.106.212.75 8082
あるユーザーは"Reading Power"を持っている。
これはVisualNovelを月にどのくらい読めるかを示している。
彼がたくさんのVisualNovelを持っているとき、彼はどの組み合わせでプレイすればその月の満足度を最大にできるか。
最大の満足度を答えよ。

example:
Reading Power = 30
Games([size, satisfaction]) =
[10, 1],
[21, 2],
[12, 3],

Answer : 4

アプローチ:パースしてDPする
基本的に前の2問と同じですが,典型的なナップサック問題を解く必要があるので条件をパースしてDPします.
10問解くとflagがでます.
CRCTF{Believe in the high efficiency processor installed in your head.}

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from socket import *
import re
import numpy as np

s = socket(AF_INET, SOCK_STREAM)
s.connect(('59.106.212.75', 8082))

def read():
    res = s.recv(4096).decode('utf-8')
    # print(res)
    return res

def dp(power, sizes, satisfactions):
    dp_table = [[0 for j in range(power + 2)] for i in range(len(sizes))]
    backtrack = [[0 for j in range(power + 2)] for i in range(len(sizes))]

    # initialization
    for y in range(power + 1):

        if sizes[0] <= y + 1:
            dp_table[0][y] = satisfactions[0]
            backtrack[0][y] = 1
        else:
            backtrack[0][y] = 0

    # DP construction
    for k in range(1, len(satisfactions)):
        for y in range(power + 1):
            if y - sizes[k] < 0: # out of range
                dp_table[k][y] = dp_table[k - 1][y]
                backtrack[k][y] = 0
                continue
            left = dp_table[k - 1][y]
            right = dp_table[k - 1][y - sizes[k]] + satisfactions[k]
            if left < right: # update
                dp_table[k][y] = right
                backtrack[k][y] = 1
            else:
                dp_table[k][y] = left
                backtrack[k][y] = 0

    argmax = []
    prev = backtrack[len(satisfactions) - 1][power - 1]
    argmax.append(prev)

    tmp_power = power - 1

    for k in range(len(satisfactions) - 2, -1, - 1):
        if prev is 1: # case previous item was selected
            tmp_power -= sizes[k + 1]
            prev = backtrack[k][tmp_power]
        else:
            prev = backtrack[k][tmp_power]
        argmax.append(prev)
    argmax.reverse()

    # print(dp_table)
    # print(backtrack)
    print(argmax)
    arr_argmax = np.array(argmax)
    arr_satisfactions = np.array(satisfactions)
    ans = np.dot(arr_argmax, arr_satisfactions)

    print(ans)
    return ans


for i in range(100):
    print('count: {}'.format(i))
    sizes = []
    satisfactions = []
    res = read()
    if res == '\ufeff' or res == '\n':
        continue

    print(res)
    lines = res.split('\n')
    for line in lines:
        if 'Power' in line:
            power = int(line.split(' ')[-1])
        if '?' in line:
            break
        if line.count(',') > 1:
            num_list = [ x for x in re.split('[, ]', line) if len(x) > 0]
            sizes.append(int(num_list[0][1:]))
            satisfactions.append(int(num_list[1][:-1]))
    ans = str(dp(power, sizes, satisfactions))
    s.send(ans.encode('utf-8')+b'\n')
    print('send')

[Recon]

Tweet

Let's check our official twitter account!

アプローチ:Twitterを見に行く
CRCTF{CyberRebeatCTF_has_started!}

CyberRebeatScripts

Do you know Github?

アプローチ:Githubリポジトリを見に行く
delete FLAGというcommitがあるので編集差分を確認します.
CRCTF{I cut down her gag in a single strike}

github.com

ChangeHistory

I changed my history on Github!

アプローチ:gitの使い方のお勉強

当該リポジトリに行ってみると怪しいissueがたってる.

github.com

とりあえずgit cloneしてgit loggit reflogをしてみるが手がかりなし.
git refloglocal logしか取得できなかったのでなんとかremote logを取得する方法を調べる.

stackoverflow.com

上記サイトによるとcurl https://api.github.com/repos/ennach/ChangeHistory/eventsしてcommit idc476614bc439fe1910e494422b3aa207b776d486のURLを見つけるといいらしい.

https://api.github.com/repos/ennach/ChangeHistory/commits/c476614bc439fe1910e494422b3aa207b776d486

上記サイトで変更前のデータが見れるのでflagがとれる
CRCTF{the timer is set to 120 seconds}

[Stegano]

Secret.pdf

It's a secret pdf!

アプローチ:とりあえずopen
とりあえずopen secret.pdfする
flag部分が黒塗りされてるが文字選択でぬける.
CRCTF{I don't know of a time without the internet}

f:id:satto1237:20180909171815p:plain

Alpha

f:id:satto1237:20180909172105p:plain

アプローチ:alpha.pngのα値を調べる
問題名的にpngのα値を調べろということっぽいので簡単なスクリプトを書いて調べる(スクリプト書くよりも既存のツールを使ったほうが速いです).
ほとんどのPixelのα値が253であることが分かる.
怪しいのでα値が253以外のPixelを抜き出すスクリプトを書く.
CRCTF{ALPHA_IS_THE_NAME_OF_A_HACKER_IN_CYBERREBEAT} f:id:satto1237:20180909172431p:plain

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PIL import Image
import numpy as np

img = Image.open('./alpha.png')

size = img.size

flag_img = Image.new('RGBA',size)

for x in range(size[0]):
    for y in range(size[1]):
        #ピクセルを取得
        rgba = img.getpixel((x,y))
        #print(rgba)
        if rgba[3] != 253:
            flag_img.putpixel((x,y),(255,255,255,255))
        else :
            flag_img.putpixel((x,y),(0,0,0,255))
        
flag_img.show()
flag_img.save('./flag_img.png')

[Trivia]

Monero

ウェブ上からMoneroを発掘するソフトウェア。
日本で、自身のウェブサイト上にこのソフトを設置した何人かのユーザが逮捕されている。
フラグはすべて小文字。
例: CRCTF{abcdefgh}

アプローチ:日頃からセキュリティ関連のニュースをチェックしておく
これはcoinhiveのことですね.
CRCTF{coinhive}

Crossword

crossword_text.txt
FLAG:CRCTF{ABCDEFGH}
Flag format: all lowercase

f:id:satto1237:20180909173123p:plain

横
1. ___ はCyberRebeatにおける特殊なコードネーム。CyberRebeatは、ハッカーたちがこれを打倒する物語。『ぴったりだと思わないか、ええっ、英雄(ヒーロー)?』
5. CyberRebeat作中における、とあるハッカーの切り札。______はネットに接続された多数のデバイスで、それぞれがひとつあるいは複数のBOTを実行している。
8. heroine.png / 彼女の名前:____ Amamiya
10. CyberRebeatシナリオライターの代表作:__:____ ~親愛なるあなたへ~
11. CyberRebeatのキャッチフレーズ:We are h_____.
15. W_______はWindowsを実行しているコンピュータをターゲットとした、データを暗号化しBitcoinでの身代金支払いを要求するランサムウェアです。
16. CyberRebeatのシナリオライター
18. CRCTFを主催している同人サークル
19. 運営協力 : __________ Institute, Ltd., Aqutras Inc.
20. ______ はインターネットとセキュリティソフトウェアのクライアントのSSL 3.0へのフォールバックを利用した中間者攻撃です。
21. __________はBashdoorとも呼ばれ、Unix Bashシェルのセキュリティバグの一種であり、2014年9月24日にはじめて公表されました。

縦
2. Operation ______は、中国北京のElderwood GroupのようなAPTが人民解放軍と連携して行った一連のサイバー攻撃のこと。
3. CyberRebeatで利用しているゲームエンジン
4. CyberRebeatのイラストレーター:Kikyo ______
6. smile.min.svg
7. _____ Rain は、米国連邦政府が定義した2003年からのアメリカのコンピュータシステムに対する一連の組織的な攻撃のこと。
9. CyberRebeatのデザインおよび背景イラスト担当
12. 翻訳協力 : __________
13. CRCTFを主催している同人サークルが制作したノベルゲームの名称
14. https://store.____________.com/app/825320/CyberRebeat_The_Fifth_Domain_of_Warfare/
17. heart.png

アプローチ:クロスワードを解く

2. Aurora
3. Unity
4. Manose
10. Re:LieF
11. hackers
12. SekaiProject
13. CyberRebeat
14. steampowered
15. wannacry
18. e.n.nach
19. activedefence
20. poodle
21. Shellshock

CRCTF{ABCDEFGHI}
CRCTF{submarine}

フラグはCRCTF{submarine}になります.

[Web]

White page

http://hidden-field.cyberrebeat.adctf.online/index.php
id: Hiro
password: LittleGarden

f:id:satto1237:20180909173742p:plain

アプローチ:curlでid,passをPost
Webサイトにアクセスしてみると問題名の通り,White pageになっています(Loginボタンがあるだけ).
ソースコードを確認しみてると以下のようになっています.

<body>
  <form action="index.php" method="post">
   <input type="text" name="id" style="visibility:hidden" />
   <input type="text" name="password" style="visibility:hidden" />
   <button>LOGIN</button>
  </form>
</body>

id,passwordの入力フォームがvisibility:hiddenになっているため,このままでは入力できないことがわかります.
そのため,curlを使用してid, passwordPOSTします.
curl http://hidden-field.cyberrebeat.adctf.online/index.php -X POST -d "id=Hiro&password=LittleGarden"
ログインに成功してflagがとれます.
CRCTF{All I typed were four letters.}

Let's Tweet!

http://tweet.cyberrebeat.adctf.online/LetsTweet.php
LetsTweet.php

アプローチ:ついーとする
この問題は正直よく分かりませんでした.
phpソースコードを確認するとtest.dbを読み込んでいることが分かるのでディレクトリトラバーサルtest.dbを抜こうとしたのですが,Not Foundが返ってきて詰みました.
仕方なく,ツイートのリンクを使ってflagをとりました.
CRCTF{Thank_you_for_your_tweet!}

Uploader

Find the secret file.
http://sqli.cyberrebeat.adctf.online/index.php
id: guest
pass: guest

f:id:satto1237:20180909175342p:plain

アプローチ:SQLi -> Blind SQLi
とりあえずFile Name :SQLiしてみるとharadaというユーザがsecret.zipをアップロードしていることが分かります.

f:id:satto1237:20180909175444p:plain

次に問題文にあったid,passでログインしてみるとsample.zippasswordを閲覧できることがわかります.
そのため,haradapassを探し出し,ログインに成功したらsecret.zipunzipできることがわかります. f:id:satto1237:20180909175821p:plain

haradapassを探すためにBlind SQLiしなければいけないのですが,自分はSQLi Beginnerなのでsqlmapに頼りました.

qiita.com

上記のサイトを参考にUsersテーブルdumpします.

sqlmap -u 'http://sqli.cyberrebeat.adctf.online/index.php' --data 'file_name=aaa&search=search' --dump -T Users

f:id:satto1237:20180909180318p:plain

userid password
guest guest
harada seishin0129

pass:seishin0129を使ってuser:haradaとしてログインするとzippasswordを得ることができます.

f:id:satto1237:20180909180625p:plain

上記のpasssecret.zipunzipしてあげるとflagがとれます.
CRCTF{Today's_internet_is_full_of_concerning_vulnerabilities}

[Binary]

0完
f:id:satto1237:20180909181011p:plain

1問目のSimpleBinaryを解きながら「これのどこがシンプルなんだよ???」とキレてた.
Binary全然わからん…Binary強くなりたい…

まとめ

  • 土日を持っていかれた
  • 生活リズムが崩壊した(現在インターン中なので月曜の朝がつらそう)
  • Binaryぜんぜんわからん
  • CTFを始めて数ヶ月経って少しずつ解ける問題が増えてきたことを実感できたので嬉しかった
  • CyberRebeatめっちゃ気になる

store.steampowered.com

現実逃避でハニーポットを構築した話

はじめに

研究室で「(報告できるような)進捗ないな〜明日の進捗報告どうすっかな〜」と嘆いていたところ突如ハニーポットを構築したくなったので構築してみました.

サーバの準備

サーバの用意から始めます.

クーポンの利用

某ハックでさくらのデータセンターを訪問したときにもらったクーポンがあったのでさくらのクラウドを利用しました.
クーポンの登録手順は下記のサイトが参考になります. manual.sakura.ad.jp

サーバの作成

用意するサーバのスペックは後述します.
サーバの作成手順は下記のサイトが参考になります.
manual.sakura.ad.jp

SSHなどの設定

下記のサイトを参考にするといいと思います. qiita.com

自分の環境はMacなのでいつもはssh-copy-idでサクッとやっちゃいます.

ハニーポットの選定

ハニーポットと言っても様々なものがありますが今回は構築が簡単かつ可視化機能が優れているという点からT-Potを選びました.
T-Pot 17.10 - Multi-Honeypot Platform rEvolution

T-Potのコンセプト

サーバの必要スペック(for T-Pot)

  • 4[GB] RAM (6-8[GB] recommended)
  • 64[GB] SSD (128[GB] SSD recommended)
  • Network via DHCP
  • A working, non-proxied, internet connection

T-Potの導入

基本的に公式サイトの手順に従うだけですが下記のサイトでは日本語で解説されています. qiita.com

しかし,上記のサイトのKibana Web UIへのアクセスの項目は情報が古くなっているため注意が必要です(T-Pot 17.10からSSHでトンネルを張る必要がなくなりました).

現在ではhttps://<your.ip>:64297にアクセスするだけで Kibana Web UI を使用することができます.

Just open a web browser and access and connect to https://<your.ip>:64297, enter

  • user: user you chose during the installation
  • pass: password you chose during the installation

可視化

Kibana Web UI のスクリーンショットです. f:id:satto1237:20180831025801p:plain f:id:satto1237:20180831030018p:plain f:id:satto1237:20180831025828p:plain

最後に

思ってたよりも簡単にハニーポットを構築することができて驚きました.
次は生のデータを分析してみたいと思います.

SecHack365@福岡に行ってきた話

SecHackのオフラインイベントで福岡に行ってきました(8/22~8/24)

0日目(8/21)

帰省先(実家)から昼頃帰ってきて研究室でSecHack用の資料を作っていた.
気がついたら0時を過ぎていた.
家に帰ってから荷造りをして2時頃に寝た.

1日目(8/22)

05:00

起床.

08:00

羽田空港到着.
台風19号と20号で欠航するんじゃないかと心配していたがなんとかなった.

11:00

福岡空港到着.
いい感じに晴れてて最高の気分になった.

12:30

ラーメンデータベース福岡ランキング1位の博多一双に到着.
今までに経験したことがないドギツイ豚骨臭で期待が高まる.
40分ほど並びようやく入店.
特製ラーメンを注文しカウンターで着丼を待つ.
3分ほどで着丼.
カプチーノのような豚骨スープの深いコクに感動して涙を流しながら麺をすすった(泣いたのは嘘
f:id:satto1237:20180826005510j:plain f:id:satto1237:20180826005534j:plain

14:00

Nulab訪問.
CEOの橋本さんとCTOの縣さんから貴重なお話を聞かせて頂いた.

18:00

宿泊先に移動して夕飯.
圧倒的人権.
イカソーメンが名物らしいがそんなに好きじゃないので肉ばっか食べてた. f:id:satto1237:20180826012830j:plain

26:00

就寝.
早めに寝るべきだったけど強い人達と雑談するのが楽しくて夜更かし(?)してしまった.

2日目(8/23)

8:30

朝ごはんチャレンジ失敗.

09:00

中間報告開始.
毎度のことながらドクペータワー最高過ぎる. f:id:satto1237:20180826014212j:plain

13:00

休憩.
海に行った.
テンションが上って15年ぶりに海に潜ってしまった. f:id:satto1237:20180826014045j:plain

15:00

中間報告再開.

18:00

中間報告終了.
完全にこれだった.
f:id:satto1237:20180826015016j:plain

18:30

中間報告終了後に自分のプロジェクトテーマが本当にこれでいいのか改めて考えた.
自分のテーマは研究に近いもので,大学でもできるためこれをSecHackでやるのは微妙だなと以前から思っていた.

進捗としては中間報告の時点である程度形にはなっており,必要なデータを揃えれば査読なしの研究会になら論文として投稿できそうだった(本当か?
しかし,このテーマを続けてもSecHackが求めるイノベーション感はだせないだろうなと感じていた.
そこで何人かのトレーニーと相談し,IoTに関するプロジェクトにJOINさせてもうら形になった.

19:00

夕飯.
人権. f:id:satto1237:20180826023455j:plain

23:00

4チームに別れてNight Challenge(ミニハッカソン)開始(1チーム5~6人)

  • 台風情報を収集する
  • 自身の位置が、暴風圏に入るかどうか判断する
  • 危険な場合は、通知する
  • 危険でない場合は、お勧めの近隣スポットをリコメンドする
  • オリジナル機能  Idea 1 (自由な発想で機能を付けて下さい)
  • オリジナル機能  Idea 2 (自由な発想で機能を付けて下さい)

28:00

Night Challenge終了.
危うくAll Night Challengeになるところだった.

自分はオリジナル機能として二郎リコメンドを実装した.
IPアドレスから現在地を取得し,最寄りの二郎をリコメンドする.
コマンドライン引数に地名が含まれていた場合はその地名から最寄りの二郎をリコメンドする.
リコメンド結果はTypetalkに通知している.

f:id:satto1237:20180826024940p:plain f:id:satto1237:20180826025037p:plain f:id:satto1237:20180826025058p:plain f:id:satto1237:20180826025111p:plain

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geocoder
import pandas as pd
import requests
import sys

def nearest_jiro():
    args = sys.argv

    if len(args) == 1:
        g = geocoder.ip('me')
    else :
        geo_address = args[1]
        g = geocoder.google(geo_address)

    if g.latlng is not None:
        lat = g.latlng[0]
        lng = g.latlng[1]
    else:
        print('Not Found')
        g = geocoder.ip('me')
        lat = g.latlng[0]
        lng = g.latlng[1]

    dist = float('inf')
    nearest_jiro_name = 'jiro'
    nearest_jiro_url = 'url'

    df = pd.read_csv('./jiro.csv')

    for index, row in df.iterrows():
        temp_dist = abs(lat-row['lat']) + abs(lng-row['lng'])
        # print(row['name'])
        if dist > temp_dist:
            dist = temp_dist
            nearest_jiro_name = row['name']
            nearest_jiro_url = row['url']

    print(nearest_jiro_name, nearest_jiro_url)
    return nearest_jiro_name, nearest_jiro_url



def typetalk_post(name, url):
    # hogeにはpost先のURLとトークンが入る
    r = requests.post('hoge', {'message': name + '\n' + url})


if __name__ == '__main__':
    name, url = nearest_jiro()
    typetalk_post(name,url)

3日目(8/24)

08:30

朝ごはんチャレンジ失敗.

09:00

コースワーク開始.
Night Challengeの発表をした後にプロジェクトの担当トレーナーにあいさつをしにいった.

13:00

倫理セッション.
法と倫理について考えた.

15:00

解散.

16:00

福岡空港到着. 実家用にお菓子と明太子と地酒,研究室用にお菓子を買った.
小腹が空いたのでラーメンを食べた(ラーメン以外の食べ物をしらないため)
f:id:satto1237:20180826031334j:plain

21:00

羽田空港到着.

まとめ

  • 本場の豚骨ラーメンは美味い
  • 海は最高
  • IoTに関する知見を増やす

TJCTF2018 Write-up

数ヶ月前にCTFを始めたのですが,まだブログでアウトプットしたことがなかったのでTJCTFのWrite-upを書くことにしました.

TJCTF2018

[Web] Blank

Someone told me there was a flag on this site, so why is it that I can only see blank?

  1. デベロッパーツールでページのソースをみる
  2. <!-- flag: tjctf{50urc3_c0d3_n3v3r_l0535} -->

[Miscellaneous] Trippy

trippy

  1. リンク先に飛ぶとgif(?)が置いてある
  2. とりあえずダウンロード
  3. fileコマンドで確かめる
    GIF image data, version 89a, 320 x 240
    本当にgifっぽい
  4. strings be37fef78cfd6c7deda71154f567e6d0cfefbda1f80698c064bab469d3a54c58_trippy.gif | grep tjctfで中身をみる
  5. tjctf{w0w}

[Forensics] Weird Logo

This company's logo stands in contrast of those of other leading edge tech companies with its poor design
Source

  1. リンク先からpngをダウンロード
  2. pngコントラストを調整すると見える
  3. tjctf{in_plain_sight}

f:id:satto1237:20180815222752p:plain f:id:satto1237:20180815222807p:plain

[Miscellaneous] Discord!

Join our Discord for a free flag!

  1. Discordにjoinする
  2. tjctf{d1sc0rd_1s_pr3tty_c0ol}

[Web] Cookie Monster

The Cookie Monster is not a fan of horses

  1. Cookie Monsterということなのでデベロッパーツールを使ってCookieを確認
  2. tjctf{c00ki3s_over_h0rs3s}

[Web] Central Savings Account

I seem to have forgotten the password for my savings account. What am I gonna do? The flag is not in standard flag format.

  1. 適当にpassを入力する
  2. もちろんLogin Failed!
  3. main.jsのソースコードを見てみる
  4. passに対してMD5でハッシュをとってそのハッシュ値698967f805dea9ea073d188d73ab7390と一致するとログイン成功するっぽい
  5. MD5は弱いのでハッシュ値ググるとでてくる
  6. hashtoolkit
  7. tjctf{avalon}
$(document).ready(function() {
    $("#login-form").submit(function() {
        if (md5($("#password").val()).toLowerCase() === "698967f805dea9ea073d188d73ab7390") {
            $("html").html("<h1>Login Succeeded!</h1>");
        }
        else {
            $("html").html("<h1>Login Failed!</h1>");
        }
    })
});

[Cryptography ] Vinegar

I just wanted something more than a Caesar salad. Maybe I should order another one? vinegar.txt

key = Kkkkk kkkkKkkkkkkkkKkkkkkkkkKkk
flag = uucbx{simbjyaqyvzbzfdatshktkbde}
sha256 = 8304c5fa4186bbce7ac030d068fdd485040e65bf824ee70b0bdbac03862bec93

  1. 問題文的にVigenère cipherだと信じる
  2. sha256が怪しい
    多分全探索(ブルートフォース)しろってこと(?)
  3. Vigenère cipherの性質からkeyの長さは9だと決めつける
  4. flagのuucbxは復号化するとtjctfになる(はず)ということを利用してpre_keyを作成
  5. blaisを得る
  6. 残りの4文字を全探索
  7. tjctf{onevinaigrettesaladplease}
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from itertools import product
import hashlib

pre_key = 'blais'
cipher = 'uucbx' + 'simbjyaqyvzbzfdatshktkbde'
plain = 'tjctf'
target = '8304c5fa4186bbce7ac030d068fdd485040e65bf824ee70b0bdbac03862bec93'

def solve_prekey():
    key = ''
    for p, c in zip(plain, cipher):
        for k in range(26):
            if (k + ord(p) - 97) % 26 == (ord(c) - 97) % 26:
                key += chr(97 + k)
                break
    print(key)


def brute_force():
    chars = 'abcdefghijklmnopqrstuvwxyz'
    pws = product(chars, repeat=4)
    for pw in pws:
        key = pre_key + ''.join(pw)
        key *= 3
        key += 'bla'
        flag = ''
        for c,k in zip(cipher, key):
            t = ord(c) - ord(k)
            t %= 26
            t += 97
            flag += chr(t)
        flag = flag[:5] + '{' + flag[5:] + '}'
        sha256 = hashlib.sha256(flag.encode()).hexdigest()
        if sha256 == target:
            print(flag)
            break

if __name__ == '__main__':
    # solve_prekey()
    brute_force()

[Miscellaneous] Interference

I was looking at some images but I couldn't see them clearly. I think there's some interference.

  1. 2枚のpng画像が渡される
  2. 見ただけだと違いがわからない
  3. 画素値を調べる
  4. ところどころ画素値が異なる
  5. 画素値が同じならば白,異なれば黒というルールで画像を生成する
  6. 出来上がった画像を透過させて最初に渡された画像と重ねる(Interferenceなので?)
  7. QRコードがうきでる
  8. tjctf{m1x1ing_and_m4tchIng_1m4g3s_15_fun}
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PIL import Image
import numpy as np

im1 = Image.open('./v1.png')
im2 = Image.open('./v2.png')

rgb_im1 = im1.convert('RGB')
rgb_im2 = im2.convert('RGB')
size = rgb_im1.size


im3 = Image.new('RGBA',size)

for x in range(size[0]):
    for y in range(size[1]):
        rgb1 = rgb_im1.getpixel((x,y))
        rgb2 = rgb_im2.getpixel((x,y))

        if rgb1 == rgb2:
            im3.putpixel((x,y),(255,255,255,255))

        else :
            print('hoge')
            print('rgb1:{}'.format(rgb1))
            print('rgb2:{}'.format(rgb2))


            im3.putpixel((x,y),(0,0,0,255))

im3.show()
im3.save('./v3.png')

f:id:satto1237:20180815232125p:plain f:id:satto1237:20180815232141p:plain f:id:satto1237:20180815232159p:plain f:id:satto1237:20180815232210p:plain f:id:satto1237:20180815232226p:plain

[Binary Exploitation] Math Whiz

The neighborhood math whiz won't stop bragging about the registration form (source) he coded. Show him who's boss!
nc problem1.tjctf.org 8001

int input(char *str, float f) {

    fgets(str, 16 * f, stdin);

    if (strlen(str) <= 1) {
        puts("No input detected. Registration failed.");
        exit(0);
    } else if (!strchr(str, 10)) {
        while (fgetc(stdin) != 10);
    } else {
        str[strlen(str) - 1] = 0;
    }
}

int main() {
    int admin = 0;
    
    char fullname[16];
    char username[16];
    char password[16];
    char recoverypin[4];
    char email[16];
    char address[16];
    char bio[64];
    
    printf("Full Name: ");
    input(fullname, 1);

    printf("Username: ");
    input(username, 1);

    printf("Password: ");
    input(password, 1);

    printf("Recovery Pin: ");
    input(recoverypin, 4);

    printf("Email: ");
    input(email, 1);

    printf("Address: ");
    input(address, 1);

    printf("Biography: ");
    input(bio, .25);
    
    if (admin) {
        printf("Successfully registered '%s' as an administrator account!\n", username);
        printf("Here is your flag: %s\n", FLAG);
    } else {
        printf("Successfully registered '%s' as an user account!\n", username);
    }

}
  1. プログラムを見た限りadminの値を書き換えるBOFを起こせばflagがとれるっぽい
  2. inputをみてみるとfgetsを使ってるので簡単にBOFできなそう
  3. もう少し詳しくinput見てみると文字列と一緒に係数を渡しおり,係数に応じて入力サイズが決まる
  4. input(recoverypin, 4);が怪しい(char recoverypin[4];なので)
  5. nc problem1.tjctf.org 8001でつなぐ
  6. Recovery Pin:のときにBOFできる程度の文字を打ち込む
  7. Here is your flag: tjctf{d4n63r0u5_buff3r_0v3rfl0w5}

[Reverse Engineering] Python Reversing

Found this flag checking file and it is quite vulnerable
Source

  1. プログラムの意味を考える
  2. どうやらflag1文字ずつに乱数をかけてlmao(定数文字列)とxorをとって2進数に変換してるっぽい
  3. ここで乱数はシード値が設定されてるので再現可能
  4. xorとってるlmaoも再現可能
  5. 3,4の性質を利用して適当にDFSするとflagがとれる
  6. tjctf{pYth0n_1s_tr1v14l}
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import string

np.random.seed(12345)
other = np.random.randint(1,5,110)
rand = [x for x in other]
ascii = string.ascii_lowercase + string.ascii_uppercase + string.digits + '{}_'
original_target = '1001100001011110110100001100001010000011110101001100100011101111110100011111010101010000000110000011101101110000101111101010111011100101000011011010110010100001100010001010101001100001110110100110011101'
lmao = [ord(x) for x in ''.join(['ligma_sugma_sugondese_'*5])]


def search(search_bit, flag, depth):
    for a in ascii:
        x = (ord(a) * rand[depth]) ^ lmao[depth]
        bit = bin(x)[2:].zfill(8)
        if search_bit.find(bit) == 0:
            if bit == search_bit:
                print(flag + a)
            else :
                search(search_bit[len(bit):], flag + a, depth + 1)

if __name__ == '__main__':
    search(original_target, '', 0)

[Web] Programmable Hyperlinked Pasta

Check out my new site! PHP is so cool!
programmable_hyperlinked_pasta.tjctf.org

  1. サイトにアクセスする
  2. デベロッパーツールでソースコードをみる
  3. <!-- <a href="flag.txt">Here's a flag!</a> -->
  4. 普通にアクセスしようとするとYou don't have permission to access /flag.txt on this server.
  5. よくWebサイトを眺めてみると?lang=en-us.phpphpファイルを呼び出してることに気づく
  6. ?lang=flag.txtでflagを見ようとするがみれない
  7. 1つ上の階層にある可能性があるので?lang=../flag.txtする(ディレクトリトラバーサル)
  8. tjctf{l0c4l_f1l3_wh4t?}

[Cryptography] Classic

My primes might be close in size but they're big enough that it shouldn't matter right?

e = 65537
n = 128299637852747781491257187842028484364103855748297296704808405762229741626342194440837748106022068295635777844830831811978557490708404900063082674039252789841829590381008343327258960595508204744589399243877556198799438322881052857422197506822302290812621883700357890208069551876513290323124813780520689585503
c = 43160414063424128744492209010823042660025171642991046645158489731385945722740307002278661617111192557638773493117905684302084789590107080892369738949935010170735247383608959796206619491522997896941432858113478736544386518678449541064813172833593755715667806740002726487780692635238838746604939551393627585159
  1. RSAを解く問題
  2. とりあえずnをなんとかしないといけないのでfactordb.comに行く
  3. なぜかキャッシュされてる
  4. 終了(多分想定解法ではない?)
  5. p,qを使って秘密鍵を生成してフラグをぬく
  6. tjctf{1_l1ke_squares}
import gmpy
import codecs

e = 65537
N = 128299637852747781491257187842028484364103855748297296704808405762229741626342194440837748106022068295635777844830831811978557490708404900063082674039252789841829590381008343327258960595508204744589399243877556198799438322881052857422197506822302290812621883700357890208069551876513290323124813780520689585503
p = 11326943005628119672694629821649856331564947811949928186125208046290130000912120768861173564277210907403841603312764378561200102283658817695884193223692869
q = 11326943005628119672694629821649856331564947811949928186125208046290130000912216246378177299696220728414241927034282796937320547048361486068608744598351187
C = 43160414063424128744492209010823042660025171642991046645158489731385945722740307002278661617111192557638773493117905684302084789590107080892369738949935010170735247383608959796206619491522997896941432858113478736544386518678449541064813172833593755715667806740002726487780692635238838746604939551393627585159


l = gmpy.lcm(p-1, q-1)
gcd, u, v = gmpy.gcdext(e, l)
m = pow(C, u, N)
print(m)
print(codecs.decode(('%x'%m),'hex_codec'))

[Reverse Engineering] Validator

I found a flag validation program. Do what you want with it.

  1. とりあえずfileコマンドするとELF 32-bit LSB executableだということがわかる
  2. Ubuntuで実行
  3. コマンドライン引数として文字列を渡してあげるとその文字列がフラグどうか判定するという処理をしていることがわかる
  4. もう少し詳しく見るためにIDAになげる
  5. ざっくりまとめると
    1. tjctf{ju57_c4ll_m3_r3v3r53_60d_fr0m_n0w_0n}というフラグを定数として持っている(これが正解のフラグではない)
    2. コマンドライン引数として渡された文字列の長さがフラグと一致するかどうか調べている(strlen)
    3. 長さが一致したらフラグと文字列が完全に一致するか調べている(strcmp)
    4. strcmpで使用している比較対象のフラグは定数として持っていたフラグの一部の文字を書きかえたモノっぽい
  6. strcmpで使っている文字列を確認するためにltraceしてあげる(IDAでも確認できますが少しめんどくさいので)
  7. strcmp("tjctf{ju57_c4ll_m3_35r3v3r_60d_f"..., "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"...) = 1
  8. フラグはtjctf{ju57_c4ll_m3_35r3v3r_60d_fr0m_n0w_0n}

[Binary Exploitation ] Tilted Troop

Can you help us defeat the monster? binary (source) nc problem1.tjctf.org 8002

  1. とりあえずnc problem1.tjctf.org 8002する
  2. コマンドがでてくる
  3. Aでチームメンバを追加して,Fでモンスターと戦って,Qで終了らしい
  4. プログラムを見てみるとチームメンバを追加するたびに0~9までの乱数をチームの強さとして追加している
  5. Fで戦ってチームの強さが400になるとフラグがとれる
    Your team had 3 strength, but you needed exactly 400!
    しかし,プログラム的には8人までしかチームメンバを登録できず,チームの強さは最大でも72までにしかならない
    t.strength = malloc(sizeof(int) * MAX_TEAM_SIZE);
  6. 何らかのBOFをしなければいけない
  7. プログラムを確認するとチームメンバの追加処理の条件式が正しくないため,9人目のチームメンバを入力できることが分かる
  8. aはasciiで97なのでasciiで100になる文字も4文字打ち込めばいいことが分かる(dddd)
  9. tjctf{0oPs_CoMP4Ri5ONs_r_h4rD}
Commands:
A <name> - Add a team member
F - Fight the monster
Q - Quit
if(t.teamSize > MAX_TEAM_SIZE) {
    printf("Your team is too large!\n");
} else {
    t.strength[t.teamSize] = rand() % 10;
    char* newMember = malloc(256);
    strcpy(newMember, &input[2]);
    t.names[t.teamSize] = newMember;
    t.teamSize++;
}
A a
F
Your team had 97 strength, but you needed exactly 400!

[Forensics] Ssleepy

I found this super suspicious transmission lying around on the floor. What could be in it?

  1. .pcapngが渡されるのでとりあえずwiresharkで開く
  2. TCP,FTP,TLSパケットがメイン
  3. とりあえずTCPストリームをみる
  4. 220 Welcome to my super-secure, private-key-transmitting, FTP server とかいってるめちゃ怪しい
  5. RETR key.zipでzipファイル渡してるっぽい
  6. zipを抽出するとserver_key.pemがとれる
  7. TLSパケットがあったのでそのパケットをzipから抽出したサーバ鍵を使って復号してあげる
  8. GET /flag.jpg HTTP/1.1\r\nとか怪しいパケットが走ってることがわかる
  9. SSLストリームをみる
  10. .jpgを抜くためにSSLストリームをRaw形式で保存
  11. foremostなどで.jpgを抽出するとフラグがとれる
  12. TJCTF{WIRESHARK_OR_SHARKWIRE?}

f:id:satto1237:20180816003727j:plain

Ess Kyoo Ell

Find the IP address of the admin user! (flag is tjctf{[ip]})

  1. Web問なのでとりあえずWebサイトにアクセスする
  2. 登録フォームがでてくるのでmail addressとpasswordを打ち込んでSign inする
  3. This is what I got about you from the database: no such column: password

    passwordというカラムがないぞと怒られる
    怪しい

  4. POSTで色々送ってみる
    curl https://ess-kyoo-ell.tjctf.org/ -X POST -d 'email=a@a&password=hoge'

    This is what I got about you from the database: no such column: password

    curl https://ess-kyoo-ell.tjctf.org/ -X POST -d 'email=a@a'

    This is what I got about you from the database: 'NoneType' object is not iterable

    ここでデータベースにありそうなカラムを予測する(例えばusernameとか)
    adminのip addressがフラグなのでusername=adminでadmin情報を抜いてみる
    curl https://ess-kyoo-ell.tjctf.org/ -X POST -d 'username=admin'

    This is what I got about you from the database: {'id': 706, 'username': 'admin', 'first_name': 'Administrative', 'last_name': 'User', 'email': '[email protected]', 'gender': 'Female', 'ip_address': '145.3.1.213'}

    あった

  5. tjctf{145.3.1.213}

SecHack365@北海道に行ってきた話

SecHackのオフラインイベントで北海道に行ってきました(6/29~7/1)

0日目 (6/28)

期末試験があったがSecHack関連のタスクが未完了だったので何も対策せずに受けた.
単位はちゃんときました

1日目 (6/29)

05:00

起床. まだ荷造り終わってなかったので最終確認とかをした.

10:00

羽田空港到着. f:id:satto1237:20180808164714p:plain

12:30

新千歳空港到着.
(北海道着いたらめっちゃ雨降ってた) f:id:satto1237:20180808164556p:plain

12:45

ラーメン道場で昼食
やっぱり空港のラーメンはスープが微妙 f:id:satto1237:20180808170922p:plain f:id:satto1237:20180808164610p:plain

15:00

さくらインターネットの見学
データセンタの中に入るのは初めてだったのでとても新鮮だった.
区域毎に反省点を改善するために設備をアップデートしていく姿勢に感動した. f:id:satto1237:20180808173718j:plain f:id:satto1237:20180808174009p:plain

20:00

夕飯.
圧倒的人権 f:id:satto1237:20180808181504p:plain

2日目 (6/30)

09:00

ここからが本番.
くぼたつ本 の著者の久保田 達也さんにアイデア発想法についてレクチャーをしてもらった.(くぼたつ本はただでもらった).

今までの自分のアイデアは自身の技術力に依存する傾向があり,ありきたりのモノしか思いつくことができなかった.(どうすれば実現できるか?考える癖がついていたため)
一度実現可能性を考えずにめちゃくちゃな案をだしてみるのも1つの手だということを知ったので日々の生活に取り入れていきたいと思う.

11:00

NICTER Open Network Security Test-Out Platform (NONSTOP)のハンズオンを受けた.
個人的に興味があるデータセットもあったので時間ができたら弄りたい.

13:00

コースワーク
自分のプロジェクトは研究寄りでイノベーション感がないのでとても不安になったが,周りに似たような不安を抱いている院生がいたので安心した(?).
本当にこのまま進めていいのか?と不安になっていたが,NICTの人に「このまま進めていいんじゃない?」と言われたのでこのまま進めることにした.

15:00

縁日

  • データセット活用入門(ついでに感染IoT機器を探してみよう)
  • ネットワークハッキング ~自由を手に入れよう!誰でもできるネットワークすり抜け術~

に参加した.

データセット活用入門(ついでに感染IoT機器を探してみよう)

簡単なスクリプトを書いてダークネットトラフィックに関するデータを扱った.

  1. IoT機器に関連した宛先ポートにスキャンしているホストを探す
  2. ホストの80/TCPにアクセスする
  3. HTTPレスポンスを収集
ネットワークハッキング ~自由を手に入れよう!誰でもできるネットワークすり抜け術~

ネットワークのトンネリング技術の体験をした.

などのコマンドを使った
ネットワークトンネリングツールの使い方よりも使いどころを知ることが大切

様々なレベルの制約がついたネットワーク環境を与えられ,wgetできれば勝ち?という講義だった. 最終的にWeb(80/TCP), mail(25/TCP), SSH(22/TCP), ICMP(ICMP)通信が禁止されたネットワークからwgetすることができた(iodine).

まとめ
SSHすごい!

19:00

夕飯.
普段食べてるものと比べるとレベルが高すぎて人権を感じた.

3日目 (7/1)

09:00

コースワーク
色々とアドバイスを頂いた.

13:00

解散.
そのまま,バスで新千歳空港に行き,実家と研究室用に日本酒とお菓子を買った.

19:00

羽田空港

飯まとめ

f:id:satto1237:20180808194051j:plain f:id:satto1237:20180808194122j:plain f:id:satto1237:20180808194159j:plain f:id:satto1237:20180808194520j:plain

3 + 1日目(7/2)

月曜の1限から期末テスト!
飛行機の中で1時間くらい勉強してそのままテストを受けた
院生の期末試験に対するモチベはこんなものだと思う
もちろん単位はきた

まとめ

  • みんな無限に進捗出しててすごいと思った
  • イデア発想法の重要性
  • 習慣化を引き続きがんばる
  • ダークネットトラフィック面白い!
  • SSHすごい!
  • 飛行機の証憑は早めに提出する

SecHack365@神奈川に行ってきた話

SecHack365の初顔合わせに行ってきました(5/18~5/20).

 

1日目

10:00

起床(14:00受付ということなので遅め)

11:30

出発

13:45

目的地到着(乗り換えミスって昼食をとる時間が消滅)

14:00

歓迎セッションとオリエンテーション開始

トレーナーもトレーニーも強い人ばかりでちょっと怖くなった(場違い感)

習慣化についての話がとても印象に残った(ラーメンを食べすぎて高血圧?になったので毎晩4kmランニングをしよう!と春休み中に決意したにもかかわらず3週間でやめてしまった自分には考えさせられる話だった).習慣化のコツを雑に説明すると「高い目標を設定すると継続が難しい.なので,このくらいなら毎日継続できるかな?程度のやさしめの目標を設定する.」ということっぽい.

要は目標を実行に移すタイミングがボトルネックになっているのでそこのハードルを下げて継続していこうという話.

その話を踏まえてマンダラートを書いた.

19:00

夕食(バイキング形式)と交流会

久しぶりに人権のある飯を食べた

21:00

発表スライドの微修正とか就寝準備とか

25:00

就寝

2日目

08:00

起床&朝食(バイキング形式)

やはり人権のある飯はうまい

09:00

イデアソンをした.

みんな面白いことを考えていてすごいなとなった(マネしたい).それと同時に自分はこんなアイデアでいいのか???ともなったが「面白いですね」とか「細部までよく考えているんですね」とか言われてちょっと嬉しくなった.

12:00

昼食(メイン以外バイキング)

人権のある飯はうまい

13:00

コースワーク(表現駆動)

自己紹介を含めた持ち込みアイデアのプレゼンをした.参加者のプレゼンをみて「実績や経歴も強いし,アイデアも面白いし最強かよ」となった.

自分は膨大なWebアクセスログから悪性Webアクセスログを高速に抽出する手法についてプレゼンした.現時点で色々と問題点があるので今後は論文を読んだり助言をもらったりして解決していきたい.

19:00

夕食(バイキング形式)

人権のある飯はうまい

f:id:satto1237:20180528222951j:plain

20:00

Night Challenge

適当に決まったチームに分かれていくつかの課題を解いた(俳句の自動生成とか)

25:00

就寝

3日目

08:00

起床&朝食(バイキング形式)

人権のある飯はうまい

09:00

コースワーク(表現駆動)

昨日のプレゼンの続き

12:00

昼食(メイン以外バイキング形式)

人権のある飯はうまい

13:00

個人活動

自分は同じような技術を使いそうなアイデアを発表した人や院生の人と世間話?をしていた.この時間がかなり有意義だった.同様の技術を使いそうな人とはその技術についての話で盛り上がったし,似た分野の研究をしている院生とは最近読んだ面白い論文の話をして盛り上がった.

話をしたほとんどの人がセキュスペを持っていたので安全確保支援士の登録について(するか or しないか)聞いてみたけどやっぱりみんなしないらしい.

自分も学生のうちは16万円も払えないし失効してもいいかなと思っていたので1人で納得してしまった.

15:30

解散

本当に楽しい3日間だった.次の北海道回まで進捗をだしていきたい.

19:00

90分ならんで関内二郎を食べた(横浜といえば関内二郎)

ちなみに大豚 汁なし ニンニクヤサイです.

やはり関内二郎の乳化スープは最高ですね.

f:id:satto1237:20180528224319j:plain

f:id:satto1237:20180528224349j:plain

23:00

自宅到着(寄り道したので時間がかかった)

まとめ

  • みんなつよい
  • 習慣化がんばる
  • 進捗出す
  • 関内二郎は美味しい