Mencantumkan temuan keamanan menggunakan Security Command Center API

Temuan Security Command Center membuat model potensi risiko keamanan aset dalam suatu project atau organisasi. Temuan selalu berkaitan dengan aset tertentu di Security Command Center.

Panduan ini menunjukkan cara menggunakan library klien Security Command Center untuk mengakses temuan. Setiap temuan berasal dari sebuah sumber. Sebagian besar pendeteksi atau penyedia temuan menghasilkan temuan dalam sumber yang sama.

Peran IAM untuk Security Command Center dapat diberikan di tingkat organisasi, folder, atau project. Kemampuan Anda untuk melihat, mengedit, membuat, atau memperbarui temuan, aset, dan sumber keamanan bergantung pada tingkat akses yang diberikan kepada Anda. Untuk mempelajari peran Security Command Center lebih lanjut, lihat Kontrol akses.

Sebelum memulai

Sebelum menyiapkan sumber, Anda harus menyelesaikan langkah-langkah berikut:

Ukuran halaman

Semua daftar API Security Command Center diberi nomor halaman. Setiap respons akan menampilkan halaman hasil dan token untuk menampilkan halaman berikutnya. Ukuran halaman dapat dikonfigurasi. Ukuran halaman default adalah 10. Anda dapat menetapkannya ke minimum 1 dan maksimum 1.000.

Retensi temuan

Temuan tetap tersedia untuk dicantumkan atau ditelusuri setidaknya selama 13 bulan.

Security Command Center menyimpan snapshot setiap temuan. Snapshot temuan disimpan setidaknya selama 13 bulan. Jika semua snapshot untuk temuan dihapus, temuan tersebut tidak dapat lagi dicantumkan atau dipulihkan.

Untuk mengetahui informasi selengkapnya tentang retensi data Security Command Center, lihat Retensi data.

Membuat daftar semua temuan

gcloud

Untuk menampilkan daftar semua temuan dalam project, folder, atau organisasi, jalankan perintah berikut:

gcloud scc findings list PARENT_ID

Ganti PARENT_ID dengan salah satu nilai berikut:

  • ID organisasi dalam format berikut: ORGANIZATION_ID (khusus ID numerik)
  • ID folder dalam format berikut: folders/FOLDER_ID
  • Project ID dalam format berikut: projects/PROJECT_ID

Untuk contoh lainnya, jalankan:

gcloud scc findings list --help

Untuk melihat contoh dalam dokumentasi, lihat daftar temuan scc gcloud.

Python

from google.cloud import securitycenter

# Create a client.
client = securitycenter.SecurityCenterClient()

# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
parent = f"organizations/{organization_id}"
# The "sources/-" suffix lists findings across all sources.  You
# also use a specific source_name instead.
all_sources = f"{parent}/sources/-"
finding_result_iterator = client.list_findings(request={"parent": all_sources})
for i, finding_result in enumerate(finding_result_iterator):
    print(
        "{}: name: {} resource: {}".format(
            i, finding_result.finding.name, finding_result.finding.resource_name
        )
    )

Java

