カスペルスキーセキュリティセンター-自動化のための闘争

奇妙なことに、私はHabré でこのトピックに関する記事を1つだけ見つけました。サンドボックス内の記事と、製品に関する小さな作り直しの小さな断片実際に含む非常に未完成の 記事です。 そしてグーグルはクラカウトの要請に黙っている。



コマンドラインからKaspersky Security Centerの階層(以下KSCと呼びます)を管理する方法を説明するつもりはありません。これはこれまで必要ありませんでした。 自動化ツールに関するいくつかのアイデアを必要とする人と共有したいので、対処しなければならない1つのケースを分析します。 %habrauser%の場合、このトピックは興味深いものになります。



歴史的に、職場でのアンチウイルス保護の手段として、Kaspersky Lab製品(以下LCと呼びます)を好みます。 おそらく、私たちは舞台裏に個人的な意見の理由やその他の聖なる戦争を残すでしょう。



当然、美しいグラフ描画を一元的に展開、保護、 保護、防止し、既存の監視システムに統合し、仕事から患者の頭から健康なサーバーまで他のことを行いたいと思います。 そして、展開と保護の順ですべてが多かれ少なかれ(LKには何らかのオンライン製品コースがある場合でも)、統合はすでにより悲惨です: KSC 10.2.434の最新バージョンでは、統合はすでに2つで登場していますSIEM:ArcsightおよびQradar。 それだけです



KSCは、独自のものに統合するために最大2つのインターフェイスを提供します。





両方の点で、私がリンクを与えた記事に示されているように、KSCにドキュメントがあります。 確かに、このドキュメントには、CompanyAccountの企業向け製品サポートサービスに問い合わせて、 「洗練された情報。 残念ながら、klakautのスクリプトサポートは提供されていません。



klakdbの欠点は明らかです。データベースに直接アクセスするには、このデータベースにアクセスする必要があります。これにより、ファイアウォールでアクセスルールを作成したり、DBMSサーバーでアクセス権を設定したり、その他の非常に不愉快な操作を行うための追加のジェスチャーが必要になります。 もちろん、これらすべてのルールの関連性を監視することももちろんです。 特に興味深いのは、20以上のサーバーがあり、それぞれが独自の管理者を持つ異なるブランチにある場合です。



さて、このケーキのチェリー:読み取り専用にアクセスし、控えめに言っても、環境に関する不完全な情報にアクセスしてください。 利点はそれほど明白ではありませんが、ホストの数、使用されているウイルス対策およびウイルス対策データベースのバージョンについて、単一のサーバーに統計を非常に迅速にアップロードできます。 。



klakautはこの点で非常に興味深いです。階層のルートサーバーに接続することにより、KSCを使用してこの階層を通過し、必要なすべてのデータにアクセスできます。 たとえば、KSCサーバーのツリーを作成し、その中に生きているものとそうでないものがある場合、タスクを実行し、コンピューターを移動し、一般的に想像力を自由にします。



短所ももちろん、長くて難しいです。 統計を収集する必要がある場合は、最初に長時間スクリプトを作成し、次にバグを長時間キャッチして、それが機能するのを待つ必要があります。



当然、両方のメカニズムを一緒に使用することを誰も禁止していません(少なくとも私は知りません)。たとえば、klakautを使用してサーバー階層を調べ、使用されているデータベースに関する情報を含むKSCサーバーの完全なリストを取得し、この情報を他のユーザーに転送します廃止されたルールをファイアウォールから削除し、新しいルールを作成し、アクセス許可を与えてコーヒーを寝かせ、監視システム内のデータソースのリストを編集し、それがリストをポーリングし、 クラカウトの助けを借りて、彼は何か逸脱したことで、何か良いことをするでしょう。 まあ、または単にトラッカーにインシデントを登録してください。 その後、管理者は手動で適切な処理を行います。



これらすべての考慮事項に触発されて、最初のスクリプトを書きました。



ここにいる
 $Params = New-Object -ComObject 'klakaut.KlAkParams'; $Params.Add('Address', 'localhost:13000'); $Params.Add('UseSSL', $true); $Proxy = New-Object -ComObject 'klakaut.KlAkProxy'; try { $Proxy.Connect($Params); $Proxy.Disconnect(); } catch { $_; } Remove-Variable -Name 'Params'; Remove-Variable -Name 'Proxy';
      
      







サーバー上で起動しました:



 Exception calling "Connect" with "1" argument(s): "Transport level error while connecting to http://localhost:13000: authentication failure" At line:7 char:5 + $Proxy.Connect($Params); + ~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ComMethodTargetInvocation
      
      





