Ir al contenido
GitHub

Actividad y memoria

Alt-M o Comando → Monitor de actividad abre el monitor de procesos. Lo proporciona el complemento Sistema incluido, que está activado por defecto y se puede desactivar en Opciones → Complementos. La lista de procesos ocupa el panel activo, y el otro panel muestra un resumen de la memoria del proceso seleccionado. Enter o un doble clic abre ese proceso en una ventana sobre el monitor, con su mapa de memoria a un lado y una vista previa de los bytes de la región seleccionada al otro. Esc la cierra, y Tab alterna entre los dos lados. Alt-W o el botón [+] maximiza el panel con el foco, [=] restaura la división y [-] oculta el monitor. El monitor toma una muestra por segundo mientras está abierto y se detiene al cerrarlo. El muestreo se pausa mientras se ejecuta una inspección de memoria y se reanuda cuando llega el resultado.

La lista muestra la CPU, la memoria residente, el crecimiento de la memoria y las velocidades de lectura y escritura en disco. Una CPU al 100 % equivale a un núcleo totalmente ocupado. Las páginas residentes compartidas entre procesos cuentan para cada uno de ellos, así que sumar la RAM de todos los procesos no da el total del sistema. Las velocidades de CPU y de disco aparecen a partir de la segunda muestra.

La CPU es una media de los últimos segundos en la que el uso más antiguo va perdiendo peso, como en top, así que una lista ordenada por CPU se queda quieta mientras un proceso trabaja a ráfagas cortas. El resumen y la CPU de todo el sistema en la parte superior del monitor se calculan igual. H oculta los procesos que no usaron CPU en ese tiempo, y la fila del filtro indica cuántos hay ocultos. Un proceso que deja de trabajar sigue en la lista hasta que su media baja a 0.0. En el árbol, los procesos de los que desciende uno ocupado siguen en la lista con él. Pulsa H otra vez para mostrarlos todos.

Tecla Acción
Enter Abrir el mapa de memoria del proceso / pasar a la vista previa de la región
/ Filtrar por nombre o PID; ↑↓ siguen moviendo, Enter conserva el filtro, Esc lo borra
C / M / G / N / P Ordenar por CPU / RAM / crecimiento / nombre / PID; pulsa de nuevo para invertir
I / O Ordenar por velocidad de lectura / escritura
T Mostrar u ocultar el árbol de procesos
H Ocultar o mostrar los procesos que no usaron CPU en los últimos segundos
Left / Right En el árbol, plegar o desplegar la rama del proceso seleccionado
K Enviar una señal o cambiar la prioridad, también desde la ventana del proceso
E Buscar entropía alta en todos los procesos
Alt-N Mostrar el tráfico del proceso seleccionado en la pantalla de red
Alt-O Abrir la carpeta del programa seleccionado junto a la lista
Space Pausar o reanudar el muestreo
R Actualizar la vista actual
Esc Volver; en la lista de procesos, cerrar el monitor o regresar a la pantalla de red

Alt-O abre la carpeta del programa del proceso seleccionado en el otro panel, con el cursor en el programa, y los archivos reciben las teclas. La lista conserva su filtro, su orden y el proceso que seleccionaste. Tab pasa las teclas entre la lista y los archivos, y Alt-O en otra fila lleva los archivos allí. En esos archivos puedes ver, editar, eliminar, comprimir y extraer, y crear carpetas. Copiar y mover necesitan el otro panel, así que esperan a que se cierre el monitor. Esc en la lista, o Alt-M, recupera el resumen, y Alt-M otra vez cierra el monitor. En los archivos abiertos y en el mapa de memoria, Alt-O muestra el archivo abierto seleccionado o el archivo que mapea la región. Si el programa se eliminó mientras se ejecuta, su carpeta se abre con un aviso. Un aviso también te dice cuándo el archivo no está en su carpeta en esta computadora, como pasa con un programa que se ejecuta dentro de un contenedor. Las alertas, los elementos de inicio y la vista de Docker funcionan igual.

Cada pantalla guarda su filtro al cerrarla y lo vuelve a mostrar al abrirla. Para borrar un filtro, pulsa / y después Esc.

Haz clic en el encabezado de una columna para ordenar, y doble clic en un proceso para abrir su mapa de memoria. El resumen muestra la memoria residente actual, el valor más alto observado, el cambio desde que empezó la monitorización, la CPU, el espacio de direcciones virtual y un gráfico de la memoria residente de los últimos 60 segundos. Los totales de memoria usada, en swap, privada y compartida aparecen una vez leído el mapa de memoria, si el sistema los proporciona. Enter en el panel de memoria abre el mapa de memoria. El mapa de memoria se lee cuando lo pides; pulsa R para volver a leerlo después de que el proceso cambie sus asignaciones.

Debajo del gráfico, Árbol de procesos lista los procesos de los que desciende el seleccionado, el propio proceso y todo lo que ha iniciado, cada uno sangrado debajo del que lo inició y con su memoria residente. Cuando no caben todos, la última línea indica cuántos quedan fuera.

En el árbol que muestra T, cada proceso aparece debajo del que lo inició, y ▾ marca un proceso que tiene otros debajo. Left pliega la rama del proceso seleccionado; en un proceso sin nada debajo, Left pliega la rama a la que pertenece y selecciona el proceso que lo inició. Right despliega una rama plegada y, en una abierta, pasa al primer proceso de esa rama. Un proceso plegado muestra ▸ y cuántos procesos oculta. Una rama sigue plegada hasta que su proceso termina. Mientras se aplica un filtro, la lista es plana.

K abre Señal o prioridad para el proceso seleccionado, en la lista y en la ventana del proceso con el mapa de memoria o los archivos abiertos. Pulsa la letra de una opción, o muévete hasta ella y pulsa Enter. Esc cierra el diálogo sin enviar nada.

Tecla Opción Qué hace
T Terminar Envía TERM, que pide al proceso que salga
I Interrumpir Envía INT, lo mismo que Ctrl-C en su terminal
H Colgar Envía HUP; muchos servicios vuelven a leer su configuración
K Matar Envía KILL, que termina el proceso al instante sin dejarle limpiar
S Detener Envía STOP, que pone el proceso en pausa
C Continuar Envía CONT, que reanuda un proceso detenido
L Bajar prioridad Sube su valor nice en 5, hasta 19, para que espere más a la CPU cuando el sistema está ocupado
R Subir prioridad Baja su valor nice en 5, hasta -20