static ImmutableList<ListFindingsResult> listAllFindings(OrganizationName organizationName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Input parameters for SourceName must be in one of the following formats:
    //    * OrganizationName organizationName = OrganizationName.of("organization-id");
    //      organizationName.getOrganization();
    //    * ProjectName projectName = ProjectName.of("project-id");
    //      projectName.getProject();
    //    * FolderName folderName = FolderName.of("folder-id");
    //      folderName.getFolder();
    //
    // "-" Indicates listing across all sources.
    SourceName sourceName = SourceName.of(organizationName.getOrganization(), "-");

    ListFindingsRequest.Builder request =
        ListFindingsRequest.newBuilder().setParent(sourceName.toString());

    // Call the API.
    ListFindingsPagedResponse response = client.listFindings(request.build());

    // This creates one list for all findings.  If your organization has a large number of
    // findings this can cause out of memory issues.  You can process them in incrementally
    // by returning the Iterable returned response.iterateAll() directly.
    ImmutableList<ListFindingsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Findings:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listFindings prints all findings in orgID to w. orgID is the numeric
// identifier of the organization.
func listFindings(w io.Writer, orgID string) error {
	// orgID := "12321311"
	// Instantiate a context and a security service client to make API calls.
	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListFindingsRequest{
		// List findings across all sources.
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}/sources/-"
		//		"projects/{projectId}/sources/-"
		//		"folders/{folderId}/sources/-"
		Parent: fmt.Sprintf("organizations/%s/sources/-", orgID),
	}
	it := client.ListFindings(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("it.Next: %w", err)
		}
		finding := result.Finding
		fmt.Fprintf(w, "Finding Name: %s, ", finding.Name)
		fmt.Fprintf(w, "Resource Name %s, ", finding.ResourceName)
		fmt.Fprintf(w, "Category: %s\n", finding.Category)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();
//  organizationId is the numeric ID of the organization.
/*
 * TODO(developer): Uncomment the following lines
 */
// const organizationId = "1234567777";

async function listAllFindings() {
  const [response] = await client.listFindings({
    // List findings across all sources.
    // parent: must be in one of the following formats:
    //    `organizations/${organization_id}/sources/-`
    //    `projects/${project_id}/sources/-`
    //    `folders/${folder_id}/sources/-`
    parent: `organizations/${organizationId}/sources/-`,
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.finding.name} ${result.finding.resourceName}`
    )
  );
}
listAllFindings();

Output untuk setiap temuan mirip dengan berikut ini:

"finding": {
    "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID",
    "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID",
    "resourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "state": "ACTIVE",
    "category": "Malware: Cryptomining Bad Domain",
    "sourceProperties": {
      "sourceId": {
        "projectNumber": "PROJECT_NUMBER",
        "customerOrganizationNumber": "ORGANIZATION_ID"
      },
      "detectionCategory": {
        "technique": "cryptomining",
        "indicator": "domain",
        "ruleName": "bad_domain",
        "subRuleName": "cryptomining"
      },
      "detectionPriority": "LOW",
      "affectedResources": [{
        "gcpResourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER"
      }],
      "evidence": [{
        "sourceLogId": {
          "projectId": "PROJECT_ID",
          "resourceContainer": "projects/PROJECT_ID",
          "timestamp": {
            "seconds": "1636566099",
            "nanos": 5.41483849E8
          },
          "insertId": "INSERT_ID"
        }
      }],
      "properties": {
        "domains": ["DOMAIN"],
        "instanceDetails": "/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_ID",
        "network": {
          "project": "PROJECT_ID",
          "location": "ZONE"
        },
        "dnsContexts": [{
          "authAnswer": true,
          "sourceIp": "SOURCE_IP_ADDRESS",
          "queryName": "DOMAIN",
          "queryType": "A",
          "responseCode": "NXDOMAIN"
        }],
        "vpc": {
          "vpcName": "default"
        }
      },
      "findingId": "FINDING_ID",
      "contextUris": {
        "mitreUri": {
          "displayName": "MITRE Link",
          "url": "https://attack.mitre.org/techniques/T1496/"
        },
        "virustotalIndicatorQueryUri": [{
          "displayName": "VirusTotal Domain Link",
          "url": "https://www.virustotal.com/gui/domain/DOMAIN/detection"
        }],
        "cloudLoggingQueryUri": [{
          "displayName": "Cloud Logging Query Link",
          "url": "https://console.cloud.google.com/logs/query;query\u003dtimestamp%3D%222021-11-10T17:41:39.541483849Z%22%0AinsertId%3D%22INSERT_ID%22%0Aresource.labels.project_id%3D%22PROJECT_ID%22?project\u003dPROJECT_ID"
        }],
        "relatedFindingUri": {
        }
      }
    },
    "securityMarks": {
      "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks"
    },
    "eventTime": "2021-11-10T17:41:41.594Z",
    "createTime": "2021-11-10T17:41:42.014Z",
    "severity": "LOW",
    "workflowState": "NEW",
    "canonicalName": "projects/PROJECT_NUMBER/sources/SOURCE_ID/findings/FINDING_ID",
    "mute": "UNDEFINED",
    "findingClass": "THREAT",
    "indicator": {
      "domains": ["DOMAIN"]
    }
  },
  "resource": {
    "name": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "projectName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "projectDisplayName": "PROJECT_ID",
    "parentName": "//cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID",
    "parentDisplayName": "PARENT_NAME",
    "type": "google.cloud.resourcemanager.Project",
    "displayName": "PROJECT_ID"
  }

Filter temuan

Sebuah project, folder, atau organisasi mungkin memiliki banyak temuan. Contoh sebelumnya tidak menggunakan filter, sehingga semua catatan temuan ditampilkan. Dengan Security Command Center, Anda dapat menggunakan filter temuan untuk mendapatkan informasi hanya tentang temuan yang diinginkan.

Filter penemuan seperti klausa "di mana" dalam pernyataan SQL, tetapi bukan kolom, klausa tersebut berlaku untuk objek yang ditampilkan oleh API.

Contoh berikut hanya mencantumkan temuan yang memiliki kategori "MEDIUM_RISK_ONE". Penyedia temuan yang berbeda (juga dikenal sebagai sumber keamanan) menggunakan kumpulan kategori yang berbeda. Untuk menentukan kategori yang dapat digunakan dalam filter, lihat dokumentasi penyedia temuan.

gcloud

Gunakan perintah berikut untuk memfilter temuan:

gcloud scc findings list PARENT_ID --source=SOURCE_ID --filter="FILTER"

Ganti kode berikut:

  • FILTER dengan filter yang perlu Anda gunakan. Misalnya, filter berikut menampilkan temuan dari kategori MEDIUM_RISK_ONE saja:
    --filter="category=\"MEDIUM_RISK_ONE\""
  • PARENT_ID dengan salah satu nilai berikut:
    • ID organisasi dalam format berikut: ORGANIZATION_ID (khusus ID numerik)
    • Project ID dalam format berikut: projects/PROJECT_ID
    • ID folder dalam format berikut: folders/FOLDER_ID
  • SOURCE_ID dengan ID sumber keamanan yang menyediakan jenis temuan.

Untuk contoh lainnya, jalankan:

gcloud scc findings list --help

Untuk melihat contoh dalam dokumentasi, lihat daftar temuan scc gcloud.

Python

from google.cloud import securitycenter

# Create a new client.
client = securitycenter.SecurityCenterClient()

# 'source_name' is the resource path for a source that has been
# created previously (you can use list_sources to find a specific one).
# Its format is:
# source_name = f"{parent}/sources/{source_id}"
# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
# You an also use a wild-card "-" for all sources:
#   source_name = "organizations/111122222444/sources/-"
finding_result_iterator = client.list_findings(
    request={"parent": source_name, "filter": 'category="MEDIUM_RISK_ONE"'}
)
# Iterate an print all finding names and the resource they are
# in reference to.
for i, finding_result in enumerate(finding_result_iterator):
    print(
        "{}: name: {} resource: {}".format(
            i, finding_result.finding.name, finding_result.finding.resource_name
        )
    )

Java

static ImmutableList<ListFindingsResult> listFilteredFindings(SourceName sourceName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // parentId: must be one of the following:
    //    "organization-id"
    //    "project-id"
    //    "folder-id"
    // SourceName sourceName = SourceName.of(parentId, sourceId);

    // Create filter to category of MEDIUM_RISK_ONE
    String filter = "category=\"MEDIUM_RISK_ONE\"";

    ListFindingsRequest.Builder request =
        ListFindingsRequest.newBuilder().setParent(sourceName.toString()).setFilter(filter);

    // Call the API.
    ListFindingsPagedResponse response = client.listFindings(request.build());

    // This creates one list for all findings.  If your organization has a large number of
    // findings this can cause out of memory issues.  You can process them in incrementally
    // by returning the Iterable returned response.iterateAll() directly.
    ImmutableList<ListFindingsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Findings:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listFilteredFindings prints findings with category 'MEDIUM_RISK_ONE' for a
// specific source to w. sourceName is the full resource name of the source
// to search for findings under.
func listFilteredFindings(w io.Writer, sourceName string) error {
	// Specific source:
	// 		sourceName := "{parent}/sources/{sourceId}"
	// All sources:
	// 		sourceName := "{parent}/sources/-"
	// where,
	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	// Instantiate a context and a security service client to make API calls.
	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListFindingsRequest{
		Parent: sourceName,
		Filter: `category="MEDIUM_RISK_ONE"`,
	}
	it := client.ListFindings(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("it.Next: %w", err)
		}
		finding := result.Finding
		fmt.Fprintf(w, "Finding Name: %s, ", finding.Name)
		fmt.Fprintf(w, "Resource Name %s, ", finding.ResourceName)
		fmt.Fprintf(w, "Category: %s\n", finding.Category)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();
//  sourceName is the full resource path of the source to search for
//  findings.
/*
 * TODO(developer): Uncomment the following lines
 */
// const sourceName = `${parent}/sources/${sourceId}`;
// where,
// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
async function listFilteredFindings() {
  const [response] = await client.listFindings({
    // List findings across all sources.
    parent: sourceName,
    filter: 'category="MEDIUM_RISK_ONE"',
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.finding.name} ${result.finding.resourceName}`
    )
  );
}
listFilteredFindings();

