Sicherheitsergebnisse mit Security Command Center API auflisten

Security Command Center-Ergebnisse modellieren die potenziellen Sicherheitsrisiken von Assets in einem Projekt oder einer Organisation. Ein Ergebnis bezieht sich immer auf einen bestimmten Asset im Security Command Center.

In diesem Leitfaden erfahren Sie, wie Sie mit Security Command Center-Clientbibliotheken auf Ergebnisse zugreifen. Jedes Ergebnis gehört zu einer Quelle. Die meisten Detektoren oder Anbieter von Ergebnissen liefern Ergebnisse innerhalb derselben Quelle.

IAM-Rollen für Security Command Center können auf Organisations-, Ordner- oder Projektebene gewährt werden. Ob Sie Ergebnisse, Assets und Sicherheitsquellen ansehen, bearbeiten, erstellen oder aktualisieren können, hängt davon ab, auf welcher Ebene Sie Zugriff erhalten. Weitere Informationen zu Security Command Center-Rollen finden Sie unter Zugriffssteuerung.

Hinweise

Bevor Sie eine Quelle einrichten, müssen Sie die folgenden Schritte ausführen:

Seitengröße

Alle Security Command Center-Listen-APIs sind paginiert. Jede Antwort gibt eine Seite mit Ergebnissen und ein Token zurück, um die nächste Seite zurückzugeben. Die Seitengröße kann konfiguriert werden. Die Standardseitengröße ist 10. Sie können ein Minimum von 1 bis zu einem Maximum von 1.000 festlegen.

Aufbewahrung von Ergebnissen

Ein Ergebnis bleibt mindestens 13 Monate lang verfügbar, damit Sie es auflisten oder abfragen können.

Security Command Center speichert Snapshots der einzelnen Ergebnisse. Ein Snapshot eines Ergebnisses wird mindestens 13 Monate lang aufbewahrt. Wenn alle Snapshots für einen Befund gelöscht werden, kann der Befund nicht mehr aufgeführt oder wiederhergestellt werden.

Weitere Informationen zur Datenaufbewahrung in Security Command Center finden Sie unter Datenaufbewahrung.

Alle Ergebnisse auflisten

gcloud

Führen Sie den folgenden Befehl aus, um alle Ergebnisse in einem Projekt, Ordner oder einer Organisation aufzulisten:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
  --location=LOCATION

Ersetzen Sie Folgendes:

  • PARENT_TYPE: Die Ebene der Ressourcenhierarchie, für die Ergebnisse aufgelistet werden sollen. Verwenden Sie organizations, folders oder projects.
  • PARENT_ID: Die numerische ID der Organisation, des Ordners oder des Projekts oder die alphanumerische Projekt-ID.
  • LOCATION: Wenn der Datenstandort aktiviert ist, der Standort im Security Command Center, an dem die Ergebnisse aufgeführt werden sollen. Wenn der Datenstandort nicht aktiviert ist, verwenden Sie den Wert global.

Führen Sie den folgenden Befehl aus, um weitere Beispiele aufzurufen:

gcloud scc findings list --help

Beispiele finden Sie in der Dokumentation unter gcloud scc findings list.

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv2"
	"cloud.google.com/go/securitycenter/apiv2/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/-/locations/global"
		//		"projects/{projectId}/sources/-/locations/global"
		//		"folders/{folderId}/sources/-/locations/global"
		Parent: fmt.Sprintf("organizations/%s/sources/-/locations/global", 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
}

Java


import com.google.cloud.securitycenter.v2.ListFindingsRequest;
import com.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;
import com.google.cloud.securitycenter.v2.SecurityCenterClient;
import java.io.IOException;

public class ListAllFindings {

  public static void main(String[] args) throws IOException {
    // organizationId: The source to list all findings for.
    // You can also use project/ folder as the parent resource.
    String organizationId = "google-cloud-organization-id";

    // Specify the location to list the findings.
    String location = "global";

    // The source id to scope the findings.
    String sourceId = "source-id";

    listAllFindings(organizationId, sourceId, location);
  }

