Inspeccionar una VM para detectar indicios de manipulación de la memoria del kernel

En esta página se describen las tareas que puedes llevar a cabo para confirmar la validez de una detección de rootkit en modo kernel de Virtual Machine Threat Detection. Los resultados de rootkits en modo kernel indican que el malware puede haber manipulado la memoria del kernel de una VM.

Cuando recibas una detección de rootkit en modo kernel de Detección de amenazas de VMs, te recomendamos que ejecutes estos comandos de Linux en la instancia de Compute Engine afectada para analizar tu sistema en busca de puntos de datos que puedan indicar anomalías, como llamadas al sistema pirateadas o módulos del kernel ocultos.

También puedes ejecutar la secuencia de comandos de recogida de datos proporcionada en la VM afectada. La secuencia de comandos ejecuta los comandos que se describen en esta página.

A menos que se indique lo contrario, cada tarea de inspección de esta página es relevante para todos los resultados de rootkits en modo kernel.

En este documento, se da por sentado lo siguiente:

  • Estás realizando las tareas de este documento después de recibir una detección de rootkit en modo kernel de Detección de amenazas de VM. Para ver una lista de las categorías de detecciones pertinentes, consulta Detecciones de amenazas de rootkit en modo kernel.

  • Conocimientos sobre las herramientas de línea de comandos de Linux y el kernel de Linux.

Acerca de Virtual Machine Threat Detection

Virtual Machine Threat Detection es un servicio integrado de Security Command Center. Este servicio analiza las máquinas virtuales para detectar aplicaciones potencialmente maliciosas, como software de minería de criptomonedas, rootkits en modo kernel y malware que se ejecutan en entornos de nube vulnerados.

VM Threat Detection forma parte de la suite de detección de amenazas de Security Command Center y se ha diseñado para complementar las funciones de Event Threat Detection y Container Threat Detection.

Para obtener información sobre Virtual Machine Threat Detection, consulta el resumen de Virtual Machine Threat Detection. Para saber cómo ver los detalles de una detección de amenazas de una VM, consulta el artículo Revisar las detecciones en la consolaGoogle Cloud .

Antes de empezar

Para obtener los permisos que necesitas para ver todos los recursos y resultados de Security Command Center y gestionar la instancia de Compute Engine afectada, pide a tu administrador que te conceda los siguientes roles de gestión de identidades y accesos:

Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

También puedes conseguir los permisos necesarios a través de roles personalizados u otros roles predefinidos.

Identifica la VM afectada

  1. Consulta los detalles de la detección.
  2. En la sección Recurso afectado, en el campo Nombre completo del recurso, haga clic en el enlace. La vista de detalles de la instancia de Compute Engine afectada se abre en una pestaña nueva.
  3. Conéctate a la instancia. Para obtener más información, consulta el artículo Conectarse a VMs Linux de la documentación de Compute Engine.

Buscar módulos de kernel inesperados

La presencia de módulos inesperados en una máquina virtual puede indicar que la memoria del kernel de la máquina virtual está en peligro.

Para encontrar módulos del kernel inesperados, sigue estos pasos:

  1. Lista todos los módulos del kernel cargados en la VM:

    lsmod
    cat /proc/modules
    
  2. Lista las entradas sysfs de los módulos cargados y descargados:

    ls -l /sys/module/
    
  3. Compara los resultados de estas listas con las de otras VMs del proyecto. Busca módulos que aparezcan en la VM afectada, pero no en las demás.

Buscar syslog módulos fuera del árbol

Los signos que indican que se ha cargado un módulo fuera del árbol en una VM pueden indicar que se han cargado módulos del kernel atípicos. Puedes buscar en el búfer de registro del kernel y en los mensajes de syslog para determinar si se ha cargado un módulo externo al árbol. En las entradas de registro, un módulo externo al árbol se marca como carga dañada.

En el búfer de registro del kernel y en los mensajes de syslog, busca entradas de registro que se parezcan a las siguientes:

MODULE_NAME: loading out-of-tree module taints kernel.
  • Busca en el búfer de registro del kernel entradas de registro que indiquen la presencia de módulos externos al árbol:

    sudo dmesg | grep out-of-tree
    
  • Busca en todos los mensajes syslog entradas de registro que indiquen la presencia de módulos externos:

    grep "out-of-tree" /var/log/syslog*
    

Comprobar si hay parches activos

La aplicación de parches en tiempo real en una VM puede interferir con las detecciones de Virtual Machine Threat Detection y puede provocar falsos positivos.

Para comprobar si está disponible, sigue estos pasos:

  1. Consulta syslog para obtener información sobre la instalación y el registro de módulos de livepatching. El parcheo en directo suele modificar el código del kernel instalando ftracepuntos del kernel.

    sudo grep livepatch /var/log/syslog*
    
  2. Busca los nuevos módulos del kernel instalados para aplicar parches en directo (normalmente, tienen el prefijo livepatch):

    sudo lsmod | grep livepatch
    
  3. Buscar archivos de parche:

    sudo ls -l /sys/kernel/livepatch
    

Para obtener información sobre Livepatch, consulta Livepatch en la documentación del kernel de Linux.

Comprobar si se han detectado otras actividades potencialmente maliciosas en la VM

  1. En Security Command Center, consulta los detalles del resultado de detección de amenazas de la VM que estés investigando.
  2. En la sección Recurso afectado, en el campo Nombre completo del recurso, haga clic en la flecha desplegable y, a continuación, en Mostrar todos los resultados con este nombre completo del recurso. La consulta de resultados se actualiza para mostrar solo los resultados de esta VM.
  3. Busca resultados que indiquen posibles actividades de minería de criptomonedas, malware, concesiones de gestión de identidades y accesos inusuales y otras amenazas de seguridad.

Comprobar si el software antivirus está provocando un falso positivo

El software antivirus puede interferir en las detecciones de Detección de amenazas de VM y puede activar falsos positivos.

Comprobar todos los procesos en ejecución del sistema

La presencia de procesos inesperados puede indicar que la detección de amenazas en máquinas virtuales es válida y que la máquina virtual se ha visto comprometida.

  1. Lista de todos los procesos que se están ejecutando en la VM:

    ps -eAf
    
  2. Busca procesos de depuración, como gdb, strace y pstack, que no suelas ejecutar en esta VM. Los procesos del depurador pueden espiar otros procesos.

  3. Busca otros procesos sospechosos en la VM.

Comprobar el kernel arrancado

Comprueba el kernel arrancado para identificar tu kernel de Linux:

cat /proc/version

Si el valor devuelto no es la versión del kernel que esperabas, puede indicar que se ha producido un ataque de secuestro mediante la explotación de la herramienta kexec en el kernel. La herramienta kexec puede reiniciar el sistema para usar otro kernel.

Tarea adicional para Unexpected system call handler

Realiza esta tarea si obtienes un Defense Evasion: Unexpected system call handler resultado.

Audita las llamadas al sistema y busca anomalías en su uso y en los elementos que las invocan. Los registros de auditoría proporcionan información sobre el proceso de invocación y los argumentos de las llamadas al sistema. También puedes realizar tareas de verificación para comprobar los comportamientos esperados de las llamadas al sistema habituales. Para obtener más información, consulta el ejemplo de inspección con el rootkit Diamorphine de esta página.

Tarea adicional para Unexpected interrupt handler

Realiza esta tarea si obtienes un Defense Evasion: Unexpected interrupt handler resultado.

Lista los controladores de interrupciones en directo del sistema y compara los resultados con la información de otras VMs similares del proyecto. Los controladores de interrupción inesperados pueden indicar que la VM está en peligro.

Para ver una lista de los controladores de interrupciones activas, ejecuta el siguiente comando:

cat /proc/interrupts

