Mutex nombrados como IOC en ciberseguridad

Relacionado: IDOR. ARIN. Forense de memoria de sistema completo. 2025 02 20 Seguridad iOS memoria permisos y sandboxing. Sistema de Gestion de la Seguridad de la Informacion.

1. Qué es un mutex( Semaforos) nombrado

Un mutex (mutual exclusion object) es un mecanismo que garantiza que solo un proceso o hilo acceda a un recurso compartido a la vez.
Un mutex nombrado se registra en el sistema operativo con un nombre único, lo que permite que diferentes procesos puedan encontrarlo y manipularlo.


2. Por qué el malware los usa

  • Evitar reinfección: El primer proceso del malware crea el mutex; si otro proceso intenta crearlo y ya existe, significa que la máquina ya está infectada, por lo que se cierra.

  • Sincronizar módulos: Si varios componentes del malware acceden a un mismo archivo o memoria compartida, usan el mutex para evitar conflictos.

  • Persistencia temporal: El mutex existe mientras el malware esté activo, pero no deja rastro en disco.


3. Ventajas como IOC

  • Muy específico: El nombre del mutex suele ser único para esa campaña.

  • Difícil de falsificar por accidente.

  • Detectable en memoria sin necesidad de analizar el disco.

  • No requiere privilegios especiales para crearlo o leerlo.


4. Cómo detectarlo

  • Windows:

    • Volatility con el plugin mutantscan en un volcado de memoria.

    • Process Explorer o Process Hacker → pestaña Handles → buscar tipo Mutant.

  • Linux:

    • Comandos IPC (ipcs -s) o inspección de memoria compartida.
  • MacOS:

    • DTrace, lldb o inspección de IPC.

5. Ejemplos reales

  • Zeus Banking Trojan → Mutex: Global\{5D2B5F39-3DCA-4E3A-A95F-2FC30DF6A982}

  • WannaCry → Mutex: Global\MsWinZonesCacheCounterMutexA


6. Diferencia con otros IOCs históricos

  • Gusano de Morris (1988) → Usaba puertos abiertos como IOC (visible en red).

  • Malware moderno → Prefiere mutex y objetos de sistema (visible en memoria).


7. Ejemplo en Java de semáforo/mutex con nombre

En Java no existe un mutex nombrado a nivel del sistema operativo como en C/WinAPI, pero se puede simular usando un FileLock o un mecanismo de ServerSocket para que varios procesos se coordinen por un identificador compartido.

Aquí un ejemplo con FileLock que actúa como un “mutex global”:

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
 
public class NamedMutexExample {
    public static void main(String[] args) {
        try {
            // Usamos un archivo como identificador del "mutex"
            File lockFile = new File(System.getProperty("java.io.tmpdir"), "MUTEX_MALWARE.lock");
            RandomAccessFile raf = new RandomAccessFile(lockFile, "rw");
            FileLock lock = raf.getChannel().tryLock();
 
            if (lock != null) {
                System.out.println("Mutex adquirido. Continuando ejecución...");
                Thread.sleep(10000); // Simula trabajo
                lock.release();
                raf.close();
                System.out.println("Mutex liberado.");
            } else {
                System.out.println("Otro proceso ya tiene el mutex. Saliendo...");
                raf.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Sí, puede ser un problema… si cada uno “bloquea” a su manera. La solución es usar el mismo mecanismo de bloqueo del SO en ambos lados. Así evitas condiciones de carrera cuando C y Java compiten por el mismo archivo.

En Linux/Unix, lo más seguro es que tu proceso en C use fcntl (bloqueos asesorados) y tu proceso en Java use FileChannel.lock() / tryLock() de NIO. Esos dos sí son interoperables porque Java se apoya en fcntl debajo. Evita flock en C si quieres interoperar con Java, porque flock y fcntl no siempre se ven entre sí. Asegúrate de bloquear la misma región (normalmente todo el archivo), abrir la misma ruta y liberar el lock al terminar. Ojo con NFS: los locks pueden ser poco fiables salvo que el servidor soporte bien lockd.

Ejemplo mínimo en C (POSIX, bloqueando todo el archivo con fcntl):

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
 
int main() {
    int fd = open("/tmp/data.bin", O_RDWR | O_CREAT, 0666);
    struct flock lk = {0};
    lk.l_type = F_WRLCK;      // bloqueo exclusivo (escritura)
    lk.l_whence = SEEK_SET;
    lk.l_start = 0;
    lk.l_len = 0;             // 0 = hasta EOF (todo el archivo)
 
    if (fcntl(fd, F_SETLKW, &lk) == -1) { perror("lock"); return 1; }
    // … trabajar con el archivo …
    sleep(5);
 
    lk.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &lk);
    close(fd);
    return 0;
}

Ejemplo equivalente en Java (NIO FileLock):

import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
 
public class CrossProcLock {
    public static void main(String[] args) throws Exception {
        try (RandomAccessFile raf = new RandomAccessFile("/tmp/data.bin", "rw");
             FileChannel ch = raf.getChannel()) {
 
            try (FileLock lock = ch.lock(0L, Long.MAX_VALUE, false)) { // false = exclusivo
                // … trabajar con el archivo …
                Thread.sleep(5000);
            } // se libera al cerrar
        }
    }
}

En Windows, Java NIO mapea FileLock a los locks del sistema (LockFile/LockFileEx). Si tu parte en C usa CreateFile y luego LockFileEx sobre la misma región, interoperará con Java. Cuida los flags de CreateFile (sharing) para no bloquearte a ti mismo.

Buenas prácticas rápidas: usa “bloqueo → escribe/lee → fsync/flush si toca → libera”; evita copiar a medias usando un patrón atómico (escribe a archivo.tmp, fsync, luego rename a destino) si varias apps consumen el fichero; y si necesitas algo más robusto que ficheros, valora SQLite o un daemon que serialice el acceso.
Si quieres, te dejo también el snippet de Windows en C con LockFileEx para que lo emparejes con el de Java.