Security Command Center juga mendukung array dan objek JSON lengkap sebagai jenis properti potensial. Anda dapat memfilter berdasarkan:

  • Elemen array
  • Objek JSON penuh dengan string yang cocok sebagian dalam objek
  • Subkolom objek JSON

Operator yang didukung

Pernyataan kueri untuk temuan Security Command Center mendukung operator yang didukung oleh sebagian besar Google Cloud API.

Daftar berikut menunjukkan penggunaan berbagai operator:

  • state="ACTIVE" AND NOT mute="MUTED"
  • create_time>"2023-08-15T19:05:32.428Z"
  • resource.parent_name:"prod"
  • severity="CRITICAL" OR severity="HIGH"

Daftar berikut menunjukkan semua operator dan fungsi yang didukung dalam pernyataan kueri untuk temuan:

  • Untuk string:
    • = untuk kesetaraan penuh
    • : untuk pencocokan string sebagian
  • Untuk angka:
    • <, >, <=, >= untuk pertidaksamaan
    • =, != untuk kesetaraan
  • Untuk boolean:
    • = untuk kesetaraan
  • Untuk hubungan logis:
    • AND
    • OR
    • NOT atau -
  • Untuk mengelompokkan ekspresi:
    • (, ) (tanda kurung)
  • Untuk array:
    • contains(), fungsi untuk membuat kueri temuan dengan kolom array yang berisi setidaknya satu elemen yang cocok dengan filter yang ditentukan
    • containsOnly(), fungsi untuk membuat kueri temuan dengan kolom array yang hanya berisi elemen yang cocok dengan filter yang ditentukan
  • Untuk alamat IP:
    • inIpRange(), fungsi untuk melakukan kueri alamat IP dalam rentang CIDR yang ditentukan

