Elenco dei risultati di sicurezza con l'API Security Command Center

I risultati di Security Command Center modellano i potenziali rischi per la sicurezza degli asset in un progetto o un'organizzazione. Un risultato è sempre correlato a un asset specifico in Security Command Center.

Questa guida mostra come utilizzare le librerie client di Security Command Center per accedere ai risultati. Ogni risultato appartiene a un'origine. La maggior parte dei rilevatori o dei provider di risultati produce risultati all'interno della stessa origine.

I ruoli IAM per Security Command Center possono essere concessi a livello di organizzazione, cartella o progetto. La possibilità di visualizzare, modificare, creare o aggiornare risultati, asset e origini di sicurezza dipende dal livello per cui ti viene concesso l'accesso. Per saperne di più sui ruoli di Security Command Center, consulta Controllo dell'accesso.

Prima di iniziare

Prima di configurare un'origine, devi completare le seguenti operazioni:

Dimensioni pagina

Tutte le API elenco di Security Command Center vengono impaginate. Ogni risposta restituisce una pagina di risultati e un token per restituire la pagina successiva. Le dimensioni della pagina sono configurabili. La dimensione predefinita della pagina è 10. Puoi impostarlo su un minimo di 1 e un massimo di 1000.

Conservazione dei risultati

Un risultato rimane disponibile per l'elenco o la query per almeno 13 mesi.

Security Command Center archivia gli snapshot di ogni risultato. Un'istantanea di un risultato viene conservata per almeno 13 mesi. Se tutti gli snapshot di un risultato vengono eliminati, il risultato non può più essere elencato o recuperato.

Per maggiori informazioni sulla conservazione dei dati di Security Command Center, consulta Conservazione dei dati.

Elenco di tutti i risultati

gcloud

Per elencare tutti i risultati in un progetto, una cartella o un'organizzazione, esegui questo comando:

gcloud scc findings list PARENT_ID

Sostituisci PARENT_ID con uno dei seguenti valori:

  • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
  • Un ID cartella nel seguente formato: folders/FOLDER_ID
  • Un ID progetto nel seguente formato: projects/PROJECT_ID

Per altri esempi, esegui:

gcloud scc findings list --help

Per esempi nella documentazione, vedi gcloud scc results list.

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();

L'output di ogni risultato è simile al seguente:

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

Filtra risultati

Un progetto, una cartella o un'organizzazione potrebbe avere molti risultati. L'esempio precedente non utilizza un filtro, quindi vengono restituiti tutti i record dei risultati. Security Command Center consente di utilizzare i filtri di ricerca per ottenere informazioni solo sui risultati che ti interessano.

I filtri dei risultati sono come clausole "where" nelle istruzioni SQL, ma anziché colonne, si applicano agli oggetti restituiti dall'API.

L'esempio seguente elenca solo i risultati con una categoria "MEDIUM_RISK_ONE". Provider di risultati diversi (noti anche come origini di sicurezza) utilizzano insiemi di categorie diversi. Per determinare le categorie che puoi utilizzare nel filtro, consulta la documentazione del provider dei risultati.

gcloud

Utilizza il seguente comando per filtrare i risultati:

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

Sostituisci quanto segue:

  • FILTER con il filtro che devi utilizzare. Ad esempio, il seguente filtro restituisce risultati solo dalla categoria di MEDIUM_RISK_ONE:
    --filter="category=\"MEDIUM_RISK_ONE\""
  • PARENT_ID con uno dei seguenti valori:
    • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
    • Un ID progetto nel seguente formato: projects/PROJECT_ID
    • Un ID cartella nel seguente formato: folders/FOLDER_ID
  • SOURCE_ID con l'ID dell'origine di sicurezza che fornisce il tipo di risultato.

Per altri esempi, esegui:

gcloud scc findings list --help

Per esempi nella documentazione, vedi gcloud scc results list.

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 supporta anche array e oggetti JSON completi come potenziali tipi di proprietà. Puoi filtrare in base a:

  • Elementi array
  • Oggetti JSON completi con corrispondenza parziale della stringa all'interno dell'oggetto
  • Sottocampi degli oggetti JSON

