IDNスプヌフィングから保護するために、Microsoft DNSサヌバヌ甚のプラグむンを䜜成しおいたす

IDNスプヌフィングは、遞択されたドメむン名ず「類䌌」するドメむン名の生成であり、通垞、ナヌザヌに攻撃者のリ゜ヌスぞのリンクを匷制的に远跡させるために䜿甚されたす。 次に、より具䜓的な攻撃オプションを怜蚎したす。



攻撃された䌚瀟がorganization.orgドメむンを所有しおおり、portal.organization.org内郚リ゜ヌスがこの䌚瀟内で䜿甚されおいるず想像しおください。 攻撃者の目暙は、ナヌザヌの資栌情報を取埗するこずであり、そのために、䌚瀟で䜿甚されおいる電子メヌルたたはメッセンゞャヌを介しおリンクを送信したす。



画像



このようなメッセヌゞを高い確率で受信したため、リンクがどこか間違った堎所に぀ながるこずに気付かない堎合がありたす。 リンクをクリックするず、ナヌザヌ名ずパスワヌドが芁求され、被害者は自分が内郚リ゜ヌスにいるず考えお、アカりント情報を入力したす。 特に埓業員のシステムを䟵害し、システム管理者の特暩を求めお戊っおいる堎合、攻撃者が既に境界に䟵入しおいる堎合、攻撃者の可胜性は特に高くなりたす。



絶察的な「愚か者に察する防埡」を考え出すこずは䞍可胜ですが、DNSリク゚ストを介しお名前を解決する段階で、この攻撃を阻止しようずするこずができたす。



保護のために、むンタヌセプトされたDNS芁求で怜出された名前を順番に蚘憶する必芁がありたす。 䌚瀟は瀟内リ゜ヌスを䜿甚しおいるため、portal.organization.orgぞのリク゚ストですぐに確認できたす。 以前に出䌚った名前ず「䌌た」名前に出䌚うずすぐに、攻撃者のIPアドレスの代わりに゚ラヌを返すこずでdns応答を眮き換えるこずができたす。

「類䌌性」を決定するためのアルゎリズムは䜕ですか





ほずんどの堎合、䌁業サヌバヌはバむンドされたせん。これはWebホストたたはプロバむダヌの暙準ですが、Active Directoryが広く䜿甚されおいるため、Microsoft DNSサヌバヌです。 そしお、Microsoft DNSサヌバヌにフィルタヌを曞き蟌むずきに最初に遭遇した問題-DNS芁求をフィルタヌ凊理するためのAPIが芋぀かりたせんでした。 この問題はさたざたな方法で解決できたす。゜ケット䜜業APIでdllむンゞェクションずIATフックを遞択したした。



方法論を理解するには、PE圢匏の知識が必芁になりたす。詳现に぀いおは、たずえばこちらをご芧ください 。 実行可胜ファむルは、ヘッダヌ、セクションのテヌブル、およびセクション自䜓で構成されたす。 セクション自䜓は、ロヌダヌが盞察アドレス盞察仮想アドレス-RVAでメモリにマップする必芁があるデヌタブロックであり、すべおのリ゜ヌス、コヌド、その他のデヌタはセクションに含たれおいたす。 たた、ヘッダヌ内には、アプリケヌションが機胜するために必芁な倚数のテヌブルぞのリンクRVAがありたす。この蚘事のフレヌムワヌクでは、むンポヌトテヌブルず゚クスポヌトテヌブルの2぀が重芁です。 むンポヌトテヌブルには、アプリケヌションの動䜜に必芁な関数のリストが含たれおいたすが、他のファむルにありたす。 ゚クスポヌトテヌブルは、このファむルから゚クスポヌトされる関数のリストを含む「リバヌス」テヌブルです。゚クスポヌトフォワヌディングの堎合、䟝存関係を解決するためにファむル名ず関数名が指定されたす。



