すべてのプロダクト
Search
ドキュメントセンター

Security Center:悪意のあるファイルの検出

最終更新日:Sep 17, 2026

悪意のあるファイルの検出は、Security Center が提供するファイルセキュリティ検出サービスです。ファイルアップロード、コードリリース、データ共有などのビジネスシナリオで持ち込まれる可能性のあるランサムウェア、マイニングプログラム、Webshel​​l などの悪意のあるファイルを検出し、ビジネスシステムやデータのセキュリティへの脅威を防ぐために使用されます。マルチエンジン検出プラットフォーム上に構築されたこのサービスは、Object Storage Service (OSS) およびサーバー側のファイルを検出でき、コンソール操作や SDK 統合など複数の検出方法を提供します。従量課金で有効化されたエージェント型悪意のあるファイル検出は、AI 大規模言語モデル検出、Skill ファイル検出、NAS ファイル検出をさらにサポートします。このトピックでは、さまざまな役割のユーザーが、ビジネスシナリオに応じて最適な検出方法を迅速に選択できるよう、その方法について説明します。

事前準備

悪意のあるファイルの検出を有効化済みであること。利用できる検出機能は、サービスを有効化した際の課金方法によって異なります。

  • サブスクリプションベースで悪意のあるファイルの検出を有効化した場合、マルチエンジン検出、圧縮ファイル検出、暗号化ファイル検出などの基本機能を使用できます。AI 大規模言語モデル検出、Skill ファイル検出、NAS ファイル検出はサポートされていません

  • 従量課金ベースでエージェント型悪意のあるファイル検出を有効化した場合、悪意のあるファイルの検出機能に加えて、AI 大規模言語モデル検出、Skill ファイル検出、NAS ファイル検出も使用できます。

適用範囲

  • サポートされているファイルタイプ

    • 圧縮ファイル検出:暗号化されていない圧縮パッケージの展開とスキャンをサポートします。展開レベルとファイル数は設定可能です。この設定は OSS ファイルにのみ適用されます。

    • 暗号化ファイル検出:OSS サーバー側暗号化 (SSE-KMS, SSE-OSS) で暗号化されたデータの自動復号とスキャンをサポートします。これは OSS ファイルにのみ適用されます。

    • NAS ファイル検出 (従量課金のみ):Apsara File Storage NAS 内のファイルの検出をサポートします。サポートされているファイルシステムタイプ、ゾーン、および制限は、コンソールの表示に準じます。

    • Skill ファイル検出 (従量課金のみ):Skill ファイルに特化した検出機能を提供し、より多くのファイル形式と攻撃シナリオをカバーします。

  • サポートされているファイル形式:圧縮パッケージ、スクリプト/Webshel​​l、イメージ、実行可能ファイル/バイナリファイルなど、複数のファイルタイプがサポートされています。ここでは一般的なタイプのみをリストアップしています。サポートされているタイプの完全なリストについては、コンソールの表示をご参照ください。

    • 圧縮パッケージ:.7z.zip.rar.tar.gz.bz2.xz.lzma.ar.tar.gz など。

    • スクリプト/WebShell:.php.jsp.jspx.asp.aspx.sh.py.ps1.pl.bat.html など。

    • ドキュメント:.doc.pdf.ppt.xsl.rtf.hta.chm.docx など。

    • イメージ:.jpg.jpeg.png など。

    • 実行可能ファイルとバイナリ:.apk.exe.dll.ocx.com.so.sys.ko.obj など。

  • サポートされているウイルスの種類:リバースシェルバックドア、DDoS 攻撃型トロイの木馬、マイニングプログラム、その他のウイルスファイルの検出をサポートします。詳細については、「サポートされているウイルスの種類」をご参照ください。

  • ストレージクラスの制限:検出できるのは、ストレージクラスが標準または低頻度アクセスの OSS に保存されているファイルのみです。アーカイブストレージクラスはサポートされていません。

  • サポートされているリージョン

    • 中国 (青島)、中国 (北京)、中国 (張家口)、中国 (フフホト)、中国 (ウランチャブ)

    • 中国 (杭州)、中国 (上海)

    • 中国 (深セン)、中国 (河源)、中国 (広州)

    • 中国 (成都)、中国 (香港)

    • シンガポール、マレーシア (クアラルンプール)、インドネシア (ジャカルタ)、フィリピン (マニラ)、タイ (バンコク)、日本 (東京)、韓国 (ソウル)、米国 (シリコンバレー)、米国 (バージニア)、ドイツ (フランクフルト)、イギリス (ロンドン)

検出タスクの設定と実行

Security Center は、検出タスクを実行するための2つの方法を提供します:コンソール操作と SDK 統合

機能

コンソール操作

SDK 統合

使用方法

Security Center コンソールにログインし、グラフィカルインターフェイスで操作を実行します。

ビジネスコードに SDK を統合して呼び出します。Java と Python がサポートされています。

サポートされているファイル

Object Storage Service (OSS) ファイルと Apsara File Storage NAS ファイルをサポートします。異なるタブに対応するリソースリストが表示され、操作は同じです。

説明

NAS ファイル検出は、従量課金 (エージェント型悪意のあるファイル検出) を使用している場合にのみサポートされます。

  • サーバーファイル:ユーザーがリアルタイムでアップロードしたファイルや、サーバー上の特定のローカルファイルなど、直接アクセスして処理できます。

  • OSS ファイル:OSS に保存されているファイルに対して有効なダウンロード URL を生成し、システムが抽出して検出します。

  • NAS ファイル (従量課金のみ):NAS に保存されているファイルに対して有効なアクセスパスまたはダウンロード URL を生成し、システムが抽出して検出します。

コンソール操作

検出対象のファイルが Alibaba Cloud Object Storage Service (OSS) バケットまたは NAS ファイルシステムに保存されている場合、Security Center コンソールでターゲットの OSS バケットまたは NAS ファイルシステム内のファイルを直接バッチまたは定期的にスキャンできます。

  • 手動検出:この方法は、既存ファイルの1回限りのスキャンに適用されます。完全検出増分検出をサポートします。

  • 自動検出:この方法は、新しく追加されたファイルの継続的な自動スキャンに適用されます。

手動検出 (既存ファイル)

  1. ファイル検出ページへの移動

    Security Center コンソール - リスクガバナンス - 悪意のあるファイルの検出にアクセスします。ページの左上隅で、資産のリージョンを選択します:中国本土または中国本土以外

  2. 検出タスクの開始

    OSS ファイルの検出

    1. OSS ファイルの検出 タブをクリックします。

    2. ファイルの同期 (任意):バケットが OSS ファイルの検出 のリストにない場合は、バケットの同期 をクリックして最新のバケットリストを同期します。

    3. 検出タスクの作成

      • 完全検出:

        • 説明:1つまたは複数のバケット内のすべてのファイルを検出します。

        • 操作エントリ:

          • 単一検出:ターゲットバケットの 操作する 列で、検出 をクリックします。

          • バッチ検出:複数のバケットを選択し、リストの下にある 一括検出 をクリックします。

      • 増分検出

        • 説明:検出済みで、最後の検出以降にファイルの更新があったバケットについて、最後のタスク以降に追加または変更されたファイルのみを検出します。

        • 操作エントリ:ターゲットバケットの 操作する 列で、増分検出 をクリックします。

    4. 検出パラメーターの設定:表示されるダイアログボックスで、次のパラメーターを設定します。

      • ファイル検出タイプ:スキャンするファイルの拡張子を選択します。デフォルトでは、すべてのファイルタイプが検出されます。

      • 解凍レベル単一圧縮パッケージの解凍ファイル数制限:圧縮パッケージの内容をスキャンする場合は、展開レベル (最大 5 レベル) と単一の圧縮パッケージ内のファイル数 (最大 1,000) を設定します。デフォルトでは、展開は無効になっています。

      • ファイルの復号タイプ:OSS ファイルがサーバー側暗号化 (SSE-OSS または SSE-KMS) を使用している場合、Security Center がファイルを復号して検出できるように、対応する復号方法を選択します。

      • 検出ファイル範囲:検出の日時範囲を選択します。この範囲内のファイルのみがスキャンされます。

      • スキャンパス

        • プレフィックスで一致:ファイル名のプレフィックスを入力して、指定したファイルをスキャンします。

        • バケット全体に設定:バケット内のすべてのファイルをスキャンします。

    NAS ファイル検出 (従量課金のみ)

    1. NAS ファイル検出 タブをクリックします。

    2. ファイルの同期 (任意):ファイルシステムが NAS ファイル検出 のリストにない場合は、ファイルシステムの同期 をクリックして最新のファイルシステムリストを同期します。

    3. 検出タスクの作成

      • 完全検出:

        • 説明:1つまたは複数のファイルシステム内のすべてのファイルを検出します。

        • 操作エントリ:

          • 単一検出:ターゲットファイルシステムの 操作する 列で、検出 をクリックします。

          • バッチ検出:複数のファイルシステムを選択し、リストの下にある 一括検出 をクリックします。

      • 増分検出

        • 説明:検出済みで、最後の検出以降にファイルの更新があったファイルシステムについて、最後のタスク以降に追加または変更されたファイルのみを検出します。

        • 操作エントリ:ターゲットファイルシステムの 操作する 列で、増分検出 をクリックします。

    4. 検出パラメーターの設定:表示されるダイアログボックスで、次のパラメーターを設定します。

      • ファイル検出タイプ:スキャンするファイルの拡張子を選択します。デフォルトでは、すべてのファイルタイプが検出されます。

      • ファイル検出範囲:検出の日時範囲を選択します。この範囲内のファイルのみがスキャンされます。

  3. 検出タスクの完了を待つ:バケットまたはファイルシステムリストページで、ターゲットの ファイル検出ステータス を表示できます。ステータスが 未検査 から 選択済み に変わると、検出は完了です。

    説明

    検出タスクが完了した後、バックグラウンドでデータ統計と同期が実行されます。結果の表示には通常 1〜2 時間の遅延が発生します。しばらくお待ちください。