  // List all findings under a given parent resource.
  public static void listAllFindings(String organizationId, String sourceId, String location)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {
      ListFindingsRequest request =
          ListFindingsRequest.newBuilder()
              // To list findings across all sources, use "-".
              .setParent(
                  String.format("organizations/%s/sources/%s/locations/%s", organizationId,
                      sourceId,
                      location))
              .build();

      for (ListFindingsResult result : client.listFindings(request).iterateAll()) {
        System.out.printf("Finding: %s", result.getFinding().getName());
      }
      System.out.println("\nListing complete.");
    }
  }
}

Node.js

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

// Creates a new client.
const client = new SecurityCenterClient();

// TODO(developer): Update the following for your own environment.
const organizationId = '1081635000895';
const location = 'global';

// Required. Name of the source the findings belong to. If no location is
// specified, the default is global. The following list shows some examples:
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
// - `folders/[folder_id]/sources/[source_id]`
// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`
// - `projects/[project_id]/sources/[source_id]`
// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`
// To groupBy across all sources provide a source_id of `-`.
const parent = `organizations/${organizationId}/sources/-/locations/${location}`;

// Build the list findings request.
const listFindingsRequest = {
  parent,
};

async function listAllFindings() {
  // Call the API.
  const iterable = client.listFindingsAsync(listFindingsRequest);
  let count = 0;

  for await (const response of iterable) {
    // Just print a few for demonstration.
    if (count > 5) break;
    console.log(
      `${++count} ${response.finding.name} ${response.finding.resourceName}`
    );
  }
}

await listAllFindings();

Python

def list_all_findings(organization_id, source_name, location_id) -> int:
    """
    lists all findings for a source
    Args:
       organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
       source_name: is the resource path for a source that has been created
       location_id: GCP location id; example: 'global'
    Returns:
        int: returns the count of all findings for a source
    """
    from google.cloud import securitycenter_v2

    # Create a client.
    client = securitycenter_v2.SecurityCenterClient()
    parent = f"organizations/{organization_id}"
    all_sources = f"{parent}/sources/{source_name}/locations/{location_id}"

    # Create the request dictionary
    request = {"parent": all_sources}

    # Print the request for debugging
    print("Request: ", request)

    finding_result_iterator = client.list_findings(request={"parent": all_sources})
    for count, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                count, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    return finding_result_iterator

Die Ausgabe für jedes Ergebnis sieht in etwa so aus:

{
  "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"
  }
}

Ergebnisse filtern

Ein Projekt, ein Ordner oder eine Organisation hat möglicherweise viele Ergebnisse. Im vorherigen Beispiel wird kein Filter verwendet, daher werden alle Ergebnisdatensätze zurückgegeben.

Mit Ergebnisfiltern können Sie sich nur die Informationen zu den gewünschten Feldern anzeigen lassen. Diese Filter ähneln „where“-Klauseln in SQL-Anweisungen, aber statt für Spalten gelten sie für die von der API zurückgegebenen Objekte.

Im folgenden Beispiel werden nur Ergebnisse mit der Kategorie "MEDIUM_RISK_ONE" aufgelistet. Verschiedene Ergebnisanbieter (auch als Sicherheitsquellen bezeichnet) verwenden unterschiedliche Kategorien. Informationen zu den Kategorien, die Sie in Ihrem Filter verwenden können, finden Sie in der Dokumentation des Ergebnisanbieters.

gcloud

Verwenden Sie den folgenden Befehl, um Ergebnisse zu filtern:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
  --location=LOCATION \
  --source=SOURCE_ID \
  --filter="FILTER"