La salida es similar a la siguiente:

           CPU0       CPU1
  0:         44          0   IO-APIC   0-edge      timer
  1:          9          0   IO-APIC   1-edge      i8042
  4:      17493          0   IO-APIC   4-edge      ttyS0
  8:          0          0   IO-APIC   8-edge      rtc0
  9:          0          0   IO-APIC   9-fasteoi   acpi
 12:          0        152   IO-APIC  12-edge      i8042
 24:         16          0   PCI-MSI 81920-edge      virtio2-config
 25:          0      40194   PCI-MSI 81921-edge      virtio2-inflate
 26:      58528          0   PCI-MSI 81922-edge      virtio2-deflate
 27:          0     966356   PCI-MSI 81923-edge      virtio2-stats
 28:          0          0   PCI-MSI 49152-edge      virtio0-config
 29:          0          0   PCI-MSI 49153-edge      virtio0-control
 30:          0          0   PCI-MSI 49154-edge      virtio0-event
 31:          0     555807   PCI-MSI 49155-edge      virtio0-request
 32:          0          0   PCI-MSI 98304-edge      virtio3-config
 33:        184          0   PCI-MSI 98305-edge      virtio3-input
 34:          0          0   PCI-MSI 65536-edge      virtio1-config
 35:     556203          0   PCI-MSI 65537-edge      virtio1-input.0
 36:     552746          1   PCI-MSI 65538-edge      virtio1-output.0
 37:          1     426036   PCI-MSI 65539-edge      virtio1-input.1
 38:          0     408475   PCI-MSI 65540-edge      virtio1-output.1

Tarea adicional para Unexpected processes in runqueue

Sigue estos pasos si recibes un resultado de Defense Evasion: Unexpected processes in runqueue. En esta sección se explica cómo recopilar más datos para investigar los resultados. Es posible que estos puntos de datos no indiquen directamente un problema de malware.

En esta tarea, revisas la cola del programador por CPU. Aunque algunos procesos pueden ser breves, puedes evaluar el comportamiento de la cola del programador con los procesos en ejecución por CPU para detectar comportamientos anómalos.

  1. Muestra detalles sobre el tiempo que dedica cada proceso en ejecución por CPU. De esta forma, puedes ver si una CPU concreta está muy ocupada. Puedes correlacionar los resultados con las interrupciones fijadas en la CPU desde /proc/interrupts.

    cat /proc/schedstat
    

    Para obtener más información sobre este comando, consulta Estadísticas del programador en la documentación del kernel de Linux.

  2. Muestra todas las tareas ejecutables actuales y los detalles sobre los cambios de contexto de cada CPU.

    cat /proc/sched_debug
    

    La salida es similar a la siguiente:

    Sched Debug Version: v0.11, 5.4.0-1081-gke #87-Ubuntu
    ktime                                   : 976187427.733850
    sched_clk                               : 976101974.761097
    cpu_clk                                 : 976101973.335113
    jiffies                                 : 4538939132
    sched_clock_stable()                    : 1
    
    sysctl_sched
      .sysctl_sched_latency                    : 12.000000
      .sysctl_sched_min_granularity            : 1.500000
      .sysctl_sched_wakeup_granularity         : 2.000000
      .sysctl_sched_child_runs_first           : 0
      .sysctl_sched_features                   : 2059067
      .sysctl_sched_tunable_scaling            : 1 (logarithmic)
    
    cpu#0, 2199.998 MHz
      .nr_running                    : 0
      .nr_switches                   : 16250401
      .nr_load_updates               : 0
      .nr_uninterruptible            : 12692
      .next_balance                  : 4538.939133
      .curr->pid                     : 0
      .clock                         : 976101971.732857
      .clock_task                    : 976101971.732857
      .avg_idle                      : 880408
      .max_idle_balance_cost         : 500000
    
    runnable tasks:
     S           task   PID         tree-key  switches  prio     wait-time             sum-exec        sum-sleep
    -----------------------------------------------------------------------------------------------------------
     S        systemd     1     51740.602172    326778   120         0.000000    165741.786097         0.000000 0 0 /init.scope
     S       kthreadd     2   1482297.917240      1361   120         0.000000       112.028205         0.000000 0 0 /
     I      rcu_sched    11   1482642.606136   1090339   120         0.000000     17958.156471         0.000000 0 0 /
     S        cpuhp/1    15       537.058588         8   120         0.000000         2.275927         0.000000 0 0 /
     S  idle_inject/1    16        -2.994953         3    49         0.000000         0.012780         0.000000 0 0 /
     S    migration/1    17         0.000000    245774     0         0.000000      5566.508869         0.000000 0 0 /
     S    ksoftirqd/1    18   1482595.656315     47766   120         0.000000      1235.099147         0.000000 0 0 /
     I   kworker/1:0H    20       536.961474         5   100         0.000000         0.043908         0.000000 0 0 /
     S      kdevtmpfs    21     11301.343465       177   120         0.000000         3.195291         0.000000 0 0 /
     I          netns    22         6.983329         2   100         0.000000         0.021870         0.000000 0 0 /
     Srcu_tasks_kthre    23        10.993528         2   120         0.000000         0.010200         0.000000 0 0 /
     S        kauditd    24   1482525.828948       319   120         0.000000        14.489652         0.000000 0 0 /
    
  3. Busca lo siguiente:

    • Nombres de los procesos en ejecución.
    • Número de cambios de contexto por CPU. Comprueba si un proceso está incurriendo en demasiados o muy pocos cambios en la CPU.
    • Tiempo de CPU empleado (tiempo no inactivo).