自動検出 (増分ファイル)

  1. ポリシー管理ページへの移動

    1. Security Center コンソール - リスクガバナンス - 悪意のあるファイルの検出にアクセスします。ページの左上隅で、資産のリージョンを選択します:中国本土または中国本土以外

    2. 右上隅の ポリシー管理 をクリックします。

  2. 検出ポリシーの作成または変更

    • 新しいポリシーの作成:ポリシー管理 パネルで、ポリシーの新規追加 をクリックします。

    • 既存のポリシーの変更:ターゲットポリシーの 操作する 列で、編集 をクリックして、ターゲットのバケットまたはファイルシステムをポリシーの有効範囲に追加します。

  3. 基本情報の設定:ポリシーの構成 ページで、ポリシーの基本情報を設定します。

    • 対象プロダクト:OSS を選択します。

    • ポリシー名:ポリシー名を入力します。

    • ポリシー有効化ステータス:ポリシーを有効または無効にします。

    • 有効な製品OSS/NAS を選択します。

  4. ポリシー詳細の設定:設定項目は有効な製品によって異なります。選択した製品に基づいてパラメーターを設定します。

    OSS ポリシー

    • リアルタイム増分検出

      説明

      リアルタイム増分検出は 中国本土 リージョンでのみ設定できます。中国本土以外 のリージョンではサポートされていません。

      • 有効:指定されたバケットに新しいファイルがアップロードされると、すぐに検出がトリガーされます。

      • 無効:設定された検出サイクル (毎日または3日ごとなど) とファイル検出時間 (02:00-04:00 など) に基づいて、新しく追加されたファイルをスキャンします。

    • スキャンパス:プレフィックスマッチングを選択するか、バケット全体に適用します。

    • 検出ファイル範囲:検出の日時範囲を選択します。この範囲内のファイルのみがスキャンされます。

    • ファイル検出タイプ:スキャンするファイルの拡張子を選択します。デフォルトでは、すべてのファイルタイプが検出されます。

    • 解凍レベル単一圧縮パッケージの解凍ファイル数制限:圧縮パッケージの内容をスキャンする場合は、展開レベル (最大 5 レベル) と単一の圧縮パッケージ内のファイル数 (最大 1,000) を設定します。デフォルトでは、展開は無効になっています。

    • ファイルの復号タイプ:OSS ファイルがサーバー側暗号化 (SSE-OSS または SSE-KMS) を使用している場合、Security Center がファイルを復号して検出できるように、対応する復号方法を選択します。

    • バケットの有効化:このポリシーが適用される1つまたは複数のバケットを選択します。ターゲットバケットがすでに別のポリシーで使用されている場合、再度選択することはできません。

      警告

      ポリシーが有効になった後、新しく追加されたバケット内のファイルは自動的に検出されません。それらを検出する必要がある場合は、手動でポリシーを編集し、有効なバケットリストに追加してください。

    NAS ポリシー (従量課金のみ)

    • 検出サイクル:検出タスクの実行サイクルを選択します。

    • 検出時間:検出タスクの実行時間を選択します。間隔は1時間未満にすることはできません。

      警告

      検出タスクが設定された検出時間を超えた場合、自動的に一時停止され、次の検出サイクルで再開されます。

    • ファイル検出範囲:検出の日時範囲を選択します。この範囲内のファイルのみがスキャンされます。

    • ファイル検出タイプ:スキャンするファイルの拡張子を選択します。デフォルトでは、すべてのファイルタイプが検出されます。

    • 対象ファイルシステム:このポリシーが適用される1つまたは複数の NAS ファイルシステムを選択します。ターゲットファイルシステムがすでに別のポリシーで使用されている場合、再度選択することはできません。

  5. 設定が完了したら、OK をクリックします。

SDK 統合

ビジネスコードに悪意のあるファイルの検出サービスを統合して、返された結果から悪意のあるファイル情報を取得し、ファイル検出を実装します。従量課金で有効化されたエージェント型悪意のあるファイル検出は、AI 大規模言語モデル検出、Skill ファイル検出、その他の機能も提供します。