Ersetzen Sie Folgendes:

  • PARENT_TYPE: Die Ebene der Ressourcenhierarchie, für die Ergebnisse aufgelistet werden sollen. Verwenden Sie organizations, folders oder projects.
  • PARENT_ID: Die numerische ID der Organisation, des Ordners oder des Projekts oder die alphanumerische Projekt-ID.
  • LOCATION: Wenn die Datenspeicherung aktiviert ist, der Security Command Center-Speicherort, an dem Ergebnisse mit einem Filter aufgelistet werden sollen. Wenn die Datenspeicherung nicht aktiviert ist, verwenden Sie den Wert global.
  • SOURCE_ID: Die ID der Sicherheitsquelle, die den Ergebnistyp angibt.
  • FILTER: Der Filter, den Sie verwenden müssen. Mit dem folgenden Filter werden beispielsweise nur Ergebnisse aus der Kategorie MEDIUM_RISK_ONE zurückgegeben:
    --filter="category=\"MEDIUM_RISK_ONE\""

Führen Sie den folgenden Befehl aus, um weitere Beispiele aufzurufen:

gcloud scc findings list --help

Beispiele in der Dokumentation finden Sie unter gcloud scc findings list.

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv2"
	"cloud.google.com/go/securitycenter/apiv2/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
}

Java


import com.google.cloud.securitycenter.v2.ListFindingsRequest;
import com.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;
import com.google.cloud.securitycenter.v2.SecurityCenterClient;
import java.io.IOException;

public class ListFindingsWithFilter {

  public static void main(String[] args) throws IOException {
    // TODO: Replace the variables within {}
    // organizationId: Google Cloud Organization id.
    // You can also use project/ folder as the parent resource.
    String organizationId = "google-cloud-organization-id";

    // Specify the location to list the findings.
    String location = "global";

    // The source id to scope the findings.
    String sourceId = "source-id";

    listFilteredFindings(organizationId, sourceId, location);
  }

  // List filtered findings under a source.
  public static void listFilteredFindings(String organizationId, String sourceId, String location)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      // Use any one of the following formats:
      //  * organizations/{organization_id}/sources/{source_id}/locations/{location}
      //  * folders/{folder_id}/sources/{source_id}/locations/{location}
      //  * projects/{project_id}/sources/{source_id}/locations/{location}
      String parent = String.format("organizations/%s/sources/%s/locations/%s", organizationId,
          sourceId,
          location);

      // Listing all findings of category "MEDIUM_RISK_ONE".
      String filter = "category=\"MEDIUM_RISK_ONE\"";

      ListFindingsRequest request =
          ListFindingsRequest.newBuilder()
              .setParent(parent)
              .setFilter(filter)
              .build();

      for (ListFindingsResult result : client.listFindings(request).iterateAll()) {
        System.out.printf("Finding: %s", result.getFinding().getName());
      }
      System.out.println("\nListing complete.");
    }
  }
}

Node.js

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

// Creates a new client.
const client = new SecurityCenterClient();

// TODO(developer): Update the following for your own environment.
const organizationId = '1081635000895';
const location = 'global';

// Required. Name of the source to groupBy. If no location is specified,
// finding is assumed to be in global.
//  The following list shows some examples:
// - `organizations/[organization_id]/sources/[source_id]`
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
// - `folders/[folder_id]/sources/[source_id]`
// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`
// - `projects/[project_id]/sources/[source_id]`
// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`
// To groupBy across all sources provide a source_id of `-`.
const parent = `organizations/${organizationId}/sources/-/locations/${location}`;

// Listing all findings of category "MEDIUM_RISK_ONE".
const filter = 'category="MEDIUM_RISK_ONE"';

// Build the list findings with filter request.
const listFilteredFindingsRequest = {
  parent,
  filter,
};

async function listFilteredFindings() {
  // Call the API.
  const iterable = client.listFindingsAsync(listFilteredFindingsRequest);
  let count = 0;
  console.log('Findings:');
  for await (const response of iterable) {
    // Just print a few for demonstration.
    if (count > 5) break;
    console.log(
      `${++count} ${response.finding.name} ${response.finding.resourceName}`
    );
  }
}
await listFilteredFindings();

Python

