收集 Qualys Virtual Scanner 記錄
支援的國家/地區:
Google SecOps
SIEM
這個剖析器會將原始 JSON 格式的 Qualys Virtual Scanner 記錄轉換為結構化格式,符合 Google Security Operations UDM。這項服務會擷取相關欄位,例如資產資訊、掃描詳細資料和偵測到的安全漏洞,並將這些欄位對應至相應的 UDM 欄位,以確保呈現和分析結果一致。
事前準備
請確認您已完成下列事前準備事項:
- Google Security Operations 執行個體。
- Google Cloud的特殊存取權。
- Qualys 的特殊存取權。
啟用必要的 API:
- 登入 Google Cloud 主控台。
- 依序前往「API 和服務」>「程式庫」。
- 搜尋並啟用下列 API:
- Cloud Functions API
- Cloud Scheduler API
- Cloud Pub/Sub (Cloud Scheduler 必須使用這項服務才能叫用函式)
建立 Google Cloud 儲存空間 bucket
- 登入 Google Cloud 主控台。
前往「Cloud Storage Buckets」(Cloud Storage bucket) 頁面。
點選「建立」。
設定 bucket:
- 名稱:輸入符合值區名稱規定的專屬名稱 (例如 qualys-vscanner-bucket)。
- 選擇資料的儲存位置:選取位置。
- 為資料選擇儲存空間級別:選取值區的預設儲存空間級別,或選取「Autoclass」(自動分類),讓系統自動管理儲存空間級別。
- 選擇如何控制物件的存取權:選取「否」可強制禁止公開存取,並為 bucket 物件選取存取權控管模型。
- 儲存空間級別:根據需求選擇 (例如「標準」)。
點選「建立」。
建立 Google Cloud 服務帳戶
- 依序前往「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)。
- 建立新的服務帳戶。
- 為其設定描述性名稱 (例如 qualys-user)。
- 在您於上一個步驟建立的 Cloud Storage bucket 中,將「Storage 物件管理員」角色授予服務帳戶。
- 將 Cloud Functions 叫用者角色授予服務帳戶。
- 為服務帳戶建立 SSH 金鑰。
- 下載服務帳戶的 JSON 金鑰檔案。請妥善保管這個檔案。
選用:在 Qualys 中建立專屬的 API 使用者
- 登入 Qualys 控制台。
- 前往使用者。
- 依序點選「新增」>「使用者」。
- 輸入使用者的一般資訊。
- 選取「使用者角色」分頁標籤。
- 確認角色已勾選「API 存取權」核取方塊。
- 按一下 [儲存]。
找出特定 Qualys API 網址
選項 1
如「平台識別」一節所述,找出網址。
選項 2
- 登入 Qualys 控制台。
- 依序點選「說明」>「關於」。
- 捲動畫面,即可在「資安營運中心 (SOC)」下方查看這項資訊。
- 複製 Qualys API 網址。
設定 Cloud 函式
- 前往 Google Cloud 控制台的「Cloud Functions」。
- 按一下 [Create Function] (建立函式)。
設定函式:
- 名稱:輸入函式名稱 (例如 fetch-qualys-vscanner)。
- 「Region」(區域):選取靠近 Bucket 的區域。
- 觸發條件:視需要選擇 HTTP 觸發條件,或選擇 Cloud Pub/Sub 進行排程執行。
- 驗證:透過驗證確保安全。
- 使用內嵌編輯器編寫程式碼:
```python from google.cloud import storage import requests import base64 import json # Google Cloud Storage Configuration BUCKET_NAME = "<bucket-name>" FILE_NAME = "qualys_virtual_scanners.json" # Qualys API Credentials QUALYS_USERNAME = "qualys-username" QUALYS_PASSWORD = "<qualys-password>" QUALYS_BASE_URL = "https://<qualys_base_url>" # for example, https://qualysapi.qualys.com def fetch_virtual_scanners(): """Fetch Virtual Scanner details from Qualys.""" auth = base64.b64encode(f"{QUALYS_USERNAME}:{QUALYS_PASSWORD}".encode()).decode() headers = { "Authorization": f"Basic {auth}", "Content-Type": "application/xml" } url = f"{QUALYS_BASE_URL}/api/2.0/fo/scanner/" payload = { "action": "list", "scanner_type": "virtual" } response = requests.post(url, headers=headers, data=payload) response.raise_for_status() return response.text # Qualys API returns XML data def upload_to_gcs(data): """Upload data to Google Cloud Storage.""" client = storage.Client() bucket = client.get_bucket(BUCKET_NAME) blob = bucket.blob(FILE_NAME) blob.upload_from_string(data, content_type="application/xml") def main(request): """Cloud Function entry point.""" try: scanners = fetch_virtual_scanners() upload_to_gcs(scanners) return "Qualys Virtual Scanners data uploaded to Cloud Storage successfully!" except Exception as e: return f"An error occurred: {e}", 500 ```
完成設定後,按一下「Deploy」(部署)。
設定 Cloud Scheduler
- 前往控制台的「Cloud Scheduler」頁面。 Google Cloud
- 按一下 [Create Job] (建立工作)。
設定工作:
- 名稱:輸入工作名稱 (例如 trigger-fetch-qualys-vscanner)。
- 頻率:使用 cron 語法指定排程 (例如,0 0 * * * 代表每天午夜)。
- 時區:設定偏好的時區。
- 觸發條件類型:選擇「HTTP」。
- 「觸發網址」:輸入 Cloud Function 的網址 (部署後可在函式詳細資料中找到)。
- 方法:選擇「POST」。
建立工作。
設定動態饋給
在 Google SecOps 平台中,有兩種不同的進入點可設定動態饋給:
- 「SIEM 設定」>「動態消息」
- 內容中心 > 內容包
依序前往「SIEM 設定」>「動態饋給」,設定動態饋給
如要設定動態消息,請按照下列步驟操作:
- 依序前往「SIEM 設定」>「動態消息」。
- 按一下「新增動態消息」。
- 在下一個頁面中,按一下「設定單一動態饋給」。
- 在「動態消息名稱」欄位中輸入動態消息的名稱,例如「Qualys Virtual Scanner Logs」。
- 選取「Google Cloud Storage」做為「來源類型」。
- 選取「Qualys Virtual Scanner」做為「記錄類型」。
- 點選「下一步」。
指定下列輸入參數的值:
- 儲存空間值區 URI:儲存空間值區來源 URI。 Google Cloud
- URI 為:選取「單一檔案」。
- 來源刪除選項:根據偏好設定選取刪除選項。
點選「下一步」。
在「Finalize」畫面上檢查新的動態饋給設定,然後按一下「Submit」。
從內容中心設定動態饋給
為下列欄位指定值:
- 儲存空間值區 URI:儲存空間值區來源 URI。 Google Cloud
- URI 為:選取「單一檔案」。
來源刪除選項:根據偏好設定選取刪除選項。
進階選項
- 動態饋給名稱:系統預先填入的值,用於識別動態饋給。
- 來源類型:將記錄收集到 Google SecOps 的方法。
- 資產命名空間:與動態饋給相關聯的命名空間。
- 擷取標籤:套用至這個動態饋給所有事件的標籤。
UDM 對應表
記錄欄位 | UDM 對應 | 邏輯 |
---|---|---|
ASSET_ID | entity.entity.asset.asset_id | 直接對應「ASSET_ID 」欄位。 |
CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME | entity.relations.entity.resource.attribute.labels.key | 直接對應「CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME 」欄位。 |
CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE | entity.relations.entity.resource.attribute.labels.value | 直接對應「CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE 」欄位。 |
CLOUD_RESOURCE_ID | entity.relations.entity.resource.id | 直接對應「CLOUD_RESOURCE_ID 」欄位。 |
DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME | entity.metadata.threat.first_discovered_time | 直接從 DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME 欄位對應,並轉換為時間戳記。 |
DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME 」欄位。金鑰是以硬式編碼設為「FIRST_REOPENED_DATETIME」。 |
DETECTION_LIST.DETECTION.IS_DISABLED | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.IS_DISABLED 」欄位。索引鍵會以硬式編碼方式指定為「IS_DISABLED」。 |
DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME 」欄位。金鑰會以硬式編碼寫成「LAST_FIXED_DATETIME」。 |
DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME 」欄位。金鑰會以硬式編碼寫成「LAST_FOUND_DATETIME」。 |
DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME 」欄位。金鑰會以硬式編碼寫成「LAST_PROCESSED_DATETIME」。 |
DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME 」欄位。金鑰會以硬式編碼寫成「LAST_REOPENED_DATETIME」。 |
DETECTION_LIST.DETECTION.LAST_TEST_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_TEST_DATETIME 」欄位。金鑰會以硬式編碼寫成「LAST_TEST_DATETIME」。 |
DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME 」欄位。索引鍵會以硬式編碼寫成「LAST_UPDATE_DATETIME」。 |
DETECTION_LIST.DETECTION.PORT | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.PORT 」欄位。索引鍵會以硬式編碼寫成「PORT」。 |
DETECTION_LIST.DETECTION.PROTOCOL | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.PROTOCOL 」欄位。索引鍵會以硬式編碼寫成「PROTOCOL」。 |
DETECTION_LIST.DETECTION.QID | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.QID 」欄位。索引鍵會以硬式編碼寫成「QID」。 |
DETECTION_LIST.DETECTION.RESULTS | entity.metadata.threat.summary | 直接對應「DETECTION_LIST.DETECTION.RESULTS 」欄位。 |
DETECTION_LIST.DETECTION.SEVERITY | entity.metadata.threat.severity_details | 直接對應「DETECTION_LIST.DETECTION.SEVERITY 」欄位。 |
DETECTION_LIST.DETECTION.SSL | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.SSL 」欄位。金鑰以硬式編碼寫成「SSL」。 |
DETECTION_LIST.DETECTION.STATUS | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.STATUS 」欄位。索引鍵是以硬式編碼方式指定為「STATUS」。 |
DETECTION_LIST.DETECTION.TIMES_FOUND | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.TIMES_FOUND 」欄位。索引鍵會以硬式編碼寫成「TIMES_FOUND」。 |
DETECTION_LIST.DETECTION.TIMES_REOPENED | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.TIMES_REOPENED 」欄位。索引鍵是以硬式編碼寫成「TIMES_REOPENED」。 |
DETECTION_LIST.DETECTION.TYPE | entity.metadata.threat.severity | 對應自「DETECTION_LIST.DETECTION.TYPE 」欄位。如果值為「info」(不區分大小寫),則會對應至「INFORMATIONAL」。否則,系統會將其新增為偵測欄位,並使用「TYPE」鍵。 |
DETECTION_LIST.DETECTION.UNIQUE_VULN_ID | entity.metadata.threat.detection_fields.value | 直接對應「DETECTION_LIST.DETECTION.UNIQUE_VULN_ID 」欄位。金鑰會以硬式編碼寫成「UNIQUE_VULN_ID」。 |
DNS | entity.entity.asset.hostname | 如果 DNS_DATA.HOSTNAME 為空白,則會從 DNS 欄位對應。 |
DNS_DATA.HOSTNAME | entity.entity.asset.hostname | 直接對應「DNS_DATA.HOSTNAME 」欄位。 |
EC2_INSTANCE_ID | entity.relations.entity.resource.product_object_id | 直接對應「EC2_INSTANCE_ID 」欄位。 |
ID | entity.entity.asset.product_object_id | 直接對應「ID 」欄位。 |
ID | entity.metadata.product_entity_id | 直接對應「ID 」欄位。 |
IP | entity.entity.ip | 直接對應「IP 」欄位。 |
LAST_SCAN_DATETIME | entity.metadata.interval.start_time | 直接從 LAST_SCAN_DATETIME 欄位對應,並轉換為時間戳記。 |
METADATA.AZURE.ATTRIBUTE.NAME | entity.relations.entity.resource.attribute.labels.key | 直接對應「METADATA.AZURE.ATTRIBUTE.NAME 」欄位。 |
METADATA.AZURE.ATTRIBUTE.VALUE | entity.relations.entity.resource.attribute.labels.value | 直接對應「METADATA.AZURE.ATTRIBUTE.VALUE 」欄位。 |
作業系統 | entity.entity.asset.platform_software.platform | 對應自「OS 」欄位。如果值包含「windows」(不區分大小寫),則會對應至「WINDOWS」。如果包含「Linux」(不區分大小寫),則會對應至「LINUX」。 |
TAGS.TAG.NAME | entity.relations.entity.resource.attribute.labels.key | 直接對應「TAGS.TAG.NAME 」欄位。 |
TAGS.TAG.TAG_ID | entity.relations.entity.resource.attribute.labels.value | 對應自「TAGS.TAG.TAG_ID 」欄位。值的前置字串為「TAG_ID: 」。 |
entity.metadata.collected_timestamp | 記錄項目的時間戳記。 | |
entity.metadata.entity_type | 根據 IP 欄位是否存在而決定。如果存在 IP ,則會設為「IP_ADDRESS」。否則會設為「ASSET」。 |
|
entity.metadata.interval.end_time | 硬式編碼為非常大的時間戳記值 (253402300799 秒)。 | |
entity.metadata.product_name | 硬式編碼為「QUALYS_VIRTUAL_SCANNER」。 | |
entity.metadata.vendor_name | 硬式編碼為「QUALYS_VIRTUAL_SCANNER」。 | |
entity.relations.entity.resource.resource_type | 如果 CLOUD_SERVICE 為「VM」,則會設為「VIRTUAL_MACHINE」。 |
|
entity.relations.entity_type | 硬式編碼為「RESOURCE」。 | |
entity.relations.relationship | 硬式編碼為「MEMBER」。 |
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。