SecHack365(2018年度) 参加記
まとめ
2019年度も参加したかった
注意事項
ポエムを書きがちなので苦手な方は閲覧しないほうがいいと思います。 あとダラダラ書き連ねています。表現がおかしいところとかあるかもしれません。すみません。 また、SecHack365の詳細や応募概要などについては触れません。そのあたりについては公式をご覧ください。
他にも、修了生がブログを書いたみたいなので、そちらもご覧ください。 (修了生の方へ:私が知らないだけで他にあれば教えてください)
目次
- 参加のきっかけ
- 各オフライン会での出来事
- 最終的な成果物
- 参加する前と参加した後の状態の変化
- アドバイスとかいろいろ
- 感想
1. 参加のきっかけ
大学の先輩・後輩が前年度に参加し、成果を出しているのを見てちょっと羨ましくなったので、「いい加減何か自分で誇れるものがほしいな」と思いながら応募フォームを申し込みました。
SecHack365の存在は初年度(2017)から知っていました。ただ、当時の学業が一番忙しい時期で、仮にその時に参加したとしても、上手く両立できずに終了(悪い意味で)してしまうのではという懸念があり、初年度は見送りでした。 翌年度(2018)は時間的な余裕もあり、しっかり参加できるという見込みがあったので応募しました。
1.1. まともな開発をしたかった
プログラミングをすることはあっても、日常的に何かを開発しているわけではなく、自分の目的達成のために小さなコード片をたまに書くぐらいでした。 プログラミングは好きですが、その勉強スタイルが受動的で、コードを書くよりは参考書籍を読む時間のほうが長かったぐらいです。 GitHubのリポジトリを見ても、まともに開発したものが見当たらないために、なんとなく恥ずかしく感じていました(少なくとも、私が憧れているような人はめちゃくちゃコード書いてるので)。
1.2. 低レイヤー関連でなにかやりたかった
私は低レイヤー(ソフトウェア寄りの方)が好きなので、低レイヤー関係で何か開発が出来ればいいなと思っていました。 SecHack365の応募概要の中身を見てみると、開発駆動コースの坂井ゼミでは主に低レイヤー関係を取り扱うとありました。 丁度仮想化技術に興味があり、エミュレータだったらハードウェアについても学べるのでは?と思い、セキュアなエミュレータみたいなのを作りたいなという気持ちがありました。
1.3. 「一定の成果が求められる」ことに対する恐怖を克服したかった
これが一番大きかったです。誰しも怒られたくはないはず。「ちゃんとできなかったらどうしよう?」「途中でファイアされたらどうしよう?」きっとみんなが通っている道のはずなのに、そこに一歩踏み出すのが怖かったです。でも心の中ではもっと成長して、もっと先に進みたいという気持ちがあるんです。今後も成長するにはこの恐怖心がどうしても障害になるし、いつまで経ってもチキンなままなのは(例え人から見て分からなくても)絶対に嫌でした。だからこそ、このイベントを通じて、ちゃんと成果を出して恐怖を克服したかったのです。心の中のチキンは焼き鳥にでもして食ってしまえ!
2. 各オフライン回での出来事
神奈川回(5/18-5/20)
イベント開始前には既にコミュニケーションツールを使って自己紹介等を済ませていましたが、ちゃんと実体同士で会うのはこれが初めてになります。 顔見知りの人もいれば、Twitterのアカウントだけは分かるのに実際の顔が分からない人、全く関わりが無かった人…色んな人がいました。それは多分他の人も同じだったと思います。 加えて、私は人の顔と名前を対応付けて覚えるのが非常に苦手で、何度か名前を聞き返していました。早くARか何かで人の頭の上にTwitterアイコン載せるやつほしいです。
2日目には自分たちのアイディアを紙に書いて発表し合うことをやりました。私はその頃には緩和っぽい技術ができないかなぁと結構雑多に考えていました。緩和の仕組みを具体的に想像できていたのはBOFによるリターンアドレス書き換え攻撃ぐらいでしたが、他はぼんやりとしていて、他の人に説明するときも結構適当だった気がします(それっぽいことを言ってお茶を濁した)。 みんなも色々と書いていて、なんか熱意に溢れているなぁと思う発表や、発表慣れしていないんだろうなという人、発表スタイルもバラバラで、「(いよいよSecHackが)始まったなぁ〜」って気持ちになりました。
その後、コース別にコースワークを行います。開発駆動コース、特に坂井ゼミでは担当トレーナーの坂井さんとの面談を一人ひとり行っている間、ゼミ生で色々話しながらコードを書いていました。 私はというと、コードを書くことはせずにひたすらQEMUのコードを眺めていました。流石にすぐに開発に取り掛かれるほどQEMUを知っていたわけではないので、私の場合はまずコードを読んでQEMUの動作の仕組みを知るところから始まりました。お菓子が供給されるので脳内に糖分を補給しながらパソコンをカタカタします。楽しい。お気に入りはブラックサンダーです。
ちなみに表現駆動コースはNight Challengeという名目で夜も開発をしていたらしいです。色んな種類の技術に触れつつ、課題を解決していくみたい(?)なのですが、それはそれですごく技術力上がるよなーと思う半面、彼ら彼女らは夜ちゃんと寝ているのか分かりませんでした。私はセキュリティキャンプで眠い時の苦痛を味わった経験があるので、ちゃんと睡眠時間を確保しようと頑張っていました。でもイベントに参加したら興奮してなかなか寝付けないものです。
北海道回(6/29-7/1)
人生発、自分だけ(※友人はいました)で飛行機に乗るという経験をする回でした。嬉しいことに前泊が認められ、札幌駅に降り立った後にラーメンを食べに行きました。美味しかった…また食べたい! この後の回もそうなのですが、1年を通して色んな所に行くので、そのばその場の雰囲気が全く違っていて楽しいものでした。 7月に入ることもあって暑くなる…はずが、北海道に行くと寒いんです。寒暖差で風邪引くんじゃないかと思っていましたが特に体調が悪くなることはありませんでした。 ただ持っていく服を選ぶのにはちょっと迷った。防寒をするとなると荷物がかさばるんですよね…
この回はさくらインターネットの石狩データセンターの見学です。VPSを借りている身としてワクワクしながら見学へ。 詳しいことは書けないのですが、とにかく圧巻でした。 公式レポートにもありますが、たこやきのレシピをGitHub上で管理しているという話もありました(驚愕)。
その後、自分たちの進捗報告も兼ねて開発駆動コースではLT大会が開かれました。 私は特段進捗がなく、やったことと言えばQEMUの実行状態を少しだけ見ることができるデバッグ出力をQEMU本体に追加しただけでした。 この時もまだコードを読んでいるだけに等しく、今思えばもうちょっとコードを書いていても良かったのではないかと思いました。 他の人の発表は、進捗がある人ない人それぞれ。でもLT大会をするという名目で何かスライドを作らないといけない、と思うと、最低限の成果物が必然と出来上がるので、定期的なアウトプットは大切だなと思いました。
LT大会が終わると、ワークショップ(ハンズオン)が開かれました。 私が受講したのは花田さんの「はじめての開発プロジェクト」と、衛藤さんの「ネットワークハッキング 〜自由を手に入れよう!誰でもできるネットワークすり抜け術〜」の2つです。 内容を書いてはいけない気がするので雑多に感想だけ言うと、花田さんの講座では「根を詰めずに開発しよう、気が楽になった!」と思いましたし、衛藤さんの講座では「ネットワークおもしろいじゃん!」と思いました。
この回はネットワークの事が面白かった回(DC見学やワークショップ)だったので、開発テーマをネットワークに変えようかな…とか思っていました。ネットワーク系のテーマをやっている人が途端に羨ましくなった。
福岡回(8/22-8/24)
明太子美味しかった。
思わず本音が。このことは後で書くとして、この回は「中間発表」という、ちょっと緊張感が高まる回でした。事前にスライドの提出を求められていたので、間に合うか不安になりながらスライドを作成していました。 この時も私は進捗を出していませんでした。強いて言えば、QEMUのおおまかな動作原理を知ったぐらいです。とりあえずコードの中身を理解して、それをスライドにまとめて…という作業を繰り返していました。 なんとか間に合ったので良かったのですが、今度は発表の練習をしていない。発表時間も5分と短い中で効率的に喋らなくてはならず、ちょっと大変でした。 (スライドは後で気が向いたら公開します)
他の人の発表を聞いている間も、なるべく全員にコメントを書いたりアイディアを提案したりしながら過ごしました。自分とは違うジャンルの発表に対してアイディアを考えるのも面白かったです。 あと、中間発表の後、同じゼミ生の中に本を書く人が二人いたので、レビューというものをやってみたくて提案してみたら快諾してくれました。嬉しい。 (※ただし、この後私が自己管理がしっかりできていなくて、大したレビューもできなかった…二人とも、ごめんなさい…)
前回は寒かったのに、今回は暑い!なんじゃこりゃ!?と思いながら過ごしていましたが、室内は快適でした。相変わらずお菓子と飲み物の供給があるので最高です。 後で海にも入りました。そこで担当トレーナーの坂井さんをゼミ生みんなで砂浜に埋めて遊ぶのですから、もうなんかおかしくて笑っていました。 一応海に入るイベントはアイディア発想法の一種です。ゆらゆらと海に揺れながら、進捗がなかった自分のことを思い返していました。開発したいものの本質的なアイディアを思い浮かぶことが出来ればよかったのかもしれませんが、具体的な実装をしていない私にはそれができませんでした。代わりに、現状の問題点(生活習慣とか)に対する解決策を考えてたりしました。それと坂井さんが安らかな顔をしていたなぁとも思っていました。
明太子は帰り道に空港で購入しました。ゆず味の明太子が美味しくて、しばらくコンビニで明太子買ったり、現地で買った明太子と同じものを通販でわざわざ取り寄せたりしてました。今ではおにぎりも明太子ばかり食べてます。すっかりハマってしまった。
山形回(10/12-10/14)
この回では進捗がかなり出た回でした。今回の作品の骨子はこの回で構築することができました。 本当はポスター提出締切一週間前ぐらいから「やばい何もできていない」となって焦っていました。ですが、ポスターを作って「こういう機能がほしいな」と具体的にしてたからこそできたと思います。 ポスター自体は締切に余裕を持って完成したので、山形に向かうまでの期間でちょっとコードを改造していたら、荒い作りでもちゃんと動いてくれたのです。ちょっとうまく動いただけでも私にとっては大きな進歩でした。思わずコロンビアをしてしまう。
勢いに乗ってそのままスライド(別に作らなくてもいい)も用意して、結構なウキウキ気分で山形に向かいます。誰だって進捗が出たら嬉しくなる(はず)。 ポスター発表の時はデモと一緒に見せながら自分の作った作品と今後の展望を含めてプレゼンし、トレーナーやトレーニーからレビューをしてもらいます。色んなコメントが出てきて嬉しかったです。プレゼンのみでレビューを受けるのと、実際にデモを作ってレビューを受けるのとは全然違うなぁと思いました。
その後は鳥兜山山頂に登ってリフレッシュするわけですが、その帰り道にゴンドラに乗ればいいものを、誰かが坂を登って走ったらしく、それにつられて私も坂を走って登りました。 まぁヒドイ酸欠を起こして、登りきった頃には疲労困憊。誰かこのまま担架で運んでくれというお気持ちになりました。 更にその後も麓まで走って降りる人がいました。肉体のハッカソンをする必要があると強く感じました。貧弱すぎて泣ける。
愛媛回(11/30-12/2)
この回は進捗がなくて辛かった回でした。
というのも、丁度その頃に北海道の方でミニキャンプの講師をしたり、SECCONの作問をしたり、Kernel/VMで発表をしたりと…何故か山形回から愛媛回にかけてイベントが多かったので、開発に割く時間がありませんでした。 ただ、そうは言っても時間管理の改善の余地はあったはずなので、自分の管理の甘さが目立っていた期間でもありました。丁度前回のポスタープレゼンの時にスライド資料も作っていたので、提出物自体は何も問題はありませんでしたが、「進捗どうですか?」→「進捗ダメです」と答えるのが心苦しかったです。
この時期はTLに流れてくる色んな人の強そうな成果を見て「自分もこの分野に強くなりたい!」と手当たりしだいに手を付けていた結果、自分の本当にやりたいことややるべきことを見失っていました。 このままじゃまずいと思って、今やるべきこと(SecHackの成果物を作ること)に集中することにしました。沖縄回までにしっかり開発できないといけないので、その回は悪習慣の排除や集中すべき点を洗い出したり、応募時の課題フォームを読み返したりしていました。応募した時の内容を見るのはポエムが多くて恥ずかしくなるのですが、その分純粋にやりたいことが書かれていたので、初心を思い出すには丁度いいと思います。
色々と考えながら過ごした回でしたが、落語を聞いてとても気持ちが楽になりました。人を笑わせる事ができる才能って本当に凄いことだよなぁって思いました。 このときから落語が好きになったので、また聞きたいなぁと思っています。 笑って気持ちが少し回復したのか、発表のときのような落ち込みは無く、余計な雑念が少ない状態でコードを書くことができました。
沖縄回(2/1-2/3)
全日程をほとんど発表で費やすという、怒涛の3日間でした。
今回はちゃんと進捗を出すことができ、スライドも作り込んでいたのですが、いろいろとやらかしたり…自分の想定していた発表とは少しずれる感じになりました。 ただ坂井さんのアドバイスを受けて、ちょっと発表の方法を工夫したりして本番に望みました。
分かってはいたことですが、みんな仕上げてきていました。 しっかりと形に落とし込んでいて、それでいて内容も面白い。正直何やってるのか分からなくて、でも凄さは伝わってくる作品もあれば、「頭おかしいんじゃないのか(最大級の褒め言葉)」という作品もありました。 全部の発表にコメントをつけている間も「やべぇよ、みんなヤバすぎでしょ…」と思いながら過ごしていました。 (※自分の知っている範囲を超えて凄いのを見せてくるので、コメント内容もそんな簡単に思い浮かばないし、そもそも恐れ多くなってくるという) しかもその上自分の発表順番が回ってくるまでの緊張もあるので、足がそわそわして落ち着きませんでした。
いよいよ自分の発表順番が回ってくると、とりあえず仕込んでおいたネタを色々とやってみたらみんなが笑ってくれて、それだけで心の救いになりました。 そこから先は自分のやってきたことを伝え、まとめや改善点、今後の展望などをまとめて終わりました。 この時の発表が、私が一番好き放題にやることができた発表だったので、一番楽しかったです。
終わりに優秀賞を貰えて、帰り道の脳内ではUndertaleのLast Goodbyeが流れていました。泣きそうでした。
成果発表会(3/7-3/8)
優秀賞を貰った人は予めプレゼン練習をすることになっていました。なので3/7から東京へレッツゴーです。
ここで思い知らされるのは、成果発表会に来るのはあくまで「一般の人」ということです。専門的な知識を必ずしも有しているわけではなく、説明のやり方次第でちゃんと伝わるか全く伝わらないかが決まってしまいます。 今まではSecHackの中で発表していたので、何回もプレゼンを重ねるうちに理解してくれる人が多かったのですが、今回は全くの初見な人も来るわけです。私の母もそのうちの一人で、私は母の理解度具合を基準にスライドを再構築し直しました。
さすがに一般の人の前で発表することになるので緊張度はMAXです。しかもトップバッターでした。会場がどんな空気感になるのかも想像がつかなかったので余計に緊張しました。 とにかく、分かりやすく発表することを心がけ、スライドを作成し、発表練習もしたので後はやるだけです。折角人の前で発表する機会を頂いたので、しっかりやりきらないとという気持ちで本番に臨みました。
発表は無事終了し、なんとか次の人にバトンタッチすることができました。 発表自体は早口であまり理解してもらえなかったかもしれません。作品自体も、スライドも、プレゼンも、どれも改善の余地はあると思いました。
発表はちゃんと頑張って進めることができましたが、今考えると他のトレーニーの発表に比べたら私は大したことをしていないのではないかという気持ちになります。それは多分、「隣の芝生は青い」というやつなのかもしれません。実質的に書いているコードの量やそこにかけている努力量は彼らの方が上に思えます。「私は本当に運が良かったのだ」とすら思います。ですが、彼らと同じ壇上に立ち、自分のやってきたことを発表することができる機会を貰ったのだから、それを活かさなくてはならないと思いました。今後もその事実に背かないよう、成長を続けていかなければならないと思います。
3. 最終的な成果物
トレーニー全体のポスターはこちらになります。
私のポスターはこちらになります。
加えて、秋葉原回での発表時に使用した資料はこちらになります。
作ったのは、攻撃に対する緩和機構を持ったエミュレータです。 もともとQEMUと呼ばれるOSSのエミュレータがあり、私はそこに改造を施して攻撃をよしなに防いでくれる仕組みを作りました。 詳しくはスライドやスライド中に記載されているGitHubのリポジトリをご覧ください。
4. 参加する前と参加した後の状態の変化
参加前は石橋を叩いても渡らないような性格でした。何かリスクがあると躊躇ってしまって、その先にある成長の機会をたくさん逃していたんだと思います。 参加後はある程度気持ちを強く持って先に進むことができるようになりました。
5. アドバイスとかいろいろ
- 応募用紙は後で見返せるように保存しておくといいかも。それが思い入れの強い文章であればあるほど、自分の本質的にやりたい部分が思い出せていいかもしれないです。
- 開発自体が目的なようにも思えますが、私はアイディア発想の方法や、習慣化について学ぶ(そして自分のものにする)ことこそがこのイベントの本質なのではないかと考えます。だから習慣化をおろそかにして私のように進捗がなくなったり、アイディアを一人で考え続けて唸りっぱなしにならないほうがいいと思います。
- 各地の有名なお土産を必ず買って帰っていたので、個人的な旅行の練習になるかもしれません。名産品とか知るのはいいことだと思います。
- 提出物の期限とその内容はしっかり把握したほうがいいです。後になって慌てても困るのは自分だけ、と思いきや周りにも迷惑がかかる場合も有ります。
- 最初に自分がやりたいなと思ったことは見失わないほうがいいです。もちろん途中で開発するものを変更するのはありです。ただ、自分の方向性だけは一貫したほうがいいかもしれません。
- 開発は楽しんでやったほうがいいと思います。と言って「楽しむように頑張る」みたいになっても良くないと思うので、とりあえず「好きにする」のが一番だと思います。
6. 感想
1年間を通じたハッカソンの参加が初めて、しっかりと開発するのも初めて、と最初はとても不安でした。 成果物なんて作れるんだろうかと疑問でしたが、なんとか作り終えることができてホッとしています。 その上スライドを公開した後に、色んな人に目を通してもらえたり、プロの方々にコメントを貰えてとても嬉しかったです。
そして感じるのが、SecHack365を修了したと言っても、これはスタートラインに過ぎないということです。 まだまだ上には上がいるというか、現状で満足してはいけないなと強く思わされました。 またReturnsのような修了生イベントもあるらしいので、そこに向けて地道に開発を続けていきたいと思います。
あと、今年度の開催概要を見てみたら、コンテンツを作ってみるコースもあるらしいです。それに参加したくなりました。小説書きたかった… (※2016年のキャンプ参加ブログには小説を書きたいな〜みたいなコト書いていました。3年も経って全然進んでない)
おまけ
私の母は最後の最後までSecHackとキャンプの区別がつかなかった
Rootkitに関するまとめ
この記事は個人的にRootkitに関する情報を集めているだけのページです。 あくまで教育目的で集めているので、リンク先の扱いにはご注意ください。 (尚、作成中のため量は少ないです)
実際のRootkitのコード
スライド・Paper
https://www.blackhat.com/presentations/bh-dc-07/Heasman/Paper/bh-dc-07-Heasman-WP.pdf
Webページ
まとめ・リスト
ARPのキャプチャをしてみる
前回の記事に引き続いて、今度はARPをキャプチャできるようにプログラムを作成してみた。
作成したプログラムはこちら。
これまでの知識やWiresharkでキャプチャした結果を頼りに作ってみた。
以下に示すのは重要な部分のコード。
int displayARP(u_char *arp_data){ nextfunc = NULL; printf("|============= ARP DATA =============|\n"); int hardware_type = data2value16(&arp_data[0]); int protocol_type = data2value16(&arp_data[2]); int hardware_size = data2value8(&arp_data[4]); int protocol_size = data2value8(&arp_data[5]); int opcode = data2value16(&arp_data[6]); printf("[!!] Hardware type : "); switch(hardware_type){ case 0x0001: printf("Ethernet\n"); break; default: printf("Unknown...\n"); break; } printf("[!!] Protocol type : "); switch(protocol_type){ case 0x0800: printf("IPv4\n"); break; default: printf("Unknown...\n"); break; } printf("[!!] Hardware size : 0x%x\n",hardware_size); printf("[!!] Protocol size : 0x%x\n",protocol_size); printf("[!!] Opcode : 0x%04x\n",opcode); switch(opcode){ case 0x0001: printf("[=>] Request : Who has "); displayIP(&arp_data[24]); printf("? Tell "); displayIP(&arp_data[14]); printf("\n"); break; case 0x0002: printf("[=>] Response : "); displayIP(&arp_data[24]); printf(" is at "); displayMAC(&arp_data[8]); printf("\n"); break; default: printf("[=>] Opcode Unknown...\n"); printf("[!!] Sender MAC Address : "); displayMAC(&arp_data[8]); printf("\n"); printf("[!!] Sender IP Address : "); displayIP(&arp_data[14]); printf("\n"); printf("[!!] Target MAC Address : "); displayMAC(&arp_data[18]); printf("\n"); printf("[!!] Target IP Address : "); displayIP(&arp_data[24]); printf("\n"); break; } printf("|============= END DATA =============|\n"); return 0; }
ARPの中身を見ようとするだけでかなり長いコードになってしまった。
ARPの中身は以下のようになっており、重要なのはOpcode
とSender MAC address
,Sender IP address
,Target MAC address
,Target IP address
であると考えられる。
(※横並びに繋がっているものとして見てください) | Hardware type (2byte) | Protocol type (2byte) | | Hardware size (1byte) | Protocol size (1byte) | | Opcode (2byte) | | Sender MAC address (6byte) | Sender IP address (4byte) | | Target MAC address (6byte) | Sender IP address(4byte) |
ARPは、IPアドレスに対応するMACアドレスを取得するプロトコルで、
Opcode
の部分でその要求と応答とを区別している。
Address Resolution Protocol - Wikipedia
Opcode
が0x0001のときはRequest(要求)となり、Target MAC addressが全部0埋めでデータが送信される。
Opcode
が0x0002のときはReply(応答)となり、Requestで要求されていたTarget MAC addressに該当するアドレスが`Sender MAC addressの領域に格納されてデータが送信されることになる。
それらをWiresharkの表示のように、Request時にはWho has XX.XX.XX.XX? Tell XX.XX.XX.XX
と表示し、Reply時にも同様にXX.XX.XX.XX is at XX:XX:XX:XX:XX:XX
と表示するようにしたのが上記コードである。
先人から学ぶ
前回と同じく、tcpdumpのリポジトリ内にあるprint-arp.cというファイルから参考にできないか探していたところ、以下のようなコードがあった。
#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ #define ARPOP_REVREPLY 4 /* response giving protocol address */
ARPのOpcode
に該当する部分が、3,4という数値でもOKらしい。なんとなくRARPっぽい感じがするので念ののために調べてみると…
このサイトで3,4がRARPのRequestとReplyに該当するOpcode
になるということが分かった。
他にも、各領域のサイズをチェックしているような処理が見受けられた。
else if (PROTO_LEN(ap) != 4) ND_PRINT("<wrong len>");
tcpdumpでは構造体を使って各データを表現している。しかし、私のプログラムはただ表示するだけで構造体等は意識していない。 効率的にデータを扱うのなら構造体を使うべきなのだと思う。そして、その場合はしっかりとサイズを確認しなければ、オーバーフローなどの脆弱性を生んでしまうのだと感じた。
感想
コードが増えると、その管理も煩雑になってくるので、ソースコードを複数のファイルに分割したり、重複処理を関数化したりなど、きれいにしなければならないとも感じた。 加えて、セキュリティを勉強しているのにもかかわらず、サイズのチェック処理などを施していないのが良くないなと思った。未然に防ぐ立場も簡単ではないと思う。
LinuxのRAWソケットからイーサネットフレームを取得してみる
パケットの中身を覗きたくなったので作ってみた。ネットワークの理解をするために今後も続けていきたい。
とりあえず作ってみる
これまでの知識やWiresharkでキャプチャした結果を頼りに作ってみる。
作ったリポジトリと該当するコードはこちら。
このコードは以下のサイトを参考にして作成している。RAWソケットの取得方法だけ知りたかったので、全部読んでいない。 (閲覧すると文字化けしていたが、ある意味最低限の情報を知るにはちょうどいいと思ってそのままコードだけ読んだ)
http://www.is.noda.tus.ac.jp/~t-matsu/NetworkProgramming/
重要な部分は以下に示すコード。
// in main() soc = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); // in captureFrame() len = read(fd,&buf[len],malloc_usable_size(buf));
ここでは、RAWソケットからパケットを取得するための初期設定と読み出しを行っている。 最初にsocket関数を使ってRAWソケットのファイルディスクリプタを取得する。 次に、そのファイルディスクリプタからデータを読み取る。
読み取られたデータは、以下の関数でMACアドレスとタイプを表示するのに使われる。
void printMACAddress(u_char *frame){ int type; printf("[!] Dst : %02x,%02x,%02x,%02x,%02x,%02x\n",frame[0],frame[1],frame[2],frame[3],frame[4],frame[5]); printf("[!] Src : %02x,%02x,%02x,%02x,%02x,%02x\n",frame[6],frame[7],frame[8],frame[9],frame[10],frame[11]); type = data2value16(&frame[12]); printf("[!] Type : %04x\n",type); switch(type){ case 0x0800: printf("[=>] IPv4\n"); break; case 0x0806: printf("[=>] ARP\n"); break; } }
イーサネットフレームは先頭6バイトが宛先MACアドレス、次の6バイトが送信元MACアドレス、次の2バイトがイーサネットフレーム内の中にあるデータの種別を表している。
|Destination MAC Address (6byte) | Source MAC Address (6byte) | Type (2byte) | Data |
Wiresharkを使って適当にキャプチャしたパケットのうち、ARPとIPv4だけその種別を表示させるようにした。
先人から学ぶ
あまりコードが美しくないように感じるので、tcpdumpのリポジトリを参考にしながら色々と改造してみる。
閲覧したのはtcpdumpリポジトリ内のethertype.h
というファイル。
まずイーサネットフレームの長さを覚えていなかった。最初は65536バイトの領域を確保できるようにしていたが、実際には1500バイトの領域だけで事足りるようだった。 また、フレームタイプにIPv6(0x86dd)とRARP(0x8035)を追加した。他にもバナーを表示してみたり、関数名や表示そのものを見やすくしたりするなど、色々と変更を加えた。
変更後のコードはこちら。
感想
ネットワークのデータを分解するのは想像していたよりも手間がかかることがわかった。 また、コードを書いていると「汚いなこれ」と思うようになったり、「もうちょっと機能を追加したいな」とか考えるようにもなった。コードを書くのは色んな発見ができて大切だと思う。
おまけ
今回はVirtualBox上で動作するUbuntu 16.04のVM内で作業したが、パケットキャプチャをする際にWireshark側でインタフェースをany
にしていた。
そのせいで、イーサネットフレームを取得したくても、Linux cooked-mode caputure
なる形式に変わるらしく、思い通りにいかなかった。ちゃんとインタフェースを指定しないとだめだと学んだ。
対処するのに参考にしたサイトはこれ。
ちゃんと形式を変換するためのものも用意されているらしい。知らなかった。
CVE-2018-7602の検証
Web系の脆弱性について勉強していきたいと思い、いくつか検証してみた。この記事はそのうちの3つ目。
CVE-2018-7602について
Drupal 7.x系、8.x系にRCEの脆弱性が存在する。
今回検証するのはこのコード。
尚、こちらのPoCも参考にしている。
検証コードとDrupal7.57のソースをまとめたリポジトリを作成した。以降の検証はこのリポジトリ内にあるスクリプト等でインストール作業を自動化している。
検証環境は、Virtualbox上で動作するVM(Ubuntu 16.04 64bit)。予めgitがインストールされているものとする。
インストール
$ git clone https://github.com/happynote3966/CVE-2018-7602.git $ cd CVE-2018-7602 $ sudo ./install.sh # (途中でMySQLのrootパスワードの設定を求められる) $ sudo ./install.2sh # (ここでも途中でMySQLのrootパスワードの入力が2回求められる。)
ここまで実行したら、次はInstallation Script(Webコンソール)でDrupalをインストールする。 以降のインストール作業はこちらの手順と同様のため省略する。詳しくはこの記事を参照のこと。
検証
この脆弱性は、ログインしているユーザが管理者によって認証され、記事の削除権限を持っていることが必要となる。 そのため、一般ユーザを作成し、そのユーザに対し記事の作成権限と削除権限を追加する。その後に、ログインを行ってからPoCを実行する。
まずは管理者権限でテスト用のユーザを作成する。画面上のPeople
のタブをクリックし、以下のような画面を出す。
次に、現れた画面の上部にあるAdd user
をクリックし、一般ユーザを作成する。
ユーザ名はhappynote3966
、パスワードはpassword
としておく。下にあるCreate new account
をクリックして作成は完了。
次に、一般ユーザの権限を追加する。まずは画面上のPeople
のタブをクリックし、更にその中のPERMISSIONS
のタブをクリックする。
この中のNode
の項目内にあるArticle: Create new content
とArticle: Delete own content
のAUTHENTICATED USER
の列にチェックを入れ、Save Permissionをクリックして、権限を反映する。
最後に、記事を追加する。 まずはログアウトし、先ほど作成した一般ユーザ名とパスワードでログインする。
ログインできると、以下のような画面になる。
ここから、Add new content
をクリックし、記事の作成を行う。
記事の内容は適当にした。
一番下にあるSaveをクリックすると、作成した記事が反映される。
このときのURLを確認し、?q=node/1
の最後の数字の部分を見てみると、1
となっていることが分かる。これがノードIDとなる。
準備が完了したので、これからPoCを実行してみる。まずはブラウザ内でCookieをチェックする。 このサイトのCookie(今回はlocalhost)を閲覧する。今回は以下のようになっていた。
Name:SESS29af1facda0a866a687d5055f2fade2c Content:bBJ40SrtSVWc7Y9-By57oyIqSElDNO1nPEghwMTMb9s
この情報と、ノードIDを用いてPoCを実行する。今回の場合は、以下のよう実行する。CookieのNameとContentは=
で連結させる。
$ python drupalgeddon3_update.py http://localhost/drupal/ "SESS29af1facda0a866a687d5055f2fade2c=bBJ40SrtSVWc7Y9-By57oyIqSElDNO1nPEghwMTMb9s" 1 "ls -al"
すると、以下のような実行結果が表示された。
ls -al
を実行することができている。
感想
ログインした状態で、且つ記事を削除できる権限を持ち合わせていること、などがRCEの条件になるというのを知った。特定の条件下でのみ攻撃が通ってしまうような脆弱性は見つけるのが難しいのかもしれないが、いずれそのような脆弱性も発見してみたい。
CVE-2018-7600の検証
Web系の脆弱性について勉強していきたいと思い、いくつか検証してみた。この記事はそのうちの2つ目。
CVE-2018-7600について
Drupal 8.x系の8.5.1より前のバージョン、加えて7.x系の7.58よりも前のバージョンにRCEの脆弱性がある。
今回検証するのはこのコード。
検証コードとDrupal8.5.0のソースをまとめたリポジトリを作成した。以降の検証はこのリポジトリ内にあるスクリプト等でインストール作業を自動化している。
検証環境は、Virtualbox上で動作するVM(Ubuntu 16.04 64bit)。予めgitがインストールされているものとする。
インストール
$ git clone https://github.com/happynote3966/CVE-2018-7600.git $ cd CVE-2018-7600 $ sudo ./install.sh # (途中でMySQLのrootパスワードの設定を求められる) $ sudo ./install.2sh # (ここでも途中でMySQLのrootパスワードの入力が2回求められる。)
ここまで実行したら、次はInstallation Script(Webコンソール)でDrupalをインストールする。
VM内のブラウザでhttp://localhost/drupal/core/install.php
にアクセスすると、インストール画面が現れる。
デフォルトのまま次へ進めていく。
ここでは、データベースの名前やパスワードなどを聞かれる。データベースの名前はdrupal
、ユーザ名はroot
、パスワードは自身が設定したものを入力する。
サイトの設定をする。管理者はdrupal
というユーザ名で、パスワードはpassword
とする。
インストールが完了し、そのままDrupalのページに飛ぶことができる。
検証
まずは念のためにログアウトしておく。
その後、rubyで検証コードを以下のように実行する。
$ ruby ./drupalgeddon2_update.rb http://localhost/drupal
このPoCは今回構築した環境に合わせてオリジナルのPoCから少しだけ修正したものを使っている。
実行した後、drupalgeddon2>>
というプロンプトが表示されるので、ls
コマンドを入力してみる。
すると、ls
を実行した結果が出てくる。他にも、whoami
コマンドを入力してみる。
任意のコマンドが実行できるRCEが存在していることが分かる。
感想
自分が見つけたわけでもなく、人のPoCを動かしてやってみるだけになったが、それでもRCEができているとすごくワクワクする。いずれこんな脆弱性を見つけてCVEを取得したい。
CVE-2014-3704の検証
Web系の脆弱性について勉強していきたいと思い、いくつか検証してみた。この記事はそのうちの1つ目。
CVE-2014-3704について
Drupal 7.x系の7.31から前のバージョンにSQLインジェクションの脆弱性がある。
今回検証するのはこのコード。
検証コードとDrupal7.31のソースをまとめたリポジトリを作成した。以降の検証はこのリポジトリ内にあるスクリプト等でインストール作業を自動化している。
検証環境は、Virtualbox上で動作するVM(Ubuntu 16.04 64bit)。予めgitがインストールされているものとする。
インストール
$ git clone https://github.com/happynote3966/CVE-2014-3704.git $ cd CVE-2014-3704 $ sudo ./install.sh # (途中でMySQLのrootパスワードの設定を求められる) $ sudo ./install.2sh # (ここでも途中でMySQLのrootパスワードの入力が2回求められる。)
ここまで実行したら、次はInstallation Script(Webコンソール)でDrupalをインストールする。
VM内のブラウザでhttp://localhost/drupal/install.php
にアクセスすると、インストール画面が現れる。
デフォルトのまま次へ進めていく。
ここでは、データベースの名前やパスワードなどを聞かれる。データベースの名前はdrupal
、ユーザ名はroot
、パスワードは自身が設定したものを入力する。
(ここで続行しても、反応がない場合がある。その場合はF5で更新するとうまく行くはず)
サイトの設定をする。管理者はdrupal
というユーザ名で、パスワードはpassword
とする。
インストールが完了し、リンクをクリックすることでDrupalのページに飛ぶことができる。
検証
まずはログアウトを行う。その後、ユーザ名happynote3966
、パスワードもhappynote3966
でログイン試行をする。
インストール作業の際にはアカウントを作成していないため、ログインが弾かれる。
その後、pythonで検証コードを以下のように実行する。
$ python 34992.py -t http://localhost/drupal -u happynote3966 -p happynote3966
これで、ユーザ名happynote3966、パスワード
happynote3966`でアカウントの作成を行う。
実行後、再度そのユーザ名とパスワードでログインを行う。
結果としてログインに成功している。