def list_filtered_findings(organization_id, source_name, location_id) -> int:
    """
    lists filtered findings for a source
    Args:
        organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
        source_name: is the resource path for a source that has been created
        location_id: GCP location id; example: 'global'
    Returns:
         int: returns the filtered findings for a source
    """
    count = 0
    from google.cloud import securitycenter_v2

    # Create a new client.
    client = securitycenter_v2.SecurityCenterClient()
    parent = f"organizations/{organization_id}"
    all_sources = f"{parent}/sources/{source_name}/locations/{location_id}"
    finding_result_iterator = client.list_findings(
        request={"parent": all_sources, "filter": 'severity="LOW"'}
    )
    # Iterate an print all finding names and the resource they are
    # in reference to.
    for count, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                count, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    return count

Security Command Center unterstützt auch vollständige JSON-Arrays und Objekte als potenzielle Property-Typen. Sie können nach folgenden Kriterien filtern:

  • Arrayelemente
  • Vollständige JSON-Objekte mit partieller Stringübereinstimmung im Objekt
  • Untergeordnete JSON-Objekt-Felder

Unterstützte Operatoren

Die Abfrageanweisungen für Security Command Center-Ergebnisse unterstützen die Operatoren, die von den meisten Google Cloud APIs unterstützt werden.

In der folgenden Liste sind die verschiedenen Operatoren aufgeführt:

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

Die folgende Liste enthält alle Operatoren und Funktionen, die in Abfrageanweisungen für Ergebnisse unterstützt werden:

  • Für Strings:
    • = für vollständige Gleichberechtigung
    • : für Teilstringabgleich
  • Für Zahlen:
    • <, >, <=, >= für Ungleichungen
    • =, != für Gleichberechtigung
  • Für boolesche Werte:
    • = für Gleichberechtigung
  • Für logische Beziehungen:
    • AND
    • OR
    • NOT oder -
  • Für Gruppierungsausdrücke:
    • (, ) (Klammern)
  • Für Arrays:
    • contains(), eine Funktion zum Abfragen von Ergebnissen mit einem Array-Feld, das mindestens ein Element enthält, das mit dem angegebenen Filter übereinstimmt
    • containsOnly(): Funktion zum Abfragen von Ergebnissen mit einem Arrayfeld, das nur Elemente enthält, die mit dem angegebenen Filter übereinstimmen
  • Für IP-Adressen:
    • inIpRange(), eine Funktion zum Abfragen von IP-Adressen innerhalb eines bestimmten CIDR-Bereichs

Nach IP-Adressen filtern

Bestimmte Suchergebnisseigenschaften enthalten IP-Adressen. Sie können die Ergebnisse nach bestimmten IP-Adressen oder einem IP-Adressbereich filtern.

IP-Adressen werden als Strings in einer Vielzahl von Ergebnissen und Ergebnisattributen angezeigt, darunter:

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

Wenn Sie nach einer bestimmten IP-Adresse filtern möchten, können Sie den Gleichheitsoperator verwenden, wie im folgenden Beispiel gezeigt:

access.caller_ip="192.0.2.0"

Wenn Sie Ergebnisse nach einem IP-Adressbereich filtern möchten, verwenden Sie die Funktion inIpRange. Mit der Funktion inIpRange können Sie Ergebnisse auf diejenigen beschränken, die eine IP-Adresse in einem bestimmten CIDR-Bereich enthalten. Wenn Sie die NOT-Operation mit inIpRange verwenden, können Sie die Ergebnisse auf diejenigen eingrenzen, die eine IP-Adresse außerhalb des angegebenen CIDR-Bereichs enthalten.

Das folgende Beispiel zeigt die Syntax der Funktion inIpRange:

inIpRange(IP_FINDING_FIELD, "CIDR_RANGE")

Wenn sich die IP-Adresse in einem Arrayelement in einem Ergebnisfeld befindet, das ein Array enthält, verwenden Sie die folgende Syntax sowohl mit der Funktion contains als auch mit der Funktion inIpRange:

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