Memfilter alamat IP

Properti temuan tertentu menyertakan alamat IP. Anda dapat memfilter temuan berdasarkan alamat IP tertentu atau rentang alamat IP.

Alamat IP muncul sebagai string dalam berbagai properti temuan dan temuan, termasuk yang berikut:

  • access.caller_ip
  • connections.destinationIp
  • connections.sourceIp
  • indicator.ip_addresses

Untuk memfilter alamat IP tertentu, Anda dapat menggunakan operator kesetaraan, seperti yang ditunjukkan pada contoh berikut:

access.caller_ip="192.0.2.0"

Untuk memfilter temuan berdasarkan rentang alamat IP, gunakan fungsi inIpRange. Dengan menggunakan fungsi inIpRange, Anda memfilter temuan hanya ke temuan yang berisi alamat IP dalam rentang CIDR yang ditentukan. Dengan menggunakan operasi NOT dengan inIpRange, Anda dapat memfilter temuan hanya untuk temuan yang berisi alamat IP di luar rentang CIDR yang ditentukan.

Contoh berikut menunjukkan sintaksis fungsi inIpRange:

inIpRange(IP_FINDING_FIELD, "CIDR_RANGE")

Jika alamat IP berada dalam elemen array di kolom temuan yang berisi array, gunakan sintaksis berikut dengan fungsi contains dan fungsi inIpRange:

contains(ATTRIBUTE_WITH_ARRAY, inIpRange(IP_FINDING_FIELD, "CIDR_RANGE"))