Justo antes de enviar, Borg comprueba que el PID sigue perteneciendo al proceso que elegiste, iniciado a la misma hora, para que un proceso nuevo que haya reutilizado el PID quede intacto. La línea de estado confirma lo que se envió y la lista vuelve a muestrear al instante. La vista general indica cuándo un proceso está detenido y muestra su valor Nice cuando no es 0.

Puedes enviar señales a tus propios procesos y bajar su prioridad. El sistema rechaza el resto: los procesos de otro usuario y subir una prioridad, algo que solo puede hacer un administrador. Entonces Borg ofrece A Administrador, que envía la misma opción a través del asistente descrito en Acceso de administrador. Borg no se envía señales a sí mismo; F10 lo cierra.

El mapa tiene tres columnas:

  • Memoria usada es la memoria imputada solo a este proceso: las páginas que ha escrito, más las páginas enviadas a swap o comprimidas. Es la cifra que hay que vigilar para detectar fugas, y en macOS coincide con la columna Memoria del Monitor de Actividad.
  • Residente son las páginas que están ahora en la RAM, incluidas las compartidas con otros procesos.
  • Mapeada es espacio de direcciones, incluidas las reservas. No dice nada del uso de RAM.

Un proceso puede mapear gigabytes, en su mayoría bibliotecas del sistema compartidas con todos los demás procesos, y aun así tener una memoria usada de solo unos pocos megabytes. Las regiones aparecen al principio agrupadas por finalidad: heap y asignaciones, pilas de hilos, el código y los datos del propio programa, bibliotecas compartidas, archivos mapeados, memoria compartida, asignaciones del sistema y otras, y rangos reservados y páginas de protección. Los grupos y sus regiones se ordenan por memoria usada, con las reservas al final. Las bibliotecas y los archivos mapeados tienen una fila por archivo; despliega un archivo para ver sus regiones. Los nombres de los grupos se deducen de las etiquetas que da el sistema operativo. Al seleccionar un grupo o un archivo se explica qué es y se muestran su parte de la memoria usada y sus miembros más grandes. Enter o Right despliegan un grupo o un archivo; Left lo pliega, o pliega el que contiene la fila seleccionada. G alterna entre la lista agrupada y la lista sin agrupar.

1 Memoria y 2 Archivos abiertos alternan entre las pestañas de inspección; también puedes hacer clic en ellas. La lista de archivos abiertos muestra cada descriptor, su modo de acceso, su tipo y su ruta o extremo de red; el otro panel muestra todos los detalles, el tamaño del archivo y el desplazamiento actual cuando están disponibles. En macOS también incluye entradas como cwd (directorio actual) y txt (ejecutable mapeado). R actualiza la lista. Cada pestaña conserva su posición en la lista al cambiar de una a otra. Cuando el acceso está restringido, Borg ofrece volver a intentarlo como administrador. En un archivo normal, los detalles también muestran una vista previa de su contenido, como la vista rápida: Tab entra en la vista previa para que puedas desplazarte por ella, y F3 abre el archivo en el visor. Borg abre el archivo por su ruta con tus propios permisos y deja en paz el descriptor del proceso.

Cuando seleccionas una región legible, Borg captura hasta 64 KiB de ella en el otro panel. Si el principio de la región solo contiene ceros, la captura salta hasta la primera página con datos, y la línea sobre los bytes indica en qué parte de la región está la ventana. Cada fila empieza con su posición contada desde el principio de la región, y un panel ancho muestra más bytes por fila. Cuando te mueves rápido, Borg espera un momento antes de leer; seleccionar otra región borra la vista previa anterior y cancela su lectura pendiente. Las regiones que no se pueden leer muestran un mensaje. Pulsa Tab o Enter para desplazarte por la vista previa. Esc ahí vuelve a la lista, y Esc en el mapa vuelve a la lista de procesos con el cursor y el filtro como estaban.