Ejemplo de inspección con el rootkit Diamorphine

En esta sección se muestra una inspección de una VM que tiene instalado el rootkit Diamorphine. Diamorfine es un módulo de kernel cargable (LKM) popular. Este rootkit activa las siguientes categorías de resultados:

  • Defense Evasion: Unexpected system call handler
  • Defense Evasion: Unexpected kernel modules
  • Defense Evasion: Unexpected kernel read-only data modification

Para obtener más información sobre estas categorías de detecciones, consulte Detecciones de amenazas de rootkit en modo kernel.

Estos son los pasos de inspección que se han seguido y los síntomas que se han observado en la VM:

  1. Busca syslog para ver todos los módulos del kernel externos al árbol que se han cargado.

    1. Buscar en el búfer de registro del kernel:

      sudo dmesg | grep out-of-tree
      

      Resultado:

      diamorphine: loading out-of-tree module taints kernel.
      
    2. Buscar en los mensajes de syslog:

      grep "out-of-tree" /var/log/syslog*
      

      Resultado:

      /var/log/syslog: diamorphine: loading out-of-tree module taints kernel.
      
  2. Busca syslog para ver si hay errores de verificación de módulos (no disponible en todas las distribuciones de Linux).

    1. Buscar en el búfer de registro del kernel:

      sudo dmesg | grep "module verification failed"
      

      Resultado:

      diamorphine: module verification failed: signature and/or required key missing - tainting kernel
      
    2. Buscar en los mensajes de syslog:

      sudo grep "module verification failed" /var/log/syslog*
      

      Resultado:

      /var/log/syslog: diamorphine: module verification failed: signature and/or required key missing - tainting kernel
      
  3. Confirma que el módulo está oculto en los comandos /proc/modules y lsmod.

    sudo grep diamorphine /proc/modules
    sudo lsmod | grep diamorphine
    

    No se han mostrado resultados.

  4. Confirma que el módulo tiene una entrada en sysfs.

    sudo cat /sys/module/diamorphine/coresize
    

    Resultado:

    16384
    
  5. Obtén la tabla de llamadas al sistema de la arquitectura:

    sudo ausyscall --dump
    

    Resultado:

    Using x86_64 syscall table:
    0       read
    1       write
    2       open
    3       close
    

    Audita las anomalías en las llamadas al sistema, como kill y getdents, que suelen manipularse con rootkits.

  6. Para comprobar si se ha manipulado el controlador de llamadas del sistema, audita las llamadas del sistema y comprueba si hay comportamientos anómalos. Estos comportamientos varían en función de cada llamada al sistema.

    Una llamada al sistema que se suele hackear es la llamada kill. Puedes comprobar si se ha omitido la llamada al sistema kill. En el ejemplo siguiente, se ha auditado la llamada al sistema kill.

    1. Instala auditd y observa el comportamiento de la VM sin el rootkit Diamorphine:

      $ sudo apt-get update && sudo apt-get install auditd
      $ # Add audit rules for specific system calls
      $ sudo echo "-a exit,always -F arch=b64 -S kill -k audit_kill" >> /etc/audit/rules.d/audit.rules
      $  sudo /etc/init.d/auditd restart
      Restarting auditd (via systemctl): auditd.service.
      
      $ # Behavior observed without rootkit
      $ sleep 600 &
      [1] 1119
      $ sudo kill -9 1119
      $ sudo ausearch -k audit_kill | grep -A 3 "pid=1119"
      type=OBJ_PID msg=audit(1677517839.523:198): opid=1119 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep"
      type=SYSCALL msg=audit(1677517839.523:198): arch=c000003e syscall=62 success=yes exit=0 a0=45f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0
      tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
      $ sleep 600 &
      [1] 1087
      $ sudo kill -31 1087
      $ sudo ausearch -k audit_kill | grep -A 3 "pid=1087"
      type=OBJ_PID msg=audit(1677517760.844:168): opid=1087 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep"
      type=SYSCALL msg=audit(1677517760.844:168): arch=c000003e syscall=62 success=yes exit=0 a0=43f a1=1f a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0        ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
      

      En este punto de la inspección, se había instalado el rootkit Diamorphine. En los siguientes pasos se muestra el comportamiento de la VM después de instalar el rootkit.

    2. Confirma que ya no hay ninguna entrada de registro de auditoría para la señal después de instalar el rootkit Diamorphine:

      $ sudo ausearch -k audit_kill | grep -A 3 "pid=1158"
      $ sleep 600 &
      [2] 1167
      
    3. Consulta los detalles de la entrada del registro de auditoría de la señal. En este ejemplo, aunque esta señal en concreto no se ha pirateado por completo con el rootkit, se puede acceder a la información sobre el proceso de invocación.

      $ sudo kill -9 1167
      $ sudo ausearch -k audit_kill | grep -A 3 "pid=1167"
      type=OBJ_PID msg=audit(1677518008.586:237): opid=1167 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep"
      type=SYSCALL msg=audit(1677518008.586:237): arch=c000003e syscall=62 success=yes exit=0 a0=48f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0
      tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
      