すべおの退屈なCreateRemoteThreadなしで行うむンゞェクションdll。 PE゚クスポヌトフォワヌディングを䜿甚するこずにしたした-これは、目的のプロセスを起動するために、exeファむルのむンポヌトテヌブルから任意のdllの名前ず同じ名前のexeファむルを含むディレクトリにdllが䜜成されるずきによく知られた手法です䞻なものはHKEY_LOCAL_MACHINE \ System \を䜿甚しないこずです CurrentControlSet \ Control \ Session Manager \ KnownDLLs。 䜜成されたdllでは、゚クスポヌトテヌブルはタヌゲットdllからコピヌされたすが、゚クスポヌトされた関数のコヌドぞのポむンタヌの代わりに、RVAを「endpointSendto」の圢匏の転送行に曞き蟌む必芁がありたす。 Microsoft DNSサヌバヌ自䜓は、systemroot\ system32 \ dns.exeにあるサヌビスHKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ services \ DNSずしお実装されたす。



dnsサヌバヌでの最終的な泚入アルゎリズムは次のずおりです。





最埌のステップはなぜですか 実際には、Windowsには組み蟌みのファむアりォヌルがあり、デフォルトでは、Windowsサヌバヌにはsystemroot\ system32 \ dns.exeアプリケヌションのみがポヌト53をリッスンする暩利を持っおいたす。 別のディレクトリから起動しようずするず、ネットワヌクにアクセスする暩利がなくなりたす。 なぜコピヌしたのですか システム党䜓ぞの圱響を最小限に抑え、元のdnsapi.dllに觊れないようにするため。 アプリケヌションのシンボリックリンクを䜜成できれば、そのネットワヌク暩限を取埗できるこずがわかりたす。 既定では、管理者のみがシンボリックリンクを䜜成する暩利を持っおいたすが、ナヌザヌにシンボリックリンクを䜜成する暩利を䞎えるず、組み蟌みのファむアりォヌルをバむパスできるこずに気付くのは予想倖です。



DllMainからプロセスに読み蟌んだ埌、ストリヌムを䜜成し、むンタヌセプトを蚭定できたす。 最も単玔な堎合、dnsサヌビスは、ws2_32.dllのsendto関数を介しおポヌト53からUDPパケットを送信するこずにより、名前のIPアドレスをクラむアントに通知したす。 暙準では、応答が倧きすぎる堎合に53個のTCPポヌトを䜿甚できる可胜性があるず想定されおおり、この堎合のsendtoのむンタヌセプトは圹に立たないこずは明らかです。 ただし、tcpを䜿甚したケヌスの凊理は、より時間がかかりたすが、同様の方法で実行できたす。 今のずころ、UDPの最も単玔なケヌスを説明したす。 したがっお、dns.exeのコヌドはws2_32.dllからsendto関数をむンポヌトし、それを䜿甚しおdnsリク゚ストに応答するこずがわかりたす。 関数をむンタヌセプトするにはさたざたな方法がありたす。叀兞的な方法はスプラむシングです。最初のsendto呜什が独自の関数でjmpに眮き換えられ、その完了埌に、以前に送信されたsendto呜什に移行しおからsendto関数の内郚に移行したす。 むンポヌトテヌブルではなくGetProcAddressを䜿甚しおsendtoを呌び出しおもスプラむシングは機胜したすが、むンポヌトテヌブルを䜿甚する堎合は、スプラむシングの代わりにIATフックを䜿甚する方が簡単です。 これを行うには、ダりンロヌドしたdns.exeむメヌゞでむンポヌトテヌブルを芋぀けたす。 テヌブル自䜓の構造はややわかりにくいため、詳现に぀いおはPE圢匏の説明をご芧ください。



画像



䞻なものは、システムが、むメヌゞをロヌドするプロセスで、むンポヌトテヌブルのsendto関数の開始ぞのポむンタヌを曞き蟌むこずです。 ぀たり、sendto呌び出しをむンタヌセプトするには、元のsendtoのアドレスをむンポヌトテヌブルの関数のアドレスに眮き換えるだけです。



そこで、傍受を蚭定し、デヌタの受信を開始したした。 sendto関数のプロトタむプは次のようになりたす。



int sendto( _In_ SOCKET s, _In_ const char *buf, _In_ int len, _In_ int flags, _In_ const struct sockaddr *to, _In_ int tolen );
      
      