Operatori supportati

Le istruzioni di query per i risultati di Security Command Center supportano gli operatori supportati dalla maggior parte delle API di Google Cloud.

Il seguente elenco mostra l'utilizzo di vari operatori:

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

Il seguente elenco mostra tutti gli operatori e le funzioni supportati nelle istruzioni di query per i risultati:

  • Per le stringhe:
    • = per la piena uguaglianza
    • : per la corrispondenza parziale delle stringhe
  • Per i numeri:
    • <, >, <=, >= per le disuguaglianze
    • =, != per l'uguaglianza
  • Per i valori booleani:
    • = per l'uguaglianza
  • Per le relazioni logiche:
    • AND
    • OR
    • NOT o -
  • Per raggruppare le espressioni:
    • (, ) (parentesi)
  • Per gli array:
    • contains(), una funzione per eseguire query sui risultati con un campo array contenente almeno un elemento che corrisponde al filtro specificato
    • containsOnly(), una funzione per eseguire query sui risultati con un campo array che contiene solo gli elementi che corrispondono al filtro specificato
  • Per gli indirizzi IP:
    • inIpRange(), una funzione per eseguire query su indirizzi IP all'interno di un intervallo CIDR specificato

Filtrare in base agli indirizzi IP

Alcune proprietà dei risultati includono gli indirizzi IP. Puoi filtrare i risultati in base a indirizzi IP specifici o a un intervallo di indirizzi IP.

Gli indirizzi IP vengono visualizzati come stringhe in una serie di risultati e proprietà dei risultati, tra cui:

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

Per filtrare in base a un indirizzo IP specifico, puoi utilizzare l'operatore di uguaglianza, come mostrato nell'esempio seguente:

access.caller_ip="192.0.2.0"

Per filtrare i risultati in base a un intervallo di indirizzi IP, utilizza la funzione inIpRange. Utilizzando la funzione inIpRange, filtri i risultati solo per i risultati che contengono un indirizzo IP in un intervallo CIDR specificato. Utilizzando l'operazione NOT con inIpRange, puoi filtrare i risultati solo in base a quelli che contengono un indirizzo IP esterno all'intervallo CIDR specificato.

L'esempio seguente mostra la sintassi della funzione inIpRange:

inIpRange(IP_FINDING_FIELD, "CIDR_RANGE")

Se l'indirizzo IP si trova in un elemento array in un campo di risultati contenente un array, utilizza la seguente sintassi sia con la funzione contains sia con la funzione inIpRange:

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

Nel seguente esempio, la funzione inIpRange valuta ogni elemento destination_ip dell'array contenuto nel campo di ricerca connections per un indirizzo IP compreso nell'intervallo CIDR definito da 192.0.2.0/24:

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

L'esempio seguente mostra un comando gcloud CLI che utilizza la funzione inIpRange per filtrare i risultati che hanno un indirizzo IP nel campo connections.source_ip che rientra in un intervallo, ma non in un altro. Il campo connections è un campo di tipo array, di conseguenza viene utilizzata la funzione contains:

  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"))

Oggetto JSON di esempio

Gli esempi più avanti in questa pagina presuppongono che il seguente oggetto JSON sia un attributo di rilevamento:

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

Esempio di filtraggio dei risultati

Supponiamo che il precedente esempio JSON sia un attributo dei risultati denominato my_property. L'esempio seguente include query per i risultati che hanno l'oggetto come proprietà. Puoi anche utilizzare questi filtri con altri filtri utilizzando AND e OR nella query.

# 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\""

Applicazione di filtri in base ai campi di tipo array

Quando chiami ListFindings, puoi utilizzare una corrispondenza di sottostringa :, che esegue un singolo controllo di una corrispondenza parziale di stringa in tutti i contenuti dell'array. In alternativa, puoi eseguire un sottofiltro direttamente sugli elementi dell'array e sui suoi sottocampi utilizzando una delle seguenti funzioni:

  • La funzione contains() per restituire i risultati quando qualsiasi elemento dell'array contiene il valore specificato.

  • La funzione containsOnly() per restituire i risultati solo se tutti gli elementi dell'array corrispondono al sottofiltro.