Depurar la secuencia de comandos de recogida de datos

La siguiente secuencia de comandos realiza muchas de las tareas de depuración descritas en esta página. Puedes ejecutar esta secuencia de comandos en modo sudo o root. La secuencia de comandos solo lee información de depuración del sistema.

$ cat kprot.sh
#!/bin/bash

echo "Boot command line"
cat /proc/cmdline
echo "=================================================="
echo "Loaded modules"
cat /proc/modules
echo "=================================================="
echo "Current tracer"
cat /sys/kernel/debug/tracing/current_tracer
echo "=================================================="
echo "Tracing event enable"
cat /sys/kernel/debug/tracing/events/enable
echo "=================================================="
echo "Tracing sub events enable"
for en in `find /sys/kernel/debug/tracing/events/*/enable`; do printf "\b$en\n"; cat $en; done
echo "=================================================="
echo "IP table rules"
iptables -L
echo "=================================================="
echo "Ftrace list"
cat /sys/kernel/debug/tracing/enabled_functions
echo "=================================================="
echo "Kprobes enabled"
cat /sys/kernel/debug/kprobes/enabled
echo "=================================================="
echo "Kprobes list"
cat /sys/kernel/debug/kprobes/list
echo "=================================================="
echo "Kprobes blocklist"
cat /sys/kernel/debug/kprobes/blacklist
echo "=================================================="
echo "BPF trace"
sudo apt update && sudo apt-get update && sudo apt-get install bpftrace
bpftrace -l
echo "=================================================="
echo "BPF prog list"
sudo apt update && sudo apt install linux-tools-`uname -r`
bpftool prog
echo "=================================================="

Siguientes pasos