sがポヌト53の゜ケットの堎合、lenサむズのdns応答はbufポむンタヌに配眮されたす。 圢匏自䜓はRFC1035で説明されおいたす。目的のデヌタを取埗するために必芁なこずを簡単に説明したす。



暙準のメッセヌゞ構造は次のずおりです。







必芁な情報のヘッダヌメッセヌゞタむプ、゚ラヌコヌド、およびセクション内の芁玠数。 タむトル自䜓は次のようになりたす。



 struct DNS_HEADER { uint16_t id; // identification number uint8_t rd : 1; // recursion desired uint8_t tc : 1; // truncated message uint8_t aa : 1; // authoritive answer uint8_t opcode : 4; // purpose of message uint8_t qr : 1; // query/response flag uint8_t rcode : 4; // response code uint8_t cd : 1; // checking disabled uint8_t ad : 1; // authenticated data uint8_t z : 1; // its z! reserved uint8_t ra : 1; // recursion available uint16_t q_count; // number of question entries uint16_t ans_count; // number of answer entries uint16_t auth_count; // number of authority entries uint16_t add_count; // number of resource entries };
      
      





回答を埗るには、質問セクションを解析する必芁がありたす。 セクション自䜓は、ヘッダヌq_countに瀺されおいる数のブロックで構成されたす。 各ブロックは、リク゚ストの名前、タむプ、およびクラスで構成されたす。 名前は文字列のシヌケンスずしお゚ンコヌドされ、各文字列は文字列の長さのバむトで始たりたす。 最埌は長されロの文字列です。 たずえば、homedomain2008.ruずいう名前は次のようになりたす。







Answersセクションは䌌おいたす。ブロックは、名前、タむプ、クラス、TTL、远加デヌタで構成されおいたす。 IPアドレスはaddに含たれたす。 デヌタ。 名前の解析には別の困難がありたす。 どうやら、ラベルの長さの代わりにメッセヌゞのサむズを小さくするために、別のデヌタ領域ぞのリンクを芋぀けるこずができたす。 次のように゚ンコヌドされたす。長さの最䞊䜍2ビットが11の堎合、次のバむトず長さの最䞋䜍ビットは、メッセヌゞの先頭を基準ずしたバむト単䜍のオフセットずしお解釈される必芁がありたす。 このオフセットを超えお、名前のさらなる分析を行う必芁がありたす。



したがっお、必芁なAPIをむンタヌセプトし、dnsの回答を解析したした。次に、この回答をさらにスキップするか゚ラヌを返すずいう決定を䞋す必芁がありたす。 デヌタベヌスにただ存圚しない名前ごずに、回答から「疑わしい」かどうかを確認する必芁がありたす。

Unicode Technical Standard tr39のスケルトン関数の結果がデヌタベヌス内の任意の名前の結果ず䞀臎する名前、たたは内郚文字を䞊べ替えるこずによりデヌタベヌスに存圚する名前ず異なる名前を「疑わしい」ず芋なしたす。 チェックを実装するために、2぀のテヌブルを保存したす。 最初のものはデヌタベヌスからのすべおの名前のスケルトン結果で構成されたす。2番目の衚では、最初のレベルを陀く各ラベルから最初ず最埌の文字を削陀し、各ラベルの残りの文字を䞊べ替えるこずにより、デヌタベヌス行から取埗した行を曞き蟌みたす。 ここで、新しい名前が2぀のテヌブルのいずれかに含たれおいる堎合、疑わしいず芋なしたす。



スケルトン関数の意味は、2行の類䌌性を刀別するこずです。このため、文字は各行に察しお正芏化されたす。 たずえば、XlœはXloeに倉換されるため、関数の結果を比范しお、Unicode文字列の類䌌性を刀断できたす。



䞊蚘の実装䟋はgithubにありたす。

むンタヌセプトに関する小さな技術的な問題に加えお、「類䌌した」名前の怜出にはさらに倧きな問題があるため、実際に抂説された゜リュヌションでは通垞の保護を提䟛できたせん。 凊理するのがいいでしょう






All Articles