Coletar registros do framework de verificação de arquivos

Versão do analisador:3.0

Compatível com:

Este documento explica como ingerir registros do File Scanning Framework no Google Security Operations usando o Google Cloud Storage V2.

O File Scanning Framework (FSF) é uma solução de verificação de arquivos recursiva, modular e de código aberto desenvolvida pela Emerson Electric Co. O FSF usa uma arquitetura cliente-servidor para analisar arquivos e gerar resultados detalhados de verificação em JSON, incluindo metadados de arquivos, correspondências de assinatura YARA, subobjetos extraídos e metadados específicos do módulo.

Antes de começar

Verifique se você atende aos seguintes pré-requisitos:

  • Uma instância do Google SecOps
  • Um projeto do GCP com a API Storage do Cloud ativada
  • Permissões para criar e gerenciar intervalos do GCS
  • Permissões para gerenciar políticas do IAM em buckets do GCS
  • Uma instância de servidor FSF implantada com acesso de gravação ao diretório de registros
  • Acesso root ou sudo ao host do servidor FSF

Criar um bucket do Google Cloud Storage

  1. Acesse o Console do Google Cloud.
  2. Selecione ou crie um projeto.
  3. No menu de navegação, acesse Cloud Storage > Buckets.
  4. Clique em Criar bucket.
  5. Informe os seguintes detalhes de configuração:

    Configuração Valor
    Nomeie seu bucket Insira um nome globalmente exclusivo (por exemplo, fsf-logs-secops).
    Tipo de local Escolha de acordo com suas necessidades (região, birregional, multirregional).
    Local Selecione o local (por exemplo, us-central1).
    Classe de armazenamento Padrão (recomendado para registros acessados com frequência).
    Controle de acesso Uniforme (recomendado).
    Ferramentas de proteção Opcional: ative o controle de versões de objetos ou a política de retenção.
  6. Clique em Criar.

Configurar o diretório de saída de registros do FSF

O FSF grava os resultados da verificação JSON em um diretório de registros configurável. Configure um diretório dedicado para a ingestão do Google SecOps.

  1. Conecte-se ao host do servidor FSF via SSH.
  2. Abra o arquivo de configuração do servidor FSF:

    sudo nano /opt/fsf/fsf-server/conf/config.py
    
  3. Localize o dicionário SCANNER_CONFIG.

  4. Atualize o parâmetro LOG_PATH para um diretório dedicado:

    SCANNER_CONFIG = {
        'LOG_PATH': '/var/log/fsf',
        'YARA_PATH': '/opt/fsf/fsf-server/yara/rules.yara',
        'PID_PATH': '/tmp/scanner.pid',
        'EXPORT_PATH': '/tmp',
        'TIMEOUT': 60,
        'MAX_DEPTH': 10
    }
    
  5. Salve e feche o arquivo.

  6. Crie o diretório de registros com as permissões adequadas:

    sudo mkdir -p /var/log/fsf
    sudo chown -R fsf:fsf /var/log/fsf
    sudo chmod 755 /var/log/fsf
    
  7. Reinicie o servidor FSF para aplicar as mudanças:

    sudo systemctl restart fsf
    
  8. Verifique se o FSF está gravando registros no novo diretório:

    ls -lh /var/log/fsf/
    

Instalar e configurar o Fluentd

O Fluentd vai rastrear os arquivos de registro do FSF e enviá-los para o Google Cloud Storage.

Instalar o Fluentd

  1. No host do servidor FSF, instale o Fluentd (td-agent):

    curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-jammy-td-agent4.sh | sh
    
  2. Instale o plug-in de saída do GCS:

    sudo td-agent-gem install fluent-plugin-gcs
    
  3. Verifique a instalação do plug-in:

    td-agent-gem list | grep fluent-plugin-gcs
    

Criar uma conta de serviço do GCP para o Fluentd

  1. No console do GCP, acesse IAM e administrador > Contas de serviço.
  2. Clique em Criar conta de serviço.
  3. Informe os seguintes detalhes de configuração:
    • Nome da conta de serviço: insira fsf-fluentd-shipper.
    • Descrição da conta de serviço: insira Service account for Fluentd to ship FSF logs to GCS.
  4. Clique em Criar e continuar.
  5. Na seção Conceder a essa conta de serviço acesso ao projeto:
    1. Clique em Selecionar papel.
    2. Pesquise e selecione Administrador de objetos do Storage.
  6. Clique em Continuar.
  7. Clique em Concluído.

