Recopila registros de PowerShell
En este documento, se explica cómo recopilar registros de PowerShell en Google Security Operations con Bindplane. El analizador transforma los registros sin procesar de Microsoft PowerShell en un modelo de datos unificado (UDM). Primero, extrae campos del mensaje de registro sin procesar, los normaliza en campos de la UDM y, luego, enriquece los datos con contexto adicional basado en IDs de eventos específicos, y, en última instancia, crea un evento de la UDM estructurado para el análisis de seguridad.
Antes de comenzar
- Asegúrate de tener una instancia de Google SecOps.
- Asegúrate de tener Windows 2016 o una versión posterior.
- Si se ejecuta detrás de un proxy, asegúrate de que los puertos del firewall estén abiertos.
Obtén el archivo de autenticación de transferencia de Google SecOps
- Accede a la consola de Google SecOps.
- Ve a Configuración de SIEM > Agentes de recopilación.
- Descarga el archivo de autenticación de transferencia. Guarda el archivo de forma segura en el sistema en el que se instalará Bindplane.
Obtén el ID de cliente de Google SecOps
- Accede a la consola de Google SecOps.
- Ve a Configuración de SIEM > Perfil.
- Copia y guarda el ID de cliente de la sección Detalles de la organización.
Instala el agente de Bindplane en Windows
- Abre el símbolo del sistema o PowerShell como administrador.
Ejecuta el siguiente comando:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Recursos de instalación adicionales
- Para obtener más opciones de instalación, consulta esta guía de instalación.
Configura el agente de Bindplane para transferir Syslog y enviarlo a Google SecOps
- Antes de configurar el archivo YAML, detén el servicio
observIQ Distro for Open Telemetry Collector
en el panel de servicios. Accede al archivo de configuración:
- Ubica el archivo
config.yaml
. Por lo general, se encuentra en el directorio/etc/bindplane-agent/
en Linux o en el directorio de instalación en Windows. - Abre el archivo con un editor de texto (por ejemplo,
nano
,vi
o Bloc de notas).
- Ubica el archivo
Edita el archivo
config.yaml
de la siguiente manera:receivers: windowseventlog/powershell: channel: Microsoft-Windows-PowerShell/Operational max_reads: 100 poll_interval: 5s raw: true start_at: end processors: batch: exporters: chronicle/powershell: endpoint: malachiteingestion-pa.googleapis.com # Adjust the path to the credentials file you downloaded in Step 1 creds: '/path/to/ingestion-authentication-file.json' log_type: 'POWERSHELL' override_log_type: false raw_log_field: body customer_id: '<customer_id>' service: pipelines: logs/winpowershell: receivers: - windowseventlog/powershell processors: [batch] exporters: [chronicle/powershell]
Reemplaza
<customer_id>
por el ID de cliente real.Actualiza
/path/to/ingestion-authentication-file.json
a la ruta de acceso en la que se guardó el archivo de autenticación en la sección Obtén el archivo de autenticación de transferencia de Google SecOps.Después de guardar el archivo
config.yaml
, inicia el servicioobservIQ Distro for Open Telemetry Collector
.
Reinicia el agente de Bindplane para aplicar los cambios.
Para reiniciar el agente de Bindplane en Windows, puedes usar la consola Services o ingresar el siguiente comando:
net stop BindPlaneAgent && net start BindPlaneAgent
Tabla de asignación de UDM
Campo de registro | Asignación de UDM | Lógica |
---|---|---|
AccountName | principal.user.userid | Se asigna directamente desde el campo AccountName en el registro sin formato. |
ActivityID | security_result.detection_fields[0].value | Se asigna directamente desde el campo ActivityID en el registro sin formato. Se quitan las llaves. |
Canal | No está asignado al objeto IDM. | |
collection_time.nanos | No está asignado al objeto IDM. | |
collection_time.seconds | No está asignado al objeto IDM. | |
Comando | No está asignado al objeto IDM. | |
CommandLine | No está asignado al objeto IDM. | |
Computadora | principal.hostname | Se asigna directamente desde el campo Computer en el registro sin procesar, si está presente. |
ContextInfo | No está asignado al objeto IDM. | |
ContextInfo_Command Name | security_result.detection_fields[0].value | Se asigna directamente desde el campo ContextInfo_Command Name en el registro sin procesar, si está presente. |
ContextInfo_Command Type | security_result.detection_fields[1].value | Se asigna directamente desde el campo ContextInfo_Command Type en el registro sin procesar, si está presente. |
Aplicación ContextInfo_Host | target.process.command_line | Se asigna directamente desde el campo ContextInfo_Host Application en el registro sin procesar si no está presente powershell.Host Application . |
ID de ContextInfo_Host | target.asset.asset_id | Se asigna directamente desde el campo ContextInfo_Host ID en el registro sin procesar si no está presente powershell.Host ID . El valor tiene el prefijo Host ID: . |
ContextInfo_Host Name | target.hostname | Se asigna directamente desde el campo ContextInfo_Host Name en el registro sin procesar si no está presente powershell.Host Name . |
ContextInfo_Script Name | target.process.file.full_path | Se asigna directamente desde el campo ContextInfo_Script Name en el registro sin procesar si no está presente script_name . |
ContextInfo_Sequence Number | security_result.detection_fields[2].value | Se asigna directamente desde el campo ContextInfo_Sequence Number en el registro sin procesar, si está presente. Se convirtió en una cadena. |
ContextInfo_Severity | No está asignado al objeto IDM. | |
create_time.nanos | No está asignado al objeto IDM. | |
create_time.seconds | No está asignado al objeto IDM. | |
customer_id | No está asignado al objeto IDM. | |
datos | No está asignado al objeto IDM. | |
Datos | security_result.detection_fields[0].value | Se asigna directamente desde el campo Data en el registro sin procesar, si está presente. |
Data_1 | security_result.detection_fields[1].value | Se asigna directamente desde el campo Data_1 en el registro sin procesar, si está presente. |
Datos_2 | security_result.detection_fields[2].value | Se asigna directamente desde el campo Data_2 en el registro sin procesar, si está presente. |
Dominio | principal.administrative_domain | Se asigna directamente desde el campo Domain en el registro sin formato. |
entradas | No está asignado al objeto IDM. | |
ERROR_EVT_UNRESOLVED | No está asignado al objeto IDM. | |
EventCategory | No está asignado al objeto IDM. | |
EventData | No está asignado al objeto IDM. | |
EventID | metadata.product_event_type, security_result.rule_name | Se asigna directamente desde el campo EventID en el registro sin formato. El valor tiene el prefijo EventID: para el campo security_result.rule_name . |
EventLevel | No está asignado al objeto IDM. | |
EventLevelName | security_result.severity | Se asigna según el valor de EventLevelName :: Information se asigna a INFORMATIONAL .: Verbose se asigna a LOW . |
EventLog | No está asignado al objeto IDM. | |
EventReceivedTime | No está asignado al objeto IDM. | |
EventType | No está asignado al objeto IDM. | |
EventTime | metadata.event_timestamp | Se usa para extraer la marca de tiempo, si está presente. |
ExecutionProcessID | principal.process.pid | Se asigna directamente desde el campo ExecutionProcessID en el registro sin procesar si está presente y no está vacío o es 0. Se convirtió en una cadena. |
ExecutionThreadID | security_result.detection_fields[2].value | Se asigna directamente desde el campo ExecutionThreadID en el registro sin procesar si está presente y no está vacío o es 0. Se convirtió en una cadena. |
Archivo | target.process.file.full_path | Se asigna directamente desde el campo File en el registro sin procesar, si está presente. |
Aplicación de host | No está asignado al objeto IDM. | |
HostApplication | No está asignado al objeto IDM. | |
Nombre de host | principal.hostname | Se asigna directamente desde el campo Hostname en el registro sin formato. |
id | No está asignado al objeto IDM. | |
Palabras clave | No está asignado al objeto IDM. | |
log_type | metadata.log_type | Se asigna directamente desde el campo log_type en el registro sin formato. |
Máquina | principal.asset.asset_id, principal.asset.platform_software.platform_version | El campo Machine se analiza para extraer el ID de la máquina y la información de la plataforma. El ID de la máquina tiene el prefijo Machine ID: . La plataforma se asigna a la enumeración de UDM según el valor: - win se asigna a WINDOWS .: mac se asigna a MAC .: lin se asigna a LINUX .: Otros valores se asignan a UNKNOWN_PLATFORM . |
ManagementGroupName | additional.fields[0].value.string_value | Se asigna directamente desde el campo ManagementGroupName en el registro sin procesar, si está presente. |
Message.EventTime | metadata.event_timestamp | Se usa para extraer la marca de tiempo, si está presente. Se convirtió en una cadena. |
Message.Message | security_result.description | Se asigna directamente desde el campo Message.Message en el registro sin procesar si EventID está en [403 , 4103 , 4104 ] y message_message_not_found . Los saltos de línea y las tabulaciones se reemplazan por comas. |
Mensaje | security_result.description | Se asigna directamente desde el campo Message en el registro sin procesar, si está presente. |
MessageNumber | No está asignado al objeto IDM. | |
MessageSourceAddress | principal.ip | Se asigna directamente desde el campo MessageSourceAddress en el registro sin procesar, si está presente. |
MessageTotal | No está asignado al objeto IDM. | |
MG | No está asignado al objeto IDM. | |
Código de operación | metadata.description | Se asigna directamente desde el campo Opcode en el registro sin formato. |
OpcodeValue | No está asignado al objeto IDM. | |
Salida | security_result.detection_fields[0].value | Se asigna directamente desde el campo Output en el registro sin procesar, si está presente. |
powershell.Command Name | security_result.detection_fields[0].value | Se asigna directamente desde el campo powershell.Command Name , si está presente. |
Tipo powershell.Command | security_result.detection_fields[1].value | Se asigna directamente desde el campo powershell.Command Type , si está presente. |
Aplicación powershell.Host | target.process.command_line | Se asigna directamente desde el campo powershell.Host Application en el registro sin procesar, si está presente. |
powershell.Host ID | target.asset.asset_id | Se asigna directamente desde el campo powershell.Host ID en el registro sin procesar, si está presente. El valor tiene el prefijo Host ID: . |
powershell.Host Name | target.hostname | Se asigna directamente desde el campo powershell.Host Name en el registro sin procesar, si está presente. |
powershell.HostApplication | target.process.command_line | Se asigna directamente desde el campo powershell.HostApplication en el registro sin procesar, si está presente. |
powershell.HostId | target.asset.asset_id | Se asigna directamente desde el campo powershell.HostId en el registro sin procesar, si está presente. El valor tiene el prefijo Host ID: . |
powershell.HostName | target.hostname | Se asigna directamente desde el campo powershell.HostName en el registro sin procesar, si está presente. |
powershell.Script Name | target.process.file.full_path | Se asigna directamente desde el campo powershell.Script Name en el registro sin procesar, si está presente. |
powershell.ScriptName | target.process.file.full_path | Se asigna directamente desde el campo powershell.ScriptName en el registro sin procesar, si está presente. |
powershell.Número de secuencia | security_result.detection_fields[2].value | Se asigna directamente desde el campo powershell.Sequence Number en el registro sin procesar, si está presente. |
powershell.SequenceNumber | security_result.detection_fields[0].value | Se asigna directamente desde el campo powershell.SequenceNumber en el registro sin procesar, si está presente. |
powershell.UserId | principal.user.userid | Se asigna directamente desde el campo powershell.UserId en el registro sin procesar, si está presente. |
ID de proceso | principal.process.pid | Se asignan directamente desde el campo Process ID en el registro sin procesar si ExecutionProcessID y ProcessID no están presentes, están vacíos o son 0. Se convirtió en una cadena. |
ProcessID | principal.process.pid | Se asigna directamente desde el campo ProcessID en el registro sin procesar si ExecutionProcessID no está presente, está vacío o es 0. Se convirtió en una cadena. |
ProviderGuid | metadata.product_deployment_id | Se asigna directamente desde el campo ProviderGuid en el registro sin formato. Se quitan las llaves. |
PSEdition | No está asignado al objeto IDM. | |
PSRemotingProtocolVersion | No está asignado al objeto IDM. | |
PSVersion | No está asignado al objeto IDM. | |
RecordNumber | metadata.product_log_id | Se asigna directamente desde el campo RecordNumber en el registro sin formato. Se convirtió en una cadena. |
RenderedDescription | security_result.description | Se asigna directamente desde el campo RenderedDescription en el registro sin procesar, si está presente. |
Usuario RunAs | No está asignado al objeto IDM. | |
ScriptBlockId | No está asignado al objeto IDM. | |
ScriptBlockText | security_result.detection_fields[0].value | Se asigna directamente desde el campo ScriptBlockText en el registro sin procesar, si está presente. |
ID de ScriptBlock | No está asignado al objeto IDM. | |
Gravedad | security_result.severity, security_result.severity_details | Se asignan según el valor de Severity :- verbose o info se asigna a LOW .: warn o err se asigna a MEDIUM .: crit se asigna a HIGH .El valor sin procesar también se asigna a security_result.severity_details . |
source.collector_id | No está asignado al objeto IDM. | |
source.customer_id | No está asignado al objeto IDM. | |
Fuente | additional.fields[1].value.string_value | Se asigna directamente desde el campo Source en el registro sin procesar, si está presente. |
SourceModuleName | principal.resource.name | Se asigna directamente desde el campo SourceModuleName en el registro sin formato. |
SourceModuleType | principal.resource.resource_subtype | Se asigna directamente desde el campo SourceModuleType en el registro sin formato. |
SourceName | metadata.product_name | Se asigna directamente desde el campo SourceName en el registro sin formato. |
start_time.nanos | No está asignado al objeto IDM. | |
start_time.seconds | No está asignado al objeto IDM. | |
TenantId | additional.fields[2].value.string_value | Se asigna directamente desde el campo TenantId en el registro sin procesar, si está presente. |
ThreadID | No está asignado al objeto IDM. | |
timestamp.nanos | No está asignado al objeto IDM. | |
timestamp.seconds | No está asignado al objeto IDM. | |
tipo | No está asignado al objeto IDM. | |
UserID | principal.user.windows_sid | Se asigna directamente desde el campo UserID en el registro sin formato. |
Nombre de usuario | principal.user.userid | Se asigna directamente desde el campo Username en el registro sin procesar si no está presente AccountName . |
metadata.vendor_name | Se define en Microsoft . |
|
metadata.event_type | Se establece en PROCESS_LAUNCH si EventID es 4104 y _Path está presente en Message , o si EventID es 4103 , o si EventID está en [800 , 600 , 400 ] y powershell.ScriptName y powershell.HostApplication están presentes. Se establece en PROCESS_TERMINATION si EventID es 403 y _HostApplication está presente en Message , o si EventID es 403 y NewEngineState es Stopped . Se establece en STATUS_UPDATE si EventID es 4104 y _Path no está presente en Message , o si EventID es 4103 y no_value , script_name está vacío, script_name_not_found y host_application_not_found son verdaderos, o si EventID es 53504 , o si EventID es 40962 , o si EventID es 40961 , o si EventID está vacío y MessageSourceAddress está presente. Se establece en USER_UNCATEGORIZED si EventID está vacío y Username está presente. Se establece en GENERIC_EVENT si EventID está vacío y MessageSourceAddress y Username no están presentes. |
|
metadata.product_name | Se establece en Powershell si SourceName no está presente. |
|
security_result.action | Se define en ALLOW . |
|
security_result.detection_fields[0].key | Se define en Activity ID . |
|
security_result.detection_fields[1].key | Se define en Sequence Number . |
|
security_result.detection_fields[2].key | Se define en ExecutionThreadID . |
|
additional.fields[0].key | Se define en Management Group Name . |
|
additional.fields[1].key | Se define en Source . |
|
additional.fields[2].key | Se define en TenantId . |
|
principal.asset.platform_software.platform | Se establece en WINDOWS si platform_software contiene win , MAC si contiene mac , LINUX si contiene lin y UNKNOWN_PLATFORM de lo contrario. |
|
target.process.file.full_path | Se establece en _Path si EventID es 4104 y _Path está presente en Message . Se establece en file_path si EventID es 4104 y file_path está presente en Message . Se establece en _HostApplication si EventID es 403 y _HostApplication está presente en Message . |
Cambios
2025-01-29
Mejora:
- Se cambió la asignación de
ScriptBlockText
desecurity_result.detection_fields
atarget.process.command_line
.
2025-01-28
Mejora:
- Se agregó
gsub
para admitir el nuevo formato de registros JSON.
2025-01-09
Mejora:
- Se asignó
Payload
asecurity_result.detection_fields
. - Se asignó
Script Name
atarget.file.full_path
.
2024-11-28
Mejora:
- Se agregó compatibilidad con el nuevo patrón de registros SYSLOG.
2024-08-20
Mejora:
- Se agregó
gsub
para quitar caracteres adicionales y analizar registros JSON.
2024-08-14
Mejora:
- Se asignó
Version
ametadata.product_version
. - Se asignó
SystemTime
ametadata.event_timestamp
. - Se asignaron
channel
,keywords
,MessageNumber
,MessageTotal
yScriptBlockId
asecurity_result.detection_fields
. - Se asignó
Path
atarget.process.file.full_path
.
2024-07-24
Mejora:
- Se agregó compatibilidad con un nuevo patrón de registros JSON.
2024-07-20
Mejora:
- Se asignó
HostApplication
aprincipal.application
. - Se asignó
HostId
aprincipal.resource.product_object_id
. - Se asignó
System.Computer
aprincipal.hostname
yprincipal.asset.hostname
. - Se asignó
System.Version
ametadata.product_version
. - Se asignó
System.ProcessID
aprincipal.process.pid
. - Se asignó
System.ProviderName
aprincipal.resource.attribute.labels
. - Se asignaron
HostVersion
,RunspaceId
,PipelineId
,EngineVersion
,DetailSequence
,DetailTotal
,SequenceNumber
yScriptName
aadditional.fields
. - Se asignaron
System.EventRecordID
,System.Task
,System.Keywords
,System.Opcode
ySystem.ThreadID
asecurity.detection_fields
.
2023-12-05
Mejora:
- Se agregó la asignación para los registros JSON sin analizar.
- Se asignó
Computer
aprincipal.hostname
. - Se asignó
EventLevelName
asecurity_result.severity
. - Se asignaron
ManagementGroupName
,Source
yTenantId
aadditional_fields
. - Se asignó
RenderedDescription
asecurity_result.description
. - Se asignó
UserName
aprincipal.user.userid
.
2023-09-14
Mejora:
- Se agregaron asignaciones para registros JSON sin analizar.
- Se asignó "winlog.activity_id" a "security_result.detection_fields".
- Se asignó "winlog.api" a "additional.fields".
- Se asignaron "winlog.channel" y "winlog.process.thread.id" a "security_result.about.resource.attribute.labels".
- Se asignó "winlog.computer_name" a "principal.hostname".
- Se asignó "winlog.event_id" a "metadata.product_event_type" y "security_result.rule_name".
- Se asignó "winlog.opcode" a "metadata.description".
- Se asignó "winlog.process.pid" a "principal.process.pid".
- Se asignó "winlog.provider_guid" a "metadata.product_deployment_id".
- Se asignó "winlog.provider_name" a "metadata.product_name".
- Se asignó "winlog.record_id" a "metadata.product_log_id".
- Se asignó "winlog.user.domain" a "principal.administrative_domain".
- Se asignó "winlog.user.identifier" a "principal.user.windows_sid".
- Se asignó "winlog.user.name" a "principal.user.userid".
2023-07-05
Mejora:
- Para "EventID = 403", se asignó "metadata.event_type" a "STATUS_UPDATE" cuando no está presente el valor de "HostApplication".
- Se extrajo el valor de "target.file.full_path" del registro con un patrón Grok cuando "Path" está vacío.
- Se agregó la función gsub para cambiar el nombre de "@timestamp" a "EventTime".
2022-11-09
Mejora:
- El campo "ProviderGuid" se asigna a "metadata.product_deployment_id".
- El campo "ExecutionProcessID" se asigna a "principal.process.pid".
- El campo "ProcessID" o "ID de proceso" se asigna a "principal.process.pid".
- El campo "SourceModuleType" se asigna a "principal.resource.resource_subtype".
- El campo "SourceModuleName" se asigna a "principal.resource.name".
- El campo "Machine" se asigna a "principal.asset.asset_id".
- El campo "MessageSourceAddress" se asigna a "principal.ip".
- El campo "Archivo" se asigna a "target.process.file.full_path".
- El campo "Host Application" o "Command" se asigna a "target.process.command_line".
- El campo "Resultado" se asigna a "security_result.detection_fields".
- El campo "Mensaje" se asigna a "security_result.description".
- El campo "ActivityID" se asigna a "security_result.detection_fields".
- Se agregó la siguiente asignación cuando EventID es "4103".
- El campo "ID de host" o "ContextInfo_Host ID" se asigna a "target.asset.asset_id".
- El campo "Nombre de host" o "ContextInfo_Host Name" se asigna a "target.hostname".
- El campo "ContextInfo_Script Name" se asigna a "target.process.file.full_path".
- El campo "ContextInfo_Host Application" se asigna a "target.process.command_line".
- El campo "ContextInfo_Command Name" se asigna a "security_result.detection_fields".
- El campo "ContextInfo_Command Type" se asigna a "security_result.detection_fields".
- El campo "ContextInfo_Sequence Number" o "Sequence Number" se asigna a "security_result.detection_fields".
- Se agregó la siguiente asignación cuando EventID es "800", "600" o "400".
- El campo "UserId" se asigna a "principal.user.userid".
- El campo "HostApplication" se asigna a "target.process.command_line".
- El campo "HostId" se asigna a "target.asset.asset_id".
- El campo "HostName" se asigna a "target.hostname".
- El campo "ScriptName" se asigna a "target.process.file.full_path".
- El campo "SequenceNumber" se asigna a "security_result.detection_fields".
2022-10-13
Corrección de errores:
- Se analizaron los registros con errores realizando los siguientes cambios.
- Se agregaron verificaciones
on_error
en los campos que no se pudieron analizar en caso de que no haya valores. Campos como "opcode", "Host Application". - Se agregó una nueva fuente, "ContextInfo", para el análisis de KV cuando "Message" no está presente en los registros.
- Mejora:
- Se modificó event_type de
GENERIC_EVENT
aSTATUS_UPDATE
.
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.