最初はいいです。



愛人メモ
jsを使用する場合、このエラーは発生しません。 なぜだろうか。



KSCコンソールを開いた後、私はすべての権利が揃っていると確信していました。



残念ながら、KSCは失敗したログイン試行を記録しません。 ベンダーとの通信では、失敗したログイン試行のロギングをオンにできることが示されました(これは別の興味深い話でしたが、まだ終了していませんでした)が、この特定の試行はとにかくログへのアクセスを拒否しました。



これを行うことができるようです:



無効なスクリプト
 $ Params = New-Object -ComObject 'klakaut.KlAkParams';
 $ Params.Add( 'Address'、 'localhost:13000');
 $ Params.Add( 'UseSSL'、$ true);

 #------------ログインデータを明示的に入力しましょう------------------------------ -
 $ Params.Add( 'User'、 'kavadmin');
 $ Params.Add( 'Password'、 'P @ ssw0rd');
 $ Params.Add( 'Domain'、 'test');
 #------------------------------------------------- ----------------------------------

 $ Proxy = New-Object -ComObject 'klakaut.KlAkProxy';
 {
     $ Proxy.Connect($パラメーター);
     $ Proxy.Disconnect();
 }

 Remove-Variable -Name 'Params';
 Remove-Variable -Name 'Proxy';




この場合、エラーは発生しませんが、スクリプト内でクリアテキストパスワードを使用してログインを示すことは、私にとって素晴らしい考えではなかったようです。 LKのテクニカルサポートとの新しいやり取りにより、次の推奨事項が得られました。



COMの設定の[既定のプロパティ]タブで設定する必要があります。

デフォルト認証レベル:パケット

デフォルトの偽装レベル:委任


この指示により元のスクリプトが機能しましたが、セキュリティの点で疑わしいように思えたので、もう少し詳しく調べることにしました。 しばらく検索した後、特定のオブジェクトに指定された認証レベルと偽装レベルを設定する方法を教えてくれた親切な人がいました。



正しいスクリプト
 $ Params = New-Object -ComObject 'klakaut.KlAkParams';
 $ Params.Add( 'Address'、 'localhost:13000');
 $ Params.Add( 'UseSSL'、$ true);

 $ Proxy = New-Object -ComObject 'klakaut.KlAkProxy';

 $ code = @ "
システムを使用して;
 System.Runtime.InteropServicesを使用します。

パブリッククラスPowershellComSecurity
 {
    [DllImport( "Ole32.dll"、CharSet = CharSet.Auto)]
    public static extern int CoSetProxyBlanket(IntPtr p0、uint p1、uint p2、uint p3、uint p4、uint p5、IntPtr p6、uint p7);

    public static int EnableImpersonation(オブジェクトobjDCOM){Return CoSetProxyBlanket(Marshal.GetIDispatchForObject(objDCOM)、10、0、0、0、3、IntPtr.Zero、0);  }
 }
 「@
 Add-Type -TypeDefinition $コード。
 Remove-Variable -Name 'code';

 [PowershellComSecurity] :: EnableImpersonation($プロキシ)| ヌルなし;

 {
     $ Proxy.Connect($パラメーター);
     #<-ここにコードを挿入します
     $ Proxy.Disconnect();
 } catch {
     $ _;
 }

 Remove-Variable -Name 'Params';
 Remove-Variable -Name 'Proxy';




そのため、スクリプトはエラーを出しませんでした。 最初のクエストが完了しました。



愛人メモ
一般に、戦闘環境では、EnableImpersonationを呼び出すときにエラーの戻り値をチェックし、それをどこにもリダイレクトしないようにすると便利です。



次のタスク:使用されるデータベースに関するデータをKSCから取得します。



しかし、ここではすべてが複雑です。これを行う方法に関するドキュメントは沈黙しています。 KlAkProxyクラスの調査では、KLADMSRV_SERVER_HOSTNAMEパラメーターがKSCがインストールされているコンピューターの識別子であることが判明したことを除いて、興味深いことは何も明らかになりませんでした。



コンピューターに移りましょう。これには特別なクラスKlAkHosts2があります。 コードの量を減らすために、tryブロックの内容のみを引用します。