Las series de filas a cero se agrupan en una sola fila, como “· 60K bytes en cero ·”. ] y [ saltan al bloque de datos siguiente y anterior, y > y < capturan los 64 KiB siguientes y anteriores de la región. H alterna entre Hex y texto, R vuelve a capturar la ventana mostrada y D resalta lo que ha cambiado desde la captura anterior del mismo proceso y dirección. La vista de texto muestra el ASCII imprimible y sustituye los demás bytes por puntos. Las capturas se toman del proceso en vivo sin pausarlo, así que una captura no es una imagen coherente de todo el proceso. Se quedan en memoria salvo que las exportes. E guarda los bytes en bruto en un archivo nuevo en la carpeta del panel de archivos activo, legible solo por ti. Los archivos existentes nunca se sobrescriben.

M alterna la vista previa entre los bytes y un mapa de páginas de la región: una celda por página de 4 KiB, o por serie de páginas en una región grande, marcada según lo que contiene: punteros a la memoria del propio proceso, texto, texto UTF-16, código, datos comprimidos o cifrados, otros datos, relleno, ceros y páginas que no están en memoria. Una leyenda muestra la proporción de cada tipo en la región. Cuando el mapa tiene el foco, las flechas, PgUp, PgDn, Home y End mueven un cursor, y Enter abre como bytes la página bajo él. Las regiones de más de 16 384 páginas se muestrean de forma uniforme. En Linux, el mapa pregunta al sistema qué páginas están en memoria y no lee las demás, así que ni recupera páginas del swap ni toca páginas nuevas; en macOS, las páginas que nunca se han tocado se leen como ceros. Los tipos se deducen solo a partir de los bytes, así que tómalos como una pista.

Las páginas cuya entropía llega a 7,2 bits por byte se dibujan en rojo y negrita, o solo en negrita donde el rojo se leería mal, sea cual sea su tipo. Así destaca el código empaquetado o cifrado en una región ejecutable, donde Borg cuenta como código todas las páginas que no son ceros ni relleno. La leyenda muestra su proporción como entropía alta, la línea del cursor añade la entropía de la página bajo él, y la misma línea termina con la entropía más alta de la región. Una nota bajo la leyenda explica qué suelen significar la entropía alta y la baja. Las cachés comprimidas, las imágenes, los archivos comprimidos y las claves también tienen entropía alta, así que mira qué contiene la región antes de sospechar de ella.

Pulsa / en el panel de memoria, o Ctrl-F en cualquiera de los dos paneles, para buscar en la memoria. Elige un modo, si deben coincidir las mayúsculas y si quieres buscar en la memoria legible del proceso o en la captura actual. El formulario se abre con lo que tenía cuando lo cerraste por última vez. Texto busca en UTF-8, UTF-16 (ambos órdenes de bytes) y UTF-32 (ambos órdenes de bytes). Unicode además normaliza los caracteres de compatibilidad y las secuencias combinadas: por ejemplo, 𝐁𝐨𝐫𝐠 coincide con Borg. No considera iguales letras distintas solo porque se parezcan. Hex acepta pares de bytes como 42 6F 72 67.

Cadenas e Indicadores solo leen la memoria que el propio proceso ha rellenado: memoria que no está respaldada por un archivo y en la que el proceso puede escribir; en macOS, también se omiten las regiones en las que nunca ha escrito. Cadenas muestra una sola vez cada serie de al menos seis caracteres ASCII imprimibles o UTF-16LE, con el número de copias en memoria, y omite el relleno, como caracteres o signos de puntuación repetidos; si escribes una consulta, conserva solo las cadenas que la contienen. Indicadores conserva las cadenas que parecen una URL, una dirección IP, una dirección de correo electrónico, una ruta de archivo, una línea de comandos, un secreto (una clave privada, un token de acceso o una asignación de contraseña) o una serie larga de base64, y etiqueta cada una.

Borg también lee las cadenas de los archivos que el proceso tiene mapeados, hasta 1 GiB, y marca con • las cadenas que solo están en memoria: texto que el proceso ha construido, recibido o descodificado, y que ninguno de sus archivos contiene. Primero aparecen los indicadores, luego las cadenas que solo están en memoria y después las que también contienen sus archivos, y las cadenas que parecen palabras van antes que el resto. La lista conserva las 2000 mejores. Donde otras coincidencias muestran su región, cada fila muestra el tipo y el número de copias, y la vista previa muestra la cadena en su sitio; C recorre sus copias. Toma estos resultados como pistas que merece la pena examinar. Los programas normales también contienen muchas URL, rutas y claves.

Las coincidencias ocupan el panel de la lista y muestran su dirección, su codificación y su región. Al seleccionar una coincidencia se previsualizan en el otro panel los bytes que la rodean, con la coincidencia resaltada. Enter entra en la vista previa, y Esc vuelve a las coincidencias. Esc en las coincidencias vuelve al mapa de memoria o a la lista de procesos de la que venías. Buscar en una captura guardada usa sus bytes sin leer el proceso en ejecución. Las búsquedas en un proceso leen la memoria por partes, informan de los bytes que no pudieron leer y se detienen tras 2000 coincidencias o 60 segundos. N continúa desde donde se detuvo la búsqueda, y Ctrl-C la detiene y conserva los resultados. El informe de cobertura separa los bytes buscados de los ilegibles. Un proceso puede cambiar su memoria mientras se busca en ella.

I, en el mapa de memoria o entre las coincidencias de búsqueda, comprueba si el proceso está ejecutando el código que contienen sus archivos. Compara el código en memoria con los archivos desde los que se mapeó e informa de las páginas que difieren, busca en la memoria no respaldada por archivos cabeceras de imágenes ejecutables (ELF, Mach-O y PE), y enumera la memoria ejecutable no respaldada por archivos, la memoria que es a la vez escribible y ejecutable, y el código procedente de archivos eliminados, sin nombre o temporales. También comprueba el proceso en su conjunto: bibliotecas inyectadas mediante LD_PRELOAD, LD_AUDIT, DYLD_INSERT_LIBRARIES o /etc/ld.so.preload, rutas de búsqueda de bibliotecas, un trazador en Linux, un programa cuyo archivo se ha eliminado o sustituido, y un nombre de proceso distinto del de su programa.

Los hallazgos ocupan el panel de la lista, con las alertas primero, luego las advertencias y después los avisos. Al seleccionar uno se previsualizan los bytes a los que se refiere, con la evidencia resaltada, y las filas bajo la lista indican qué otra cosa podría explicarlo. Los programas que compilan código mientras se ejecutan, como los navegadores y los motores de Java y JavaScript, siempre contienen código no respaldado por ningún archivo, así que para ellos esos hallazgos son solo avisos. R vuelve a comprobar, Ctrl-C detiene una comprobación y conserva lo encontrado hasta el momento, y Esc vuelve atrás. Una comprobación lee como máximo 512 MiB de código y 1 GiB de otra memoria, durante un máximo de 45 segundos, e indica si se detuvo antes de tiempo.

En Linux, las tablas de páginas muestran qué páginas de código ha modificado un proceso, así que solo se leen esas; en macOS, tampoco se leen las regiones sin páginas modificadas. El código de la caché compartida de macOS no tiene un archivo propio y no se compara. La memoria que una comprobación no puede leer se contabiliza, y Borg ofrece A Administrador. Toma los hallazgos como pistas, porque los depuradores, los perfiladores, los actualizadores y las herramientas de seguridad dejan los mismos rastros.

Y, en el mapa de memoria o entre las coincidencias de búsqueda, analiza la memoria que el propio proceso ha rellenado con las mismas reglas que un análisis de archivos: las de Borg y las de tu carpeta de reglas (consulta Analizar archivos con reglas). Igual que Cadenas, lee la memoria no respaldada por archivos y la memoria en la que el proceso puede escribir; en macOS también omite las regiones en las que nunca ha escrito. Una región sin ninguna página en memoria ni en swap no se lee, y en Linux las tablas de páginas muestran qué páginas no ha tocado nunca el proceso, así que esas tampoco se leen. Las páginas en swap sí se leen, porque una carga maliciosa puede esperar ahí. La memoria se lee en bloques de 16 MiB que se solapan 4 KiB, así que una coincidencia que pasa de un bloque al siguiente también se encuentra. Cada regla aparece una vez por región, en su primera coincidencia.

Las coincidencias ocupan el panel de la lista, con las alertas primero. Cada una indica la regla y de dónde viene, reglas de Borg o tu archivo, luego los bytes que encontró y lo que busca la regla, y las filas bajo la lista indican qué otra cosa podría explicarla. Al seleccionar una coincidencia se previsualizan los bytes que la rodean, con la coincidencia resaltada. Los archivos de reglas omitidos aparecen al final, con el mensaje del compilador. R vuelve a analizar, Ctrl-C detiene el análisis y conserva lo encontrado, y Esc vuelve atrás. Un análisis lee como máximo 1 GiB, durante un máximo de 45 segundos, muestra hasta 2000 coincidencias e indica si se detuvo antes de tiempo. La memoria que no puede leer se contabiliza, y Borg ofrece A Administrador, que ejecuta el análisis en el programa auxiliar con tu carpeta de reglas.

Un análisis con reglas es una evaluación rápida: un vistazo a un proceso o una carpeta en busca de patrones que alguien ha descrito. No vigila el sistema, no bloquea nada ni limpia, que es la tarea de la protección de endpoints. Algunas cosas quedan fuera de su alcance:

  • macOS protege la memoria de sus propios programas y de los programas creados con Hardened Runtime frente a cualquier otro programa, administradores incluidos (consulta Acceso de administrador).
  • En Linux, kernel.yama.ptrace_scope decide de quién puedes leer la memoria. Con 1, como en Ubuntu, solo puedes leer tus propios procesos hijos, así que Borg ofrece A Administrador para los demás. Con 3, nadie puede leer otro proceso, administradores incluidos.
  • Un rootkit de kernel puede ocultar memoria, archivos y procesos a cualquier programa, Borg incluido, así que un análisis limpio demuestra poco.
  • Un programa empaquetado o cifrado solo muestra su código real mientras se ejecuta. Analizar su memoria entonces ve lo que un análisis de su archivo no puede ver.

Borg lee la memoria sin adjuntarse como depurador, con process_vm_readv en Linux y mach_vm_read en macOS, así que el proceso no ve ningún trazador, que es lo que buscan la mayoría de las comprobaciones antidepuración. Los monitores que se ejecutan como administrador, como auditd, las herramientas eBPF y los clientes de Endpoint Security de macOS, pueden registrar las lecturas de todos modos. Un análisis de archivos abre cada archivo que lee, y inotify y fanotify lo notifican. En Linux, deja intacta la hora de acceso de los archivos que son tuyos.

Análisis de entropía de todos los procesos

Sección titulada «Análisis de entropía de todos los procesos»

E en la lista de procesos abre el Análisis de entropía, que lee una muestra de las páginas de todos los procesos en busca de bytes tan densos como el código empaquetado. Pulsa la letra de una opción, o muévete hasta ella y pulsa Enter. Esc cierra el diálogo.

Tecla Opción Qué lee
C Código de todos los procesos Las regiones ejecutables, donde aparece el código empaquetado o cifrado
M Toda la memoria de todos los procesos Todas las regiones legibles, así que también datos como claves y archivos comprimidos
L Últimos resultados Nada nuevo: vuelve a mostrar los hallazgos del último análisis

Borg lee hasta 1024 páginas de 4 KiB de una región y 32 768 de un proceso, repartidas de forma uniforme. Un proceso con muchas regiones recibe menos páginas por región, pero nunca menos de 16. Una región con al menos una página de 7,2 bits por byte o más es un hallazgo. Los hallazgos ocupan el panel de la lista: primero el código, luego la memoria que escribió el proceso y por último los archivos mapeados tal como están en el disco, y dentro de cada grupo primero la región con mayor proporción de páginas con entropía alta. El código con el 70 % o más de sus páginas con entropía alta aparece en negrita, según la misma regla que la búsqueda de ejecutables empaquetados. Cada fila indica el tipo (código, escrita o archivo), esa proporción con la entropía más alta, y el nombre del proceso, el PID y la región. El otro panel muestra las direcciones, el tamaño y el acceso de la región, cuántas páginas de la muestra tienen entropía alta, dónde empieza la primera de ellas y qué suelen ser esos bytes. Se conservan los 2000 hallazgos más fuertes, y el resumen cuenta los más débiles que se omitieron.

Enter en un hallazgo abre el mapa de memoria del proceso en esa región, con el mapa de páginas activado y el cursor en la primera página densa de la muestra, para que veas los bytes que la rodean. Esc vuelve al mapa y, otra vez, a los hallazgos.

Borg lee 4 procesos a la vez. Una región sin ninguna página en memoria ni en swap no se lee, y en Linux las tablas de páginas muestran qué páginas están en memoria, así que el análisis no toca páginas nuevas ni recupera las que están en swap. Se omiten las cachés que todos los procesos mapean igual: la caché compartida de dyld en macOS y las páginas que el kernel mapea en todos los procesos en Linux. Un archivo mapeado sin cambios, como una biblioteca compartida, solo se lee en el primer proceso que lo mapea.

Un análisis se detiene a los 90 segundos y deja el resto para N, que sigue con los procesos a los que no llegó. Ctrl-C lo detiene antes y conserva los hallazgos, y R vuelve a analizar desde el principio. Encima de los hallazgos, una línea cuenta los procesos analizados y los hallazgos, y la siguiente los procesos omitidos: ilegibles, protegidos y no alcanzados. En macOS, vmmap tarda unos segundos en listar las regiones de un proceso, así que analizar todos los procesos puede requerir varias rondas de N.

Los procesos cuya memoria protege macOS se cuentan y se omiten, porque nadie puede leerlos. Para los procesos que Borg no pudo leer, ofrece A Administrador, que los analiza en el programa auxiliar durante un máximo de 60 segundos, para que el auxiliar termine dentro de su límite de 2 minutos incluso tras una petición de contraseña lenta. Los bytes densos son habituales: las cachés comprimidas, las imágenes, las fuentes y las claves tienen entropía alta por naturaleza, así que toma los hallazgos como pistas y lee los detalles antes de sospechar de un proceso.

Cuando la lectura de un mapa de memoria o de una captura está restringida, una búsqueda no pudo leer parte de la memoria, un análisis de entropía no pudo leer algunos procesos, o el sistema rechaza una señal o un cambio de prioridad, Borg ofrece A Administrador. En macOS, esto abre la petición de autorización del sistema; en Linux usa pkexec y necesita que haya un agente de autorización en ejecución. Solo un asistente de corta duración se ejecuta con privilegios elevados. Borg sigue ejecutándose con normalidad, y el asistente solo devuelve datos del mapa, una cantidad limitada de bytes o los hallazgos de un análisis, o envía la señal o la prioridad que elegiste.

macOS protege la memoria de sus propios programas (Protección de la Integridad del Sistema) y de los programas compilados con Hardened Runtime frente a cualquier otro programa, administradores incluidos. Borg lo detecta a partir de la firma del programa: los detalles del proceso indican Memoria protegida, una lectura rechazada explica el motivo, y no se ofrece A Administrador, ya que no serviría de nada. Sus mapas de memoria y sus archivos abiertos se siguen mostrando. Tampoco se ofrece cuando Borg ya se ejecuta como administrador. En Linux, la política de seguridad puede seguir denegando el acceso; Borg muestra el error y el monitor de procesos sigue funcionando con normalidad.

Un proceso se identifica junto con su hora de inicio, de modo que un proceso nuevo que reutiliza un PID no hereda el historial de otro. Los mapas de memoria, los resultados de inspección, las capturas y el historial tienen límites de tamaño. El nombre Borg Commander permanece visible en la esquina inferior derecha en todas partes, incluidos la consola, el visor, el monitor, los diálogos y el salvapantallas.

Borg puede vigilar lo que arranca en una máquina y avisarte cuando algo parece mal. Activa Vigilar: arranques de procesos inusuales en F9 → Opciones → Complementos. El vigilante vive en el servicio en segundo plano que comparten todos tus Borg de la máquina, así que todos leen las mismas alertas. Ese servicio funciona mientras haya un Borg abierto. Para seguir vigilando sin ninguna terminal abierta, haz que el servicio arranque con el sistema como describe Sesiones con nombre y el servicio en segundo plano.

Las alertas se quedan en esa máquina hasta que indiques un destino para ellas, y la página lo recuerda mientras tanto (consulta Alertas fuera de la máquina).

Alt-L o Comando → Alertas abre la página. La lista ocupa el panel activo, con la alerta más reciente primero, y el otro panel muestra la alerta seleccionada por completo. Cada fila muestra la hora, la regla que se disparó, el programa, el proceso padre que lo inició, el usuario con el que corrió y qué ha sido del proceso. La línea sobre la lista cuenta las alertas y cuántas no ha leído nadie todavía.

Los detalles dicen en una frase por qué se disparó la regla y después el comando, el programa, el proceso padre, el usuario, a dónde llevaban los flujos estándar y dónde está el proceso ahora. En Árbol de procesos cada padre aparece encima de su hijo, de modo que puedes leer el camino desde un servicio hasta el comando que te preocupa. Conexiones enumera los sockets que el proceso tenía en ese momento, Hash del programa es el SHA-256 de su programa, y Reglas muestra lo que las reglas de Borg y las tuyas encontraron en ese programa (consulta Analizar archivos con reglas).

Un comando de más de 2 KiB conserva su principio y su final, 2 KiB en total, con … entre ambos. Los comandos de sus procesos padre y los valores de sus variables de precarga se cortan del mismo modo. Así las 200 alertas más recientes caben en el registro por largos que sean sus comandos, y un primer argumento largo no puede sacar de la vista el final de un comando. Ctrl-C copia el comando tal como lo guarda el registro.

Tecla Acción
Enter Mostrar el proceso en el monitor de actividad
C Dejar que un proceso congelado siga corriendo
K Terminar el proceso, después de una pregunta
A Permitir arranques como este desde ahora
Alt-O Abrir la carpeta del programa de la alerta junto a la lista
/ Filtrar las filas; ↑↓ siguen moviendo, Enter mantiene el filtro, Esc lo borra
R Volver a leer el registro
Ctrl-C Copiar el comando que ejecutó el proceso
Alt-W Maximizar la lista
Esc Cerrar la página, que guarda su filtro

El filtro mantiene las alertas que contienen todas las palabras que escribas, en la regla, su nombre corto, el motivo, el programa, el proceso padre, el usuario, el comando y lo que hizo Borg. Pon ! delante de una palabra para dejar fuera lo que encuentra: shell-on-socket !root mantiene las shells remotas de todos los demás usuarios.

Las alertas viven en alerts.json en la carpeta de estado, accesible solo a su propietario, las 200 más recientes. Una alerta sobre un proceso que sigue congelado se conserva más allá de ese límite, para que siempre puedas dejarlo seguir o terminarlo. Borg mantiene el archivo dentro de 8 MiB, lo máximo que vuelve a leer, y deja fuera las alertas más antiguas cuando no caben. La ventana Archivos de Borg las cuenta en Estado (consulta Archivos de Borg). Abrir la página marca como leídas las alertas que muestra, y la cuenta de alertas sin leer sigue al registro mientras Borg esté abierto, con la página abierta o sin ella.

Cuando Borg encuentra un alerts.json que no puede leer, como uno que una versión anterior dejó crecer por encima de 8 MiB, le cambia el nombre a alerts-unreadable.json antes de escribir un registro nuevo, así que las alertas que contiene siguen en el disco. Uno posterior recibe un nombre numerado como alerts-unreadable (2).json. La página de alertas indica el archivo debajo de la lista mientras siga ahí, así que bórralo cuando lo hayas revisado.

Cada regla nombra una cosa rara de un proceso que acaba de arrancar. El nivel dice cuánto significa: alerta rara vez es inocente, aviso suele tener un motivo corriente, nota está ahí para que el retrato quede completo.

Regla Qué la dispara Nivel
Shell en un socket de red Una shell cuya entrada, salida o errores van a un socket de red, que es el aspecto de una shell remota. Un socket que se queda en la máquina, como el que systemd da a la salida de un servicio para el journal, no cuenta alerta
Shell remota en un terminal Una shell en un terminal que un programa abrió para ella, donde la entrada, la salida o los errores de ese programa van a un socket de red, o el programa es un repetidor como socat o nc. Es una shell remota convertida en un terminal completo, como la que crea pty.spawn de Python alerta
Programa borrado mientras corre El archivo del programa ya no existe, así que nada en el disco dice qué es el proceso alerta
Programa sin archivo Borg no encuentra ningún archivo de programa para el proceso alerta
Biblioteca forzada en un programa LD_PRELOAD, LD_AUDIT o DYLD_INSERT_LIBRARIES está fijado en su entorno alerta
Shell desde un servicio Un servidor web, un entorno de ejecución de aplicaciones o una base de datos inició una shell aviso
Shell sin terminal Una shell sin terminal en ninguno de los dos lados, así que nadie la escribió aviso
Shell en el terminal de un programa Una shell en un terminal que un programa abrió para sí mismo y en el que nadie inició sesión, como el que abren expect o docker exec aviso
Exploración de la máquina Cuatro comandos distintos como whoami, id, uname y ss del mismo programa en menos de una hora, sin nadie con la sesión iniciada en el terminal donde se ejecutan. Los comandos que ejecuta a través de una shell tras otra cuentan juntos, así que también se detecta una web shell que inicia sh -c para cada comando aviso
Programa en una carpeta temporal El programa está en /tmp, /var/tmp, /dev/shm o /run/shm aviso
Nombre distinto del programa El proceso se llama de una manera y ejecuta otra cosa aviso
El padre nunca lo había iniciado Este padre nunca ha iniciado este programa en esta máquina nota

De cada proceso Borg lee el programa que ejecuta y si su archivo se borró, el comando, el usuario, el terminal al que pertenece y quién lo abrió, a dónde llevan su entrada, salida y errores estándar, las variables de precarga de su entorno y la cadena de padres que tiene encima. Un socket cuenta como socket de red cuando la red del proceso lo lista como TCP o UDP.

Si alguien inició sesión en un terminal se decide igual que para congelar (consulta Congelar un proceso): por SSH, en la consola, en tmux o screen, mediante sudo o su, o en una ventana de terminal. Un terminal que un programa abrió para sí mismo no cuenta, ya lo abriera el servidor remoto de un editor, docker exec o una shell inversa.

Borg aprende la máquina antes de actuar. Durante los primeros 7 días registra qué padre inicia qué programa aquí y no congela nada, y la columna Respuesta dice Habría congelado donde lo habría hecho. Después, un par que ya ha visto se queda en silencio para las reglas que se pueden aprender: las tres reglas de las shells, el nombre distinto y el padre que nunca lo había iniciado. La serie de comandos se aprende por el programa del que viene: se queda en silencio cuando ese programa ejecutó cada uno de sus comandos durante la semana de aprendizaje, así que un agente de monitorización que ejecuta df y ps todo el día se queda en silencio, y un servidor web que nunca ejecutó id no. Las cinco reglas de nivel alerta se disparan siempre, porque una shell en un socket o una biblioteca forzada nunca se vuelven normales por ocurrir a menudo. Todo lo que se ejecuta durante esa semana cuenta como normal, así que activa el vigilante mientras confías en la máquina. Los arranques en los que se disparó una regla que el aprendizaje no puede silenciar quedan fuera de lo que Borg aprende.

A en una alerta permite arranques como ese desde entonces, por su programa y su padre. Esos permisos van a watch-allowed.json en la carpeta de estado, que el vigilante lee y adopta en menos de un minuto. La sección [watch] de la configuración guarda lo mismo a mano (consulta Configuración). Borg anota como máximo 20 procesos por minuto y congela como máximo 5, y la línea sobre la lista dice cuántos hallazgos omitió cuando se dispararon más a la vez. Un proceso que Borg congela siempre queda anotado, por muchas alertas que hayan llegado antes, para que puedas dejarlo continuar. Las notas se cuentan aparte, así que una serie de ellas nunca ocupa el lugar de un aviso, y también quedan anotados hasta 20 procesos por minuto que Borg habría congelado por encima del límite de 5.

Una vez terminado el periodo de aprendizaje, Borg congela el proceso en el que se disparó una regla de nivel alerta o aviso. Congelar envía una señal de parada al proceso y a todo lo que está debajo de él. Un proceso congelado no ha terminado, así que su servicio sigue corriendo, systemd y Docker no tienen nada que reiniciar, y lo que estaba a punto de hacer espera donde está hasta que lo mires. La columna Respuesta dice Congelado, C lo deja continuar y K lo termina. Terminarlo es definitivo, así que Borg pregunta primero.

La congelación empieza cuando hayas visto todas las alertas de la semana de aprendizaje que dicen Habría congelado, o 3 días después de que termine la semana, lo que ocurra primero. Abrir la página de alertas las marca como leídas, y el vigilante lo nota en menos de un minuto. Así puedes revisar lo que encontró la semana y permitir un programa inofensivo con A antes de que nada se detenga, y una máquina que nadie mira sigue protegida. Mientras tanto, el pie de la página dice hasta cuándo espera la congelación, y los detalles de una alerta nueva dicen que está esperando.

Borg nunca congela el primer proceso del sistema, ni a sí mismo ni nada que haya iniciado, ni un programa de la lista que nunca congela (init, systemd, sshd, sudo, su, login y parecidos, más cualquier nombre que añadas en keep-running), ni un proceso en un terminal en el que alguien inició sesión, ni un arranque que hayas permitido. Una nota nunca detiene un programa. Los detalles dicen cuál de estos motivos mantuvo el proceso en marcha.

Un programa de la lista incorporada solo se respeta donde el sistema guarda sus programas, como /usr y /bin, así que una copia llamada sshd en otra carpeta se congela como cualquier otra cosa. Los nombres que añadas en keep-running coinciden esté donde esté el programa. Un terminal cuenta cuando alguien inició sesión en él: por SSH, en la consola, en tmux o screen, a través de sudo o su, o en una ventana de terminal. Un multiplexor de terminal solo cuenta para root y para las cuentas de personas, numeradas desde UID_MIN en /etc/login.defs (1000 en la mayoría de los sistemas), porque una cuenta de servicio también puede iniciar uno. Un terminal que un programa abrió para sí mismo no cuenta, lo que impide que una shell remota se esconda detrás de uno. Los terminales que abre el servidor remoto de un editor o docker exec tampoco cuentan, así que si Borg congela algo que ejecutaste ahí, C lo deja continuar y A lo permite.

Borg comprueba la identidad de un proceso, su número junto con el momento en que arrancó, justo antes de enviarle una señal, así que un número que otro proceso haya tomado entretanto se queda tranquilo.

Sin más derechos, Borg sabe solo de los procesos de su propio usuario, mirando la lista de procesos cuatro veces por segundo, y la página lo dice debajo de la lista. Un comando breve puede desaparecer antes de la mirada siguiente.

Para saber de cada proceso en el momento en que arranca, instala la parte que corre como root:

Ventana de terminal
borg service watch install

Esto pide tu contraseña una vez e instala una unidad aparte, borg-commander-watch.service, que ejecuta borg --watch-root. Esa parte carga en el kernel unos pequeños programas propios de Borg, que leen cada arranque de programa antes de que el programa nuevo se ejecute: el programa, la línea de comandos tal como se pasó, el proceso que lo inició y el usuario. Un comando que termina al instante se informa igualmente, y también la línea de comandos de un proceso que la reescribe después. La parte root lee /proc para el resto, y detiene, continúa o termina un proceso cuando Borg se lo pide. No hace nada más: la unidad renuncia a todas las capacidades que no necesita, y la interfaz de Borg sigue corriendo como tú. Los dos lados hablan por un socket de la carpeta de estado al que solo llega su propietario, Borg acepta una conexión únicamente de un proceso que corre como root, y la parte root se conecta únicamente a un socket que pertenece al usuario para el que se instaló. borg service watch uninstall la quita, y borg service watch status imprime de dónde vienen los eventos y qué se ha encontrado. La instalación y el estado avisan mientras las alertas no tengan destino (consulta Alertas fuera de la máquina).

Los programas necesitan Linux 5.8 o posterior. En un kernel más antiguo, o donde la parte root no puede cargarlos, escucha los eventos de procesos del kernel y lee todo de /proc, y la página lo indica bajo la lista. Después de actualizar Borg, vuelve a ejecutar borg service watch install para que la unidad reciba los permisos que necesite la nueva versión.

Las alertas de cualquiera de los dos lados son las mismas alertas, en el mismo registro. Un proceso de otro usuario solo lo puede congelar la parte root, así que reanudarlo o terminarlo desde la página pasa por el vigilante del servicio. Cuando nada puede alcanzarlo, la página dice que solo el propietario o un administrador puede hacerlo.

El vigilante es por ahora una función de Linux. En macOS la página se abre y lee su registro, y el origen dice que nada está vigilando.

La página Alertas vive en la máquina que vigila, así que quien se haga con esa máquina puede borrar el registro. Envía cada alerta a otro sitio en cuanto ocurre: una copia que ya llegó queda fuera de su alcance, y el latido te avisa cuando el vigilante se queda callado. Añade [watch.notify] a la configuración del servidor, con cualquiera de estos destinos o con varios. Todas las direcciones usan https://, o http:// hacia el propio servidor:

[watch.notify]
name = "web-01" # how messages name this machine, its host name otherwise
level = "warning" # the least an alert needs to be sent: alert, warning or notice
[watch.notify.telegram]
token = "123456:ABC-your-bot-token"
chat = "123456789"
[watch.notify.ntfy]
url = "https://ntfy.sh/a-long-random-topic"
token = "tk_your_token" # where the topic needs one
[watch.notify.webhook]
url = "https://example.com/borg"
secret = "a long random string"
[watch.notify.heartbeat]
url = "https://hc-ping.com/your-check-id"
minutes = 5

Luego ejecuta borg service watch notify. Envía un mensaje de prueba a cada destino y muestra lo que respondió cada uno.

  • Telegram: crea un bot con @BotFather, que te da el token. Envía un mensaje al bot, abre https://api.telegram.org/bot<token>/getUpdates y toma chat.id de la respuesta.
  • ntfy: suscríbete en la app de ntfy a un tema con un nombre largo que nadie pueda adivinar, o a uno de tu propio servidor ntfy.
  • Webhook: Borg envía cada mensaje a la dirección como JSON. Con secret, cada petición lleva X-Borg-Signature: t=<time>,v1=<signature>: el HMAC-SHA256, con el secreto, de la hora, un punto y el cuerpo, para que tu receptor distinga los mensajes de Borg de los falsificados. X-Borg-Event dice qué es el mensaje: alert, evidence (el SHA-256 del programa y las coincidencias de reglas, que siguen a una alerta cuando Borg ha leído el programa), started, armed o test.
  • Latido: Borg llama a la dirección cada minutes minutos mientras el vigilante funciona y añade /fail cuando algo va mal: el hilo que calcula el hash de los programas se detuvo, un destino lleva 30 minutos sin aceptar mensajes, Borg abandonó uno, o Borg no pudo leer su bandeja de salida. Un servicio como healthchecks.io te avisa cuando las llamadas se detienen, que es lo que ocurre cuando alguien mata al vigilante.

Mientras ningún destino reciba alertas, se quedan en el registro de la máquina, y Borg lo dice allí donde te encuentres con el vigilante. La página Alertas muestra Las alertas se quedan en esta máquina. encima de los detalles de la alerta seleccionada, o en la última fila de la lista cuando está maximizada. Verás la misma línea al activar el vigilante en Opciones → Complementos, en borg service watch install y borg service watch status, y en la salida del servicio cuando arranca el vigilante. Un latido por sí solo no quita el aviso. Te dice que el vigilante está en marcha y no lleva alertas, así que añade también Telegram, ntfy o un webhook.

El aviso se vuelve más fuerte cuando Borg está cerca de actuar. Desde un día antes de que termine el periodo de aprendizaje dice Borg está a punto de congelar procesos aquí y nadie recibirá aviso., y una vez empezada la congelación, Borg congela procesos aquí y nadie recibe aviso. Borg sigue vigilando, aprendiendo y congelando sin un destino para las alertas, así que configura uno antes de que termine el periodo de aprendizaje en una máquina que no revisas a diario.

El servicio envía cada alerta pocos segundos después de anotarla, y también avisa cuando el vigilante arranca y cuando empieza la congelación. Las alertas de nivel nota se quedan en la página salvo que level sea notice. Un mensaje que un destino rechaza espera en watch-outbox.json, en la carpeta de estado, y se reintenta, a los 5 segundos la primera vez y cada 30 minutos como máximo. Borg guarda hasta 500 mensajes en espera, menos cuando los largos harían que el archivo pasara de 16 MiB, e intenta cada uno durante 48 horas. El mensaje siguiente dice cuántos abandonó.

Un mensaje lleva como máximo 1000 bytes de la línea de comandos, de la ruta del programa y del motivo de la alerta. Uno más largo conserva el principio y el final, con puntos suspensivos entre ambos, así que rellenar el principio de un comando no oculta lo que hace.

Cuando Borg encuentra un watch-outbox.json que no puede leer, cambia el nombre del archivo a watch-outbox-unreadable.json y empieza una bandeja de salida nueva. Uno posterior recibe un nombre numerado, como watch-outbox-unreadable (2).json. Los mensajes que esperaban se quedan en ese archivo y nunca se envían, así que el latido falla una vez y dice por qué, y la numeración de cada destino vuelve a empezar en 1. Revisa el archivo y luego bórralo.

Cada destino numera sus mensajes desde 1, y el JSON de cada mensaje lleva en previous el SHA-256 del anterior. Un salto en la numeración, o un previous que no coincide, significa que un mensaje se perdió o se cambió por el camino. La numeración se hace en el servidor, así que no detecta a quien controla el servidor.

Los tokens están en la configuración, que cualquier cosa que se ejecute como tu usuario en el servidor puede leer. Con ellos, alguien puede enviar mensajes que parecen de Borg y seguir la numeración sin saltos, y un bot de Telegram puede borrar lo que envió en las últimas 48 horas. Quien se haga con el servidor también puede borrar los mensajes que aún esperan para salir. Lo que llegó antes queda como estaba, y un webhook a una máquina que controlas lo conserva tal como llegó. Cuando el vigilante se queda callado, es el latido el que te avisa.

El vigilante juzga cada programa cuando arranca, y eso deja algunas cosas fuera de su vista. Conócelas antes de confiar en él.

  • El código que se ejecuta dentro de un programa que ya está en marcha no inicia nada nuevo, así que ninguna regla lo mira. Una aplicación web cuyo propio intérprete ha sido tomado conserva el nombre y el padre de siempre.
  • Los procesos que ya corrían antes de que arrancara el vigilante nunca se examinan, y todo lo que se ejecuta durante la semana de aprendizaje cuenta como normal.
  • Sin el vigilante como root, Borg solo ve tus propios procesos, y un comando que termina en menos de un cuarto de segundo puede desaparecer antes de que Borg mire. Los servicios que se ejecutan como otro usuario, como www-data o postgres, necesitan el vigilante como root. Cuando el vigilante como root se detiene, Borg vuelve a vigilar tus propios procesos hasta que se ejecute de nuevo.
  • Antes de Linux 5.8, o donde la parte root no puede cargar sus programas, Borg lee cada proceso nuevo en /proc después de que el kernel lo informa. Un comando que termina al instante puede haber desaparecido para entonces, y un proceso puede cambiar antes su línea de comandos.
  • Algunos kernels no envían eventos de procesos, como en ciertas máquinas virtuales y entornos de contenedores. Borg ejecutándose como root y el vigilante como root miran entonces todos los procesos cuatro veces por segundo, y un comando breve puede terminar antes de que miren.
  • Una ráfaga de procesos nuevos puede llenar la cola entre el kernel y Borg, y entonces el kernel descarta eventos, así que algunos arranques nunca se examinan.
  • Un comando que terminó antes de que Borg pudiera leer /proc lleva solo lo que leyeron los programas: su programa, su línea de comandos, su proceso padre y su usuario. Su terminal, sus flujos estándar y sus variables de precarga terminaron con él, así que las reglas sobre ellos no pueden activarse. Programa borrado mientras corre solo se activa con él cuando su archivo ya no existía al arrancar, como en un programa ejecutado desde la memoria.
  • Los programas guardan los primeros 4 KiB de una línea de comandos, y Borg toma una más larga de /proc mientras el proceso sigue ahí. Encuentran la línea de comandos y el archivo del programa gracias a la información de tipos que el kernel publica en /sys/kernel/btf/vmlinux. En un kernel compilado sin ella, la línea de comandos también sale de /proc. Un comando que terminó antes se nombra entonces por la ruta con la que se inició, que puede ser relativa a su carpeta de trabajo o pasar por un enlace simbólico, así que Programa en una carpeta temporal puede pasarlo por alto.
  • Cualquier cosa que se ejecute como el usuario del vigilante puede detener el vigilante, cambiar sus archivos en la carpeta de estado o dejar continuar un proceso congelado con kill -CONT. Congelar te da tiempo para mirar, y el dueño del proceso todavía puede deshacerlo.
  • Un proceso en un terminal en el que alguien inició sesión nunca se congela, aunque la sesión usara una contraseña o clave robada. Las reglas siguen disparándose y anotando alertas.
  • Exploración de la máquina cuenta los comandos de un programa en una hora. Quien espera más entre comandos, o ejecuta cada uno desde un programa distinto, se queda por debajo.
  • Un proceso que se separa de su padre antes de que Borg congele al padre sigue en marcha.
  • Sin [watch.notify], las alertas solo te llegan cuando abres la página. Con él, quien se haga con la máquina en los segundos que siguen a una alerta todavía puede frenar el mensaje antes de que salga, y entonces es el silencio del latido lo que te avisa.

Esta guía sigue la rama main · Borg 0.11.0 · 1f6bce6
Puede que la última versión publicada no incluya todo lo que se describe aquí. Notas de la versión

Traducción de la guía en inglés. Las correcciones son bienvenidas. Los comandos y los atajos de teclado no se traducen.