Entrambe le funzioni supportano le funzionalità di query dei filtri secondari come le seguenti:

  • Corrispondenza esatta degli elementi: consente di abbinare gli elementi dell'array contenenti la stringa esatta "example".
  • Operazioni numeriche specifiche: associa gli elementi dell'array maggiori o uguali a 100.
  • Filtraggio complesso in base a strutture array: associa gli elementi array che contengono la proprietà x con un valore corrispondente y.

Formato della funzione contains()

La funzione contains() ha il seguente formato:

contains(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Sostituisci quanto segue:

  • ARRAY_ATTRIBUTE_NAME: un campo o sottocampo di tipo array (un elenco).
  • SUBFILTER: un'espressione che definisce i valori da cercare nell'array. Il formato del filtro secondario varia a seconda che ARRAY_ATTRIBUTE_NAME sia un array di oggetti o un array di elementi di tipo primitivo. Se ARRAY_ATTRIBUTE_NAME è un array di oggetti con array nidificati, puoi utilizzare un filtro secondario basato sull'ambito per specificare che vuoi che tutte le condizioni siano soddisfatte all'interno dello stesso elemento ARRAY_ATTRIBUTE_NAME.

L'API Security Command Center restituisce risultati in cui ARRAY_ATTRIBUTE_NAME contiene almeno un elemento che soddisfa SUBFILTER.

Formato della funzione containsOnly()

La funzione containsOnly() ha il seguente formato:

containsOnly(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Sostituisci quanto segue:

  • ARRAY_ATTRIBUTE_NAME: un campo o sottocampo di tipo array (un elenco). Quando esegui query con l'API Security Command Center, puoi utilizzare la funzione containsOnly() per qualsiasi attributo array disponibile.

  • SUBFILTER: un'espressione che definisce i valori da cercare nell'array. Il formato del filtro secondario varia a seconda che ARRAY_ATTRIBUTE_NAME sia un array di oggetti o un array di elementi di tipo primitivo. Se ARRAY_ATTRIBUTE_NAME è un array di oggetti con array nidificati, puoi utilizzare un filtro secondario basato su ambito per indicare che vuoi che siano soddisfatte tutte le condizioni all'interno dello stesso elemento ARRAY_ATTRIBUTE_NAME.

L'API Security Command Center restituisce i risultati in cui tutti gli elementi ARRAY_ATTRIBUTE_NAME corrispondono a SUBFILTER.

Filtro secondario per un array di oggetti

Di seguito è riportato un estratto dell'esempio JSON precedente. In questo caso, il campo list_middle_object è un array di oggetti:

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

L'esempio seguente esegue query per trovare risultati in cui almeno uno degli elementi nel campo list_middle_object ha un sottocampo v con un valore maggiore o uguale a 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)"

Per esempi pratici che utilizzano le funzioni contains() e containsOnly(), consulta Risultati che contengono valori di array specifici.

Sottofiltro per un array che contiene elementi di tipo primitivo

I tipi primitivi sono stringhe, numeri e booleani. Per utilizzare la funzione contains() con un array che contiene tipi primitivi, devi utilizzare la parola chiave speciale elem.

Di seguito è riportato un estratto dell'esempio JSON precedente. Qui, il campo u è un array di elementi di tipo primitivo:

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

L'esempio seguente esegue query per trovare risultati in cui almeno uno degli elementi nel campo u è "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\")"

Per esempi pratici che utilizzano la funzione contains(), consulta Risultati che contengono valori di array specifici.

Sottofiltro con ambito

Di seguito è riportato un estratto dell'esempio JSON precedente. In questo caso, il campo list_middle_object è un array di oggetti e gli oggetti in questo array contengono un array nidificato.

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

L'esempio seguente esegue query per trovare risultati in cui vengono soddisfatte entrambe le seguenti condizioni all'interno dello stesso elemento list_middle_object:

  • Il sottocampo v ha un valore maggiore o uguale a 321.
  • Il sottocampo w non contiene un elemento con una proprietà a uguale a 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))"

