Analizar tareas programadas en el navegador: caso práctico
Paso a paso: cargue XML de tareas, archivos .job y el hive SOFTWARE en un parser gratuito en el navegador, lea tareas ocultas, ajuste la zona horaria y exporte.
Resumen. Recopile System32\Tasks, SysWOW64\Tasks, C:\Windows\Tasks y el hive SOFTWARE (con sus .LOG1/.LOG2), suéltelos, o el ZIP de triaje, en Scheduled Tasks Parser, lea las advertencias, confirme el desfase UTC deducido y recorra los hallazgos: primero tareas solo en el registro, SD ausente y discrepancias de hash; después rutas, comandos codificados, LOLBins y privilegios. Exporte en CSV, JSON o un CSV de cronología. Nada sale del navegador. El caso ficticio de abajo, que es la muestra integrada, ilustra cada paso.
Este es el complemento práctico de la guía de análisis forense de tareas programadas. La adquisición se trata en ubicaciones y adquisición de las tareas programadas.
Qué hace la herramienta y qué no hace
El parser está escrito en Rust compilado a WebAssembly y se ejecuta en un Web Worker dentro de su navegador. Los archivos se leen localmente y nunca se suben. La herramienta:
- lee el XML de las tareas (UTF-16LE, esquema 1.2 y posteriores): RegistrationInfo, todos los tipos de desencadenador, entidades de seguridad, configuración y acciones
Exec/ComHandler/SendEmail/ShowMessage; - lee los archivos
.jobheredados: secciones fija y variable, desencadenadores y hora de la última ejecución tal como está almacenada (SYSTEMTIME local); - lee TaskCache del hive SOFTWARE:
Tree(Id,Index,SDdescodificado a SDDL, hora de última escritura de las claves) yTasks\{GUID}(Path,URI,Author,Date,Hash,Schema,DynamicInfo,Actionsdescodificado, cabecera deTriggersy entidad de seguridad); - correlaciona el XML con TaskCache por ruta, recalcula el hash y marca las tareas que están solo en el registro, solo en disco o sin SD;
- avisa cuando el hive está sucio. No reproduce los registros de transacciones, no recupera claves eliminadas ni analiza registros de eventos.
Los hallazgos son heurísticas para ordenar la revisión, no veredictos.
El caso ficticio
Todo lo que sigue es inventado con fines formativos: el equipo, la cuenta, las direcciones y los archivos no existen, y los comandos son marcadores inofensivos. Es exactamente la muestra que obtiene con Try a sample en la página de inicio, así que puede seguirlo paso a paso.
Una estación de trabajo de finanzas, FIN-WKS-07, configurada en una zona horaria UTC+02:00. El 2026-09-14 salta una alerta por tráfico saliente inusual. Otros artefactos muestran una cuenta que nadie reconoce, svc_backup. La pregunta en esta fase: ¿dejó el intruso tareas programadas y qué hizo entre las 10:00 y las 10:55 UTC?
Paso 1: Recopilar las carpetas de tareas y el hive SOFTWARE
La recopilación sigue la estructura de KAPE, tal como la genera:
kape.exe --tsource C: --tdest C:\triage\kape --target ScheduledTasks,RegistryHivesSystem
El ZIP resultante contiene C/Windows/System32/Tasks (19 archivos XML), C/Windows/Tasks (un archivo .job) y C/Windows/System32/config/SOFTWARE. Una recopilación Windows.Triage.Targets de Velociraptor con los mismos targets funciona igual. Calcule el hash del archivo comprimido antes de empezar.
Paso 2: Cargar los archivos en el navegador
Abra la herramienta y suelte el ZIP. También puede soltar archivos sueltos o una carpeta. El parser recorre el archivo comprimido (estructura de KAPE, o estructura de Velociraptor con rutas codificadas con porcentajes y nombres de entrada con barras invertidas), selecciona los archivos de tareas y el hive SOFTWARE e ignora el resto. Tarda uno o dos segundos.
La barra de resumen de la muestra indica: 21 tareas (19 XML, 1 .job, 16 entradas de TaskCache fusionadas con ellas), 8 marcadas, 1 oculta (sin SD), 1 solo en el registro, 1 solo en XML, 5 registradas recientemente.
Paso 3: Leer las advertencias
Antes de concluir que una tarea «falta», lea las advertencias del parser:
| Advertencia | Significado | Acción |
|---|---|---|
| Hive sucio | Los registros de transacciones contienen cambios que no están en el archivo principal | Reprodúzcalos con una herramienta que tenga en cuenta los logs y vuelva a comprobar las ausencias |
| Sin hive SOFTWARE | Solo se analizaron XML/.job; no es posible comprobar tareas ocultas ni tareas solo en el registro | Recopile el hive |
| Sin carpeta de tareas | Solo se analizó TaskCache | Recopile System32\Tasks |
El hive de la muestra está limpio: no hay advertencia de hive sucio, así que los hallazgos «solo en el registro» y «solo en XML» pueden leerse tal cual. En una recopilación en vivo verá a menudo la advertencia de hive sucio; reproduzca los logs antes de fiarse de las ausencias.
Paso 4: Comprobar la zona horaria
Los valores Date y StartBoundary del XML suelen ser horas locales sin desfase (por qué). El parser compara el Date del XML de cada tarea con el FILETIME UTC de creación en DynamicInfo de la misma tarea y cuenta los desfases que encuentra. Para la muestra indica UTC+02:00 ×4, UTC+01:00 ×1 y aplica +02:00. Dos de las comparaciones:
| Tarea | Date del XML (sin zona) | Creación en DynamicInfo (UTC) | Diferencia |
|---|---|---|---|
\IntelGfxTelemetry | 2026-09-14T12:09:58.4413872 | 2026-09-14 10:09:58 | +02:00 |
\MicrosoftEdgeUpdateTaskMachineCore | 2026-03-02T09:44:22 | 2026-03-02 08:44:22 | +01:00 |
La que se sale de la norma no es un error: el actualizador de Edge se registró en marzo, en horario de invierno (CET, UTC+01:00), y las tareas de septiembre en horario de verano (CEST, UTC+02:00). Por eso un único desfase aplicado a toda una máquina puede ser incorrecto para las tareas más antiguas. En este caso, todas las tareas de interés se registraron el 2026-09-14, así que +02:00 es correcto. A partir de aquí todas las horas se muestran en UTC.
Paso 5: Priorizar los hallazgos
Ordene por gravedad. De las 21 tareas, 13 son tareas corrientes de Microsoft, Office, Edge y sincronización de feeds sin ningún hallazgo. Otras dos están marcadas pero son benignas, y conviene leerlas primero para calibrar:
\GoogleUpdateTaskMachineUA: Elevada, no es de Microsoft. Se ejecuta como SYSTEM y no tiene autor. Así es como se registra el actualizador de Google.\OneDrive Standalone Update Task-S-1-5-21-…-1104: Ruta escribible por el usuario. Su comando está bajo%localappdata%, que es donde reside el actualizador de OneDrive por usuario.
Los hallazgos son pistas, no veredictos. Las seis tareas siguientes son las que importan.
\Microsoft\Windows\UPnP\UPnPHostConfigSync: oculta, sin SD
- Autor: dice ser
Microsoft Corporation, y la tarea está bajo\Microsoft\Windows\para pasar desapercibida. - Registrada a las 10:12:40 UTC (
Datedel XML 2026-09-14T12:12:40.0918251 local). - Entidad de seguridad: SYSTEM,
HighestAvailable. Desencadenadores:LogonTriggery unTimeTriggerdesde las 12:12:40 local, con repetición cada 30 minutos (PT30M). - Acción:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -EncodedCommand VwByAGkAdABlAC0ATwB1AHQAcAB1AHQAIAAnAHMAeQBuAHQAaABlAHQAaQBjACAAcwBhAG0AcABsAGUAJwA=, que el parser descodifica comoWrite-Output 'synthetic sample'(un sustituto de un script real). - TaskCache: la clave
TreetieneIdeIndex= 2, pero ningún valorSD. Su hora de última escritura es 10:13:05 UTC, 25 segundos después del registro. - DynamicInfo: última ejecución 10:42:40 UTC, última ejecución correcta 10:42:41 UTC.
Hallazgos: Oculta: sin SD en TaskCache (crítico), PowerShell codificado (alto), Registrada recientemente. Es el patrón Tarrask: en el equipo en vivo, schtasks /query no la mostraría. La escritura de la clave 25 segundos después del registro es coherente con que el SD se eliminara a las 10:13, lo que además significa que el intruso ya tenía SYSTEM en ese momento.
\IntelGfxTelemetry: ajuste oculto, SYSTEM, ruta escribible por el usuario
- Autor
FIN-WKS-07\svc_backup, descripción "Intel graphics telemetry", carpeta raíz. - Registrada a las 10:09:58 UTC. Entidad de seguridad:
S-1-5-18,HighestAvailable.<Hidden>true</Hidden>. - Desencadenadores:
BootTriggery unTimeTriggerdesde las 12:15:00 local (10:15 UTC), cada hora. - Acción:
C:\ProgramData\Intel\m64.exe -svc. - DynamicInfo: última ejecución 10:15:00 UTC, último resultado
0x00041301(SCHED_S_TASK_RUNNING: el programa seguía en ejecución en el momento de la recopilación).
Hallazgos: Ruta escribible por el usuario, Elevada, no es de Microsoft, Ajuste oculto, Registrada recientemente. A diferencia de la tarea UPnP, conserva su SD: solo está oculta en la vista por defecto de la consola, no para schtasks.
\a8Xq2LmZ: la definición cambió tras el registro
- Nombre de aspecto aleatorio en la raíz, registrada a las 10:21:30 UTC por
svc_backupy ejecutada comosvc_backup(InteractiveToken,LeastPrivilege) al iniciar sesión ese usuario. Actionsde TaskCache:C:\Windows\System32\rundll32.exe C:\Users\svc_backup\Downloads\tools\helper.dll,Init.- XML en disco: el mismo comando con
helper.dll,Start. ElHashde TaskCache ya no coincide con el archivo. - DynamicInfo: última ejecución 10:24:02 UTC.
Hallazgos: XML modificado tras el registro y La acción del registro difiere del XML (alto), LOLBin, Ruta escribible por el usuario, Nombre de aspecto aleatorio, Registrada recientemente. Alguien editó directamente el archivo XML en lugar de volver a registrar la tarea, así que el servicio sigue conservando la versión registrada. Lea ambas: el registro dice qué se registró; el archivo, qué aspecto quería alguien que tuviera después.
\Microsoft\Windows\Maintenance\CleanupTemp: nunca registrada
- Solo el archivo XML: no hay ninguna entrada en TaskCache.
- Autor: dice ser
Microsoft Corporation;Date12:31:05 local (10:31:05 UTC con el desfase +02:00);Hidden=true; entidad de seguridadsvc_backup;TimeTriggera las 12:35 local. - Acción:
C:\Windows\System32\mshta.exe C:\Users\svc_backup\Downloads\tools\cleanup.hta.
Hallazgos: No registrada (medio), LOLBin, Ruta escribible por el usuario, Registrada recientemente. Un archivo dejado en la carpeta Tasks no es una tarea hasta que el servicio lo registra. Como el hive está limpio, la ausencia en TaskCache es significativa: esta tarea se preparó pero, según estas evidencias, nunca llegó a programarse.
\SyncBackup: solo en el registro
- No hay archivo XML en disco; TaskCache conserva
TreeyTasks\{GUID}. Datede TaskCache 2026-09-14T12:44:10.2059113 (local); DynamicInfo: creada 10:44:10 UTC, última ejecución 10:47:12 UTC, última ejecución correcta 10:53:51 UTC, resultado 0.Actionsdescodificado:C:\Users\Public\rclone.exe copy C:\Users\Public\data E:\exfil.- Cabecera de
Triggers: límite de inicio 2026-09-14T12:47:00 local, entidad de seguridad con SID terminado en-1119(svc_backup).
Hallazgos: Falta el archivo XML (alto), Ruta escribible por el usuario, Registrada recientemente. Se borró el archivo pero la tarea nunca se dio de baja, así que seguiría apareciendo en schtasks en el equipo en vivo. El registro es la única definición que sobrevive, y apunta a una herramienta de copia que escribe en E:\exfil, una unidad que conviene identificar.
\Cleanup: un .job heredado
- Archivo:
C:\Windows\Tasks\Cleanup.job, autorFIN-WKS-07\svc_backup. - Comando:
cmd.exe /c del /q C:\Users\svc_backup\Desktop\creds.txt. - Desencadenador: una vez, a las 12:52 local. Última ejecución: 2026-09-14 12:52:30 local (10:52:30 UTC), estado
0x00041305(SCHED_S_TASK_NOT_SCHEDULED: no hay más ejecuciones previstas).
Hallazgos: .job heredado, Ruta escribible por el usuario. Un archivo .job en un sistema moderno ya es inusual de por sí; este borra un archivo del escritorio de la cuenta al final de la sesión, lo que tiene todo el aspecto de una limpieza.
Paso 6: Acotar el intervalo de tiempo y exportar
Abra \SyncBackup y centre el intervalo de tiempo en ella con más o menos 1 hora. La herramienta se centra en la primera hora de la tarea, su registro a las 10:44:10 UTC, así que la ventana va de 09:44:10 a 11:44:10 UTC. La franja de densidad muestra la ráfaga entre las 10:09 y las 10:54; las trece tareas de la línea base desaparecen. También puede escribir Desde 2026-09-14 10:00:00 y Hasta 10:55:00 UTC con precisión de segundos.
Exporte la vista filtrada en CSV, JSON o el CSV de Timeline, cuyas columnas message, datetime y timestamp_desc se importan directamente en Timesketch. La secuencia reconstruida, toda en UTC:
| Hora | Fuente | Evento |
|---|---|---|
| 10:09:58 | DynamicInfo, Date del XML | Se registra \IntelGfxTelemetry (SYSTEM, arranque + cada hora) |
| 10:12:40 | DynamicInfo, Date del XML | Se registra \Microsoft\Windows\UPnP\UPnPHostConfigSync (SYSTEM, PowerShell codificado) |
| 10:13:05 | Última escritura de la clave Tree | SD eliminado de la tarea UPnP (deducido) |
| 10:15:00 | Última ejecución en DynamicInfo | Se inicia m64.exe -svc, todavía en ejecución en la recopilación |
| 10:21:30 | DynamicInfo, Date del XML | Se registra \a8Xq2LmZ (rundll32 helper.dll,Init) |
| 10:24:02 | Última ejecución en DynamicInfo | Se ejecuta \a8Xq2LmZ; el XML se edita después a ,Start |
| 10:31:05 | Date del XML | Se escribe el XML de CleanupTemp, nunca registrado |
| 10:42:40 | Última ejecución en DynamicInfo | Última ejecución de la tarea UPnP |
| 10:44:10 | Creación en DynamicInfo | Se registra \SyncBackup |
| 10:47:12 a 10:53:51 | DynamicInfo | Copia con rclone a E:\exfil: última ejecución y última ejecución correcta |
| después de 10:44 | XML ausente | Se borra el archivo XML de \SyncBackup |
| 10:52:30 | Última ejecución del .job | Cleanup.job borra un archivo del escritorio |
Próximos pasos fuera de esta herramienta: confirmar la ejecución de m64.exe, rclone.exe y rundll32.exe con Prefetch y Amcache, buscar los eventos 4698/106 y 200/201 en los registros de eventos, identificar el volumen E:, recuperar helper.dll y cleanup.hta y averiguar cómo obtuvo svc_backup privilegios de SYSTEM. La lista de indicadores en la que se basan estos hallazgos está en cómo detectar tareas programadas maliciosas.