悪意のあるファイル検出用SDKは、Security Centerのさまざまな脅威検出エンジンに基づいて開発された機能です。 この機能は、オフラインファイルやObject Storage Service (OSS) オブジェクト内のランサムウェアやマイニングプログラムなどの一般的なウイルスを検出して、悪意のあるファイルの拡散や実行を防ぐことができます。 このトピックでは、悪意のあるファイル検出にSDKを使用する方法について説明します。
使用上の注意
悪意のあるファイル検出用のSDKは、クラウド検出ソリューションです。 この機能を使用すると、ファイルが検出のためにクラウドにアップロードされます。
検出されたウイルスの種類
検出されたウイルスタイプ (virus_type) テーブル
検出されたファイル
悪意のあるファイル検出用のSDKは、暗号化されていないパッケージを解凍および検出できます。
SDKを使用してオフラインファイルを検出する場合、パッケージはデフォルトで解凍されません。 解凍設定を構成する必要があります。 パッケージを認識して解凍するかどうか、最大解凍レベル、および解凍できるパッケージの最大数を指定できます。
Security CenterコンソールでOSSオブジェクトをチェックした場合、Security CenterはデフォルトでOSSオブジェクトを解凍しません。 解凍設定を構成する必要があります。 すべてのバケットまたは特定のバケットの解凍レベルを設定できます。
悪意のあるファイル検出用のSDKは、サーバー側の暗号化方式を使用して暗号化されたOSSオブジェクトを復号化およびチェックできます。 次のサーバー側暗号化方法は、さまざまなシナリオでサポートされています。 詳細については、「サーバー側の暗号化」をご参照ください。
KMS管理CMK (SSE-KMS) を使用するサーバー側暗号化: key Management Service (KMS) によって管理される既定の顧客マスターキー (CMK) を使用するか、CMKを指定してオブジェクトを暗号化または復号化できます。 暗号化または復号化のためにネットワーク経由でKMSにデータを送信する必要はありません。
OSS管理キー (SSE-OSS) を使用するサーバー側暗号化: OSS管理キーを使用してオブジェクトを暗号化できます。
悪意のあるファイルを検出する方法
ビジネスサーバーでSDKを呼び出してオフラインファイルを検出
悪意のあるファイル検出用のSDKをビジネスサーバーに統合して、悪意のあるファイルを検出します。 SDKを使用して、悪意のあるファイルを検出し、返された結果から悪意のあるファイルに関する情報を取得できます。 Security Centerコンソールで、リスクが検出されたファイルを表示することもできます。
SDK for JavaまたはSDK for Pythonを使用できます。
Security CenterコンソールでのOSSオブジェクトの検出
Security CenterコンソールでOSSバケットのオブジェクトを検出できます。 リスクが検出されたオブジェクトを表示することもできます。
検出結果
セキュリティセンターは、検出された悪意のあるファイルのリスクレベルを評価し、高、中、低に分類します。 この評価は、セキュリティの専門知識を持つ複数のウイルス検出エンジンからの結果を組み込み、検出されたファイルの潜在的な悪意と検出の精度の両方を考慮します。 セキュリティセンターは、悪意のあるファイルを処理するための説明と提案も提供します。
ログ分析
Security Centerのログ分析機能を有効にした場合、悪意のあるファイル検出の記録は、Security Center専用のログストアに配信されます。 詳細については、「ログ分析の概要」および「ログタイプとログフィールド」をご参照ください。
シナリオ
シナリオ | 悪意のあるファイル |
使用中のサーバー | 多くの場合、サーバーは、ワーム、マイニングソフトウェア、DDoSトロイの木馬、および悪意のあるスクリプトなど、広く拡散した悪意のあるファイルの影響を受けます。 これらの悪意のあるファイルは、システムリソースを枯渇させたり、分散型サービス拒否 (DDoS) 攻撃を開始したり、不正な活動のためにサーバーをハイジャックしたりするために複製して拡散する可能性があります。 |
標的型攻撃を受けているサーバー | サーバーが標的型攻撃を受けている場合、システムのセキュリティと安定性を維持するために、ハッキングツール、プロキシツール、バックドアプログラムなどの悪意のあるファイルを監視することが重要です。 攻撃者は悪意のあるファイルを埋め込み、機密データを漏らしたり、システムを制御したり、ネットワークに侵入するための足場を確立したりします。 |
包括的な環境検出 | すべての環境で、破壊的なランサムウェアやファイルに感染するウイルスに注意を払う必要があります。 ランサムウェアはユーザーデータを暗号化することでユーザーを人質にしますが、ファイルに感染するウイルスは自己複製して他のファイルに広がる可能性があります。 どちらも重大なデータ損失と潜在的なシステム障害を引き起こす可能性があります。 |
Officeネットワークとファイルストレージ | オフィスネットワークにいる場合、またはファイルを保存する必要がある場合は、マクロウイルスを含むofficeファイルや有害なペイロードを含む圧縮パッケージなどの悪意のあるドキュメントファイルに注意を払う必要があります。 このようなファイルは、日常の仕事のコミュニケーションで通常のドキュメントになりすまして、ユーザーにそれらを開くように促し、資格情報の盗難やリモートアクセストロイの木馬の起動などの攻撃につながる可能性があります。 |
制限事項
悪意のあるファイルを検出するためにSDKを呼び出すと、この呼び出しは100 MB以下のファイルしかチェックできません。
無料トライアルの既定の1秒あたりのクエリ (QPS) は、Security Center Enterpriseの既定のQPSとは異なります。
無料トライアルのQPS: 10。
セキュリティセンターエンタープライズのQPS: 20。
次のタイプのパッケージを確認できます。
. 7z
,. zip
,. タール
,. gz
,. rar
,. ar
,. bz2
,. xz
、および. lzma
.パッケージの最大解凍レベルは5です。 解凍後、パッケージから最大1,000個のファイルを抽出できます。すべてのファイルの合計サイズは1 GBを超えることはできません。 制限を超えたファイルはチェックできません。
悪意のあるファイルの検出速度は、ネットワークの状態、コンピューターのパフォーマンス、クラウドサービスの制限などの要因の影響を受けます。 悪意のあるファイル検出用のSDKは、キューを使用して外部リクエストスパイク中にリクエストを処理します。 これにより、同時実行性の高いシナリオでの処理能力が向上します。 内部キューがいっぱいになると、システムは外部要求を拒否し、キューが利用可能なスペースを持つまで外部要求を処理しません。
キューの長さを増やして、より多くの同時リクエストを処理できます。 しかしながら、この方法は、いくつかのサンプルの検出期間に影響を及ぼす。
timeout_ms
パラメーターは、サンプルのタイムアウト期間を指定します。 単位:ミリ秒。 タイムアウトエラーを減らすために、timeout_ms
パラメーターを60秒に相当する60000に設定することを推奨します。Security CenterコンソールでOSSオブジェクトをチェックすると、ストレージクラスが標準または低頻度アクセス (IA) であるオブジェクトのみが検出できます。 ストレージクラスがArchiveのオブジェクトは検出できません。 ストレージクラスの詳細については、「概要」をご参照ください。
Security CenterコンソールでOSSオブジェクトをチェックすると、中国 (青島) 、中国 (北京) 、中国 (張家口) 、中国 (フフホト) 、中国 (杭州) 、中国 (上海) 、中国 (深セン) 、中国 (河源) 、中国 (広州) 、中国 (成都) 、中国 (香港) 、シンガポールのOSSバケットのみを検出できます。インドネシア (ジャカルタ) 、タイ (バンコク) 、フィリピン (マニラ) 、マレーシア (クアラルンプール) 、韓国 (ソウル) 、日本 (東京) 、米国 (シリコンバレー) 、英国 (ロンドン) 、米国 (バージニア) 、ドイツ (フランクフルト) 。
課金
悪意のあるファイル検出にSDKの機能を使用する場合は、機能のクォータが使用されます。 パッケージをチェックした場合、使用するクォータはパッケージから抽出されたファイルの数です。
企業の実名検証に合格したAlibaba Cloudアカウントは、悪意のあるファイル検出のためにSDKの無料トライアルを使用できます。 無料トライアルを使用する場合、悪意のあるファイル検出のためにSDKで10,000のクォータが提供されます。
Security Center Enterpriseを購入した場合、ビジネス要件に基づいてクォータを指定できます。
課金の詳細については、「課金の概要」をご参照ください。
機能の有効化と悪意のあるファイルの検出
前提条件
RAM (Resource Access Management) ユーザーを使用する場合は、AliyunYundunSASFullAccessポリシーがRAMユーザーにアタッチされていることを確認します。 詳細については、「RAMユーザーへの権限の付与」をご参照ください。
ステップ1: 悪意のあるファイル検出のためのSDKの有効化
悪意のあるファイル検出のための無料トライアルまたは購入SDKを申請できます。
無料トライアル
Alibaba Cloudアカウントがエンタープライズ実名検証に合格した場合、悪意のあるファイル検出のためにSDKの無料トライアルを使用し、悪意のあるファイル検出のためにSDKの10,000の無料クォータを取得できます。 各Alibaba Cloudアカウントは、無料トライアルを1回だけ使用できます。
Security Center コンソールにログインします。 上部のナビゲーションバーで、管理するアセットのリージョンとして 中国 を選択します。
左側のナビゲーションウィンドウで、 .
SDK for Malicious File Detectionページで、[今すぐ試す] をクリックします。
お支払い
無料トライアルが要件を満たさない場合は、悪意のあるファイル検出用のSDKを購入できます。
無料クォータが使い果たされていない場合、機能を購入した後、残りの無料クォータが購入済みクォータに追加されます。
Security Center コンソールにログインします。 上部のナビゲーションバーで、管理するアセットのリージョンとして 中国 を選択します。
左側のナビゲーションウィンドウで、 .
悪意のあるファイルの検出 SDKページで、[今すぐ購入] をクリックします。 表示されるページで、[悪意のあるファイル検出SDK] で [はい] を選択し、チェックするファイルの総数に基づいて [悪意のあるファイル検出SDKのクォータ] パラメーターを設定します。
Security Centerの有料版を購入した場合、悪意のあるファイル検出のためにSDKのクォータを指定できます。 セキュリティセンターの有料版を購入しなかった場合は、ビジネス要件に基づいてセキュリティセンターの有料版を選択します。
Security Centerの他の機能が必要ない場合は、[付加価値プランエディション] を選択します。
セキュリティセンターの他の機能 (脆弱性の修正やコンテナの脅威の検出など) を使用する場合は、必要なエディションのセキュリティセンターを選択します。 各エディションでサポートされている機能の詳細については、「機能と特徴」をご参照ください。
読んで利用規約を選択し、[今すぐ購入] をクリックして支払いを完了します。
悪意のあるファイル検出のためにSDKを有効にした後、SDK for malicious file detectionページで、悪意のあるファイル検出のためのSDKの残りのクォータを表示できます。 残りのクォータがその後の検出に不十分な場合は、[設定のアップグレード] をクリックして、悪意のあるファイル検出用のSDKの追加クォータを購入できます。 詳細については、「Security Centerのアップグレードとダウングレード」をご参照ください。
ステップ2: 検出悪意のあるファイルs
次のいずれかの方法を選択して、ビジネスシナリオに基づいて悪意のあるファイルを検出します。
検出する前に、Alibaba Cloudアカウントに十分なチェッククォータが残っていることを確認してください。 クォータが不十分な場合は、悪意のあるファイルの検出 SDK ページの [Risk File Overview] タブで、アップグレード設定 をクリックしてさらに購入できます。
SDKを呼び出してビジネスサーバーのオフラインファイルを検出する
準備
ALIBABA_CLOUD_ACCESS_KEY_ID
およびALIBABA_CLOUD_ACCESS_KEY_SECRET
環境変数を設定します。デフォルトの資格情報を設定するには、環境変数
ALIBABA_CLOUD_ACCESS_KEY_ID
とALIBABA_CLOUD_ACCESS_KEY_SECRET
を定義します。 API操作を呼び出すと、システムはデフォルトの資格情報からAccessKeyペアを読み取り、AccessKeyペアを使用して認証を完了します。 詳細については、「Linux、macOS、およびWindowsでの環境変数の設定」をご参照ください。次の表に基づいて、アクセス方法を選択し、SDKを取得する必要があります。
アクセス方法
バージョン
手順
Java
Java開発キット (JDK) 1.8以降
次の方法を使用して、SDK for Javaを取得できます。
SDK for Javaオフラインのインポートとインストール: インターネット経由でSDKコードライブラリfor Javaにアクセスし、SDK for Javaをダウンロードして、SDK for Javaをプロジェクトに追加します。
Python
Python 3.6以降
次のいずれかの方法を使用して、SDK for Pythonを取得できます。
インターネットにアクセスできる場合は、pipを使用してPython用SDKをインストールします。
pip install -U alibabacloud_filedetect
インターネットにアクセスできない場合は、SDK for Pythonをオフラインでインストールします。Code library for Pythonにアクセスし、インターネット経由でSDK for Pythonをダウンロードします。 SDK for Pythonをプロジェクト環境にアップロードし、SDKパッケージを解凍して、次のインストールコマンドを実行します。
# Switch to the root directory of SDK for Python. cd alibabacloud-file-detect-python-sdk-master # Install SDK for Python that is for the correct Python version. python setup.py install
例
SDK for Pythonを使用する場合は、次の例のpath
パラメーターの値を変更します。
package com.aliyun.filedetect.sample;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.aliyun.filedetect.*;
public class Sample {
/**
* Synchronous file detection operation.
* @param detector The detector object.
* @param path The path to the file that you want to detect.
* @param timeout_ms The timeout period. Unit: milliseconds.
* @param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
* @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;
}
/**
* Asynchronous file detection operation.
* @param detector The detector object.
* @param path The path to the file that you want to detect.
* @param timeout_ms The timeout period. Unit: milliseconds.
* @param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
* @param callback The callback function.
* @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;
}
/**
* Synchronous URL file detection operation.
* @param detector The detector object.
* @param url The URL file that you want to detect.
* @param md5 The MD5 hash value of the file that you want to detect.
* @param timeout_ms The timeout period. Unit: milliseconds.
* @param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
* @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;
}
/**
* Asynchronous URL file detection operation.
* @param detector The detector object.
* @param url The URL file that you want to detect.
* @param md5 The MD5 hash value of the file that you want to detect.
* @param timeout_ms The timeout period. Unit: milliseconds.
* @param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
* @param callback The callback function.
* @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;
}
/**
* Format the detection result.
* @param result The detection result.
* @return The formatted string.
*/
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;
}
/**
* Synchronous detection of directories or files.
* @param path The path. You can specify a file or directory. Directories are recursively traversed.
* @param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to false. Valid values: true: synchronous. false: asynchronous.
* @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);
}
/**
* Asynchronous detection of directories or files.
* @param path The path. You can specify a file or directory. Directories are recursively traversed.
* @param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to false. Valid values: true: synchronous. false: asynchronous.
* @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));
}
/**
* Start the detection on files or directories.
* @param path The path. You can specify a file or directory. Directories are recursively traversed.
* @param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to false. Valid values: true: synchronous. false: asynchronous.
* @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);
}
});
// Wait until the task is complete.
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 {
// Obtain the detector instance.
OpenAPIDetector detector = OpenAPIDetector.getInstance();
// Initialize the SDK.
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());
// Configure the decompression parameters. These parameters are optional. By default, packages are not decompressed.
Boolean decompress=true; // Specify whether to recognize and decompress packages. Default value: false.
int decompressMaxLayer = 5; // The maximum decompression levels. This parameter is valid only when the decompress parameter is set to true.
int decompressMaxFileCount=1000; // The maximum number of packages that can be decompressed. This parameter is valid only when the decompress parameter is set to true.
ERR_CODE initdec_ret = detector.initDecompress(decompress, decompressMaxLayer, decompressMaxFileCount);
System.out.println("INIT_DECOMPRESS RET: " + initdec_ret.name());
if (true) {
// Example 1: Scan an on-premises directory or file.
boolean is_sync_scan=false; // Specify whether to perform an asynchronous detection or a synchronous detection. An asynchronous detection provides better performance. The value false indicates an asynchronous detection.
int timeout_ms=500000; // The detection time of a sample. Unit: milliseconds.
String path = "test2.php"; // The file or directory that you want to scan.
// Start the scan and wait until the scan is complete.
scan(detector, path, timeout_ms, is_sync_scan);
}
if (true) {
// Example 2: Scan a URL file.
int timeout_ms=500000; // The detection time of a sample. Unit: milliseconds.
String url = "https://xxxxxxxx.oss-cn-hangzhou-1.aliyuncs.com/xxxxx/xxxxxxxxxxxxxx?Expires=1*****25&OSSAccessKeyId=xxx"; // The URL file that you want to scan.
String md5 = "a767f*************6e21d000000"; // The MD5 hash value of the URL file that you want to scan.
// Synchronously scan the URL file. To asynchronously scan the URL file, call the detectUrl operation.
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)));
}
// Deinitialize the SDK.
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
"""
Synchronous file detection operation.
@param detector The detector object.
@param path The path to the file that you want to detect.
@param timeout_ms The timeout period. Unit: milliseconds.
@param wait_if_queuefull Specify the operation that is performed when the queue is full. The value False indicates that the system directly returns an error, and the value True indicates the system waits until the queue has space available.
"""
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
"""
Asynchronous file detection operation.
@param detector The detector object.
@param path The path to the file that you want to detect.
@param timeout_ms The timeout period. Unit: milliseconds.
@param wait_if_queuefull Specify the operation that is performed when the queue is full. The value False indicates that the system directly returns an error, and the value True indicates the system waits until the queue has space available.
@param callback The callback function.
"""
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
"""
Synchronous URL file detection operation.
@param detector The detector object.
@param url The URL file that you want to detect.
@param md5 The MD5 hash value of the file that you want to detect.
@param timeout_ms The timeout period. Unit: milliseconds.
@param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
"""
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
"""
Asynchronous URL file detection operation.
@param detector The detector object.
@param url The URL file that you want to detect.
@param md5 The MD5 hash value of the file that you want to detect.
@param timeout_ms The timeout period. Unit: milliseconds.
@param wait_if_queuefull Specify the operation that is performed when the queue is full. The value false indicates that the system directly returns an error, and the value true indicates the system waits until the queue has space available.
@param callback The callback function.
"""
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
"""
Format the detection result.
@param result The detection result.
@return The formatted string.
"""
@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
"""
Synchronous detection of directories or files.
@param path The path. You can specify a file or directory. Directories are recursively traversed.
@param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to False. Valid values: True: synchronous. False: asynchronous.
"""
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
"""
Asynchronous detection of directories or files.
@param path The path. You can specify a file or directory. Directories are recursively traversed.
@param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to False. Valid values: True: synchronous. False: asynchronous.
"""
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
"""
Start the detection on files or directories.
@param path The path. You can specify a file or directory. Directories are recursively traversed.
@param is_sync Specify whether to use a synchronous operation. We recommend that you set the value to False. Valid values: True: synchronous. False: asynchronous.
"""
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())
# Wait until the task is complete.
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):
# Obtain the detector instance.
detector = OpenAPIDetector.get_instance()
# Obtain the AccessKey ID and AccessKey secret in environment variables.
access_key_id = os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID')
access_key_secret = os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET')
# Initialize the SDK.
init_ret = detector.init(access_key_id, access_key_secret)
print("INIT RET: {}".format(init_ret.name))
# Configure the decompression parameters. These parameters are optional. By default, packages are not decompressed.
decompress = True # Specify whether to recognize and decompress packages. Default value: false.
decompressMaxLayer = 5 # The maximum decompression levels. This parameter is valid only when the decompress parameter is set to true.
decompressMaxFileCount = 1000 # The maximum number of packages that can be decompressed. This parameter is valid only when the decompress parameter is set to true.
initdec_ret = detector.initDecompress(decompress, decompressMaxLayer, decompressMaxFileCount)
print("INIT_DECOMPRESS RET: {}".format(initdec_ret.name))
if True:
# Example 1: Scan an on-premises directory or file.
is_sync_scan = False # Specify whether the detection is an asynchronous detection or a synchronous detection. An asynchronous detection provides better performance. The value False indicates an asynchronous detection.
timeout_ms = 500000 # The detection time of a sample. Unit: milliseconds.
path = "test.bin" # The file or directory that you want to scan.
# Start the scan and wait until the scan is complete.
self.scan(detector, path, timeout_ms, is_sync_scan)
if True:
# Example 2: Scan a URL file.
timeout_ms = 500000
url = "https://xxxxxxxx.oss-cn-hangzhou-1.aliyuncs.com/xxxxx/xxxxxxxxxxxxxx?Expires=1671448125&OSSAccessKeyId=xxx" # The URL file that you want to scan.
md5 = "a767ffc59d93125c7505b6e21d000000"
# Synchronously scan the URL file. To asynchronously scan the URL file, call the detectUrl operation.
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)))
# Deinitialize the SDK.
print("Over.")
detector.uninit()
if __name__ == "__main__":
sample = Sample()
sample.main()
返された結果
SDKを呼び出した後、検出結果はSecurity Centerコンソールに同期されません。 結果は、SDK呼び出しの返された結果でのみ表示できます。 Security Centerコンソールで、悪意のあるファイル検出に対するSDKの残りのクォータを確認できます。 SDK for Malicious File Detectionページには、検出統計が表示されます。 たとえば、リスクファイルの概要 タブの [合計ファイル] パラメーターには、スキャンしたファイルの総数を指定します。
struct DetectResult {
std::string md5; // The MD5 hash value of the sample.
long time = 0; // The time that is required to process this request. Unit: milliseconds.
ERR_CODE error_code; // The error code.
std::string error_string; // The extended error message.
enum RESULT {
RES_WHITE = 0, // The number of secure files.
RES_BLACK = 1, // The number of suspicious files.
RES_PENDING = 3 // The number of files that are being detected.
};
RESULT result; // The detection result.
int score; // The detection score. Valid values: 0 to 100.
std::string virus_type; // The virus type. Examples: WebShell, MalScript, and Hacktool.
std::string ext_info; // The extended information. The value of this parameter is a JSON string.
struct CompressFileDetectResultInfo {
std::string path; // The path to the package.
RESULT result; // The detection result.
int score; // The detection score. Valid values: 0 to 100.
std::string virus_type; // The virus type. Examples: WebShell, MalScript, and Hacktool.
std::string ext_info; // The extended information. The value of this parameter is a JSON string.
};
std::list<struct CompressFileDetectResultInfo> compresslist = null; // If the files that you detect are a package and the decompress parameter is set to true, the value of this parameter is the detection result of the files in the package.
};
次のエラーコードが返される場合があります。
enum ERR_CODE {
ERR_INIT = -100, // Initialization or re-initialization is required.
ERR_FILE_NOT_FOUND = -99, // The file is not found.
ERR_DETECT_QUEUE_FULL = -98, // The detection queue is full.
ERR_CALL_API = -97, // An error occurred while the API is called.
ERR_TIMEOUT = -96, // The operation timed out.
ERR_UPLOAD = -95, // The file failed to be uploaded. You can reinitiate the detection and try again.
ERR_ABORT = -94, // The program exits, and the sample is not detected.
ERR_TIMEOUT_QUEUE = -93, // The queue timed out. You initiated detections too frequently, or the timeout period that you set is too short.
ERR_MD5 = -92, // The MD5 hash value is invalid.
ERR_URL = -91, // The URL format is invalid.
ERR_SUCC = 0 // The operation is successful.
};
より高い検出スコアは、より高いリスクレベルを示す。 次の表に、検出スコアとリスクレベルの間のマッピングを示します。
スコア範囲 | リスクレベル |
0 ~ 60 | 安全性 |
61 ~ 70 | リスク |
71 ~ 80 | 疑わしい |
81 ~ 100 | 悪意のある |
Security Centerコンソールでバケットの検出を実行する
Security Center コンソールにログインします。 上部のナビゲーションバーで、管理するアセットのリージョンとして 中国 を選択します。
左側のナビゲーションウィンドウで、 .
OSS ファイルの検出 タブをクリックし、検出方法を選択して検出を開始します。
OSS ファイルの検出 タブのリストにバケットが表示されていない場合は、バケットの同期 をクリックしてバケットの最新リストを取得します。
検出方法
説明
手順
マニュアルフル検出
1つ以上のバケット内のすべてのオブジェクトを確認します。
OSS ファイルの検出 タブで、バケットを見つけて 操作する 列の 検出 をクリックするか、複数のバケットを選択して 一括検出 をクリックします。
[チェック] ダイアログボックスで、ファイルチェックタイプ、スコープ、スキャンパスなどのパラメーターを設定します。 以下にパラメーターを説明します。
解凍レベル: ファイルチェックタイプパラメーターに圧縮パッケージタイプが指定されている場合は、解凍レベルパラメーターを設定する必要があります。 このパラメーターを [解凍しない] 以外の値に設定する場合は、パッケージから抽出できるファイルの数を指定する [抽出制限] パラメーターを設定する必要があります。 最大値は 1,000 です。
ファイル解読タイプ: デフォルト値は [復号化しない] です。 SSE-KMSまたはSSE-OSSを使用して暗号化されたオブジェクトを確認する場合は、復号化方法を指定する必要があります。 値OSSは、SSE-OSSを使用して暗号化されるOSSオブジェクトの復号化方法を指定します。 値KMSは、SSE-KMSを使用して暗号化されるOSSオブジェクトの復号化方法を指定します。
スコープ: このパラメーターはオプションです。 時点を指定できます。 システムは、指定された時点より後に更新されたオブジェクトをチェックします。
スキャンパス: [プレフィックスで一致] または [バケット全体の設定] を選択できます。 値Match by Prefixは、指定されたプレフィックスで名前が付けられたオブジェクトのみがチェックされることを示します。 値Configure for Entire Bucketは、システムがバケット内のすべてのオブジェクトをチェックすることを示します。
OK をクリックします。
手動インクリメンタル検出
チェックされたバケット内の新しく追加されたオブジェクトのみをチェックします。
OSS ファイルの検出 タブで、必要なバケットを見つけ、操作する 列の 増分検出 をクリックします。
[増分チェック] ダイアログボックスで、ファイルチェックタイプ、ファイル復号タイプ、スコープ、スキャンパスなどのパラメーターを設定します。 ファイルチェックタイプパラメーターに圧縮パッケージタイプが指定されている場合は、解凍レベルパラメーターも設定する必要があります。 スキャンパスパラメーターの有効な値は、[プレフィックスによる一致] と [バケット全体の設定] です。
OK をクリックします。
自動検出
設定されたスキャンポリシーに基づいて、指定されたバケットの定期的な自動検出を有効にします。 スキャンポリシーを設定する前に、次の項目に注意してください。
バケットは1つのポリシーでのみ指定できます。
このメソッドは、OSSに新しく追加されたオブジェクトに対してのみ有効です。 ファイルは繰り返し検出されません。
OSS ファイルの検出 タブで、[ポリシー管理] の下にある [ポリシー設定] をクリックします。
[ポリシー管理] パネルで、ポリシーの新規追加 をクリックします。
既存のポリシーがビジネス要件を満たしている場合は、ポリシーの [操作] 列の 編集 をクリックします。 [ポリシーの編集] パネルで、自動検出を有効にするバケットを選択し、[OK] をクリックします。
[ポリシーの作成] パネルで、ポリシー名 、ポリシー有効化ステータス 、スキャンパス 、[スコープ] 、検出サイクル 、ファイル検出時間 、ファイル検出タイプ 、[解凍レベル] 、[ファイル解読タイプ] 、バケットの有効化 などのパラメーターを設定します。 ファイルチェックタイプパラメーターに圧縮パッケージタイプが指定されている場合は、解凍レベルパラメーターも設定する必要があります。 スキャンパスパラメーターの有効な値は、[プレフィックスによる一致] と [バケット全体の設定] です。 デフォルトでは、Policy Statusパラメーターのスイッチがオンになっています。
[OK] をクリックします。
オプション: DingTalkチャットボットの設定
DingTalkチャットボットは、指定されたDingTalkグループ内のSecurity Centerによって検出された悪意のあるファイルによってトリガーされたアラートの通知をリアルタイムで受信するように設定できます。 詳細については、「DingTalkチャットボットタブの通知設定」をご参照ください。
検出結果の表示とエクスポート
リスクファイルの概要
リスクファイルの概要 タブ:
リスクファイルの統計情報の表示
リスクレベル (高リスク、中リスク、低リスク) は、高リスク (赤) 、中リスク (オレンジ) 、低リスク (グレー) の異なる色で示されます。
リスクファイルリストで、SDK (API) またはコンソール (OSS) で検出された悪意のあるファイル情報をフィルタリングして表示するには、[検出シナリオ] 列から選択します。 左上隅のドロップダウンボックスを使用して、[リスクレベル] 、[ファイル名] 、[脅威タグ] 、[MD5] 、または [最新の検出時刻] でフィルタリングします。
圧縮パッケージファイルの場合は、展開アイコンをクリックして、内部のリスクファイルのリストを表示します。 パッケージファイルのリスクレベルは、そのコンテンツの中で最も高いリスクレベルを反映します。
対象となるリスクファイルの詳細を表示する
リスクファイルリストで、対象のリスクファイルの 操作する 列をクリックし、詳細 をクリックして、ファイルの詳細パネルにファイルの詳細や [イベントの説明] (悪意のあるファイルの説明や廃棄の提案を含む) などの情報を表示します。.
圧縮パッケージファイルのリスク詳細パネルには、パッケージ内のリスクファイルの数、解凍後に検出されたファイルの総数、およびリスクファイルのリストも表示されます。
すべてのリスクファイルのリストをエクスポートする
アイコンをクリックし、エクスポートが完了したら、通知ボックスでダウンロードを選択します。
OSS ファイルの検出
OSS ファイルの検出 タブで:
OSSバケットの観点からリスクファイルの統計情報を表示する
リスクレベル (高リスク、中リスク、低リスク) は、高リスク (赤) 、中リスク (オレンジ) 、低リスク (グレー) の異なる色で表されます。
特定のOSSバケットの検出の詳細を表示する
バケットリストで、対象のバケットの 操作する 列をクリックし、詳細 を選択してバケットの基本情報とリスクファイルの詳細を表示します。
[ファイルの検出の詳細] ページには、設定ファイルの解凍ステータス、解凍後のファイルの総数、検出されたファイルの数、スキャン済みおよびスキャン済みのリスクファイルのリストも表示できます。
すべてのリスクファイルのリストをバケットディメンションでエクスポートする
OSS ファイルの検出 タブでアイコンをクリックし、エクスポートが完了したら、通知ボックスの [ダウンロード] をクリックします。
リスクのあるファイルのアラートを処理する
リスクのあるファイルが検出されたら、リスクレベル、およびセキュリティセンターから提供されたイベントの説明とアドバイスに基づいて、それらを評価して修正する必要があります。
高リスクイベント: これらのイベントは、偽陽性の割合が低く、悪意の程度が高く、即時のアクションが必要です。
中リスクおよび低リスクのイベント: これらのイベントは、事業運営において一般的です。 行動を起こす前に、ビジネスへの影響を評価することが重要です。
通常のビジネスファイルまたは誤検知として識別された場合、対応するアラートは安全に無視できます。 ビジネスアプリケーションがファイル検出のためにSDKを呼び出す場合は、そのようなファイルをバイパスまたはホワイトリスト化するロジックをアプリケーションに追加することを検討してください。
関連ドキュメント
次のAPIを呼び出して、悪意のあるファイル検出にSDKを使用できます。