Per esempi pratici che utilizzano la funzione contains(), consulta Risultati che contengono valori di array specifici.

Esempio di ordinamento dei risultati

Puoi ordinare i risultati in base a sottocampi rigidi di tipi primitivi: stringhe, numeri e booleani. Supponiamo che il precedente esempio JSON sia un attributo di ricerca denominato my_property. L'esempio seguente include query per ordinare i campi dei risultati. La parola chiave DESC specifica che il campo che segue deve essere ordinato in ordine decrescente. L'ordine predefinito è crescente.

# 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"

Esempi di filtro

Le seguenti sezioni mostrano esempi pratici dei filtri dei risultati.

Filtra per i risultati che si sono verificati dopo un determinato momento

Questi filtri di esempio corrispondono ai risultati che si sono verificati più di recente dopo mercoledì 5 giugno 2019 alle 22:12:05 GMT. Con il filtro event_time, puoi esprimere il tempo utilizzando i seguenti formati e tipi:

  • Tempo epoch Unix (in millisecondi) come valore letterale intero

    "event_time > 1559772725000"
    
  • RFC 3339 come valore letterale stringa

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

Filtra in base ai campi di tipo array

L'esempio seguente mostra l'utilizzo di una corrispondenza parziale di stringa su un campo di tipo array all'interno di un filtro:

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

L'API Security Command Center restituisce qualsiasi risultato con una stringa parziale website.com nell'array. Ad esempio, corrisponde a un risultato con indicator.domains = [\"onewebsite.com\"] perché "website.com" è una sottostringa in un elemento dell'array.

Nelle sezioni seguenti, i filtri di esempio mostrano alcune opzioni per l'utilizzo del filtro avanzato di tipo array con la funzione contains().

Filtra in base al campo vulnerability.cve.references

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array vulnerability.cve.references ha una proprietà source uguale a SOURCE_OF_REFERENCE e una proprietà uri con FILTERED_URI.

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

Sostituisci quanto segue:

Filtra in base al campo indicator.domains

L'esempio seguente restituisce risultati in cui almeno un dominio indicatore ha sia mycompanyprefix che .ca.

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

Filtra in base al campo indicator.ip_addresses

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array indicator.ip_addresses è uguale a IP_ADDRESS.

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

Sostituisci IP_ADDRESS con un indirizzo IP associato ai risultati che stai cercando.

Filtra in base agli assegnatari di sistema esterni

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array external_systems.EXTERNAL_SYSTEM_NAME.assignees è uguale a ASSIGNEE.

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

Sostituisci quanto segue:

  • EXTERNAL_SYSTEM_NAME: il nome di un sistema SIEM/SOAR di terze parti, ad esempio demisto.
  • ASSIGNEE: un assegnatario nel sistema esterno.

Filtra in base al campo resource.folders.resource_folder

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array resource.folders.resource_folder è diverso da FOLDER_NAME.

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

Filtra in base al campo resource.folders.resource_folder_display_name

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array resource.folders.resource_folder_display_name è uguale a DISPLAY_NAME.

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

Sostituisci DISPLAY_NAME con il nome definito dall'utente della cartella associata ai risultati che stai cercando.

Il filtro include solo account di servizio specifici

L'esempio seguente restituisce i risultati solo quando il valore membro di ogni voce iam_bindings è uguale a uno degli account di servizio forniti.

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

Sostituisci SERVICE_ACCOUNT1, SERVICE_ACCOUNT2 e SERVICE_ACCOUNT3 con gli indirizzi email degli account di servizio.

Per scoprire come utilizzare le funzioni contains() e containsOnly() in un filtro dei risultati, consulta Filtro in base ai campi di tipo array.

Passaggi successivi

Scopri di più sulla configurazione delle notifiche sui risultati.