Criar chave da conta de serviço

  1. Na lista Contas de serviço, clique na conta de serviço (fsf-fluentd-shipper).
  2. Acesse a guia Chaves.
  3. Clique em Adicionar chave > Criar nova chave.
  4. Selecione JSON como o tipo de chave.
  5. Clique em Criar.
  6. O arquivo de chave JSON será baixado no seu computador.
  7. Transfira o arquivo de chave para o host do servidor FSF:

    scp /path/to/downloaded-key.json user@fsf-server:/etc/td-agent/gcp-key.json
    
  8. Defina as permissões adequadas no arquivo de chave:

    sudo chown td-agent:td-agent /etc/td-agent/gcp-key.json
    sudo chmod 600 /etc/td-agent/gcp-key.json
    

Conceder permissões do IAM no bucket do GCS

  1. Acesse Cloud Storage > Buckets.
  2. Clique no nome do bucket (fsf-logs-secops).
  3. Acesse a guia Permissões.
  4. Clique em Conceder acesso.
  5. Informe os seguintes detalhes de configuração:
    • Adicionar principais: insira o e-mail da conta de serviço (por exemplo, fsf-fluentd-shipper@PROJECT_ID.iam.gserviceaccount.com).
    • Atribuir papéis: selecione Administrador de objetos do Storage.
  6. Clique em Salvar.