Im folgenden Beispiel wird mit der inIpRange-Funktion jedes destination_ip-Element des Arrays im connections-Suchfeld auf eine IP-Adresse im von 192.0.2.0/24 definierten CIDR-Bereich geprüft:

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

Im folgenden Beispiel wird ein gcloud CLI-Befehl mit der Funktion inIpRange verwendet, um Ergebnisse zu filtern, deren IP-Adresse im Feld connections.source_ip in einem Bereich liegt, aber nicht in einem anderen. Das Feld connections ist ein Array-Feld. Daher wird die Funktion contains verwendet:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(connections, inIpRange(source_ip, \"2001:db8::/32\")) \
      AND NOT contains(connections, inIpRange(source_ip, \"192.0.2.0/24\"))"

Beispiel für ein JSON-Objekt

In den Beispielen weiter unten auf dieser Seite wird davon ausgegangen, dass das folgende JSON-Objekt ein Ergebnisattribut ist:

{
  "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"
    ]
  }
}

Beispiel für das Filtern von Ergebnissen

Angenommen, das vorherige JSON-Beispiel ist ein Ergebnisattribut mit dem Namen my_property. Das folgende Beispiel enthält Abfragen für Ergebnisse, die das Objekt als Attribut haben. Sie können diese Filter auch mit anderen Filtern verwenden, indem Sie AND und OR in der Abfrage verwenden.

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.deeply_nested_object.x = 123"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.y = \"some-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.y : \"string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.z = \"some-other-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.z : \"other-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-1\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-2\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-3\""

Unterfilter für Arrayfelder

Beim Aufrufen von ListFindings können Sie einen Teilstring-Abgleich : verwenden. Damit wird eine einzelne Prüfung auf eine Teilstring-Übereinstimmung für den gesamten Inhalt des Arrays durchgeführt. Alternativ können Sie einen Unterfilter mithilfe einer der folgenden Funktionen direkt für Elemente des Arrays und seine Unterfelder ausführen:

  • Die Funktion contains() gibt Ergebnisse zurück, wenn eines der Elemente des Arrays den angegebenen Wert enthält.

  • Mit der Funktion containsOnly() werden nur Ergebnisse zurückgegeben, wenn alle Elemente des Arrays mit dem Unterfilter übereinstimmen.

Beide Funktionen unterstützen Unterfilterabfragen wie die folgenden:

  • Genauer Elementabgleich: Arrayelemente abgleichen, die den genauen String "example" enthalten.
  • Operationen mit spezifischen Zahlen: Arrayelementen abgleichen, die größer oder gleich 100 sind.
  • Komplexe Filterung nach Arraystrukturen: Arrayelemente abgleichen, die das Attribut x mit einem entsprechenden Wert y enthalten.

Format der contains()-Funktion

Die Funktion contains() hat das folgende Format:

contains(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Ersetzen Sie Folgendes:

  • ARRAY_ATTRIBUTE_NAME: Ein Feld oder Unterfeld vom Typ „Array“ (eine Liste).
  • SUBFILTER: Ein Ausdruck, der die Werte definiert, nach denen im Array gesucht werden soll. Das Format des Unterfilters variiert je nachdem, ob ARRAY_ATTRIBUTE_NAME ein Array von Objekten oder ein Array von Elementen mit primitivem Typ ist. Wenn das ARRAY_ATTRIBUTE_NAME ein Array von Objekten mit verschachtelten Arrays ist, können Sie mit einem Bereichsunterfilter angeben, dass alle Bedingungen innerhalb des ARRAY_ATTRIBUTE_NAME-Elements erfüllt sein sollen.

Die Security Command Center API gibt Ergebnisse zurück, bei denen ARRAY_ATTRIBUTE_NAME mindestens ein Element enthält, das dem SUBFILTER entspricht.

Format der containsOnly()-Funktion

Die Funktion containsOnly() hat das folgende Format:

containsOnly(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Ersetzen Sie Folgendes:

  • ARRAY_ATTRIBUTE_NAME: Ein Feld oder Unterfeld vom Typ „Array“ (eine Liste). Wenn Sie Abfragen mit der Security Command Center API ausführen, können Sie die Funktion containsOnly() für jedes verfügbare Arrayattribut verwenden.
  • SUBFILTER: Ein Ausdruck, der die Werte definiert, nach denen im Array gesucht werden soll. Das Format des Unterfilters variiert je nachdem, ob ARRAY_ATTRIBUTE_NAME ein Array von Objekten oder ein Array von Elementen des primitiven Typs ist. Wenn das ARRAY_ATTRIBUTE_NAME ein Array von Objekten mit verschachtelten Arrays ist, können Sie mit einem Bereichsunterfilter angeben, dass alle Bedingungen innerhalb des ARRAY_ATTRIBUTE_NAME-Elements erfüllt sein sollen.

Die Security Command Center API gibt Ergebnisse zurück, bei denen alle ARRAY_ATTRIBUTE_NAME-Elemente mit dem SUBFILTER übereinstimmen.

Unterfilter für ein Array von Objekten

Folgendes ist ein Auszug aus dem vorherigen JSON-Beispiel. Hier ist das Feld list_middle_object ein Array von Objekten:

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

Das folgende Beispiel fragt nach Ergebnissen ab, bei denen mindestens eines der Elemente im Feld list_middle_object das Unterfeld v mit einem Wert größer oder gleich 321 enthält:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.list_middle_object, v  >= 321)"

Praktische Beispiele für die Verwendung der Funktionen contains() und containsOnly() finden Sie unter Ergebnisse, die bestimmte Arraywerte enthalten.

Unterfilter für ein Array mit einfachen Elementen

Einfache Typen sind Strings, Zahlen und boolesche Werte. Wenn Sie die Funktion contains() für ein Array verwenden möchten, das einfache Typen enthält, verwenden Sie das spezielle Schlüsselwort elem.

Folgendes ist ein Auszug aus dem vorherigen JSON-Beispiel. Hier ist das Feld u ein Array von einfachen Elementen:

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

Im folgenden Beispiel wird nach Ergebnissen abgefragt, in denen mindestens eines der Elemente im Feld u "list-element-1" ist:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.u, elem = \"list-element-1\")"

Praktische Beispiele, die die Funktion contains() verwenden, finden Sie unter Ergebnisse, die bestimmte Arraywerte enthalten.

Bereichsunterfilter

Folgendes ist ein Auszug aus dem vorherigen JSON-Beispiel. Hier ist das Feld list_middle_object ein Array von Objekten und Objekte in diesem Array enthalten ein verschachteltes Array.

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

Im folgenden Beispiel wird nach Ergebnissen abgefragt, in denen beide der folgenden Bedingungen innerhalb desselben list_middle_object-Elements erfüllt sind:

  • Das Unterfeld v hat einen Wert größer oder gleich 321.
  • Das Unterfeld w enthält kein Element mit einem Attribut a, das den Wert 3 hat.
gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.list_middle_object, v  >= 321 AND -contains(w, a = 3))"

Praktische Beispiele, die die Funktion contains() verwenden, finden Sie unter Ergebnisse, die bestimmte Arraywerte enthalten.

Beispiel für das Sortieren von Ergebnissen

Sie können Ergebnisse nach strengen Teilfeldern sortieren, die einfache Typen sind, wie Strings, Zahlen und boolesche Werte. Angenommen, das vorherige JSON-Beispiel ist ein Ergebnisattribut mit dem Namen my_property. Das folgende Beispiel enthält Abfragen zum Sortieren der Ergebnisfelder. Das Schlüsselwort DESC gibt an, dass das Feld, dem gefolgt wird, in absteigender Reihenfolge sortiert werden muss. Die Standardreihenfolge ist aufsteigend.

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.deeply_nested_object.x DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.deeply_nested_object.x"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.y DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.y"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.z DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.z"

