ちょっと某所でやっていてハマったのでメモ。
次に書いたような設定を書いても、反対側の口から何も出てこなかった場合にチェック。
cloned_interfaces="bridge0" ifconfig_bridge0="addm hn0 addm hn1 up" ifconfig_hn0="up" ifconfig_hn1="up"
チェックするところは下図で、オレンジ色で括っているところ。
「MAC アドレスのスプーフィングを有効にする」を ON にしているかどうかをチェック。
7/4 追記:
http://atom.someguy123.com/#sthash.qFfvJCrT.21QtBbhw.dpbs
ここで自動的にビルドしたやつを公開しているっぽいです。(やっぱし。。)
でも安定版を追っかけてるっぽいので、
git から clone してきて・・とする場合は、やっぱり自分でビルドする必要がありそうです。
GitHub さんが出しているコードエディタ。
何となく話題になっていましたので使おうと思ったのですが、
Mac 版しかバイナリが提供されておらず、
しょうが無いのでソースを取ってきて Windows 向けにビルドしました。
やったことはこのページに従っただけ。
https://github.com/atom/atom/blob/master/docs/build-instructions/windows.md
ただ、手持ちの常用環境ではうまくビルド出来ず、
仮想環境を用意してやったところ成功したので、ビルド出来ていない人は多いのかも。
リファレンスについてはこのあたりを見ておくととても良い気がします。
http://qiita.com/spesnova/items/d3096d062d70e7385e9d
Mac 用ですが、ここの “cmd” をすべて “CTRL” に読み替えれば大丈夫です。
というわけで、以下のリンクよりダウンロード可能です。
(容量が大きいので Google Drive にリダイレクトされます)
( Atom-0.109.0-68f2bd5.zip – Google Drive )
http://go.mimumimu.net/1xqfwoz
ビルドしたバージョンは 0.109.0-68f2bd5 になります。
またこのプログラムは MIT ライセンスになります。
http://opensource.org/licenses/mit-license.php
http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license
どうもみむらです。
先日、IPA が主催するセキュリティキャンプ 2014 の応募が締め切られまして、
噂では結構な倍率だったそうです。
http://www.ipa.go.jp/jinzai/camp/2014/zenkoku2014_sheet2.html
応募用紙は各クラス毎に大変難しい問題が用意されていて、
その中でも、特に今回は「ネットワーク・セキュリティ・クラス」の問題が難しいということで
少しやってみることにしました。
Windows 7 Service Pack1 の環境を用意します。
ファイルをダウンロードして・・
テキストファイル!
ということで開いてみますと・・
・・・全然テキストファイルじゃないですね。
これが闇か。
くよくよしていられませんので早速がんばってみます。
読めそうな部分に、 “Server : Apache/2.2.16(debian)” というようなものがあります。
“Apache” という名前で調べてみると、どうやら Web サーバのようで、
もしかするとこれは HTTP の通信では無いかというところが分かります。
また、先頭が “ヤテイ” になっているところから、pcap ファイルということで間違いなさそうです。
切り出してみれば何か分かるかもしれない!
HTTP なら “GET” があるはずということでそこ以降を切り出してみます。
・・・何か読めそうな文字が続きますが、それ以降が読めません。
帰ってくる内容だけ取り出してみることにします。
返答部分の最後が “Content-Type: text/plain” なのでそれを使います。
メモ帳で文字数をカウント。どうやら24文字のようです。
早速切り出してみます。でもやっぱりよく分からないデータはよく分からないデータ。
なにか余計なデータがあって、それによって化けてしまっているのかも!
・・てことで数字でデータを眺めてみます。
13,10,13,10.. 改行ですね。必要ないので削りましょう。
うん。良い感じ。これなら読める・・?
やっぱりダメですか・・?
エンコーディングが間違っているのかもしれません。
変換する処理を書くのは面倒なので、ファイルに書き出してメモ帳に与えてみます。
・・・やっぱり出ません。ちょっと何か見落としているんでしょうか。
HTTP ヘッダのところに “Content-Encoding: gzip” とあります。
でもメモ帳ではそういうエンコーディングは対応していないようです。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
仕様を見てみると、どうやらこれは gzip 圧縮を意味しているようです。
では残りの部分を gzip で展開させればデータが出ますね。
・・・いや、出ません。。
どうも調べてみると、通信時にパケットで分割されているらしく
そのまま後半の部分を与えても読めないようです。
確かに Content-Length をみるとなかなかに大きい値になっています。
TCP パケットの情報が分かれば・・というところですが、
「オプションフィールド」ということで可変長のデータが最後にくっついているため
後ろから見つけ出すのは問題がありそうです。
では pcap を頭から読むかとしても、
さすがに pcap を読むライブラリは入っていません。どうしたら良いでしょうか。
困ったときは仕様を見ます。
まず pcap から
http://wiki.wireshark.org/Development/LibpcapFileFormat
最初に pcap ファイルに関する情報が入っているようです。 (pcap_hdr_s)
ですが余りここには必要な情報はなさそうですので
4+2+2+4+4+4+4 = 0x18 分読み飛ばします。
typedef struct pcap_hdr_s { guint32 magic_number; /* magic number */ guint16 version_major; /* major version number */ guint16 version_minor; /* minor version number */ gint32 thiszone; /* GMT to local correction */ guint32 sigfigs; /* accuracy of timestamps */ guint32 snaplen; /* max length of captured packets, in octets */ guint32 network; /* data link type */ } pcap_hdr_t;
次に各パケット毎の情報が入っているようです。 (pcaprec_hdr_s)
取得時間とパケットのファイル上のサイズと実サイズが記述されています。
読み飛ばす際やパケットを処理する際に必要になるので、
8 – 12 にある incl_len を切り出しておきます。
typedef struct pcaprec_hdr_s { guint32 ts_sec; /* timestamp seconds */ guint32 ts_usec; /* timestamp microseconds */ guint32 incl_len; /* number of octets of packet saved in file */ guint32 orig_len; /* actual length of packet */ } pcaprec_hdr_t;
Little Endian なので
[System.Bitconverter]::ToInt32($data | Select-Object -Skip (0x18 + 8) -First 4),0)
とかすると数字に変換できます。
incl_len で指定された範囲にあるデータが1つあたりのパケットになり、
incl_len 分読み飛ばした場所にはまた パケット毎のヘッダ情報とデータがあります。
あとは仕様書に従って読んでいきます。
まずは イーサネットヘッダから
http://www.atmarkit.co.jp/ait/articles/0107/05/news001_3.html
最初のプリアンブル部分はどうも取得されていないようなので、宛先アドレス, 送信先アドレス, タイプ ってことで 6+6+2 = 14 バイト分読み飛ばします。
次に IP ヘッダ
http://www.atmarkit.co.jp/ait/articles/0304/04/news001_2.html
まずここの部分のサイズを取得する為にヘッダ長を取得します。
4bit ということで、8bit 単位でデータを取得した後で 0x0F を AND して取り出します。
出てきた数値は 32bit 単位ということですのでその値に ×4
コードとしては、
($ipheader[0] -band 0xF) * 4
とかすると、実際のサイズが出てきます。
サイズを求めたら、そのサイズ分読み飛ばします。
次に TCP ヘッダ
http://www.atmarkit.co.jp/ait/articles/0401/29/news080_2.html
まず、データ・オフセットを読みます。
これはアプリケーションが決めた送受信データ・・がどこから始まるかというのが書いてあり、
今回欲しいデータの始まる位置が分かります。
今回の場合は 上位 4bit ということで、 0xF で AND したあとで ÷16 を行い、
IP ヘッダと同じく 32bit 単位なので ×4 します。
コードとしては、
(($tcpheader[12] -band 0xf0) / 16) *4
こんな感じ。
そして、フラグも同様に切り出します。
[PSH], [ACK] を監視して PSH – ACK or [PSH,ACK] の区間を切り出してデータとして眺めるようにしてみます。
データとしては 先ほど取り出したデータオフセット(4bit)の直後から 12bit となります。
(要は 4bit + 8it)
コードとしてはこんな感じ:
($tcpheader[12] -band 0xF) * 256 + $tcpheader[13]
後は 先ほど取得したデータ・オフセット分だけデータを読み飛ばします。
ここまで来ればここから先は HTTP の通信データになります。(やったね!
何でしょうかこの、戻ってきた感じと達成感。
マリオRPG でもありましたよね。
クッパ城に最初に行って、なんか剣が突き刺さって・・
マップをぐるーっと回ってクッパ城に戻ってくる感じの。アレに似てますよね。
・・・・ちょっと時代が古いですかね。ごめんなさい。
さて。
まず HTTP 通信が行われているかどうかをさくっと判定します。
flag を見ても良いんですが 現在の位置が最初に取得したパケットのサイズを
パケットの頭の位置に足し合わせた値が一緒ならデータが無いので次のパケットを読み込みます。
ある場合にはデータを見ていきます。
・・とはいってもデータが取れているか気になるモンです。
なにか通信しているデータがある時にその中身を適当に表示させてみると。
・・・良い感じですね。良い感じでデータが出てきました。
あとは、Flag が PSH だけの間はそのデータを結合していき、
ACK or PSH,ACK が来たときにデータが完全に送られたと判断して、処理を行います。
データが取れたら、後は一番最初でやったように HTTP ヘッダを読み飛ばして下の部分だけ切り出し、
Gzip を展開します。
C# の GzipStream が使えますので、それを呼び出します。
http://msdn.microsoft.com/ja-jp/library/system.io.compression.gzipstream(v=vs.110).aspx
あとはそれをファイルに書き出すと・・。
テキストファイルが出てきました! これなら読めそうです。
・・・でも、ここからまた問題を解く必要がありそうです。
最後に今回作ったコードを貼り付けておきます:
$file = Get-Content "C:\Users\yahihashoo\Desktop\000038855.txt" -Encoding Byte $text = New-Object System.String($file,0,$file.Length) $p = 0x18 # PCAP の Header 分 $fin = 0 $stream = New-Object System.IO.MemoryStream $output = New-Object System.IO.FileStream "C:\Users\yahihashoo\Desktop\question.txt",([IO.FileMode]::Create),([IO.FileAccess]::Write),([IO.FileShare]::ReadWrite) do{ $size = [System.BitConverter]::ToInt32(($file | Select-Object -Skip ($p+4+4) -First 4),0) #packet size. $p += 4 * 4 # PCAP の各パケット分 $packet = ($file | Select-Object -Skip $p -First $size) $packetpos = 6 + 6 + 2 # Ethernet Frame. $srcip = $packet[$packetpos + 12] * 0x1000000 + $packet[$packetpos + 13] * 0x10000 + $packet[$packetpos + 14] * 0x100 + $packet[$packetpos + 15] $dstip = $packet[$packetpos + 16] * 0x1000000 + $packet[$packetpos + 17] * 0x10000 + $packet[$packetpos + 18] * 0x100 + $packet[$packetpos + 19] $packetpos += ($packet[$packetpos] -band 0xF) * 4 # IP Frame. $srcport = $packet[$packetpos] * 256 + $packet[$packetpos+1] $dstport = $packet[$packetpos+2] * 256 + $packet[$packetpos+3] $seq = $packet[$packetpos + 4] * 0x1000000 + $packet[$packetpos + 5] * 0x10000 + $packet[$packetpos + 6] * 0x100 + $packet[$packetpos + 7] $flag = (($packet[$packetpos + 12] -band 0x0f) * 256) + $packet[$packetpos + 13] $packetpos += (($packet[$packetpos + 12] -band 0xf0) / 16) * 4 if ($packetpos -ne $packet.Length) { $data = $packet | Select-Object -Skip $packetpos $html = [System.Text.Encoding]::ASCII.GetString($data) $htmlpos = $html.IndexOf("`r`n`r`n") if($htmlpos -lt 0) { $htmlpos = 0 $htmlbody = $data } else { Write-Host ([System.Text.Encoding]::ASCII.GetString(($data | Select-Object -First $htmlpos))) Write-Host "---------------------" $htmlpos += 4 $htmlbody = $data | Select-Object -Skip $htmlpos } if($null -ne $htmlbody -and $htmlbody.Length -ne -1) { $stream.Write($htmlbody,0,$htmlbody.Length) } if(($flag -band 0x8) -eq 0x8) #ACK { if($stream.Length -gt 0) { $stream.Position = 0 $gzipstream = New-Object System.IO.Compression.GzipStream $stream,([IO.Compression.CompressionMode]::Decompress) $buf = New-Object byte[](1024) do { $read = $gzipstream.Read($buf,0,1024) $output.Write($buf,0,$read) }while($read -gt 0) $output.Flush() $gzipstream.Close() } $stream.Close() $stream = New-Object System.IO.MemoryStream } } $p += $size }while($p -lt $file.Length) $output.Flush() $output.Close()
説明文中で書いた読み飛ばしよりも、若干丁寧に読んでます。
実際は シーケンス番号がちゃんと続いてるかとか、IP, PORT あたりの情報も使って
切り出そうと思ったのですが今回はご愛敬ということで。
(ただし、出せるのでやろうと思えば。。でもパケットの順番を見ていないので逆になったりとかするとダメですし、再送とかが発生しているやつを食べさせても処理できません。)
それと注意点として。
ネットワーク上の IP アドレスの値やポート番号、シーケンス番号などは
ビッグエンディアンで取り扱われています。
そのため、一つずつ取り出して掛け合わせるというような演算で求める必要があります。
( Linq とか使って4バイト出して反転してリトルエンディアンとして処理しても求まります。)
この辺を最初忘れていて、値を取り出すのに時間がかかったのは秘密。
解けるらしいですね。
http://yagihashoo.com/archives/683
なんでも、wireshark というソフトウェアを使えば
すぐに内容が抽出できるということで。
いやー・・。なんというかなんというか。。
ツールを知っていることは重要ですね。
もちろん、今回の記事はジョークです。
やぎはしゅ氏の解き方以外の write-up を書いてみるのもいいかもとかふと思った
— みむら (@mimura1133) 2014, 6月 16
@mimura1133 追加アプリケーションなし縛りで
— やぎはしゅ (@yagihashoo) 2014, 6月 16
こういうことになってしまった手前、やらねば、と。
もちろん Wireshark は普段使いますし、普段使うマシンにはすべて入れてあります。
こういう縛りなので、Windows 7 のマシンを一つ新規で作成して、
Windows Update を OFF にしてやってました。
PowerShell は最初から入っていることを知っていましたし、
C:\Windows\Microsoft.NET 以下に csc.exe という形で C# のコンパイラが最初から
入っていることも知ってました。
・・ま、PowerShell の方が、より面白そうということで。
・・・なんでこんな無駄な事をやったかってのがあるかと思いますが、
「こんなことも出来るんだよ!」と、
MSP (Microsoft Student Partners ) の端くれとしての意地、とでも言いましょうか。
大道芸ですごい無駄な事を真面目にやるような、
そんな、なんか気持ちを味わってもらえたらなと思ってやりました。
・・・もし感じて頂けたら本望です。
そして・・。
もしこの記事を今年のセキュリティ・キャンプの応募者の方が見ていて、
全力で端折った部分の内容がきちんと分かるということであれば、
応募用紙はさくさくっと書けたのでは無いかなと思います。
是非とも、セキュリティキャンプを通して今後の人生が変わるような、
そんなステキな体験が出来るように祈っています。
どうもみむらです。
IDS というと Snort というイメージも多いかと思いますが、
ふと Google なページをさまよっていたら Suricata というものを見つけましたので、
これを入れてみようかと。
環境としては CentOS 6.5 で Hyper-V 環境。
Windows Server 2012 (Windows 8) 以降の Hyper-V であればポートミラーリングが使えますので
その辺を使いつつ。
今回の環境では eth0 をミラーポートからのデータ受け付け用に
eth1 を管理用に構築してみます。
参考にしたところ:
http://n40lab.wordpress.com/2013/06/02/snorby-in-centos-6-4/
http://n40lab.wordpress.com/2013/05/31/installing-suricata-ids-from-source-centos-6-3/
https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Suricata_Snorby_and_Barnyard2_set_up_guide
https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Basic_Setup
Snorby が稼働するとこんな感じの画面が出ます:
かなりの長文なので「続きを読む」を使っていったん切ります・・
どうもみむらです。
何となく、わくわくして書きたくなったので。
今日公開!と build で出ていましたので、早速 MSDN Subscription に接続してダウンロード。
一般向けに公開される際は、Microsoft Update の一つになったりするとおもいますが、
MSDN Subscription のユーザ向けには .msu ファイルの入った zip ファイルで提供されていました。
ということで、順番通りにインストール-。
タスクバーを右クリックし、プロパティをクリックすると出てくるこの画面。
ここの「スタート画面では無くデスクトップに移動する」のチェックが
既定で有効になりまして、スタートスクリーンでは無くて、
デスクトップがいきなり表示されます。
(タッチなマシンだと、ここも変わってくると思います。)
・・もちろん、ここのチェックを OFF にすれば、従来通りの挙動になります。
次に気づくのは、タスクバー上にモダン UI のアプリがいること。
ちゃんとマウスオーバーすれば普通のデスクトップアプリと同じように表示されます。
これも、「Windows ストアアプリをタスクバーに表示する」を OFF にすれば切ることが出来ます。
そして、このあたりも普通のデスクトップなアプリと同じようなことが行えます。
×ボタンを押して閉じるとか。
スタートスクリーンの隅っこに、こんな感じでボタンが増えます。
ちなみに、アップデート適用前はこんな感じ:
でもって、ここからも電源が切れたり、再起動できたりします。
もちろん、従来通りチャームを呼び出してもOK
アップデート前は、タイルの並び替えのモードに入りましたが、
今度からは右クリックメニューからアンインストールやライブタイルの ON/OFF などが
切り替えられるようになります。
ストア版 IE で、こういう感じで画面下部にタブが出続けるようになりました。
もちろんコレも、設定で切ることは出来ます。
今までですと、画面上を掴んで、下に下げる・・なんて動作をマウスで行っていましたが、
アップデートされると、画面上部にマウスカーソルを持って行ったときに
最小化と閉じるボタンが出ますので、ここで管理できるようになります。
そして、このアプリを画面横に並べたりする際は、
今までのように「手の形」にして動かさなくても、
この黒い部分をドラッグすれば動くようになっています。
(デスクトップアプリのタイトルバーにほぼ近い挙動をします。)
今回のアップデートで、ちゃんと名前が修正されたようです。
・・・ぱっと見つけたのはこのあたりでしょうか。
一般向けには 4月8日に公開されるそうですが、
MSDN Subscription を持っている方は入れてみてはいかがでしょうか。
細かいところが使いやすくなっていて、よいアップデートかなと思います。
(また、Build 内で公開されていたスタートメニューに関しては含まれていませんでした。 さすがにアレを見たときに「スタートスクリーンに慣れてきたし・・」と思っていたので、ある意味含まれないのはアリなのかなと。)