Pada contoh berikut, fungsi inIpRange mengevaluasi setiap elemen destination_ip array yang terdapat dalam kolom temuan connections untuk alamat IP yang berada dalam rentang CIDR yang ditentukan oleh 192.0.2.0/24:

contains(connections, inIpRange(destination_ip, "192.0.2.0/24"))

Contoh berikut menunjukkan perintah gcloud CLI yang menggunakan fungsi inIpRange untuk memfilter temuan yang memiliki alamat IP di kolom connections.source_ip yang berada dalam satu rentang, tetapi tidak di rentang lain. Kolom connections adalah kolom jenis array, sehingga fungsi contains digunakan:

  gcloud scc findings list example-organization.com \
    --source=123456789012345678 \
    --filter="contains(connections, inIpRange(source_ip, "2001:db8::/32")) \
      AND NOT contains(connections, inIpRange(source_ip, "192.0.2.0/24"))

Contoh objek JSON

Contoh di halaman ini selanjutnya mengasumsikan bahwa objek JSON berikut adalah atribut temuan:

{
  "outer_object": {
    "middle_object": {
      "deeply_nested_object": {
        "x": 123
      },
      "y": "some-string-value"
    },
    "list_middle_object": [
      {
        "v": 321,
        "w": [
          {
            "a": 3,
            "b": 4
          }
        ]
      }
    ],
    "z": "some-other-string-value",
    "u": [
      "list-element-1",
      "list-element-2",
      "list-element-3"
    ]
  }
}

Contoh temuan pemfilteran

Misalkan contoh JSON sebelumnya adalah atribut temuan bernama my_property. Contoh berikut menyertakan kueri untuk temuan yang memiliki objek sebagai properti. Anda juga dapat menggunakan filter ini dengan filter lain menggunakan AND dan OR dalam kueri Anda.

# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.middle_object.deeply_nested_object.x = 123"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.middle_object.y = \"some-string-value\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.middle_object.y : \"string-value\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.z = \"some-other-string-value\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.z : \"other-string-value\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.u : \"list-element-1\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.u : \"list-element-2\""

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="my_property.outer_object.u : \"list-element-3\""

Pemfilteran pada kolom jenis array

Saat memanggil ListFindings, Anda dapat menggunakan pencocokan substring :, yang melakukan pemeriksaan tunggal untuk kecocokan string sebagian di seluruh konten array. Atau, Anda dapat menjalankan subfilter secara langsung terhadap elemen array dan subkolomnya menggunakan salah satu fungsi berikut:

  • Fungsi contains() untuk menampilkan temuan saat ada elemen array yang berisi nilai yang ditentukan.

  • Fungsi containsOnly() untuk menampilkan temuan hanya jika semua elemen array cocok dengan subfilter.

Kedua fungsi ini mendukung kemampuan kueri subfilter seperti berikut:

  • Pencocokan elemen yang persis: Mencocokkan elemen array yang berisi string yang sama persis, "example".
  • Operasi angka tertentu: Mencocokkan elemen array yang lebih besar dari atau sama dengan 100.
  • Pemfilteran kompleks terhadap struktur array: Mencocokkan elemen array yang berisi properti x dengan nilai y yang sesuai.

Format fungsi contains()

Fungsi contains() memiliki format berikut:

contains(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Ganti kode berikut:

  • ARRAY_ATTRIBUTE_NAME: kolom atau subkolom yang merupakan array jenis (daftar).
  • SUBFILTER: ekspresi yang menentukan nilai yang akan dicari dalam array. Format subfilter berbeda-beda, bergantung pada apakah ARRAY_ATTRIBUTE_NAME adalah array objek atau array elemen jenis dasar. Jika ARRAY_ATTRIBUTE_NAME adalah array objek yang memiliki array bertingkat, Anda dapat menggunakan subfilter cakupan untuk menentukan bahwa Anda ingin semua kondisi terpenuhi dalam elemen ARRAY_ATTRIBUTE_NAME yang sama.

Security Command Center API menampilkan temuan ketika ARRAY_ATTRIBUTE_NAME berisi setidaknya satu elemen yang memenuhi SUBFILTER.

Format fungsi containsOnly()

Fungsi containsOnly() memiliki format berikut:

containsOnly(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Ganti kode berikut:

  • ARRAY_ATTRIBUTE_NAME: kolom atau subkolom yang merupakan array jenis (daftar). Saat menjalankan kueri menggunakan Security Command Center API, Anda dapat menggunakan fungsi containsOnly() untuk setiap atribut array yang tersedia.

  • SUBFILTER: ekspresi yang menentukan nilai yang akan dicari dalam array. Format subfilter berbeda-beda, bergantung pada apakah ARRAY_ATTRIBUTE_NAME adalah array objek atau array elemen jenis dasar. Jika ARRAY_ATTRIBUTE_NAME adalah array objek yang memiliki array bertingkat, Anda dapat menggunakan subfilter cakupan untuk menentukan bahwa Anda ingin semua kondisi terpenuhi dalam elemen ARRAY_ATTRIBUTE_NAME yang sama.

Security Command Center API menampilkan temuan jika semua elemen ARRAY_ATTRIBUTE_NAME cocok dengan SUBFILTER.

Subfilter untuk array objek

Berikut adalah kutipan contoh JSON sebelumnya. Di sini, kolom list_middle_object adalah array objek:

    "list_middle_object": [
      {
        "v": 321,
        "w": [
          {
            "a": 3,
            "b": 4
          }
        ]
      }
    ]

Contoh kueri berikut untuk temuan dengan setidaknya salah satu elemen dalam kolom list_middle_object memiliki subkolom v dengan nilai lebih besar dari atau sama dengan 321:

# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="contains(my_property.outer_object.list_middle_object, v  >= 321)"

Untuk contoh praktis yang menggunakan fungsi contains() dan containsOnly(), lihat Temuan yang berisi nilai array tertentu.

Subfilter untuk array yang berisi elemen jenis primitif

Jenis primitif adalah string, angka, dan boolean. Untuk menggunakan fungsi contains() terhadap array yang berisi jenis primitif, gunakan kata kunci khusus, elem.

Berikut adalah kutipan contoh JSON sebelumnya. Di sini, kolom u adalah array elemen jenis primitif:

"u": ["list-element-1", "list-element-2", "list-element-3"]

Contoh kueri berikut untuk temuan dengan setidaknya salah satu elemen di kolom u adalah "list-element-1":

# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="contains(my_property.outer_object.u, elem = \"list-element-1\")"

Untuk contoh praktis yang menggunakan fungsi contains(), lihat Temuan yang berisi nilai array tertentu.

Subfilter tercakup

Berikut adalah kutipan contoh JSON sebelumnya. Di sini, kolom list_middle_object adalah array objek, dan objek dalam array ini berisi array bertingkat.

    "list_middle_object": [
      {
        "v": 321,
        "w": [
          {
            "a": 3,
            "b": 4
          }
        ]
      }
    ]

Contoh kueri berikut untuk temuan saat kedua kondisi berikut terpenuhi dalam elemen list_middle_object yang sama:

  • Subkolom v memiliki nilai yang lebih besar dari atau sama dengan 321.
  • Subkolom w tidak berisi elemen dengan properti a yang sama dengan 3.
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --filter="contains(my_property.outer_object.list_middle_object, v  >= 321 AND -contains(w, a = 3))"

Untuk contoh praktis yang menggunakan fungsi contains(), lihat Temuan yang berisi nilai array tertentu.

Contoh pengurutan temuan

Anda dapat mengurutkan temuan berdasarkan subkolom ketat yang merupakan jenis primitif—string, angka, dan boolean. Misalkan contoh JSON sebelumnya adalah atribut temuan yang bernama my_property. Contoh berikut mencakup kueri untuk mengurutkan {i>field<i} yang ditemukan. Kata kunci DESC menentukan bahwa kolom yang diikutinya harus diurutkan dalam urutan menurun. Urutan defaultnya adalah menaik.

# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.middle_object.deeply_nested_object.x DESC"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.middle_object.deeply_nested_object.x"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.middle_object.y DESC"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.middle_object.y"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.z DESC"

gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
  --order-by="my_property.outer_object.z"

Contoh filter

Bagian berikut menunjukkan contoh praktis dari menemukan filter.

Filter temuan yang terjadi setelah waktu tertentu

Contoh ini memfilter temuan cocok yang terakhir terjadi setelah Rabu, 5 Juni 2019 pukul 22.12.05 GMT. Dengan filter event_time, Anda dapat mengekspresikan waktu menggunakan format dan jenis berikut:

  • Waktu Unix epoch (dalam milidetik) sebagai literal bilangan bulat

    "event_time > 1559772725000"
    
  • RFC 3339 sebagai string literal

    "event_time > \"2019-06-05T22:34:40+00:00\""
    

Filter pada kolom jenis array

Contoh berikut menunjukkan penggunaan pencocokan string sebagian pada kolom jenis array dalam filter:

"indicator.domains : \"website.com\""

Security Command Center API menampilkan temuan apa pun dengan string parsial website.com dalam array. Misalnya, class ini cocok dengan temuan dengan indicator.domains = [\"onewebsite.com\"] karena "website.com" adalah substring dalam elemen dalam array.

Di bagian berikut, contoh filter menunjukkan beberapa opsi untuk penggunaan pemfilteran jenis array lengkap menggunakan fungsi contains().

Filter di kolom vulnerability.cve.references

Contoh berikut menampilkan temuan dengan setidaknya satu elemen dalam array vulnerability.cve.references memiliki properti source yang sama dengan SOURCE_OF_REFERENCE dan properti uri yang memiliki FILTERED_URI.

"contains(vulnerability.cve.references, source = \"SOURCE_OF_REFERENCE\" AND uri : \"FILTERED_URI\")"

Ganti kode berikut:

Filter di kolom indicator.domains

Contoh berikut menampilkan temuan dengan setidaknya satu domain indikator memiliki mycompanyprefix dan .ca.

"contains(indicator.domains, elem : \"mycompanyprefix\" AND elem : \".ca\")"

Filter di kolom indicator.ip_addresses

Contoh berikut menampilkan temuan ketika setidaknya satu elemen dalam array indicator.ip_addresses sama dengan IP_ADDRESS.

"contains(indicator.ip_addresses, elem = \"IP_ADDRESS\")"

Ganti IP_ADDRESS dengan alamat IP yang terkait dengan temuan yang Anda telusuri.

Filter pada penerima tugas sistem eksternal

Contoh berikut menampilkan temuan ketika setidaknya satu elemen dalam array external_systems.EXTERNAL_SYSTEM_NAME.assignees sama dengan ASSIGNEE.

"contains(external_systems.EXTERNAL_SYSTEM_NAME.assignees, elem = \"ASSIGNEE\")"

Ganti kode berikut:

  • EXTERNAL_SYSTEM_NAME: nama sistem SIEM/SOAR pihak ketiga—misalnya, demisto.
  • ASSIGNEE: penerima tugas di sistem eksternal.

Filter di kolom resource.folders.resource_folder

Contoh berikut menampilkan temuan ketika setidaknya satu elemen dalam array resource.folders.resource_folder tidak sama dengan FOLDER_NAME.

"contains(resource.folders.resource_folder, -(elem = \"FOLDER_NAME\"))"

Filter di kolom resource.folders.resource_folder_display_name

Contoh berikut menampilkan temuan ketika setidaknya satu elemen dalam array resource.folders.resource_folder_display_name sama dengan DISPLAY_NAME.

"contains(resource.folders.resource_folder_display_name, elem = \"DISPLAY_NAME\")"

Ganti DISPLAY_NAME dengan nama folder yang ditentukan pengguna yang terkait dengan temuan yang Anda telusuri.

Filter hanya menyertakan akun layanan tertentu

Contoh berikut hanya menampilkan temuan jika setiap nilai anggota entri iam_bindings sama dengan salah satu akun layanan yang disediakan.

containsOnly(iam_bindings, (member = SERVICE_ACCOUNT1 OR member = SERVICE_ACCOUNT2 OR member = "SERVICE_ACCOUNT3 "))

Ganti SERVICE_ACCOUNT1, SERVICE_ACCOUNT2, dan SERVICE_ACCOUNT3 dengan alamat email untuk akun layanan.

Untuk mempelajari cara menggunakan fungsi contains() dan containsOnly() dalam filter temuan, lihat Memfilter kolom jenis array.

Langkah selanjutnya

Pelajari lebih lanjut Menyiapkan notifikasi temuan.