ステップ 1:アクセス認証情報と権限の準備

  1. アクセスキーの作成

    アカウントのセキュリティを確保するため、Alibaba Cloud アカウント (root ユーザー) の AccessKey は使用しないでください。API アクセス専用の Resource Access Management (RAM) ユーザーを作成し、最小限の権限を付与することを推奨します。詳細については、「RAM ユーザーの作成」および「AccessKey の作成」をご参照ください。

    新規アカウントの作成

    1. Alibaba Cloud アカウントまたは RAM 管理者アカウントを使用して RAM コンソールにログインします。ユーザー ページで、ユーザーを作成します をクリックします。

    2. 次の情報に基づいて設定を完了します:

      1. ユーザーアカウント情報:ログイン名、タグ、その他の情報を入力します。

      2. 直接アクセス永続的な AccessKey を使用してアクセス を選択します。

    3. セキュリティ検証を完了します。システムは RAM ユーザーの AccessKey ID と AccessKey Secret を自動的に生成します。キー情報を安全に保管してください。

      説明

      キーの CSV ファイルをダウンロードするか、内容をコピーしてローカルに保存できます。詳細については、「AccessKey ペアの作成」をご参照ください。

    既存の RAM アカウント

    1. Alibaba Cloud アカウントまたは RAM 管理者アカウントを使用して RAM コンソールにログインし、ターゲットユーザーの詳細ページに移動します。

    2. ログイン不要設定 タブの AccessKey ペア セクションで、AccessKey の作成 をクリックします。

    3. ビジネスニーズに基づいて使用シナリオを選択し、AccessKey ペアを作成する必要があることを確認します を選択してから、作成を続行 をクリックします。

    4. セキュリティ検証を完了します。システムは RAM ユーザーの AccessKey ID と AccessKey Secret を自動的に生成します。キー情報を安全に保管してください。

      説明

      キーの CSV ファイルをダウンロードするか、内容をコピーしてローカルに保存できます。詳細については、「AccessKey の作成」をご参照ください。

  2. 権限ポリシーの設定

    1. ユーザー ページで、ターゲットの RAM ユーザーをクリックします。操作する 列で、権限の追加 をクリックします。

    2. ポリシー セクションで、AliyunYundunSASFullAccess を選択し、権限付与の確認 をクリックします。

      説明

      詳細については、「RAM ユーザーへの権限付与」をご参照ください。

  3. 環境変数の設定

    Alibaba Cloud SDK は、ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数を定義することで、デフォルトのアクセス認証情報を作成することをサポートしています。API を呼び出すと、プログラムは直接認証情報にアクセスし、アクセスキー (AccessKey) を読み取り、自動的に認証を完了します。詳細については、「環境変数の設定」をご参照ください。

    Linux/macOS

    • AccessKey ID を設定して Enter キーを押します。

      # yourAccessKeyID をご自身の AccessKey ID に置き換えます。
      export ALIBABA_CLOUD_ACCESS_KEY_ID=yourAccessKeyID
    • AccessKey シークレットを設定して Enter キーを押します。

      # yourAccessKeySecret をご自身の AccessKey シークレットに置き換えます。
      export ALIBABA_CLOUD_ACCESS_KEY_SECRET=yourAccessKeySecret
    • 設定を検証します。

      echo $ALIBABA_CLOUD_ACCESS_KEY_ID コマンドを実行します。コマンドが正しい AccessKey ID を返した場合、設定は成功です。

    Windows

    グラフィカルユーザーインターフェイス (GUI) の使用

    • 手順

      以下の手順は、Windows 10 で GUI を使用して環境変数を設定する方法を説明しています。

      デスクトップで この PC を右クリックし、プロパティ > システムの詳細設定 > 環境変数 > システム環境変数 または ユーザー環境変数 の下にある 新規 を選択します。その後、設定を完了します。

      変数

      値の例

      AccessKey ID

      • 変数名:ALIBABA_CLOUD_ACCESS_KEY_ID

      • 変数値:yourAccessKeyID

      AccessKey シークレット

      • 変数名:ALIBABA_CLOUD_ACCESS_KEY_SECRET

      • 変数値:yourAccessKeySecret

    • 設定のテスト

      スタート をクリック (または Win+R キーボードショートカットを使用) し、ファイル名を指定して実行 をクリックし、`cmd` と入力して OK をクリック (または Enter キーを押す) してコマンドプロンプトを開きます。echo %ALIBABA_CLOUD_ACCESS_KEY_ID% および echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET% コマンドを実行します。コマンドが正しい AccessKey を返した場合、設定は成功です。

    コマンドプロンプト (CMD) の使用

    • 手順

      管理者としてコマンドプロンプトを開き、次のコマンドを実行して新しい環境変数をシステムに追加します。

      setx ALIBABA_CLOUD_ACCESS_KEY_ID yourAccessKeyID /M
      setx ALIBABA_CLOUD_ACCESS_KEY_SECRET yourAccessKeySecret /M

      /M パラメーターはシステム環境変数を示します。ユーザー環境変数を設定する場合は、このパラメーターを省略できます。

    • 設定のテスト

      スタート をクリック (または Win+R キーボードショートカットを使用) し、ファイル名を指定して実行 をクリックし、`cmd` と入力して OK をクリック (または Enter キーを押す) してコマンドプロンプトを開きます。echo %ALIBABA_CLOUD_ACCESS_KEY_ID% および echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET% コマンドを実行します。コマンドが正しい AccessKey を返した場合、設定は成功です。

    Windows PowerShell の使用

    PowerShell では、すべての新しいセッションで有効な新しい環境変数を設定できます:

    [System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_ID', 'yourAccessKeyID', [System.EnvironmentVariableTarget]::User)
    [System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_SECRET', 'yourAccessKeySecret', [System.EnvironmentVariableTarget]::User)

    すべてのユーザーに対して環境変数を設定するには、管理者権限が必要です:

    [System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_ID', 'yourAccessKeyID', [System.EnvironmentVariableTarget]::Machine)
    [System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_SECRET', 'yourAccessKeySecret', [System.EnvironmentVariableTarget]::Machine)

    現在のセッションでのみ有効な一時的な環境変数を設定できます:

    $env:ALIBABA_CLOUD_ACCESS_KEY_ID = "yourAccessKeyID"
    $env:ALIBABA_CLOUD_ACCESS_KEY_SECRET = "yourAccessKeySecret"

    PowerShell で、Get-ChildItem env:ALIBABA_CLOUD_ACCESS_KEY_ID および Get-ChildItem env:ALIBABA_CLOUD_ACCESS_KEY_SECRET コマンドを実行します。コマンドが正しい AccessKey を返した場合、設定は成功です。

ステップ 2:SDK のインストール

開発言語に基づいてインストール方法を選択します。現在、Java と Python のみがサポートされています。

Java
  • 前提条件:JDK 1.8 以降。

  • インストール

    1. Java SDK リポジトリにアクセスして、最新バージョンの Java SDK ファイルをダウンロードします。

    2. ダウンロードした SDK ファイルをプロジェクトに追加します。

Python
  • 前提条件:Python 3.6 以降。

  • インストール

    • オンラインインストール:pip を使用して迅速にインストールします。

      <BASH>
      
      pip install -U alibabacloud_filedetect
    • オフラインインストール

      1. ネットワーク環境で、Python SDK リポジトリにアクセスして、最新バージョンの Python SDK をダウンロードします。

      2. ダウンロードしたソースパッケージをプロジェクト環境にアップロードして解凍します。

      3. 解凍した SDK のルートディレクトリに移動し、インストールコマンドを実行します:

        <BASH>
        
        # Python SDK のルートディレクトリに移動します
        # ディレクトリ名はバージョンによって異なる場合があります (例:alibabacloud_filedetect-1.0.0)
        cd alibabacloud_filedetect-x.x.x/
        
        # ご利用の Python バージョンを使用してインストールします
        python setup.py install

ステップ 3:コードの記述と検出の実行

環境が設定された後、以下の Python および Java のコード例を参照してコードを記述します。

重要

サンプルコード内の pathURL、および MD5 パラメーターを実際の値に置き換えてください。

package com.aliyun.filedetect.sample;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import com.aliyun.filedetect.*;

public class Sample {

	/**
	 * 同期ファイル検出インターフェイス
	 * @param detector Detector オブジェクト
	 * @param path 検出対象ファイルのパス
	 * @param timeout_ms タイムアウト期間をミリ秒単位で設定
	 * @param wait_if_queuefull 検出キューが満杯の場合、false は待たずにすぐにエラーを返し、true はキューに空きができるまで待機
	 * @throws InterruptedException
	 */
	public static DetectResult detectFileSync(OpenAPIDetector detector, String path, int timeout_ms, boolean wait_if_queuefull) throws InterruptedException {
		if (null == detector || null == path) return null;
		DetectResult result = null;
		while(true) {
			result = detector.detectSync(path, timeout_ms);
			if (null == result) break;
			if (result.error_code != ERR_CODE.ERR_DETECT_QUEUE_FULL) break;
			if (!wait_if_queuefull) break;
			detector.waitQueueAvailable(-1);
		}
		return result;
	}

	/**
	 * 非同期ファイル検出インターフェイス
	 * @param detector Detector オブジェクト
	 * @param path 検出対象ファイルのパス
	 * @param timeout_ms タイムアウト期間をミリ秒単位で設定
	 * @param wait_if_queuefull 検出キューが満杯の場合、false は待たずにすぐにエラーを返し、true はキューに空きができるまで待機
	 * @param callback 結果のコールバック関数
	 * @throws InterruptedException
	 */
	public static int detectFile(OpenAPIDetector detector, String path, int timeout_ms, boolean wait_if_queuefull, IDetectResultCallback callback) throws InterruptedException {
		if (null == detector || null == path || null == callback) return ERR_CODE.ERR_INIT.value();
		int result = ERR_CODE.ERR_INIT.value();
		if (wait_if_queuefull) {
			final IDetectResultCallback real_callback = callback;
			callback = new IDetectResultCallback() {
				public void onScanResult(int seq, String file_path, DetectResult callback_res) {
					if (callback_res.error_code == ERR_CODE.ERR_DETECT_QUEUE_FULL) return;
					real_callback.onScanResult(seq, file_path, callback_res);
				}
			};
		}
		while(true) {
			result = detector.detect(path, timeout_ms, callback);
			if (result != ERR_CODE.ERR_DETECT_QUEUE_FULL.value()) break;
			if (!wait_if_queuefull) break;
			detector.waitQueueAvailable(-1);
		}
		return result;
	}

	/**
	 * 同期 URL ファイル検出インターフェイス
	 * @param detector Detector オブジェクト
	 * @param url 検出対象ファイルの URL
	 * @param md5 検出対象ファイルの MD5 ハッシュ
	 * @param timeout_ms タイムアウト期間をミリ秒単位で設定
	 * @param wait_if_queuefull 検出キューが満杯の場合、false は待たずにすぐにエラーを返し、true はキューに空きができるまで待機
	 * @throws InterruptedException
	 */
	public static DetectResult detectUrlSync(OpenAPIDetector detector, String url, String md5, int timeout_ms, boolean wait_if_queuefull) throws InterruptedException {
		if (null == detector || null == url || null == md5) return null;
		DetectResult result = null;
		while(true) {
			result = detector.detectUrlSync(url, md5, timeout_ms);
			if (null == result) break;
			if (result.error_code != ERR_CODE.ERR_DETECT_QUEUE_FULL) break;
			if (!wait_if_queuefull) break;
			detector.waitQueueAvailable(-1);
		}
		return result;
	}

	/**
	 * 非同期 URL ファイル検出インターフェイス
	 * @param detector Detector オブジェクト
	 * @param url 検出対象ファイルの URL
	 * @param md5 検出対象ファイルの MD5 ハッシュ
	 * @param timeout_ms タイムアウト期間をミリ秒単位で設定
	 * @param wait_if_queuefull 検出キューが満杯の場合、false は待たずにすぐにエラーを返し、true はキューに空きができるまで待機
	 * @param callback 結果のコールバック関数
	 * @throws InterruptedException
	 */
	public static int detectUrl(OpenAPIDetector detector, String url, String md5, int timeout_ms, boolean wait_if_queuefull, IDetectResultCallback callback) throws InterruptedException {
		if (null == detector || null == url || null == md5 || null == callback) return ERR_CODE.ERR_INIT.value();
		int result = ERR_CODE.ERR_INIT.value();
		if (wait_if_queuefull) {
			final IDetectResultCallback real_callback = callback;
			callback = new IDetectResultCallback() {
				public void onScanResult(int seq, String file_path, DetectResult callback_res) {
					if (callback_res.error_code == ERR_CODE.ERR_DETECT_QUEUE_FULL) return;
					real_callback.onScanResult(seq, file_path, callback_res);
				}
			};
		}
		while(true) {
			result = detector.detectUrl(url, md5, timeout_ms, callback);
			if (result != ERR_CODE.ERR_DETECT_QUEUE_FULL.value()) break;
			if (!wait_if_queuefull) break;
			detector.waitQueueAvailable(-1);
		}
		return result;
	}

	/**
	 * 検出結果のフォーマット
	 * @param result 検出結果オブジェクト
	 * @return フォーマットされた文字列
	 */
	public static String formatDetectResult(DetectResult result) {
		if (result.isSucc()) {
			DetectResult.DetectResultInfo info = result.getDetectResultInfo();
			String msg = String.format("[DETECT RESULT] [SUCCEED] %s", formatDetectResultInfo(info));
			if (info.compresslist != null) {
				int idx = 1;
				for (DetectResult.CompressFileDetectResultInfo comp_res : info.compresslist) {
					msg += String.format("\n\t\t\t [COMPRESS FILE] [IDX:%d] %s", idx++, formatCompressFileDetectResultInfo(comp_res));
				}
			}
			return msg;
		}
		DetectResult.ErrorInfo info = result.getErrorInfo();
		return String.format("[DETECT RESULT] [FAIL] md5: %s, time: %d, error_code: %s, error_message: %s"
				, info.md5, info.time, info.error_code.name(), info.error_string);
	}

	private static String formatDetectResultInfo(DetectResult.DetectResultInfo info) {
		String msg = String.format("MD5: %s, TIME: %d, RESULT: %s, SCORE: %d", info.md5, info.time, info.result.name(), info.score);
		if (info.compresslist != null) {
			msg += String.format(", COMPRESS_FILES: %d", info.compresslist.size());
		}
		DetectResult.VirusInfo vinfo = info.getVirusInfo();
		if (vinfo != null) {
			msg += String.format(", VIRUS_TYPE: %s, EXT_INFO: %s", vinfo.virus_type, vinfo.ext_info);
		}
		return msg;
	}
	private static String formatCompressFileDetectResultInfo(DetectResult.CompressFileDetectResultInfo info) {
		String msg = String.format("PATH: %s, \t\t RESULT: %s, SCORE: %d", info.path, info.result.name(), info.score);
		DetectResult.VirusInfo vinfo = info.getVirusInfo();
		if (vinfo != null) {
			msg += String.format(", VIRUS_TYPE: %s, EXT_INFO: %s", vinfo.virus_type, vinfo.ext_info);
		}
		return msg;
	}

	/**
	 * ディレクトリまたはファイルを同期的に検出
	 * @param path 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
	 * @param is_sync 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。true: 同期、false: 非同期
	 * @throws InterruptedException
	 */
	public static void detectDirOrFileSync(OpenAPIDetector detector, String path, int timeout_ms, Map<String, DetectResult> result_map) throws InterruptedException {
		File file = new File(path);
		String abs_path = file.getAbsolutePath();
		if (file.isDirectory()) {
			String[] ss = file.list();
	        if (ss == null) return;
	        for (String s : ss) {
	        	String subpath = abs_path + File.separator + s;
	        	detectDirOrFileSync(detector, subpath, timeout_ms, result_map);
	        }
			return;
		}

    	System.out.println(String.format("[detectFileSync] [BEGIN] queueSize: %d, path: %s, timeout: %d", detector.getQueueSize(), abs_path, timeout_ms));
		DetectResult res = detectFileSync(detector, abs_path, timeout_ms, true);
    	System.err.println(String.format("                 [ END ] %s", formatDetectResult(res)));
		result_map.put(abs_path, res);
	}

	/**
	 * ディレクトリまたはファイルを非同期的に検出
	 * @param path 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
	 * @param is_sync 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。true: 同期、false: 非同期
	 * @throws InterruptedException
	 */
	public static void detectDirOrFile(OpenAPIDetector detector, String path, int timeout_ms, IDetectResultCallback callback) throws InterruptedException {
		File file = new File(path);
		String abs_path = file.getAbsolutePath();
		if (file.isDirectory()) {
			String[] ss = file.list();
	        if (ss == null) return;
	        for (String s : ss) {
	        	String subpath = abs_path + File.separator + s;
	        	detectDirOrFile(detector, subpath, timeout_ms, callback);
	        }
	        return;
		}

		int seq = detectFile(detector, abs_path, timeout_ms, true, callback);
		System.out.println(String.format("[detectFile] [BEGIN] seq: %d, queueSize: %d, path: %s, timeout: %d", seq, detector.getQueueSize(), abs_path, timeout_ms));
	}

	/**
	 * ファイルまたはディレクトリの検出を開始
	 * @param path 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
	 * @param is_sync 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。true: 同期、false: 非同期
	 * @throws InterruptedException
	 */
	public static void scan(final OpenAPIDetector detector, String path, int detect_timeout_ms, boolean is_sync) throws InterruptedException {
		System.out.println(String.format("[SCAN] [START] path: %s, detect_timeout_ms: %d, is_sync: %b", path, detect_timeout_ms, is_sync));
		long start_time = System.currentTimeMillis();
		final Map<String, DetectResult> result_map = new HashMap<>();
		if (is_sync) {
			detectDirOrFileSync(detector, path, detect_timeout_ms, result_map);
		} else {
			detectDirOrFile(detector, path, detect_timeout_ms, new IDetectResultCallback() {
				public void onScanResult(int seq, String file_path, DetectResult callback_res) {
			    	System.err.println(String.format("[detectFile] [ END ] seq: %d, queueSize: %d, %s", seq, detector.getQueueSize(), formatDetectResult(callback_res)));
					result_map.put(file_path, callback_res);
				}
			});
			// タスクが完了するのを待機
			detector.waitQueueEmpty(-1);
		}
		long used_time = System.currentTimeMillis() - start_time;
		System.out.println(String.format("[SCAN] [ END ] used_time: %d, files: %d", used_time, result_map.size()));

		int fail_count = 0;
		int white_count = 0;
		int black_count = 0;
		for (Map.Entry<String, DetectResult> entry : result_map.entrySet()) {
			DetectResult res = entry.getValue();
			if (res.isSucc()) {
				if (res.getDetectResultInfo().result == DetectResult.RESULT.RES_BLACK) {
					black_count ++;
				} else {
					white_count ++;
				}
			} else {
				fail_count ++;
			}
		}
		System.out.println(String.format("             fail_count: %d, white_count: %d, black_count: %d"
				, fail_count, white_count, black_count));
	}

    public static void main(String[] args_) throws Exception {
    	// detector インスタンスを取得
    	OpenAPIDetector detector = OpenAPIDetector.getInstance();

    	// 初期化
    	ERR_CODE init_ret = detector.init(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
    	System.out.println("INIT RET: " + init_ret.name());

    	// 展開パラメーターを設定 (任意、デフォルトでは圧縮パッケージは展開されない)
    	boolean decompress = true; // 圧縮ファイルを識別して展開するかどうかを指定。デフォルトは false。
    	int decompressMaxLayer = 5; // 最大展開レベル。decompress が true の場合に有効。
    	int decompressMaxFileCount = 1000; // 最大展開ファイル数。decompress が true の場合に有効。
    	ERR_CODE initdec_ret = detector.initDecompress(decompress, decompressMaxLayer, decompressMaxFileCount);
    	System.out.println("INIT_DECOMPRESS RET: " + initdec_ret.name());

    	if (true) {
    		// 例 1:ローカルディレクトリまたはファイルをスキャン
    		boolean is_sync_scan = false; // 非同期または同期検出を使用するかどうかを指定。非同期検出の方がパフォーマンスが良い。false は非同期検出を示す。
        	int timeout_ms = 500000;  // 単一サンプルの検出時間 (ミリ秒)
        	String path = "test2.php"; // スキャン対象のファイルまたはディレクトリ
        	// スキャンを開始し、完了を待機
        	scan(detector, path, timeout_ms, is_sync_scan);
    	}

    	if (true) {
    		// 例 2:URL ファイルをスキャン
        	int timeout_ms = 500000;  // 単一サンプルの検出時間 (ミリ秒)
        	String url = "https://xxxxxxxx.oss-cn-hangzhou-1.aliyuncs.com/xxxxx/xxxxxxxxxxxxxx?Expires=1*****25&OSSAccessKeyId=xxx"; // スキャン対象の URL ファイル
        	String md5 = "a767f*************6e21d000000"; // スキャン対象ファイルの MD5 ハッシュ
        	// 同期スキャン。非同期スキャンを実行するには、detectUrl インターフェイスを呼び出す。
        	System.out.println(String.format("[detectUrlSync] [BEGIN] URL: %s, MD5: %s, TIMEOUT: %d", url, md5, timeout_ms));
        	DetectResult result = detectUrlSync(detector, url, md5, timeout_ms, true);
        	System.err.println(String.format("[detectUrlSync] [ END ] %s", formatDetectResult(result)));
    	}

		// 初期化解除
		System.out.println("Over.");
    	detector.uninit();
    }
}
# -*- coding: utf-8 -*-
import os
import sys
from typing import List
import threading
import time
import traceback

from alibabacloud_filedetect.OpenAPIDetector import OpenAPIDetector
from alibabacloud_filedetect.IDetectResultCallback import IDetectResultCallback
from alibabacloud_filedetect.ERR_CODE import ERR_CODE
from alibabacloud_filedetect.DetectResult import DetectResult

class Sample(object):

    def __init__(self):
        pass


    """
    同期ファイル検出インターフェイス
    @param detector: Detector オブジェクト
    @param path: 検出対象ファイルのパス
    @param timeout_ms: タイムアウト期間をミリ秒単位で設定
    @param wait_if_queuefull: 検出キューが満杯の場合、False は待たずにすぐにエラーを返し、True はキューに空きができるまで待機
    """
    def detectFileSync(self, detector, path, timeout_ms, wait_if_queuefull):
        if detector is None or path is None:
            return None
        result = None
        while True:
            result = detector.detectSync(path, timeout_ms)
            if result is None:
                break
            if result.error_code != ERR_CODE.ERR_DETECT_QUEUE_FULL:
                break
            if wait_if_queuefull is False:
                break
            detector.waitQueueAvailable(-1)
        return result


    """
    非同期ファイル検出インターフェイス
    @param detector: Detector オブジェクト
    @param path: 検出対象ファイルのパス
    @param timeout_ms: タイムアウト期間をミリ秒単位で設定
    @param wait_if_queuefull: 検出キューが満杯の場合、False は待たずにすぐにエラーを返し、True はキューに空きができるまで待機
    @param callback: 結果のコールバック関数
    """
    def detectFile(self, detector, path, timeout_ms, wait_if_queuefull, callback):
        if detector is None or path is None or callback is None:
            return ERR_CODE.ERR_INIT.value
        result = ERR_CODE.ERR_INIT.value
        if wait_if_queuefull:
            real_callback = callback
            class AsyncTaskCallback(IDetectResultCallback):
                def onScanResult(self, seq, file_path, callback_res):
                    if callback_res.error_code == ERR_CODE.ERR_DETECT_QUEUE_FULL:
                        return
                    real_callback.onScanResult(seq, file_path, callback_res)
            callback = AsyncTaskCallback()
        while True:
            result = detector.detect(path, timeout_ms, callback)
            if result != ERR_CODE.ERR_DETECT_QUEUE_FULL.value:
                break
            if wait_if_queuefull is False:
                break
            detector.waitQueueAvailable(-1)
        return result


    """
    同期 URL ファイル検出インターフェイス
    @param detector: Detector オブジェクト
    @param url: 検出対象ファイルの URL
    @param md5: 検出対象ファイルの MD5 ハッシュ
    @param timeout_ms: タイムアウト期間をミリ秒単位で設定
    @param wait_if_queuefull: 検出キューが満杯の場合、False は待たずにすぐにエラーを返し、True はキューに空きができるまで待機
    """
    def detectUrlSync(self, detector, url, md5, timeout_ms, wait_if_queuefull):
        if detector is None or url is None or md5 is None:
            return None
        result = None
        while True:
            result = detector.detectUrlSync(url, md5, timeout_ms)
            if result is None:
                break
            if result.error_code != ERR_CODE.ERR_DETECT_QUEUE_FULL:
                break
            if wait_if_queuefull is False:
                break
            detector.waitQueueAvailable(-1)
        return result


    """
    非同期 URL ファイル検出インターフェイス
    @param detector: Detector オブジェクト
    @param url: 検出対象ファイルの URL
    @param md5: 検出対象ファイルの MD5 ハッシュ
    @param timeout_ms: タイムアウト期間をミリ秒単位で設定
    @param wait_if_queuefull: 検出キューが満杯の場合、False は待たずにすぐにエラーを返し、True はキューに空きができるまで待機
    @param callback: 結果のコールバック関数
    """
    def detectUrl(self, detector, url, md5, timeout_ms, wait_if_queuefull, callback):
        if detector is None or url is None or md5 is None or callback is None:
            return ERR_CODE.ERR_INIT.value
        result = ERR_CODE.ERR_INIT.value
        if wait_if_queuefull:
            real_callback = callback
            class AsyncTaskCallback(IDetectResultCallback):
                def onScanResult(self, seq, file_path, callback_res):
                    if callback_res.error_code == ERR_CODE.ERR_DETECT_QUEUE_FULL:
                        return
                    real_callback.onScanResult(seq, file_path, callback_res)
            callback = AsyncTaskCallback()
        while True:
            result = detector.detectUrl(url, md5, timeout_ms, callback)
            if result != ERR_CODE.ERR_DETECT_QUEUE_FULL.value:
                break
            if wait_if_queuefull is False:
                break
            detector.waitQueueAvailable(-1)
        return result


    """
    検出結果のフォーマット
    @param result: 検出結果オブジェクト
    @return: フォーマットされた文字列
    """
    @staticmethod
    def formatDetectResult(result):
        msg = ""
        if result.isSucc():
            info = result.getDetectResultInfo()
            msg = "[DETECT RESULT] [SUCCEED] {}".format(Sample.formatDetectResultInfo(info))
            if info.compresslist is not None:
                idx = 1
                for comp_res in info.compresslist:
                    msg += "\n\t\t\t [COMPRESS FILE] [IDX:{}] {}".format(idx, Sample.formatCompressFileDetectResultInfo(comp_res))
                    idx += 1
        else:
            info = result.getErrorInfo()
            msg = "[DETECT RESULT] [FAIL] md5: {}, time: {}, error_code: {}, error_message: {}".format(info.md5,
                info.time, info.error_code.name, info.error_string)
        return msg


    @staticmethod
    def formatDetectResultInfo(info):
        msg = "MD5: {}, TIME: {}, RESULT: {}, SCORE: {}".format(info.md5, info.time, info.result.name, info.score)
        if info.compresslist is not None:
            msg += ", COMPRESS_FILES: {}".format(len(info.compresslist))
        vinfo = info.getVirusInfo()
        if vinfo is not None:
            msg += ", VIRUS_TYPE: {}, EXT_INFO: {}".format(vinfo.virus_type, vinfo.ext_info)
        return msg


    @staticmethod
    def formatCompressFileDetectResultInfo(info):
        msg = "PATH: {}, \t\t RESULT: {}, SCORE: {}".format(info.path, info.result.name, info.score)
        vinfo = info.getVirusInfo()
        if vinfo is not None:
            msg += ", VIRUS_TYPE: {}, EXT_INFO: {}".format(vinfo.virus_type, vinfo.ext_info)
        return msg


    """
    ディレクトリまたはファイルを同期的に検出
    @param path: 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
    @param is_sync: 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。True: 同期、False: 非同期
    """
    def detectDirOrFileSync(self, detector, path, timeout_ms, result_map):
        abs_path = os.path.abspath(path)
        if os.path.isdir(abs_path):
            sub_files = os.listdir(abs_path)
            if len(sub_files) == 0:
                return
            for sub_file in sub_files:
                sub_path = os.path.join(abs_path, sub_file)
                self.detectDirOrFileSync(detector, sub_path, timeout_ms, result_map)
            return

        print("[detectFileSync] [BEGIN] queueSize: {}, path: {}, timeout: {}".format(
            detector.getQueueSize(), abs_path, timeout_ms))
        res = self.detectFileSync(detector, abs_path, timeout_ms, True)
        print("                 [ END ] {}".format(Sample.formatDetectResult(res)))
        result_map[abs_path] = res
        return


    """
    ディレクトリまたはファイルを非同期的に検出
    @param path: 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
    @param is_sync: 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。True: 同期、False: 非同期
    """
    def detectDirOrFile(self, detector, path, timeout_ms, callback):
        abs_path = os.path.abspath(path)
        if os.path.isdir(abs_path):
            sub_files = os.listdir(abs_path)
            if len(sub_files) == 0:
                return
            for sub_file in sub_files:
                sub_path = os.path.join(abs_path, sub_file)
                self.detectDirOrFile(detector, sub_path, timeout_ms, callback)
            return

        seq = self.detectFile(detector, abs_path, timeout_ms, True, callback)
        print("[detectFile] [BEGIN] seq: {}, queueSize: {}, path: {}, timeout: {}".format(
            seq, detector.getQueueSize(), abs_path, timeout_ms))
        return


    """
    ファイルまたはディレクトリの検出を開始
    @param path: 指定されたパスはファイルまたはディレクトリ。ディレクトリの場合、その内容が再帰的にトラバースされる。
    @param is_sync: 同期インターフェイスを使用するかどうかを指定。非同期インターフェイスの使用を推奨。True: 同期、False: 非同期
    """
    def scan(self, detector, path, detect_timeout_ms, is_sync):
        try:
            print("[SCAN] [START] path: {}, detect_timeout_ms: {}, is_sync: {}".format(path, detect_timeout_ms, is_sync))
            start_time = time.time()
            result_map = {}
            if is_sync:
                self.detectDirOrFileSync(detector, path, detect_timeout_ms, result_map)
            else:
                class AsyncTaskCallback(IDetectResultCallback):
                    def onScanResult(self, seq, file_path, callback_res):
                        print("[detectFile] [ END ] seq: {}, queueSize: {}, {}".format(seq,
                            detector.getQueueSize(), Sample.formatDetectResult(callback_res)))
                        result_map[file_path] = callback_res
                self.detectDirOrFile(detector, path, detect_timeout_ms, AsyncTaskCallback())
                # タスクが完了するのを待機
                detector.waitQueueEmpty(-1)

            used_time_ms = (time.time() - start_time) * 1000
            print("[SCAN] [ END ] used_time: {}, files: {}".format(int(used_time_ms), len(result_map)))

            failed_count = 0
            white_count = 0
            black_count = 0
            for file_path, res in result_map.items():
                if res.isSucc():
                    if res.getDetectResultInfo().result == DetectResult.RESULT.RES_BLACK:
                        black_count += 1
                    else:
                        white_count += 1
                else:
                    failed_count += 1

            print("               fail_count: {}, white_count: {}, black_count: {}".format(
                failed_count, white_count, black_count))

        except Exception as e:
            print(traceback.format_exc(), file=sys.stderr)


    def main(self):

        # detector インスタンスを取得
        detector = OpenAPIDetector.get_instance()

        # 環境変数から AccessKey ID と AccessKey Secret を読み取る
        access_key_id = os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID')
        access_key_secret = os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET')

        # 初期化
        init_ret = detector.init(access_key_id, access_key_secret)
        print("INIT RET: {}".format(init_ret.name))

        # 展開パラメーターを設定 (任意、デフォルトでは圧縮パッケージは展開されない)
        decompress = True # 圧縮ファイルを識別して展開するかどうかを指定。デフォルトは false。
        decompressMaxLayer = 5 # 最大展開レベル。decompress が true の場合に有効。
        decompressMaxFileCount = 1000 # 最大展開ファイル数。decompress が true の場合に有効。
        initdec_ret = detector.initDecompress(decompress, decompressMaxLayer, decompressMaxFileCount)
        print("INIT_DECOMPRESS RET: {}".format(initdec_ret.name))

        if True:
            # 例 1:ローカルディレクトリまたはファイルをスキャン
            is_sync_scan = False # 非同期または同期検出を使用するかどうかを指定。非同期検出の方がパフォーマンスが良い。False は非同期検出を示す。
            timeout_ms = 500000 # 単一サンプルの検出時間 (ミリ秒)
            path = "test.bin" # スキャン対象のファイルまたはディレクトリ
            # スキャンを開始し、完了を待機
            self.scan(detector, path, timeout_ms, is_sync_scan)

        if True:
            # 例 2:URL ファイルをスキャン
            timeout_ms = 500000
            url = "https://xxxxxxxx.oss-cn-hangzhou-1.aliyuncs.com/xxxxx/xxxxxxxxxxxxxx?Expires=1671448125&OSSAccessKeyId=xxx" # スキャン対象の URL ファイル
            md5 = "a767ffc59d93125c7505b6e21d000000"
            # 同期スキャン。非同期スキャンを実行するには、detectUrl インターフェイスを呼び出す。
            print("[detectUrlSync] [BEGIN] URL: {}, MD5: {}, TIMEOUT: {}".format(url, md5, timeout_ms))
            result = self.detectUrlSync(detector, url, md5, timeout_ms, True)
            print("[detectUrlSync] [ END ] {}".format(Sample.formatDetectResult(result)))

        # 初期化解除
        print("Over.")
        detector.uninit()


if __name__ == "__main__":
    sample = Sample()
    sample.main()

ステップ 4:返された結果の解析

SDK を呼び出して悪意のあるファイルを検出した後、プログラムの出力で検出結果を表示できます。結果は Security Center コンソールにも同期されます。

  • 結果のデータ構造:各検出は DetectResult オブジェクトを返します。主要なフィールドは次のとおりです:

    フィールド

    タイプ

    説明

    md5

    String

    ファイルの MD5 ハッシュ値。

    time

    long

    この検出にかかった時間 (ミリ秒)。

    error_code

    ERR_CODE

    エラーコード。ERR_SUCC は成功を示します。

    error_string

    String

    詳細なエラー情報。

    result

    RESULT (enum)

    検出結果の列挙型:

    • RES_WHITE:安全

    • RES_BLACK:不審/悪意あり

    • RES_PENDING:保留中。

    score

    int

    検出スコア。範囲:0〜100。スコアが高いほどリスクが高いことを示します。

    • 0〜60:安全。ファイルは信頼されており、通常は対応不要です。

    • 61〜70:リスク (低)。ファイルには軽微なリスクがあります。手動での確認を推奨します。

    • 71〜80:不審 (中)。ファイルは悪意のある可能性が高いです。隔離または削除を推奨します。

    • 81〜100:悪意あり (高)。ファイルはほぼ確実に悪意のあるものです。直ちに隔離または削除してください。

    virus_type

    String

    ウイルスの種類。WebShell、MalScript、Hacktool など。

    ext_info

    String

    拡張情報。通常はより詳細な検出コンテキストを含む JSON 文字列。

    compresslist

    List

    検出されたファイルが圧縮ファイルで、展開が有効になっている場合、このリストには圧縮パッケージ内の各ファイルの検出結果が含まれます。

  • エラーコードとトラブルシューティング

    エラーコード

    説明

    原因

    推奨される解決策

    ERR_SUCC

    成功

    検出が正常に完了しました。

    なし

    ERR_INIT

    初期化エラー

    SDK の初期化が必要、または繰り返し初期化されました。

    検出インターフェイスを呼び出す前に、init() が正常に呼び出されていることを確認してください。

    ERR_FILE_NOT_FOUND

    ファイルが見つかりません

    指定されたローカルファイルパスが存在しません。

    ファイルパスが正しいか、プログラムにファイルの読み取り権限があるかを確認してください。

    ERR_CALL_API

    API 呼び出しエラー

    クラウド API の呼び出し中に不明なエラーが発生しました。

    コードとパラメーター値を確認してください。

    ERR_TIMEOUT

    タイムアウト

    検出時間が設定された timeout_ms を超えました。

    timeout_ms パラメーターの値を増やすか、ネットワーク接続を確認してください。

    ERR_UPLOAD

    アップロード失敗

    ファイルのクラウドへのアップロードに失敗しました。リトライできます。

    通常はネットワークの問題です。リトライロジックを追加することを推奨します。

    ERR_ABORT

    タスク中止

    検出が完了する前にプログラムが終了しました。検出ファイル数が前払いクォータを超えたか、従量課金請求のアカウント残高が不足している可能性があります。

    追加の検出数を購入するか、アカウントをチャージしてください。

    ERR_DETECT_QUEUE_FULL

    検出キュー満杯

    検出タスクの送信頻度が高すぎて、サーバー側のキューが満杯です。

    これはピーク時に発生する可能性があります。waitQueueAvailable() を呼び出してキューが利用可能になるのを待つか、後でリトライしてください。

    ERR_TIMEOUT_QUEUE

    キュータイムアウト

    キューでの待機時間が長すぎました。

    ERR_MD5

    MD5 フォーマットエラー

    提供された MD5 文字列のフォーマットが正しくありません。

    MD5 フォーマットを修正してください。

    ERR_URL

    URL フォーマットエラー

    提供された URL 文字列のフォーマットが正しくありません。

    URL フォーマットを修正してください。

検出結果の表示と処理

  • 結果の表示

    • リスクファイルの概要 タブ:

      • すべての検出メソッド (OSS 検出および API 呼び出し) で検出されたすべてのリスクのあるファイルを集中的に表示します。ここでは、リスクのあるファイルの検索や絞り込み、リスクレベルや脅威タグなどの情報を確認できます。

      • 圧縮ファイルの場合は、ファイルの前にある展開 image アイコンをクリックすると、パッケージ内のリスクのあるファイルの一覧が表示されます。

    • OSS ファイルの検出/NAS ファイル検出 タブ:

      • バケットまたはファイルシステムごとに、リスクのあるファイルの数や検出の進捗状況などのリスク統計を表示します。

      • 操作する 列にある 詳細 をクリックして、関連する不正なファイルリストを表示します。

  • 結果の配信:Security Center の ログ分析 または ログ管理 機能を有効にしている場合、不正なファイル検出ログは Security Center の専用 Logstore に自動的に保存され、詳細なクエリやトレーサビリティ分析に使用できます。詳細については、「SAS ログ配信」および「SIEM ログ」をご参照ください。

  • 結果の処理:検出結果に対しては、ホワイトリストへの追加無視アクセス禁止 などの操作が可能です。具体的な操作については、「不正なファイル検出結果の処理」をご参照ください。

通知の設定 (オプション)

Security Center は、DingTalk チャットボット通知機能を提供します。この機能により、検出された不正なファイルのアラートを DingTalk グループに自動的にプッシュし、検出リスクにタイムリーに対応できます。手順は次のとおりです:

  1. Security Center コンソール - システム設定 - 通知設定にアクセスします。ページの左上隅で、資産が所在するリージョンとして、中国本土 または 中国本土以外 を選択します。

  2. DingTalk チャットボット タブで、新しいロボットを追加する をクリックします。

    • 通知スコープ:不正なファイルの検出について、すべての重大度レベルを選択することを推奨します。

    • その他の情報:詳細については、「DingTalk チャットボット通知の設定」をご参照ください。

割り当てと制限

  • ファイルサイズの制限

    • タスクあたりの合計ファイルサイズ: 制限なし。

    • 単一ファイルのサイズ制限:

      • SDK オフラインファイル検出:単一ファイルは 100 MB 以下である必要があります。

      • コンソール OSS ファイル検出:単一ファイルは 1 GB 以下である必要があります。

    • 上限超過時の説明

      • ファイルサイズが上限を超えた場合、または展開後のファイルが数やサイズの制限を超えた場合、関連ファイルは検出されません。検出されなかったファイルは課金対象数に含まれません。

      • 不正ファイルの検出リクエストがキュー容量を超えた場合は、待機するか、同時実行処理能力を最適化する必要があります。

  • 圧縮ファイル検出の制限:最大 5 階層の展開、1,000 ファイル、合計サイズ 1 GB まで。

  • 環境の制限:金融クラウドおよびガバメントクラウド環境はサポートされていません。

  • デフォルトの API リクエストレート (QPS): トライアル版:10 リクエスト/秒。有料版:20 リクエスト/秒。

    説明
    • 検出速度は、ネットワーク条件、サーバーのパフォーマンス、クラウドプロダクトの仕様、およびその他の要因の影響を受けます。

    • SDK は非同期キューメカニズムを使用してリクエストのピークに対応し、同時実行数を向上させます。内部キューが満杯になると、キューに空きができるまで新しいリクエストは一時停止されます。

課金

不正ファイルの検出(エージェント型不正ファイル検出を含む)は、検出ファイル数(ファイル検出数)に基づいて課金されます。不正ファイルの検出を有効化するにはサブスクリプションを、エージェント型不正ファイル検出を有効化するには従量課金をご利用ください。

  • 料金:

    • サブスクリプション(不正ファイルの検出): 月額、10,000 検出あたり 1.5 米ドル。サブスクリプションは、不正ファイルの検出機能のみをサポートします。AI モデル検出、スキルファイル検出、NAS ファイル検出はサポートされていません

    • 従量課金(エージェント型不正ファイル検出): 1 ファイルあたり 0.0012 米ドル。従量課金は、エージェント型不正ファイル検出のすべての機能をサポートします。不正ファイルの検出機能に加えて、AI モデル検出、スキルファイル検出、NAS ファイル検出もサポートします。

      説明

      従量課金サービスを有効化すると、システムは追加の基本サービス料金(1 時間あたり 0.0072 米ドル)を請求します。

  • 圧縮ファイルの課金: 圧縮ファイルの検出が有効になっている場合、消費される検出数は解凍されたファイルの数に基づいて計算されます。

    例:1,000 個の小さなファイルを含む圧縮パッケージを検出すると、1,000 ファイルとしてカウントされ、1,000 検出数が消費されます。

  • プロセス検出結果: 機能サービス料金に含まれます。追加料金は発生しません。

説明

課金モデルと課金ロジックの詳細については、「サブスクリプション」および「従量課金」をご参照ください。

トラブルシューティング

  • バケットリストが空、またはターゲットバケットが見つからない

    • 原因:バケットのリージョンが、不正なファイルの検出でサポートされているリージョンに含まれていません。

      ソリューション:バケットのリージョンが、サポートされているリージョンの 適用範囲 リストに含まれているか確認してください。サポートされていない場合は、サポートされているリージョン内のバケットにファイルをコピーしてください。

    • 原因:バケットリストが同期されていません。

      ソリューションOSS ファイルの検出 タブで、バケットの同期 をクリックして、最新のバケットリストを同期します。

  • 権限が不十分、または権限付与の失敗

    • 原因:Security Center のサービスリンクロールが作成されていないか、権限ポリシーが不完全です。

    • ソリューション:現在の Alibaba Cloud アカウントに RAM 管理権限があることを確認してください。初めて不正なファイルの検出を有効にすると、システムは自動的にサービスリンクロール AliyunServiceRoleForSasFileDetect を作成します。手動で作成するには、「RAM ユーザーの作成」をご参照ください。

  • 検出タスクを開始できない、またはクォータが不十分

    • 原因:サブスクリプションリソースパックの有効期限が切れているか、従量課金アカウントの残高が不足しています。

      ソリューション:Security Center の [概要] ページに移動して、現在利用可能な検出回数を確認してください。回数が不十分な場合は、「Security Center 購入ページ」をご参照の上、更新またはチャージを行ってください。

    • 原因:検出キューが満杯で、QPS 制限を超えています。

      ソリューション:デフォルトの QPS は、トライアル版で 10 リクエスト/秒、有料版で 20 リクエスト/秒です。同時実行頻度を減らすか、後でリトライしてください。

  • 暗号化されたファイルを検出できない

    • 原因:OSS ファイルがサポートされていない暗号化方式を使用しているか、復号方式の選択が間違っています。

    • ソリューション:不正なファイルの検出は、OSS サーバ側暗号化 (SSE-KMS、SSE-OSS) のみをサポートしています。ファイルの暗号化方式に一致する ファイルの復号タイプ を選択してください。クライアント側暗号化またはサードパーティによって暗号化されたファイルはサポートされていません。

よくある質問

課金とクォータ

  • 使用済みのファイル検出回数は返金できますか?

    いいえ。誤操作によって検出回数を無駄にしないよう、検出前にファイルの範囲と検出ポリシーを確認してください。

  • OSS ファイル検出タブで「ファイル総数」と「検出済みファイル総数」が一致しないのはなぜですか?

    • ファイル総数:バケット内のファイルの自然数 (圧縮パッケージは 1 ファイルとしてカウントされます)。

    • 検出済みファイル総数:実際にスキャンされたファイルの数です。圧縮ファイルのスキャンが有効になっている場合、内部のファイルもカウントされます。総数は、解凍レベル最大展開ファイル数の設定によって決まります。この値は、現在のバケットにおけるすべての過去の検出タスクの累計であり、単一の検出によるカウントではありません。ファイルが削除されても、その過去の検出レコードは累計に含まれるため、検出済みファイル総数がバケット内の現在のファイル数よりも多くなることがあります。

    多数のファイルを含む圧縮パッケージがスキャンされると、「検出済みファイル総数」は「ファイル総数」よりもはるかに大きくなります。課金は、実際に検出されたファイル数に基づきます。

  • クォータ不足で検出タスクが中断された場合はどうすればよいですか?

    サブスクリプションモデルをご利用の場合、残りの検出回数が不足するとスキャンタスクは中断されます。以下のソリューションをご参照ください。

    • 現在のスキャンタスクのキャンセル: OSS ファイルの検出 ページで、スキャン中のバケットを見つけ、バケットの行にある [検出をキャンセル] ボタンをクリックして現在のスキャンタスクをキャンセルします。

    • 構成のアップグレード: Security Center コンソール - 概要ページにアクセスし、サービスのサブスクリプション セクションで 設定の変更>アップグレード をクリックして、十分な悪意のあるファイルの検出数を購入します。詳細については、「スペックアップまたはスペックダウン」をご参照ください。

    • 検出ポリシーの変更:検出設定で圧縮ファイルの展開を無効にして、タスクごとに消費される回数を減らしてから、スキャンを再実行します。

      現在のタスクをキャンセルせずに更新してスキャンを続行した場合、システムは引き続き圧縮パッケージ内のファイルを展開してスキャンするため、クォータを消費し続けます。

権限管理

  • 不正なファイル SDK の権限詳細 (残り回数や有効期限など) を確認するにはどうすればよいですか?

    コンソールで現在のアカウントの個人用 SDK 権限を確認できます。これには、バージョン、アクティベーションステータス、権限制限、残り回数、レート制限、有効期限が含まれます。

    1. Security Center コンソール - リスクガバナンス - 悪意のあるファイルの検出にアクセスします。 ページの左上隅で、アセットのリージョンとして中国本土 または 中国本土以外 を選択します。

    2. 右上隅のAPI と権限の詳細をクリックします。

  • 「不正なファイル検出 SDK は購入済みですが、まだ使用されていません」または「通知が設定されていません」というプロンプトが表示された場合はどうすればよいですか?

    • 購入済みですが、まだ使用されていません:これは、検出クォータは購入済みですが、検出タスクが実行されていないことを意味します。このトピックの「検出タスクの設定と実行」セクションを参照して、コンソール経由で手動検出を実行するか、SDK を統合して検出を開始してください。

    • 通知が設定されていません:これは、検出結果の通知が設定されていないことを意味しますが、検出機能自体には影響しません。不正なファイルが検出されたときに通知を受け取るには、このトピックの「通知の設定 (オプション)」セクションを参照して設定を完了してください。設定が完了すると、プロンプトは表示されなくなります。

  • API または SDK を使用して不正なファイルの検出を呼び出した際に失敗した場合、検出ポリシーを設定する必要がありますか?

    API または SDK を使用して不正なファイルの検出を呼び出す場合、コンソールで検出ポリシーを設定する必要はありません。検出ポリシーは、コンソールで Alibaba Cloud Object Storage Service (OSS) バケットまたは NAS ファイルシステムに保存されているファイルを自動検出する場合にのみ適用されます。

    API 呼び出しが失敗した場合は、次のように問題をトラブルシューティングしてください。

    1. Resource Access Management (RAM) ユーザーに AliyunYundunSASFullAccess アクセスポリシーが付与されていることを確認してください。RAM ユーザーに権限が付与されていない場合、API は Forbidden.NoPermission を返します。

    2. AccessKey が ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数に設定されているかどうかを確認します。

    3. ERR_CALL_API エラーコードが返された場合は、コードとパラメーター値を確認します。

    4. ERR_INIT エラーコードが返された場合は、検出操作の前に init() が呼び出されていることを確認してください。

付録

API リファレンス

API オペレーションを呼び出すことで、不正なファイル検出機能を使用できます。以下にいくつかの関連ドキュメントをリストアップします:

サポートされるウイルスの種類

ウイルスの種類 (virus_type)

ウイルス名

Backdoor

リバースシェルバックドア

DDoS

DDoS 攻撃型トロイの木馬

Downloader

ダウンローダートロイの木馬

Engtest

エンジンテストプログラム

Hacktool

ハッキングツール

Trojan

高リスクプログラム

Malbaseware

汚染ベースソフトウェア

MalScript

不正なスクリプト

Malware

マルウェア

Miner

マイニングプログラム

Proxytool

プロキシツール

RansomWare

ランサムウェア

RiskWare

リスクウェア

Rootkit

ルートキット

Stealer

スティーラー

Scanner

スキャナー

Suspicious

疑わしいプログラム

Virus

感染性ウイルス

WebShell

Web シェル

Worm

ワーム

AdWare

アドウェア

Patcher

パッチャー

Gametool

ゲームツール