ブロックしてみて
 {
     $ Proxy.Connect($パラメーター);
     $ KSCHost = New-Object -ComObject 'klakaut.KlAkHosts2';
     $ KSCHost.AdmServer = $プロキシ;
     $ HostParams = New-Object -ComObject 'klakaut.KlAkCollection';
     $ HostParams.SetSize(1);
     $ HostParams.SetAt(0、 'KLHST_WKS_DN');
     ($ KSCHost.GetHostInfo($ Proxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')、$ HostParams))。アイテム( 'KLHST_WKS_DN');
     Remove-Variable -Name 'HostParams';
     Remove-Variable -Name 'KSCHost';
     $ Proxy.Disconnect();
 }




注:KSCに接続するときに使用した$ Params変数は、KlAkParamsクラスのインスタンスです。 私の意見では、同様の機能を持つ変数$ HostParamsは、KlAkCollectionクラスのインスタンスです。 なぜ異なるクラスが使用されるのですか?想像することすら恐れています。 どうやら、SetAtが最初の引数として整数値のみをとるという事実は非常に基本的なポイントです。



このコードは値「KSC」を返しました。これは、私が正しい軌道に乗っていることを意味します。



KlAkHosts2クラスのGetHostInfoメソッドはよく文書化されていますが、必要な情報は含まれていません。 ああ、ああ。 ただし、GetHostSettingsメソッドがあります。 全体の説明は次のように要約されます。



ホストの設定を設定ストレージとして返します。



内部を見てみましょう:



試してみる
 {
     $ Proxy.Connect($パラメーター);
     $ KSCHost = New-Object -ComObject 'klakaut.KlAkHosts2';
     $ KSCHost.AdmServer = $プロキシ;
     $ KSCSettings = $ KSCHost.GetHostSettings($ Proxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')、 'SS_SETTINGS');
     $ KSCSettings.Enum()|  %{
         '------------------------';
         $ tmp = $ _;
         $ tmp |  %{"$ _ = $($ tmp.Item($ _))";};
         Remove-Variable -Name 'tmp';
     };
     Remove-Variable -Name 'KSCSettings';
     Remove-Variable -Name 'KSCHost';
     $ Proxy.Disconnect();
 }




結果
 ------------------------
 PRODUCT = .core
 SECTION = SubscriptionData
バージョン= .independent
 ------------------------
製品= 1093
セクション= 85
バージョン= 1.0.0.0
 ------------------------
製品= 1093
セクション= 87
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLEVP_NF_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLNAG_SECTION_DPNS
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_CONSRVINIT
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_CONSRVUPGRADE
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_DEF_NAGENT_PACKAGE
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_MASTER_SRV
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_NETSIZE_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_PKG_ANDROID_CERT_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_PROXY_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_SRVLIC_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KLSRV_USER_ACCOUNTS_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KSNPROXY_KEY_STORAGE
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION = KSNPROXY_SETTINGS
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION =パッケージ
バージョン= 1.0.0.0
 ------------------------
製品= 1093
 SECTION =アップデーター
バージョン= 1.0.0.0
 ------------------------
製品= 1103
セクション= 85
バージョン= 1.0.0.0
 ------------------------
製品= 1103
セクション= 86
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION = FileTransfer
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION = KLEVP_NF_SECTION
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION = KLNAG_KLNLA_DATA
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION = KLNAG_SECTION_NETSCAN
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION = KLNAG_SECTION_SERVERDATA
バージョン= 1.0.0.0
 ------------------------
製品= 1103
 SECTION =アップデーター
バージョン= 1.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION = .KLNAG_SECTION_REBOOT_REQUEST
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
セクション= 85
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =バックアップセクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =ビジネスロジックセクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION = HSMシステムセクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =内部製品情報
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION = KLEVP_NF_SECTION
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =通知セクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =定義済みタスクセクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =検疫セクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =レポートセクション
バージョン= 8.0.0.0
 ------------------------
製品= KAVFSEE
 SECTION =信頼できるプロセスセクション
バージョン= 8.0.0.0




klakaut.chmには、「製品のKLHST_WKS_PRODUCT_NAMEおよびKLHST_WKS_PRODUCT_VERSION値のリスト」セクションがあり、KSCのPRODUCTフィールドはそれぞれ1093である必要があり、他のすべては安全に無視できます。 これまでのところ、少なくとも。



セクションの名前に目を通したので、85と87を見ることにしました。他のものは必要なものとあまり似ていなかったからです。



試してみる
 {
     $ Proxy.Connect($パラメーター);
     $ KSCHost = New-Object -ComObject 'klakaut.KlAkHosts2';
     $ KSCHost.AdmServer = $プロキシ;
     $ KSCSettings = $ KSCHost.GetHostSettings($ Proxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')、 'SS_SETTINGS');
     $ KSCSettings.Read( '1093'、 '1.0.0.0'、 '85');
     '-----------------';
     $ KSCSettings.Read( '1093'、 '1.0.0.0'、 '87');
     Remove-Variable -Name 'KSCSettings';
     Remove-Variable -Name 'KSCHost';
     $ Proxy.Disconnect();
 }




結果
イベントフォルダ
 EventStoragePath
 KLAG_WAIT_SCHED_FOR_START_EVENT
 TaskStoragePath
 -----------------
 KLSRV_AD_SCAN_ENABLED
 KLSRV_CONNECTION_DATA
 KLSRV_DATABASENAME
 KLSRV_NET_SCAN_ENABLED
 KLSRV_SERVERINSTANCENAME
 KLSRV_SP_DPNS_ENABLE
 KLSRV_SP_FASTUPDATENET_PERIOD
 KLSRV_SP_FULLUPDATENET_PERIOD
 KLSRV_SP_INSTANCE_ID
 KLSRV_SP_MAX_EVENTS_IN_DB
 KLSRV_SP_OPEN_AKLWNGT_PORT
 KLSRV_SP_SCAN_AD
 KLSRV_SP_SERVERID
 KLSRV_SP_SERVERID_DPE
 KLSRV_SP_SERVER_AKLWNGT_PORTS_ARRAY
 KLSRV_SP_SERVER_PORTS_ARRAY
 KLSRV_SP_SERVER_SSL_PORTS_ARRAY
 KLSRV_SP_SERVER_SSL_PORTS_ARRAY_GUI
 KLSRV_SP_SYNC_LIFETIME
 KLSRV_SP_SYNC_LOCKTIME
 KLSRV_SP_SYNC_SEC_PACKET_SIZE
 KLSRV_SSL_CERT_RSA_BIT_NUMBER




どうやら、第85項はイベントの原因であり、現在、私たちには興味がありません。 しかし、87年には注意する価値のあるものがあります。



試してみる
 {
     $ Proxy.Connect($パラメーター);
     $ KSCHost = New-Object -ComObject 'klakaut.KlAkHosts2';
     $ KSCHost.AdmServer = $プロキシ;
     $ KSCSettings = $ KSCHost.GetHostSettings($ Proxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')、 'SS_SETTINGS');
     $ 87 = $ KSCSettings.Read( '1093'、 '1.0.0.0'、 '87');
     "KLSRV_SERVERINSTANCENAME = $($ 87.Item( 'KLSRV_SERVERINSTANCENAME'));
     "KLSRV_DATABASENAME = $($ 87.Item( 'KLSRV_DATABASENAME'))";
     "KLSRV_CONNECTION_DATA =` r`n $($ 87.Item( 'KLSRV_CONNECTION_DATA')|%{"` t $ _ = $($ 87.Item( 'KLSRV_CONNECTION_DATA')。Item($ _)) `r`n";} ) ";
     Remove-Variable -Name '87';
     Remove-Variable -Name 'KSCSettings';
     Remove-Variable -Name 'KSCHost';
     $ Proxy.Disconnect();
 }




結果
 KLSRV_SERVERINSTANCENAME =。
 KLSRV_DATABASENAME = KAV
 KLSRV_CONNECTION_DATA =
	 KLDBCON_DB = KAV
 	 KLDBCON_DBTYPE = MSSQLSRV
 	 KLDBCON_HOST =。




次に、KLSRV_CONNECTION_DATAから必要なデータを取得する必要があると言われた以前のケースの1つを利用しました(それが何であるかはまったくわかりませんでしたが、延期されました)。



まあ、基本的にはそれです。 使用済みデータベースのデータが受信されます。 クエストが完了しました。



サーバー階層をウォークスルーするためのスクリプトをスケッチするといいでしょう。 ここには不思議なものは何もありませんでした。すべては完全に文書通りでした。 親のUID、サーバー自体のUID、DBMSインスタンス、およびデータベース名を選択し、セパレーターを介してstdoutに表示するスクリプトを作成しました。



スクリプト
 $ SrvAddr = 'localhost:13291'

関数EnumSrv(
     $ Pxy、
     [bool] $ IsAlive = $ true、
     [文字列] $ ParentPxyId = 'ルート'
 )
 {
     [文字列] $ result = "$ ParentPxyId";
     if($ IsAlive){
         $ result + = "| $($ Pxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME'))";
        
         $ Hosts = New-Object -ComObject 'klakaut.KlAkHosts2';
         $ Hosts.AdmServer = $ Pxy;
        
         $ Settings = $ Hosts.GetHostSettings($ Pxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')、 'SS_SETTINGS')。読み取り( '1093'、 '1.0.0.0'、 '87')。Item( 'KLSRV_CONNECTION_DATA');
         Remove-Variable -Name 'Hosts';
    
         # '--------> DB情報<--------';
         $ result + = "| $($ Settings.Item( 'KLDBCON_HOST'))";
         $ result + = "| $($ Settings.Item( 'KLDBCON_DB'))";
         # '-----------------------------';
        
         Remove-Variable -Name 'Settings';
        
         $ SlaveSrvEnum = New-Object -ComObject 'klakaut.KlAkSlaveServers';
         $ SlaveSrvEnum.AdmServer = $ Pxy;
         $ SlaveServers = $ SlaveSrvEnum.GetServers(-1);
        
         $ SlaveServers |  %{
             $子= $ _;
             $ TmpSrvId = $ Child.Item( 'KLSRVH_SRV_ID');
             $ HostActive = $ true;
            試してみる
             {
                 $ TmpSrv = $ SlaveSrvEnum.Connect($ TmpSrvId、-1);
             }
            つかまえる
             {
                 $ HostActive = $ false;
             };
             if($ HostActive){$ HostActive =($ TmpSrv.GetProp( 'IsAlive')-eq 1);};
             $ result + = "` r`n $(EnumSrv -Pxy $ TmpSrv -IsAlive $ HostActive -ParentPxyId $ Pxy.GetProp( 'KLADMSRV_SERVER_HOSTNAME')) ";
         };
         Remove-Variable -Name 'SlaveServers';
         Remove-Variable -Name 'SlaveSrvEnum';
     };
     return( "$ result`r`n");
 }

ホストをクリア

 $ Params = New-Object -ComObject 'klakaut.KlAkParams'
 $ Params.Add( 'Address'、$ SrvAddr)
 $ Params.Add( 'UseSSL'、$ true)

 $ code = @ "
システムを使用して;
 System.Runtime.InteropServicesを使用します。

パブリッククラスPowershellComSecurity
 {
    [DllImport( "Ole32.dll"、CharSet = CharSet.Auto)]
    public static extern int CoSetProxyBlanket(IntPtr p0、uint p1、uint p2、uint p3、uint p4、uint p5、IntPtr p6、uint p7);

    public static int EnableImpersonation(オブジェクトobjDCOM){Return CoSetProxyBlanket(Marshal.GetIDispatchForObject(objDCOM)、10、0、0、0、3、IntPtr.Zero、0);  }
 }
 「@
 Add-Type -TypeDefinition $コード

 $ Srv = New-Object -ComObject 'klakaut.KlAkProxy'
 [PowershellComSecurity] :: EnableImpersonation($ Srv)| ヌル
 $ Srv.Connect($パラメーター)

 "ParentPxyId | KLADMSRV_SERVER_HOSTNAME | KLDBCON_HOST | KLDBCON_DB`r`n" +(EnumSrv -Pxy $ Srv);
 Remove-Variable -Name 'Srv';
 Remove-Variable -Name 'Params';




スタンドは小さいため、結果はそれほど印象的ではありませんでした。



結果
 ParentPxyId | KLADMSRV_SERVER_HOSTNAME | KLDBCON_HOST | KLDBCON_DB
ルート| 9d476a75-1e36-4c0e-8145-56e5b888df67 |。| KAV
 9d476a75-1e36-4c0e-8145-56e5b888df67 | ef4fc3be-3abd-4322-ae35-2c50afdce780 |。\ KAV_CS_ADMIN_KIT | KAV




当然、ポイントを実際のサーバー名に変換するには、KlAkHosts2.GetHostInfo()を使用する必要がありますが、これはそれほど恐ろしくなく、コードを追加するだけです。



LKのテクニカルサポートは、当然のことながら、SS_SETTINGS構造が将来のKSCリリースで変更される可能性があるので、そうしないことをお勧めします。 残念ながら、私の内部の完璧主義者でさえ、スクリプトを簡単に記述して忘れることはできないと考えています。使用するソフトウェアのバージョンを変更するときは、何らかの方法でテストおよびデバッグする必要があります。 ですから、今のところ、私たちは持っているものを使用します。幸いなことに、問題が解決した時点で問題を解決します。



All Articles