Coletar registros de segurança do ServiceNow
Este documento explica como enviar eventos de segurança do ServiceNow para o Google Security Operations usando um feed de webhook. O analisador de segurança do ServiceNow foi projetado para eventos de segurança do ServiceNow Instance Security Center, como falhas de login, logins do SNC, logins de administrador, representação e elevação de segurança. Consulte Eventos de segurança do ServiceNow Instance Security Center. Uma integração do ServiceNow envia cada evento como JSON para um endpoint de webhook do Google SecOps, em que o analisador normaliza o evento para o modelo de dados unificado (UDM).
O analisador reconhece cinco valores de evento: Failed Login, Admin Login, SNC Login, Impersonation e Security Elevation. Cada valor corresponde a um evento registrado do ServiceNow na fila sysevent. Este documento cria um feed de webhook, um Script Include que POSTa no feed e quatro ações de script que são acionadas nos registros sysevent correspondentes e chamam o Script Include.
Após essa configuração única, o ServiceNow encaminha automaticamente cada novo ocorrência de segurança para o Google SecOps. Nenhuma outra ação do administrador é necessária.
Antes de começar
Verifique se você atende os seguintes pré-requisitos:
- Uma instância do Google SecOps.
- Uma instância do ServiceNow com uma conta de usuário que tenha a função
adminou direitos para Definição do sistema > Inclusões de script, Propriedades do sistema e Política do sistema > Eventos > Ações de script e Registro. - Uma ativação do ServiceNow Instance Security Center. O ISC está em fim de venda e não pode ser ativado em novas instâncias.
- Acesso privilegiado ao console do Google Google Cloud (para criação de chaves de API).
Criar um feed de webhook no Google SecOps
As seções a seguir descrevem como criar um feed de webhook no Google SecOps.
Criar o feed
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Na próxima página, clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
ServiceNow Security Events). - Selecione Webhook como o Tipo de origem.
- Selecione Segurança do ServiceNow como o Tipo de registro.
- Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
- Delimitador de divisão: insira
\nquando a integração enviar mais de um evento JSON por solicitação. Deixe em branco se cada solicitação contiver um único evento. - Namespace do recurso: o namespace do recurso.
- Rótulos de ingestão: o rótulo aplicado aos eventos deste feed.
- Delimitador de divisão: insira
Clique em Próxima.
Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Gerar e salvar a chave secreta
- Na página de detalhes do feed, clique em Gerar chave secreta.
Copie e salve a chave secreta em um local seguro.
Receber o URL do endpoint do feed
- Acesse a guia Detalhes do feed.
Na seção Informações do endpoint, copie o URL do endpoint do feed. O formato do URL é:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateou, para um endpoint regional:
https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateSalve esse URL para uma etapa posterior.
Clique em Concluído.
Criar uma chave de API do Google Cloud
- Acesse a página Credenciais do console do Google Google Cloud .
- Selecione o projeto associado à sua instância do Google SecOps.
- Clique em Criar credenciais > Chave de API.
- Clique em Editar chave de API para restringir a chave.
- No campo Nome, insira um nome descritivo, por exemplo,
ServiceNow Webhook API Key. Em Restrições de API:
- Selecione Restringir chave.
- Na lista Selecionar APIs, escolha API Google SecOps.
Clique em Salvar.
Copie a chave de API e salve-a em um local seguro.
Armazenar credenciais do Google SecOps no ServiceNow
Armazene o URL do endpoint e as credenciais como propriedades do sistema ServiceNow para que o código de integração não contenha secrets.
- No ServiceNow, acesse Propriedades do sistema > sys_properties.list.
Clique em Novo e forneça os seguintes detalhes de configuração:
- Nome:
x_chronicle.endpoint_url - Valor: cole o URL do endpoint do feed.
- Tipo:
string
- Nome:
Clique em Enviar.
Clique em Novo e forneça os seguintes detalhes de configuração:
- Nome:
x_chronicle.api_key - Valor: cole a chave de API Google Cloud .
- Tipo:
password2
- Nome:
Clique em Enviar.
Clique em Novo e forneça os seguintes detalhes de configuração:
- Nome:
x_chronicle.secret_key - Valor: cole a chave secreta do feed do Google SecOps.
- Tipo:
password2
- Nome:
Clique em Enviar.
Criar o Script Include de utilitário de webhook
Essa inclusão de script envia um payload JSON para o endpoint de webhook do Google SecOps usando a API sn_ws.RESTMessageV2 do ServiceNow. A chave de API e a chave secreta são enviadas como cabeçalhos HTTP.
- Acesse Definição do sistema > Inclusões de script.
- Clique em Novo.
Informe os seguintes detalhes de configuração:
- Nome:
ChronicleWebhookUtil - Nome da API:
ChronicleWebhookUtil - Chamável pelo cliente: desmarcado
- Ativo: marcado
- Nome:
No campo Script, insira o seguinte código:
var ChronicleWebhookUtil = Class.create(); ChronicleWebhookUtil.prototype = { initialize: function() { this.endpointURL = gs.getProperty('x_chronicle.endpoint_url'); this.apiKey = gs.getProperty('x_chronicle.api_key'); this.secretKey = gs.getProperty('x_chronicle.secret_key'); }, // payload: a plain object whose keys match the required JSON contract. sendEvent: function(payload) { try { if (!this.endpointURL || !this.apiKey || !this.secretKey) { gs.error('[Chronicle] Missing configuration. Check System Properties: x_chronicle.*'); return false; } var request = new sn_ws.RESTMessageV2(); request.setEndpoint(this.endpointURL); request.setHttpMethod('POST'); request.setRequestHeader('Content-Type', 'application/json'); request.setRequestHeader('X-goog-api-key', this.apiKey); request.setRequestHeader('X-Webhook-Access-Key', this.secretKey); request.setRequestBody(JSON.stringify(payload)); var response = request.execute(); var statusCode = response.getStatusCode(); if (statusCode == 200 || statusCode == 201 || statusCode == 204) { gs.info('[Chronicle] Event sent: ' + payload.event + ' | Status: ' + statusCode); return true; } gs.error('[Chronicle] Failed to send event: ' + payload.event + ' | Status: ' + statusCode + ' | Response: ' + response.getBody()); return false; } catch (ex) { gs.error('[Chronicle] Exception sending event: ' + ex.message); return false; } }, type: 'ChronicleWebhookUtil' };Clique em Enviar.
Verificar o registro de eventos
Uma ação de script só é disparada quando o nome do evento existe no Registro de eventos (tabela sysevent_register). O ServiceNow envia os cinco eventos usados por essa integração prontos para uso, mas vale a pena confirmar porque uma entrada ausente não produz um erro, e a ação de script nunca é executada.
- No ServiceNow, acesse Política do sistema > Eventos > Registro (
sysevent_register.list). Filtre a coluna Nome do evento para cada uma das seguintes entradas e confirme se há um registro:
loginlogin.failedimpersonation.startsecurity.elevated_role.enabled
Se uma entrada estiver faltando, clique em Novo, defina o campo Nome do evento como o valor ausente, defina Tabela como
Global [global]e clique em Enviar.
Criar as ações de script
Cada ação de script se inscreve em um nome de evento do ServiceNow. Quando o ServiceNow insere um registro correspondente na fila sysevent, a ação de script é executada, lê os parâmetros do evento e chama ChronicleWebhookUtil para POSTar o payload.
O analisador faz o mapeamento para os seguintes eventos do ServiceNow:
Valor event do analisador |
Nome do evento do ServiceNow | Gatilho |
|---|---|---|
Failed Login |
login.failed |
Falha na tentativa de login (qualquer método de autenticação). |
Admin Login |
login |
Login bem-sucedido de um usuário com a função admin. |
SNC Login |
login |
Login bem-sucedido de um usuário com a função snc_external. |
Impersonation |
impersonation.start |
Um administrador começa a representar outro usuário. |
Security Elevation |
security.elevated_role.enabled |
Um usuário passa a ter a função security_admin ou outra função com privilégios altos. |
login e login.failed definem parm1 como o nome de usuário e parm2 como o IP de origem. Os outros eventos seguem a mesma convenção parm1/parm2, mas o conteúdo exato depende da sua versão do ServiceNow. Abra a entrada de registro de cada evento e confirme se a descrição Parâmetros corresponde ao script descrito mais adiante. Ajuste as referências parm1 ou parm2 se o registro for diferente.
Criar a ação de script de falha no login
- Acesse Política do sistema > Eventos > Ações de script.
- Clique em Novo.
Informe os seguintes detalhes de configuração:
- Nome:
Chronicle - Failed Login - Nome do evento:
login.failed - Ativo: marcado
- Nome:
No campo Script, insira o seguinte código:
(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event) { new ChronicleWebhookUtil().sendEvent({ event: 'Failed Login', event_created: event.sys_created_on.getValue(), user: event.parm1.toString(), ip_address: event.parm2.toString() }); })(current, event);Clique em Enviar.
Criar a ação de script de login
Essa ação de script é acionada a cada login bem-sucedido e encaminha o registro somente quando o usuário conectado tem a função admin ou snc_external. O campo event é definido de acordo.
- Acesse Política do sistema > Eventos > Ações de script.
- Clique em Novo.
Informe os seguintes detalhes de configuração:
- Nome:
Chronicle - Login - Nome do evento:
login - Ativo: marcado
- Nome:
No campo Script, insira o seguinte código:
(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event) { var userName = event.parm1.toString(); var ipAddress = event.parm2.toString(); var user = new GlideRecord('sys_user'); if (!user.get('user_name', userName)) { return; } function hasRole(roleName) { var role = new GlideRecord('sys_user_has_role'); role.addQuery('user', user.sys_id); role.addQuery('role.name', roleName); role.query(); return role.next(); } var eventValue; if (hasRole('snc_external')) { eventValue = 'SNC Login'; } else if (hasRole('admin')) { eventValue = 'Admin Login'; } else { return; } new ChronicleWebhookUtil().sendEvent({ event: eventValue, event_created: event.sys_created_on.getValue(), user: userName, ip_address: ipAddress }); })(current, event);Clique em Enviar.
Criar a ação de script de representação
- Acesse Política do sistema > Eventos > Ações de script.
- Clique em Novo.
Informe os seguintes detalhes de configuração:
- Nome:
Chronicle - Impersonation - Nome do evento:
impersonation.start - Ativo: marcado
- Nome:
No campo Script, insira o seguinte código:
(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event) { new ChronicleWebhookUtil().sendEvent({ event: 'Impersonation', event_created: event.sys_created_on.getValue(), user: event.parm1.toString(), // impersonator snc_user: event.parm2.toString() // impersonated user }); })(current, event);Clique em Enviar.
Criar a ação de script de elevação de segurança
- Acesse Política do sistema > Eventos > Ações de script.
- Clique em Novo.
Informe os seguintes detalhes de configuração:
- Nome:
Chronicle - Security Elevation - Nome do evento:
security.elevated_role.enabled - Ativo: marcado
- Nome:
No campo Script, insira o seguinte código:
(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event) { new ChronicleWebhookUtil().sendEvent({ event: 'Security Elevation', event_created: event.sys_created_on.getValue(), user: event.parm1.toString() }); })(current, event);Clique em Enviar.
Verificar a integração
Use uma das seguintes abordagens.
Verificar com um evento sintético
Para testar cada ação de script imediatamente sem esperar um ocorrência de segurança real, faça o seguinte para enfileirar o evento de um script em segundo plano:
- No ServiceNow, acesse System Definition > Scripts - Background.
No campo Executar script, insira uma das seguintes linhas e clique em Executar script:
gs.eventQueue('login.failed', null, 'test.user', '203.0.113.45'); gs.eventQueue('login', null, 'admin', '203.0.113.45'); gs.eventQueue('impersonation.start', null, 'admin', 'test.user'); gs.eventQueue('security.elevated_role.enabled', null, 'admin', 'security_admin');Aguarde até um minuto para que o job do Gerenciador de eventos processe a fila.
Verificar com um evento real
Gere um dos seguintes eventos de segurança mapeados no ServiceNow para verificar a integração:
- Falha no login: abra
/login.doem uma janela de navegação anônima e envie uma senha inválida. - Login de administrador: faça login com um usuário que tenha a função
adminem um endereço IP diferente do seu habitual. - Representação: em uma conta de administrador, represente outro usuário.
- Elevação de segurança: eleve para a função
security_adminum usuário que tenha a funçãoadmin.
Confirmar encaminhamento
- No ServiceNow, acesse Política do sistema > Eventos > Registro de eventos (
sysevent.list) e confirme se um registro com o nome do evento correspondente aparece. - No ServiceNow, acesse Registros do sistema > Registro do sistema > Todos e confirme se uma mensagem de informações
[Chronicle] Event sent: ...aparece com o status 200, 201 ou 204. Uma mensagem[Chronicle] Failed to send eventou[Chronicle] Exception sending eventindica um problema de credencial ou conectividade. - No Google SecOps, execute uma pesquisa UDM para
metadata.vendor_name = "SERVICENOW"emetadata.product_name = "SERVICENOW_SECURITY". - Confirme se o evento aparece com
metadata.event_typedefinido comoUSER_LOGINouUSER_CHANGE_PERMISSIONSe seprincipal.user.useridestá preenchido.
Referência de métodos de autenticação
Os feeds de webhook do Google SecOps aceitam a chave de API e a chave secreta como cabeçalhos HTTP ou parâmetros de consulta de URL. Este guia usa o método de cabeçalhos porque o sn_ws.RESTMessageV2 aceita cabeçalhos personalizados, o que mantém as credenciais fora dos URLs e dos registros de acesso ao servidor.
Cabeçalhos usados neste guia:
X-goog-api-key: a chave de API Google Cloud para a API Google SecOps.X-Webhook-Access-Key: a chave secreta do feed gerada pelo Google SecOps.
Se uma integração não puder enviar cabeçalhos personalizados, adicione as credenciais ao URL do endpoint:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>
Limites e práticas recomendadas de webhook
| Limite | Valor |
|---|---|
| Tamanho máximo da solicitação | 4 MB |
| QPS máximo (consultas por segundo) | 15.000 |
| Tempo limite da solicitação | 30 segundos |
| Comportamento de repetição | Automático com espera exponencial |
Para controlar o volume, envie apenas os eventos de segurança necessários para suas detecções e agrupe vários eventos por solicitação com o delimitador de divisão \n quando a fonte produzir eventos em rajadas.
Para mais informações sobre feeds do Google SecOps, consulte a documentação sobre feeds do Google SecOps. Para informações sobre os requisitos de cada tipo de feed, consulte Configuração de feed por tipo.
Se você tiver problemas ao criar feeds, entre em contato com o suporte do Google SecOps.
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento de UDM | Lógica |
|---|---|---|
event |
extensions.auth.type |
Mapeado: "Failed Login", "SNC Login", "Admin Login", "Impersonation" → MACHINE |
event_created |
metadata.event_timestamp |
Analisado como yyyy-MM-dd HH:mm:ss |
event_type |
metadata.event_type |
Renomeado/mapeado |
event |
metadata.product_event_type |
Mapeado quando event != `` |
ip_address |
principal.ip |
Mesclado |
user |
principal.user.userid |
Mapeado quando user != `` |
created_by |
target.user.userid |
Mapeado quando created_by != `` |
snc_user |
target.user.userid |
Mapeado quando snc_user != `` |
timestamp |
event1.idm.read_only_udm.metadata.event_timestamp |
Mapeado do registro de mudanças |
data.sys_id |
event1.idm.read_only_udm.metadata.product_log_id |
Mapeado do registro de mudanças |
data.message_data |
event1.idm.read_only_udm.metadata.description |
Mapeado do registro de mudanças |
data.source |
event1.idm.read_only_udm.principal.resource.name |
Mapeado do registro de mudanças |
source |
event1.idm.read_only_udm.additional.fields |
Mapeado do registro de mudanças |
data.sys_created_on |
event1.idm.read_only_udm.metadata.collected_timestamp |
Mapeado do registro de mudanças |
data.sys_created_by |
event1.idm.read_only_udm.principal.user.userid |
Mapeado do registro de mudanças |
data.user |
event1.idm.read_only_udm.principal.user.userid |
Mapeado do registro de mudanças |
source_instance |
event1.idm.read_only_udm.principal.namespace |
Mapeado do registro de mudanças |
data.role |
event1.idm.read_only_udm.target.resource.attribute.roles |
Mapeado do registro de mudanças |
data.granted_by |
event1.idm.read_only_udm.target.user.userid |
Mapeado do registro de mudanças |
data.level |
event1.idm.read_only_udm.security_result.severity |
Mapeado do registro de mudanças |
data.state |
event1.idm.read_only_udm.security_result.action_details |
Mapeado do registro de mudanças |
Registro de alterações
Ver o registro de alterações deste analisador
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.