Collecter les journaux PowerShell
Ce document explique comment collecter des journaux PowerShell dans Google Security Operations à l'aide de Bindplane. L'analyseur transforme les journaux bruts Microsoft PowerShell en modèle de données unifié (UDM). Il commence par extraire des champs du message de journal brut, les normalise en champs UDM, puis enrichit les données avec un contexte supplémentaire en fonction d'ID d'événement spécifiques, créant ainsi un événement UDM structuré pour l'analyse de sécurité.
Avant de commencer
- Assurez-vous de disposer d'une instance Google SecOps.
- Assurez-vous d'utiliser Windows 2016 ou une version ultérieure.
- Si vous exécutez l'application derrière un proxy, assurez-vous que les ports du pare-feu sont ouverts.
Obtenir le fichier d'authentification d'ingestion Google SecOps
- Connectez-vous à la console Google SecOps.
- Accédez à Paramètres du SIEM > Agents de collecte.
- Téléchargez le fichier d'authentification d'ingestion. Enregistrez le fichier de manière sécurisée sur le système sur lequel Bindplane sera installé.
Obtenir le numéro client Google SecOps
- Connectez-vous à la console Google SecOps.
- Accédez à Paramètres du SIEM > Profil.
- Copiez et sauvegardez le numéro client dans la section Détails de l'organisation.
Installer l'agent Bindplane sous Windows
- Ouvrez l'invite de commande ou PowerShell en tant qu'administrateur.
Exécutez la commande suivante :
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Autres ressources d'installation
- Pour plus d'options d'installation, consultez ce guide d'installation.
Configurer l'agent Bindplane pour qu'il ingère les journaux Syslog et les envoie à Google SecOps
- Avant de configurer le fichier YAML, arrêtez le service
observIQ Distro for Open Telemetry Collector
dans le panneau "Services". Accédez au fichier de configuration:
- Recherchez le fichier
config.yaml
. En règle générale, il se trouve dans le répertoire/etc/bindplane-agent/
sous Linux ou dans le répertoire d'installation sous Windows. - Ouvrez le fichier à l'aide d'un éditeur de texte (
nano
,vi
ou Bloc-notes, par exemple).
- Recherchez le fichier
Modifiez le fichier
config.yaml
comme suit :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]
Remplacez
<customer_id>
par le numéro client réel.Remplacez
/path/to/ingestion-authentication-file.json
par le chemin d'accès où le fichier d'authentification a été enregistré dans la section Obtenir le fichier d'authentification d'ingestion Google SecOps.Après avoir enregistré le fichier
config.yaml
, démarrez le serviceobservIQ Distro for Open Telemetry Collector
.
Redémarrez l'agent Bindplane pour appliquer les modifications
Pour redémarrer l'agent Bindplane sous Windows, vous pouvez utiliser la console Services ou saisir la commande suivante:
net stop BindPlaneAgent && net start BindPlaneAgent
Tableau de mappage UDM
Champ de journal | Mappage UDM | Logique |
---|---|---|
AccountName | principal.user.userid | Mappé directement à partir du champ AccountName dans le journal brut. |
ActivityID | security_result.detection_fields[0].value | Mappé directement à partir du champ ActivityID dans le journal brut. Les accolades sont supprimées. |
Canal | Non mappé sur l'objet IDM. | |
collection_time.nanos | Non mappé sur l'objet IDM. | |
collection_time.seconds | Non mappé sur l'objet IDM. | |
Commande | Non mappé sur l'objet IDM. | |
CommandLine | Non mappé sur l'objet IDM. | |
Ordinateur | principal.hostname | Mappé directement à partir du champ Computer dans le journal brut, le cas échéant. |
ContextInfo | Non mappé sur l'objet IDM. | |
ContextInfo_Command Name | security_result.detection_fields[0].value | Mappé directement à partir du champ ContextInfo_Command Name dans le journal brut, le cas échéant. |
ContextInfo_Command Type | security_result.detection_fields[1].value | Mappé directement à partir du champ ContextInfo_Command Type dans le journal brut, le cas échéant. |
Application ContextInfo_Host | target.process.command_line | Mappé directement à partir du champ ContextInfo_Host Application dans le journal brut si powershell.Host Application n'est pas présent. |
ContextInfo_Host ID | target.asset.asset_id | Mappé directement à partir du champ ContextInfo_Host ID dans le journal brut si powershell.Host ID n'est pas présent. La valeur est précédée de Host ID: . |
ContextInfo_Host Name | target.hostname | Mappé directement à partir du champ ContextInfo_Host Name dans le journal brut si powershell.Host Name n'est pas présent. |
ContextInfo_Script Name | target.process.file.full_path | Mappé directement à partir du champ ContextInfo_Script Name dans le journal brut si script_name n'est pas présent. |
ContextInfo_Numéro de séquence | security_result.detection_fields[2].value | Mappé directement à partir du champ ContextInfo_Sequence Number dans le journal brut, le cas échéant. Converti en chaîne. |
ContextInfo_Severity | Non mappé sur l'objet IDM. | |
create_time.nanos | Non mappé sur l'objet IDM. | |
create_time.seconds | Non mappé sur l'objet IDM. | |
customer_id | Non mappé sur l'objet IDM. | |
données | Non mappé sur l'objet IDM. | |
Données | security_result.detection_fields[0].value | Mappé directement à partir du champ Data dans le journal brut, le cas échéant. |
Data_1 | security_result.detection_fields[1].value | Mappé directement à partir du champ Data_1 dans le journal brut, le cas échéant. |
Data_2 | security_result.detection_fields[2].value | Mappé directement à partir du champ Data_2 dans le journal brut, le cas échéant. |
Domaine | principal.administrative_domain | Mappé directement à partir du champ Domain dans le journal brut. |
entries | Non mappé sur l'objet IDM. | |
ERROR_EVT_UNRESOLVED | Non mappé sur l'objet IDM. | |
EventCategory | Non mappé sur l'objet IDM. | |
EventData | Non mappé sur l'objet IDM. | |
EventID | metadata.product_event_type, security_result.rule_name | Mappé directement à partir du champ EventID dans le journal brut. La valeur est précédée de EventID: pour le champ security_result.rule_name . |
EventLevel | Non mappé sur l'objet IDM. | |
EventLevelName | security_result.severity | Mappé en fonction de la valeur de EventLevelName :. Information est mappé sur INFORMATIONAL .: Verbose est mappé sur LOW . |
EventLog | Non mappé sur l'objet IDM. | |
EventReceivedTime | Non mappé sur l'objet IDM. | |
EventType | Non mappé sur l'objet IDM. | |
EventTime | metadata.event_timestamp | Permet d'extraire l'horodatage, le cas échéant. |
ExecutionProcessID | principal.process.pid | Mappé directement à partir du champ ExecutionProcessID dans le journal brut s'il est présent, non vide ou égal à 0. Converti en chaîne. |
ExecutionThreadID | security_result.detection_fields[2].value | Mappé directement à partir du champ ExecutionThreadID dans le journal brut s'il est présent, non vide ou égal à 0. Converti en chaîne. |
Fichier | target.process.file.full_path | Mappé directement à partir du champ File dans le journal brut, le cas échéant. |
Application hôte | Non mappé sur l'objet IDM. | |
HostApplication | Non mappé sur l'objet IDM. | |
Nom d'hôte | principal.hostname | Mappé directement à partir du champ Hostname dans le journal brut. |
id | Non mappé sur l'objet IDM. | |
Mots clés | Non mappé sur l'objet IDM. | |
log_type | metadata.log_type | Mappé directement à partir du champ log_type dans le journal brut. |
Machine | principal.asset.asset_id, principal.asset.platform_software.platform_version | Le champ Machine est analysé pour extraire l'ID de la machine et les informations sur la plate-forme. L'ID de la machine est précédé de Machine ID: . La plate-forme est mappée sur l'énumération UDM en fonction de la valeur: - win est mappé sur WINDOWS .: mac est mappé sur MAC .: lin est mappé sur LINUX .: les autres valeurs sont mappées sur UNKNOWN_PLATFORM . |
ManagementGroupName | additional.fields[0].value.string_value | Mappé directement à partir du champ ManagementGroupName dans le journal brut, le cas échéant. |
Message.EventTime | metadata.event_timestamp | Permet d'extraire l'horodatage, le cas échéant. Converti en chaîne. |
Message.Message | security_result.description | Mappage direct à partir du champ Message.Message dans le journal brut si EventID est dans [403 , 4103 , 4104 ] et message_message_not_found . Les retours à la ligne et les tabulations sont remplacés par des virgules. |
Message | security_result.description | Mappé directement à partir du champ Message dans le journal brut, le cas échéant. |
MessageNumber | Non mappé sur l'objet IDM. | |
MessageSourceAddress | principal.ip | Mappé directement à partir du champ MessageSourceAddress dans le journal brut, le cas échéant. |
MessageTotal | Non mappé sur l'objet IDM. | |
MG | Non mappé sur l'objet IDM. | |
Code opération | metadata.description | Mappé directement à partir du champ Opcode dans le journal brut. |
OpcodeValue | Non mappé sur l'objet IDM. | |
Sortie | security_result.detection_fields[0].value | Mappé directement à partir du champ Output dans le journal brut, le cas échéant. |
powershell.Nom de la commande | security_result.detection_fields[0].value | Mappé directement à partir du champ powershell.Command Name , le cas échéant. |
powershell.Command Type | security_result.detection_fields[1].value | Mappé directement à partir du champ powershell.Command Type , le cas échéant. |
Application powershell.Host | target.process.command_line | Mappé directement à partir du champ powershell.Host Application dans le journal brut, le cas échéant. |
powershell.Host ID | target.asset.asset_id | Mappé directement à partir du champ powershell.Host ID dans le journal brut, le cas échéant. La valeur est précédée de Host ID: . |
powershell.Host Name | target.hostname | Mappé directement à partir du champ powershell.Host Name dans le journal brut, le cas échéant. |
powershell.HostApplication | target.process.command_line | Mappé directement à partir du champ powershell.HostApplication dans le journal brut, le cas échéant. |
powershell.HostId | target.asset.asset_id | Mappé directement à partir du champ powershell.HostId dans le journal brut, le cas échéant. La valeur est précédée de Host ID: . |
powershell.HostName | target.hostname | Mappé directement à partir du champ powershell.HostName dans le journal brut, le cas échéant. |
powershell.Nom du script | target.process.file.full_path | Mappé directement à partir du champ powershell.Script Name dans le journal brut, le cas échéant. |
powershell.ScriptName | target.process.file.full_path | Mappé directement à partir du champ powershell.ScriptName dans le journal brut, le cas échéant. |
powershell.Numéro de séquence | security_result.detection_fields[2].value | Mappé directement à partir du champ powershell.Sequence Number dans le journal brut, le cas échéant. |
powershell.SequenceNumber | security_result.detection_fields[0].value | Mappé directement à partir du champ powershell.SequenceNumber dans le journal brut, le cas échéant. |
powershell.UserId | principal.user.userid | Mappé directement à partir du champ powershell.UserId dans le journal brut, le cas échéant. |
ID du processus | principal.process.pid | Mappé directement à partir du champ Process ID dans le journal brut si ExecutionProcessID et ProcessID ne sont pas présents, vides ou 0. Converti en chaîne. |
ProcessID | principal.process.pid | Mappé directement à partir du champ ProcessID dans le journal brut si ExecutionProcessID n'est pas présent, vide ou égal à 0. Converti en chaîne. |
ProviderGuid | metadata.product_deployment_id | Mappé directement à partir du champ ProviderGuid dans le journal brut. Les accolades sont supprimées. |
PSEdition | Non mappé sur l'objet IDM. | |
PSRemotingProtocolVersion | Non mappé sur l'objet IDM. | |
PSVersion | Non mappé sur l'objet IDM. | |
RecordNumber | metadata.product_log_id | Mappé directement à partir du champ RecordNumber dans le journal brut. Converti en chaîne. |
RenderedDescription | security_result.description | Mappé directement à partir du champ RenderedDescription dans le journal brut, le cas échéant. |
Utilisateur RunAs | Non mappé sur l'objet IDM. | |
ScriptBlockId | Non mappé sur l'objet IDM. | |
ScriptBlockText | security_result.detection_fields[0].value | Mappé directement à partir du champ ScriptBlockText dans le journal brut, le cas échéant. |
ID de ScriptBlock | Non mappé sur l'objet IDM. | |
Gravité | security_result.severity, security_result.severity_details | Mappé en fonction de la valeur de Severity :- verbose ou info est mappé sur LOW .: warn ou err correspond à MEDIUM .: crit est mappé sur HIGH .La valeur brute est également mappée sur security_result.severity_details . |
source.collector_id | Non mappé sur l'objet IDM. | |
source.customer_id | Non mappé sur l'objet IDM. | |
Source | additional.fields[1].value.string_value | Mappé directement à partir du champ Source dans le journal brut, le cas échéant. |
SourceModuleName | principal.resource.name | Mappé directement à partir du champ SourceModuleName dans le journal brut. |
SourceModuleType | principal.resource.resource_subtype | Mappé directement à partir du champ SourceModuleType dans le journal brut. |
SourceName | metadata.product_name | Mappé directement à partir du champ SourceName dans le journal brut. |
start_time.nanos | Non mappé sur l'objet IDM. | |
start_time.seconds | Non mappé sur l'objet IDM. | |
TenantId | additional.fields[2].value.string_value | Mappé directement à partir du champ TenantId dans le journal brut, le cas échéant. |
ThreadID | Non mappé sur l'objet IDM. | |
timestamp.nanos | Non mappé sur l'objet IDM. | |
timestamp.seconds | Non mappé sur l'objet IDM. | |
type | Non mappé sur l'objet IDM. | |
UserID | principal.user.windows_sid | Mappé directement à partir du champ UserID dans le journal brut. |
Nom d'utilisateur | principal.user.userid | Mappé directement à partir du champ Username dans le journal brut si AccountName n'est pas présent. |
metadata.vendor_name | Variable définie sur Microsoft . |
|
metadata.event_type | Définissez-la sur PROCESS_LAUNCH si EventID est 4104 et que _Path est présent dans Message , ou si EventID est 4103 , ou si EventID est dans [800 , 600 , 400 ] et que powershell.ScriptName et powershell.HostApplication sont présents. Définissez cette valeur sur PROCESS_TERMINATION si EventID est 403 et que _HostApplication est présent dans Message , ou si EventID est 403 et que NewEngineState est Stopped . Définissez la valeur sur STATUS_UPDATE si EventID est 4104 et que _Path n'est pas présent dans Message , ou si EventID est 4103 et que no_value , script_name est vide, script_name_not_found et host_application_not_found sont tous définis sur "true", ou si EventID est 53504 , ou si EventID est 40962 , ou si EventID est 40961 , ou si EventID est vide et que MessageSourceAddress est présent. Définissez cette valeur sur USER_UNCATEGORIZED si EventID est vide et que Username est présent. Défini sur GENERIC_EVENT si EventID est vide et que MessageSourceAddress et Username ne sont pas présents. |
|
metadata.product_name | Défini sur Powershell si SourceName n'est pas présent. |
|
security_result.action | Variable définie sur ALLOW . |
|
security_result.detection_fields[0].key | Variable définie sur Activity ID . |
|
security_result.detection_fields[1].key | Variable définie sur Sequence Number . |
|
security_result.detection_fields[2].key | Variable définie sur ExecutionThreadID . |
|
additional.fields[0].key | Variable définie sur Management Group Name . |
|
additional.fields[1].key | Variable définie sur Source . |
|
additional.fields[2].key | Variable définie sur TenantId . |
|
principal.asset.platform_software.platform | Défini sur WINDOWS si platform_software contient win , MAC si elle contient mac , LINUX si elle contient lin et UNKNOWN_PLATFORM dans le cas contraire. |
|
target.process.file.full_path | Définissez sur _Path si EventID est 4104 et que _Path est présent dans Message . Définissez sur file_path si EventID est 4104 et que file_path est présent dans Message . Définissez sur _HostApplication si EventID est 403 et que _HostApplication est présent dans Message . |
Modifications
2025-01-29
Amélioration :
- Modification de la mise en correspondance de
ScriptBlockText
desecurity_result.detection_fields
àtarget.process.command_line
.
2025-01-28
Amélioration :
- Ajout de
gsub
pour prendre en charge le nouveau format de journaux JSON.
2025-01-09
Amélioration :
- Mappage de
Payload
sursecurity_result.detection_fields
. - Mappage de
Script Name
surtarget.file.full_path
.
2024-11-28
Amélioration :
- Ajout de la compatibilité avec un nouveau format de journaux SYSLOG.
2024-08-20
Amélioration :
- Ajout de
gsub
pour supprimer les caractères supplémentaires afin d'analyser les journaux JSON.
2024-08-14
Amélioration :
- Mappage de
Version
surmetadata.product_version
. - Mappage de
SystemTime
surmetadata.event_timestamp
. channel
,keywords
,MessageNumber
,MessageTotal
etScriptBlockId
ont été mappés sursecurity_result.detection_fields
.- Mappage de
Path
surtarget.process.file.full_path
.
2024-07-24
Amélioration :
- Prise en charge d'un nouveau format de journaux JSON.
2024-07-20
Amélioration :
- Mappage de
HostApplication
surprincipal.application
. - Mappage de
HostId
surprincipal.resource.product_object_id
. - Mappage de
System.Computer
surprincipal.hostname
etprincipal.asset.hostname
. - Mappage de
System.Version
surmetadata.product_version
. - Mappage de
System.ProcessID
surprincipal.process.pid
. - Mappage de
System.ProviderName
surprincipal.resource.attribute.labels
. HostVersion
,RunspaceId
,PipelineId
,EngineVersion
,DetailSequence
,DetailTotal
,SequenceNumber
etScriptName
ont été mappés suradditional.fields
.System.EventRecordID
,System.Task
,System.Keywords
,System.Opcode
etSystem.ThreadID
ont été mappés sursecurity.detection_fields
.
2023-12-05
Amélioration :
- Ajout d'un mappage pour les journaux JSON non analysés.
- Mappage de
Computer
surprincipal.hostname
. - Mappage de
EventLevelName
sursecurity_result.severity
. ManagementGroupName
,Source
etTenantId
ont été mappés suradditional_fields
.- Mappage de
RenderedDescription
sursecurity_result.description
. - Mappage de
UserName
surprincipal.user.userid
.
2023-09-14
Amélioration :
- Ajout de mappages pour les journaux JSON non analysés.
- Mappage de "winlog.activity_id" sur "security_result.detection_fields".
- Mappage de "winlog.api" sur "additional.fields".
- Mise en correspondance de "winlog.channel" et "winlog.process.thread.id" avec "security_result.about.resource.attribute.labels".
- Mappage de "winlog.computer_name" sur "principal.hostname".
- Mappage de "winlog.event_id" sur "metadata.product_event_type" et "security_result.rule_name".
- Mappage de "winlog.opcode" sur "metadata.description".
- Mappage de "winlog.process.pid" sur "principal.process.pid".
- Mise en correspondance de "winlog.provider_guid" avec "metadata.product_deployment_id".
- Mise en correspondance de "winlog.provider_name" avec "metadata.product_name".
- Mappage de "winlog.record_id" sur "metadata.product_log_id".
- Mappage de "winlog.user.domain" sur "principal.administrative_domain".
- Mappage de "winlog.user.identifier" sur "principal.user.windows_sid".
- Mappage de "winlog.user.name" sur "principal.user.userid".
2023-07-05
Amélioration :
- Pour "EventID = 403", mappé "metadata.event_type" sur "STATUS_UPDATE" lorsque la valeur de "HostApplication" n'est pas présente.
- Extraction de la valeur de "target.file.full_path" à partir du journal à l'aide d'un format Grok lorsque "Chemin" est vide.
- Ajout de la fonction gsub pour renommer "@timestamp" en "EventTime".
2022-11-09
Amélioration :
- Le champ "ProviderGuid" est mappé sur "metadata.product_deployment_id".
- Le champ "ExecutionProcessID" est mappé sur "principal.process.pid".
- Le champ "ProcessID" ou "ID de processus" est mappé sur "principal.process.pid".
- Le champ "SourceModuleType" est mappé sur "principal.resource.resource_subtype".
- Le champ "SourceModuleName" est mappé sur "principal.resource.name".
- Le champ "Machine" est mappé sur "principal.asset.asset_id".
- Le champ "MessageSourceAddress" est mappé à "principal.ip".
- Le champ "File" est mappé sur "target.process.file.full_path".
- Le champ "Application hôte" ou "Commande" est mappé sur "target.process.command_line".
- Le champ "Output" est mappé à "security_result.detection_fields".
- Le champ "Message" est mappé à "security_result.description".
- Le champ "ActivityID" est mappé à "security_result.detection_fields".
- Ajout du mappage suivant lorsque l'ID d'événement est "4103"
- Le champ "ID hôte" ou "ContextInfo_ID hôte" est mappé sur "target.asset.asset_id".
- Le champ "Host Name" (Nom d'hôte) ou "ContextInfo_Host Name" (Nom d'hôte ContextInfo) est mappé sur "target.hostname".
- Le champ "ContextInfo_Script Name" est mappé sur "target.process.file.full_path".
- Le champ "ContextInfo_Host Application" est mappé sur "target.process.command_line".
- Le champ "ContextInfo_Command Name" est mappé sur "security_result.detection_fields".
- Le champ "ContextInfo_Command Type" est mappé sur "security_result.detection_fields".
- Le champ "ContextInfo_Sequence Number" ou "Sequence Number" est mappé sur "security_result.detection_fields".
- Ajout de la mise en correspondance suivante lorsque l'ID d'événement est "800", "600" ou "400"
- Le champ "UserId" est mappé sur "principal.user.userid".
- Le champ "HostApplication" est mappé sur "target.process.command_line".
- Le champ "HostId" est mappé sur "target.asset.asset_id".
- Le champ "HostName" est mappé sur "target.hostname".
- Le champ "ScriptName" est mappé sur "target.process.file.full_path".
- Le champ "SequenceNumber" est mappé à "security_result.detection_fields".
2022-10-13
Correction de bug:
- Les journaux d'échec ont été analysés en apportant les modifications suivantes.
- Ajout de vérifications
on_error
sur les champs dont l'analyse a échoué en cas d'absence de valeurs. Champs tels que "opcode", "Host Application". - Ajout d'une nouvelle source, "ContextInfo", pour l'analyse KV lorsque "Message" n'est pas présent dans les journaux.
- Amélioration:
- Modification de la valeur de event_type de
GENERIC_EVENT
enSTATUS_UPDATE
.
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.