Configurar o Fluentd

  1. No host do servidor FSF, crie um arquivo de configuração do Fluentd:

    sudo nano /etc/td-agent/td-agent.conf
    
  2. Adicione a seguinte configuração:

    # Tail FSF JSON logs
    <source>
        @type tail
        path /var/log/fsf/*.log
        pos_file /var/log/td-agent/fsf.log.pos
        tag fsf.scan
        read_from_head true
        <parse>
            @type json
            time_key timestamp
            time_format %Y-%m-%dT%H:%M:%S.%L%z
        </parse>
    </source>
    
    # Ship to Google Cloud Storage
    <match fsf.scan>
        @type gcs
        project YOUR_GCP_PROJECT_ID
        keyfile /etc/td-agent/gcp-key.json
        bucket fsf-logs-secops
        object_key_format %{path}%{time_slice}_%{index}.%{file_extension}
        path fsf-logs/
        <buffer tag,time>
            @type file
            path /var/log/td-agent/buffer/gcs
            timekey 3600
            timekey_wait 10m
            timekey_use_utc true
            chunk_limit_size 10MB
        </buffer>
        <format>
            @type json
        </format>
        store_as json
        auto_create_bucket false
    </match>
    
  3. Substitua YOUR_GCP_PROJECT_ID pelo ID do projeto do GCP.

  4. Salve e feche o arquivo.

  5. Crie o diretório de buffer:

    sudo mkdir -p /var/log/td-agent/buffer/gcs
    sudo chown -R td-agent:td-agent /var/log/td-agent/buffer
    
  6. Reinicie o Fluentd para aplicar a configuração:

    sudo systemctl restart td-agent
    
  7. Ative o Fluentd para iniciar na inicialização:

    sudo systemctl enable td-agent
    
  8. Verifique se o Fluentd está em execução:

    sudo systemctl status td-agent
    

Verificar o envio de registros

  1. Verifique se há erros nos registros do Fluentd:

    sudo tail -f /var/log/td-agent/td-agent.log
    
  2. Acione uma verificação de FSF de teste para gerar registros:

    echo "test content" > /tmp/test.txt
    /opt/fsf/fsf-client/fsf_client.py /tmp/test.txt --suppress-report
    
  3. Aguarde de 1 a 2 minutos para que o Fluentd processe e envie os registros.

  4. No console do GCP, acesse Cloud Storage > Buckets.

  5. Clique no nome do bucket (fsf-logs-secops).

  6. Navegue até o prefixo fsf-logs/.

  7. Verifique se os arquivos JSON estão sendo criados com carimbos de data/hora.

  8. Faça o download e inspecione um arquivo para confirmar se ele contém resultados da verificação do FSF no formato JSON.

Recuperar a conta de serviço do Google SecOps

O Google SecOps usa uma conta de serviço exclusiva para ler dados do seu bucket do GCS. Você precisa conceder a essa conta de serviço acesso ao seu bucket.

Receber o e-mail da conta de serviço

  1. Acesse Configurações do SIEM > Feeds.
  2. Clique em Adicionar novo feed.
  3. Clique em Configurar um único feed.
  4. No campo Nome do feed, insira um nome para o feed (por exemplo, FSF File Scanning Logs).
  5. Selecione Google Cloud Storage V2 como o Tipo de origem.
  6. Selecione Estrutura de verificação de arquivos como o Tipo de registro.
  7. Clique em Receber conta de serviço. Um e-mail exclusivo da conta de serviço será exibido, por exemplo:

    secops-12345678@secops-gcp-prod.iam.gserviceaccount.com
    
  8. Copie o endereço de e-mail para usar na próxima etapa.

  9. Clique em Próxima.

  10. Especifique valores para os seguintes parâmetros de entrada:

    • URL do bucket de armazenamento: insira o URI do bucket do GCS com o caminho do prefixo:

      gs://fsf-logs-secops/fsf-logs/
      
    • Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:

      • Nunca: nunca exclui arquivos após as transferências (recomendado para testes).
      • Excluir arquivos transferidos: exclui os arquivos após a transferência.
      • Excluir arquivos transferidos e diretórios vazios: exclui arquivos e diretórios vazios após a transferência.

    • Idade máxima do arquivo: inclua arquivos modificados no último número de dias (o padrão é 180 dias).

    • Namespace do recurso: o namespace do recurso.

    • Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed.

  11. Clique em Próxima.

  12. Revise a nova configuração do feed na tela Finalizar e clique em Enviar.

Conceder permissões do IAM à conta de serviço do Google SecOps

A conta de serviço do Google SecOps precisa do papel Leitor de objetos do Storage no seu bucket do GCS.

  1. Acesse Cloud Storage > Buckets.
  2. Clique no nome do bucket (fsf-logs-secops).
  3. Acesse a guia Permissões.
  4. Clique em Conceder acesso.
  5. Informe os seguintes detalhes de configuração:
    • Adicionar participantes: cole o e-mail da conta de serviço do Google SecOps.
    • Atribuir papéis: selecione Leitor de objetos do Storage.
  6. Clique em Salvar.

Verificar a ingestão

  1. Aguarde de 10 a 15 minutos para que a ingestão inicial seja concluída.
  2. No Google SecOps, acesse Configurações do SIEM > Feeds.
  3. Localize o feed (FSF File Scanning Logs).
  4. Verifique se o Status aparece como Ativo.
  5. Clique no nome do feed para conferir as métricas de ingestão.
  6. Verifique se a contagem de Eventos ingeridos está aumentando.
  7. Acesse Pesquisar no Google SecOps.
  8. Execute uma consulta de pesquisa para verificar se os registros do FSF estão sendo ingeridos:

    metadata.log_type = "FILE_SCANNING_FRAMEWORK"
    
  9. Verifique se os resultados da verificação do FSF aparecem nos resultados da pesquisa.

Solução de problemas

Nenhum registro aparece no GCS

  • Verifique se o FSF está gravando registros em /var/log/fsf/:

    ls -lh /var/log/fsf/
    tail -f /var/log/fsf/*.log
    
  • Verifique se há erros nos registros do Fluentd:

    sudo tail -f /var/log/td-agent/td-agent.log
    
  • Verifique se a chave da conta de serviço do GCP é válida e tem as permissões corretas.

  • Confira se o nome do bucket na configuração do Fluentd corresponde ao nome real do bucket.

Erros de permissão do Fluentd

  • Verifique se a conta de serviço (fsf-fluentd-shipper) tem o papel Administrador de objetos do Storage no bucket.
  • Verifique se o caminho da chave na configuração do Fluentd está correto.
  • Verifique se o arquivo de chave tem a propriedade e as permissões corretas:

    ls -l /etc/td-agent/gcp-key.json
    

O Google SecOps não está ingerindo registros

  • Verifique se a conta de serviço do Google SecOps tem o papel Leitor de objetos do Storage no bucket.
  • Verifique se o URI do bucket na configuração do feed está correto e inclui a barra à direita.
  • Verifique se os arquivos existem no bucket do GCS no caminho de prefixo especificado.
  • Verifique o status do feed em Configurações do SIEM > Feeds para encontrar mensagens de erro.

Registros do FSF não estão no formato esperado

  • Verifique se o FSF está configurado para gravar a saída JSON (comportamento padrão).
  • Verifique se a seção <parse> do Fluentd está configurada com @type json.
  • Inspecione um arquivo de registro manualmente para verificar se ele contém JSON válido:

    head -n 1 /var/log/fsf/*.log | jq .
    

Tabela de mapeamento de UDM

Campo de registro Mapeamento de UDM Lógica
CompressType_label, compressed_parents about.labels Mesclado de CompressType_label (chave "Tipo de compactação", valor de Object.EXTRACT_ZIP.Object_0.Compress Type se a mensagem contiver "Tipo de compactação") e compressed_parents (chave "Arquivos principais compactados", concatenados de Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.additional_info.compressed_parents)
Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_SWF.META_BASIC_INFO.MD5, Object.EXTRACT_GZIP.META_BASIC_INFO.MD5, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5 intermediary.file.md5 Valor de Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5 se EXTRACT_EMBEDDED estiver presente. Caso contrário, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5 se EXTRACT_ZIP estiver presente. Caso contrário, Object.EXTRACT_SWF.META_BASIC_INFO.MD5 se EXTRACT_SWF estiver presente. Caso contrário, Object.EXTRACT_GZIP.META_BASIC_INFO.MD5 se EXTRACT_GZIP estiver presente. Caso contrário, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5.
Object.EXTRACT_EMBEDDED.Object_0.Description intermediary.file.mime_type Valor copiado diretamente
Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_SWF.META_BASIC_INFO.SHA1, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1 intermediary.file.sha1 Valor de Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1 se EXTRACT_EMBEDDED estiver presente. Caso contrário, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1 se EXTRACT_ZIP estiver presente. Caso contrário, Object.EXTRACT_SWF.META_BASIC_INFO.SHA1 se EXTRACT_SWF estiver presente. Caso contrário, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1 se EXTRACT_GZIP estiver presente. Caso contrário, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1.
Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_SWF.META_BASIC_INFO.SHA256, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256 intermediary.file.sha256 Valor de Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256 se EXTRACT_EMBEDDED estiver presente. Caso contrário, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256 se EXTRACT_ZIP estiver presente. Caso contrário, Object.EXTRACT_SWF.META_BASIC_INFO.SHA256 se EXTRACT_SWF estiver presente. Caso contrário, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256 se EXTRACT_GZIP estiver presente. Caso contrário, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256.
Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_SWF.META_BASIC_INFO.Size, Object.EXTRACT_GZIP.META_BASIC_INFO.Size, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size intermediary.file.size Valor de Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size se EXTRACT_EMBEDDED estiver presente, caso contrário, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size se EXTRACT_ZIP estiver presente, caso contrário, Object.EXTRACT_SWF.META_BASIC_INFO.Size se EXTRACT_SWF estiver presente, caso contrário, Object.EXTRACT_GZIP.META_BASIC_INFO.Size se EXTRACT_GZIP estiver presente, caso contrário, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size; sem o " .*" final e convertido para uinteger
Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.scan_id intermediary.resource.id Valor copiado diretamente
Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.permalink intermediary.url Valor copiado diretamente
Object.META_EMERSON_INFO.results intermediary.user.email_addresses Mesclado de "matched_email" na matriz de resultados
Summary.Observations metadata.description Concatenado de matriz com separador ", ", vírgula inicial removida
Tempo de verificação metadata.event_timestamp Convertido usando o filtro de data com o formato aaaa-MM-dd HH:mm:ss
Origem metadata.event_type Definido como "SCAN_FILE" se a origem não estiver vazia. Caso contrário, "GENERIC_EVENT".
Object.META_VT_CACHE._id metadata.product_log_id Valor copiado diretamente
result.ad_data.message network.http.response_code Extraído como um número inteiro usando o padrão grok INT de result.ad_data.message
Origem principal.hostname Valor copiado diretamente
Object.META_EMERSON_INFO.result_summary, Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg security_result.summary Definido como Object.META_EMERSON_INFO.result_summary, se presente. Caso contrário, Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg
Filename target.file.full_path Valor copiado diretamente
Object.META_BASIC_INFO.MD5 target.file.md5 Valor copiado diretamente
Summary.Yara target.file.mime_type Extraído do primeiro índice de Summary.Yara, convertido para maiúsculas e "FT_" removido se Yara estiver presente. Caso contrário, definido como "ZIP" se EXTRACT_ZIP estiver presente, "SWF" se EXTRACT_SWF estiver presente, "GZIP" se EXTRACT_GZIP estiver presente e "CAB" se EXTRACT_CAB estiver presente.
Object.META_BASIC_INFO.SHA1, Object.META_VT_CACHE.SHA1 target.file.sha1 Valor de Object.META_BASIC_INFO.SHA1 se não estiver vazio. Caso contrário, Object.META_VT_CACHE.SHA1.
Object.META_BASIC_INFO.SHA256 target.file.sha256 Valor copiado diretamente
Object.META_BASIC_INFO.Size target.file.size Removido o " .*" final e convertido para uinteger
metadata.vendor_name Definido como "EMERSON"
metadata.product_name Defina como "FILE SCANNING FRAMEWORK"

Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.