Networkの話
インターネットはどう動いているのか。小さいネットワークから順番に構成を考える。
2つのPCが1本のケーブルでつながっているネットワークは簡単に作れる。
電気が流れてきたらそれは自分宛てのデータだし、電気を流せばそれは相手へのデータ。
衝突回避は適当にやればよい。
MACアドレス
3つ、4つ、...とコンピュータをつなげようとすると、完全グラフをつくるわけにもいかなくなってくる。
そのとき、どのような形で効率的につなげるかは(ネットワークトポロジ)場合によるが、いずれにせよすべてのPCにユニークなIDをつけなければならない。(さもなくば電気信号として着信したデータが自分宛なのかわからない。)
このため、LANカードには世界で(だいたい)一意なMACアドレスがついている。
ip a
=> xx:xx:xx:xx:xx:xx
IPアドレス
続けて、さらに多くのコンピュータをつなげることを考える。
100,1000,10000とかの規模だとすると、一つの中核ハブからそれぞれのコードを引っ張ってくるわけにも行くまい。
リング型にしたり一直線にするわけにもいかない。どこかの経路に障害が起きたら大きな被害がでてしまう。
障害が起きたときに責任も明確にしたい。そういうわけで、ネットワークが階層を作るようになる。
ここで考えられたのがIPアドレス。二進数的に上のビットから見ていくこでどこに所属しているかがわかるようになってる。(イメージ: 日本十進分類法)
ip a
=> 192.168.xx.xx
or 172.xx.xx.xx
or 10.xx.xx.xx
IPアドレスとMACアドレスは、たとえばARPを用いて動的に対応付けられる。
arp -a
こうしてまとまりをもたせた上で、各コンピュータ、ルータなどにルーティングテーブルというのを作って、IPアドレスさえ示されれば目的の端末までの経路が各々導き出せるようにする。われわれユーザに近いところでは、そこまでの手間でもないので、大抵は人間が静的にルーティングテーブルを書く。NTTやOCNなどの上層部では、それこそインターネットが網の目のように複雑になっているため、お互いの息を確認しあい、ルーティングテーブルの更新も動的に行われる(RIP,BGPなど)。
FQDN
MACアドレスは我々にとってほぼ乱数だし、IPアドレスは階層を作っているだけで、とても人間の扱うものではない。
そこでアルファベット(ついには日本語でも何でも)を使ったDomain Nameというものが編み出された。
これとIPアドレスはDNSというシステムで対応付けられる。これまた管理が階層構造を成しており、結構大規模なシステムになってる。
nslookup www.tsg.ne.jp
ポート
1つのLANカード(〜1つのマシン)には1つのMACアドレス(〜1つのIPアドレス)が割り振られるが、一つのマシン中でネットワーク通信したいアプリケーションは複数ある。ブラウザとオンラインゲームを起動したとき、自分のIPアドレスに来た通信がどちら宛かわからないようでは困る。そこでTCP/UDPプロトコルのレベルではポート番号(0-65535)というものがさらに識別番号として加わる。通信する各アプリケーションが自分の通信用ポート番号をもつ。ポート番号とアプリの対応付は、ソケットという仮想的な通信路を使いながら、OSがうまくやってくれる。
チャットツール netcat
-
Windows: telnet or https://eternallybored.org/misc/netcat/
-
Server:
netcat -l -p [port]
ornetcat -l [port]
(バージョンによって違う) -
Client:
netcat [host] [port]
あとで使います。
パケットキャプチャ Wireshark
https://www.wireshark.org/download.html
宛先にかかわらず、自分のもとに届いたパケットを解析結果付きでよめる
Webの話
Webの技術は上のネットワーク技術の上に成り立つ。インターネット上を流れる通信で使われるプロトコルはもっぱらHTTP。
HTML (WHATWG/W3C)
Markup Language。羅列された文字情報のうち、どこがどのように重要なのかを書いておく。ブラウザが適当に重要なところを目立たせてくれる。画像やなんかを途中に埋め込めたり、 ハイパーリンクを貼れるのも特徴。
CTFをする上では、HTMLを細かく見る必要はない。どうせマークアップ言語。formタグとその中身くらい見れば良い。type=hiddenとかの要素はHTMLを見ないとでてこないのでチェック。あとはコメントに手がかりが書いてあったり。
自分で書くときは、変わり種タグを知っている必要があったりなかったり。
CSS
HTMLだけでは表示はブラウザに任せることになってしまうけど、これによって表示のさせ方を調整できる。
CTFではあまりみなくてよさそう。display: noneな要素とかは調べてもいいかも。
JavaScript (MDN)
クライアントサイドで動く(だいたい)唯一のプログラミング言語。
ブラウザ上で、ユーザの動きに合わせて要素を書き換えたり、裏で通信をしたり(後述)がんばっている。
HTML中にscriptタグで書かれていることが多い。
CTFでは、ある程度読むことは必要だろうけれど、書く方はlocation.hash、location.href、document.cookie、document.write、getElementById、alertくらいしか僕は知らない。
HTTP (RFC 2616(obsolete))
HTMLなどのデータ送信用プロトコル。HeaderとBody(省略可)からなる。
HTTP/1.1が今の所多い。HTTP/2がでてき始めてるけれど、ガラリと変わっていてよくわからない。
典型的なHTTP Request
GET /index.html HTTP/1.1
Host: www.tsg.ne.jp
POST /index.html HTTP/1.1
Host: www.tsg.ne.jp
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
abc
典型的なHTTP Response
HTTP/1.1 200 OK
Server: Apache
Accept-Ranges: bytes
Content-Length: 13
Content-Type: text/html; charset=utf-8
Hello, world!
HTTPサーバとお話してみよう!
> nc www.tsg.ne.jp 80
GET /inde(以下略.上と同じ.)
400 Bad Requestが帰ってきたら、HTTPの体裁をなしていないということで、入力ミスを疑うべき。
HTTP/1.1ではHostヘッダは省略不可です。
Ajax / WebSocket (RFC 6455)
ページの遷移なしに、裏でJavaScriptがWWWサーバと通信できる。
Ajaxの通信はただのHTTPで、WebSocketではHTTPのようなはじめ方をしてから双方向通信を始められる。
CGI (RFC 3875)
サーバでプログラムを動かすためのインタフェース。動的なサイトを作れる。
環境変数(ex. %PATH%/$PATH)や標準入力にHTTP Requestの内容を入れ込んで、アプリケーションを起動するだけ。その標準出力を適当に加工してResponseとする。
SQL (Various implementations!)
Relational DataBaseというやつを使う時の操作のための言語。管理がしやすくなっている保存領域という認識で良さそう。
典型的な問い合わせ
select uid from user where email = 'hoge@example.com' and pass = 'P@ssword'
データの挿入
insert into user ( uid, email, pass ) values ( 10, 'mail@example.com', 'pass' )
データを保存する仕組み
もともとHTTPはstaticなデータを渡すのが目的だったから、設計上はひとつひとつの通信が独立になる。
SQLやCGIといった技術によって、サーバ側にデータを蓄積できるようになったが、クライアント側には残せない。
(inputタグをいちいち挿入することを思いつくかもしれない。しかし画面遷移のたびにsubmitボタンを押させなくてはならない。URLにデータを埋め込むのはわりとよい解決策かもしれない。セキュリティ的観点からはよくないだろうが。)
クライアント側にもデータを残せるように次のような技術が作られた。
Cookie (RFC 6265)
domain/pathによって影響の及ぶ範囲や、expiresで有効期限が設定できる。
JavaScriptやHTTP Headerによって読み書き可能。
HTTP RequestではCookie headerによって送信され、ResponseではSet-Cookie headerによって記憶すべきデータが送られる。
JavaScriptではdocument.cookieから読み書きできる。
SessionというのはCookieの特殊な使い方で、もともとのCookieのようにデータを直に入れるのではなく、idの役割を果たす乱数のみ記憶させておき、それに対応する実際のデータはサーバに記憶させておくというもの。番号札で荷物を預かるようなイメージ。
WebStorage / IndexedDB
よく知らない。
HTML5で読み書きできるストレージ。
JavaScriptでアクセスできたり。
HTTPで送信させることもできるらしい。
Script in HTTPd と HTTPd in Script
CGIの仕組みを使うと毎回プロセスを立ち上げるコストがかかってしまうため、実際のところはFastCGIという技術や、HTTP daemonにModuleとしてインタプリタを組み込んでしまうことも多い。このほうが大量にアクセスが来たときに早くさばける。
逆に、スクリプト言語で開発用HTTP daemonを立てている場合もある。WEBrickとかmorboとかDjangoとか。
例
Developer Tool
僕はもっぱらGoogleChromeを使っています。Firefoxには拡張機能でFirebugというのがあった気がします。IEにもあります。
- 要素を検証
- Elements - HTMLが読める
- Event Listeners - JavaScriptでイベント待ちしてるところが分かる。
- Break Points - 要素が書き換わったときにブレークできる。
- Network - XHRやWebSocketを含めた通信一覧がみれる。
- Copy as cURL - 同じRequestを再現するコマンドをコピーできる
- Sources - JavaScriptのデバッガ
- Pretty Print - 難読化,minifyされたものをある程度読みやすくできる。やばいものはjsbeautifierとかを使おう。
- Step over/into/out - 動的デバッガには必須だよね
- Console - JavaScriptを直に叩ける。
- Resources - Cookie/WebStorageなどを表示できる。
- Network conditions - UserAgentの書き換え。
- Sensors - GPS情報のemulate
実際
備考 | ||
---|---|---|
HTML/CSS | [deleted] | |
CGI | [deleted] | |
SQL | http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all | |
Ajax | https://twitter.com/signup | メール欄とか |
WebSocket | http://agar.io | バイナリ... |
Cookie | https://wri.pe/app | 一瞬しか見せないよ |
WebStorage | http://www.rapidtables.com/tools/notepad.htm |