Beispiele für Filter

In den folgenden Abschnitten finden Sie praktische Beispiele für Ergebnisfilter.

Nach Ergebnissen filtern, die nach einem bestimmten Zeitpunkt erfasst wurden

Diese Beispielfilter stimmen mit Ergebnissen überein, die erst nach Mittwoch, 5. Juni 2019, 22:12:05 Uhr (GMT) aufgetreten sind. Mit dem Filter event_time können Sie die Zeit in den folgenden Formaten und Typen angeben:

  • Unixzeit (in Millisekunden) als Ganzzahlliteral

    "event_time > 1559772725000"
    
  • RFC 3339 als String-Literal

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

Nach Arrayfeldern filtern

Im folgenden Beispiel wird die Verwendung eines Teilstring-Abgleichs für ein Arrayfeld innerhalb eines Filters gezeigt:

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

Die Security Command Center API gibt alle Ergebnisse mit einem website.com-Teilstring innerhalb des Arrays zurück. Beispielsweise wird ein Ergebnis mit indicator.domains = [\"onewebsite.com\"] zurückgegeben, da "website.com" ein Teilstring in einem Element im Array ist.

In den folgenden Abschnitten zeigen die Beispielfilter einige Optionen für die Verwendung einer umfassenden Arrayfilterung mit der Funktion contains().

Nach dem Feld vulnerability.cve.references filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, bei denen mindestens ein Element im Array vulnerability.cve.references sowohl ein Attribut source mit dem Wert SOURCE_OF_REFERENCE als auch ein Attribut uri mit dem Wert FILTERED_URI hat.

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

Ersetzen Sie Folgendes:

Nach dem Feld indicator.domains filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, in denen mindestens eine Indikatordomain sowohl mycompanyprefix als auch .ca enthält.

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

Nach dem Feld indicator.ip_addresses filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, bei denen mindestens ein Element im Array indicator.ip_addresses gleich IP_ADDRESS ist.

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

Ersetzen Sie IP_ADDRESS durch eine IP-Adresse, die den Ergebnissen zugeordnet ist, nach denen Sie suchen.

Nach Beauftragten im externen System filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, bei denen mindestens ein Element im Array external_systems.EXTERNAL_SYSTEM_NAME.assignees gleich ASSIGNEE ist.

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

Ersetzen Sie Folgendes:

  • EXTERNAL_SYSTEM_NAME: Der Name eines SIEM-/SOAR-Systems eines Drittanbieters, z. B. demisto.
  • ASSIGNEE: Ein Beauftragter im externen System.

Nach dem Feld resource.folders.resource_folder filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, bei denen mindestens ein Element im Array resource.folders.resource_folder nicht gleich FOLDER_NAME ist.

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

Nach dem Feld resource.folders.resource_folder_display_name filtern

Im folgenden Beispiel werden Ergebnisse zurückgegeben, bei denen mindestens ein Element im Array resource.folders.resource_folder_display_name gleich DISPLAY_NAME ist.

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

Ersetzen Sie DISPLAY_NAME durch den benutzerdefinierten Namen des Ordners, der den Ergebnissen zugeordnet ist, nach denen Sie suchen.

Filter enthält nur bestimmte Dienstkonten

Im folgenden Beispiel werden nur Ergebnisse zurückgegeben, wenn der Mitgliedswert jedes iam_bindings-Eintrags mit einem der angegebenen Dienstkonten übereinstimmt.

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

Ersetzen Sie SERVICE_ACCOUNT1, SERVICE_ACCOUNT2 und SERVICE_ACCOUNT3 durch die E-Mail-Adressen der Dienstkonten.

Informationen zum Verwenden der Funktionen contains() und containsOnly() in einem Ergebnisfilter finden Sie unter Unterfilter für Felder vom Typ „Array“.

Nächste Schritte

Weitere Informationen zum Einrichten von Ergebnisbenachrichtigungen