This compilation of open-source tools aim to provide resources you can use for some of the step of the secure development life cycle of your organization, ie:
Environment variables are great to configure and change the behavior of your applications, however there’s a downside for that, if someone uses the `docker inspect` command your precious secrets will get revealed there, because of that you should never pass any sensitive data to your container using environment variables (the `-e` flag), I’ll show you an example.
Suppose you have a simple python application (Download the source code of the app here: https://github.com/Alevsk/docker-containers-env-vars-security ) that returns the hmac signature for a provided message using a configured secret, the code will look like this:
app_secret = os.environ.get('APP_SECRET')
if app_secret is None:
app_secret = ""
# derive key based on configured APP_SECRET
salt = binascii.unhexlify('aaef2d3f4d77ac66e9c5a6c3d8f921d1')
secret = app_secret.encode("utf8")
key = pbkdf2_hmac("sha256", secret, salt, 4096, 32)
app = Flask(__name__)
@app.route("/")
def hello():
message = request.args.get('message')
if message is None:
return "Give me a message and I'll sign it for you"
else:
h = hmac.new(key, message.encode(), hashlib.sha256)
return "<b>Original message:</b> {}<br/><b>Signature:</b> {}".format(message, h.hexdigest())
if __name__ == "__main__":
app.run()
Pretty straightforward, then you build the docker image with:
docker build -t alevsk/app-env-vars:latest .
And run the application on a container with:
docker run --rm --name hmac-signature-service -p 5000:5000 -e APP_SECRET=mysecret alevsk/app-env-vars:latest
Test the endpoints works fine running a `curl` command:
Additionally, you can get the `process id` of the app inside the container (`1869799` in this case) and then look at the content of the `/proc/[pid]/environ` file and your application secret will be there too.
Mount secret file to the container and read from there instead
You can fix that by doing a small change in the application source code, mainly how the application reads the secret, this time instead of reading from the `APP_SECRET` environment variable the app will read from a file located at `/tmp/app/secret`.
secret_path = "/tmp/app/secret"
app_secret = open(secret_path).readline().rstrip() if os.path.exists(secret_path) else ""
Build the docker image and run the container mounting the secret file.
Also, if you exec into the container by running `docker exec -it hmac-signature-service sh` the `APP_SECRET` environment variable is not there, nor in the `/proc/1/environ` file or in the `printenv` command output.
What if I cannot change the source code of my application?
In case you don’t have access or cannot change the source code of the application not all is lost This time, instead of passing the `APP_SECRET` environment variable via docker `-e` flags, you will mount a `secret` file directly into the container and then modify the container entry point to source from that secret file.
The `secret` file will contain something like this:
However `APP_SECRET` will still be visible inside `/proc/[container-parent-pid]/environ` (requires to be inside the container or root privileges on the machine running the container)
Takeaway
Environment variables are great but the risk of leaking secrets is just not worth it, if you give access to the docker command to somebody on your system that person can pretty much look what’s running inside the container by running the docker inspect command (having docker access is equivalent to have root access on the system anyways), because of this reason it’s preferable that applications read configurations and secrets directly from files and to leverage on the OS file system permissions.
I have been using Mac OSX for development for half a decade now, I love the macbook pro design, the operating system and that everything works out of the box, but I’ve always struggled with the fact that once you got your mac you “cannot” upgrade its components, that is a problem if you are a distributed systems engineer and the projects you are working on increase in complexity (ie: adding new services), of course you can always rent a big machine on the cloud but sometimes you just don’t have an Internet connection.
Anyway this blog post it’s about how can you transfer docker images between docker registries on different machines, currently I’m using a 15 inches 2019 Macbook pro with 16GB of Ram and when I open a couple of Chrome windows, IntelliJ and run a couple of services everything start to run very slow. I need more power.
So a couple of weeks ago I got the Lenovo X1 Extreme Gen 2 with 6 cores and 64GB of Ram, powerful enough, this laptops come with Windows preinstalled and you can even play videogames on them, but the main goal was to leverage the resources to the Macbook pro and I was not planning on switching machines right now, I love Linux, I use it every day but I still think the Linux desktop experience isn’t great yet, so the first thing I did was to install PopOShttps://pop.system76.com/ a distro based on Ubuntu.
Once you have ssh access enabled, and docker installed with a couple lines of bash you can start transferring docker images between your machines.
Let’s say you have a docker image called minio/minio:edge in your local registry and want to use it in your remote machine (and you don’t want to use the docker public registry for that), first you will need to export the image as a TAR file:
docker save -o /tmp/minio.tar minio/minio:edge
Next is transfer the file to the remote machine using scp.
Se acabó el 2016 y como ultima publicación del año les traigo un tutorial exprés que involucra docker y seguridad informática. En publicaciones anteriores explicaba que durante estos últimos meses he estado trabajando bastante con docker, orchestration e infraestructura de cloud en general (parte habitual en un trabajo de full stack engineer).
Docker es una herramienta muy poderosa para desarrolladores pues nos ayuda a construir imágenes con todas sus dependencias y nos deja el paso libre para enfocarnos en lo que realmente importa: deployar rápidamente una aplicación (o varias) que sabemos que va a funcionar.
Bajo esa premisa no es de extrañarse que la comunidad de seguridad haya adoptado docker tan rápidamente, docker es una herramienta fantástica 🙂 y así como nos permite dockerizar una aplicación también podemos dockerizar herramientas de seguridad y en general cualquier cosa que tengamos en nuestro arsenal para pentest.
La gente que trabaja o ha trabajado en seguridad, específicamente en el área de penetration testing, estará de acuerdo en que uno de los recursos más importantes que tenemos son las ventanas de tiempo, por lo general cuando se realiza una prueba de penetración a alguna aplicación o sistema se hace durante un periodo de tiempo bien definido, el tiempo es valioso y no podemos desperdiciarlo en instalar y configurar herramientas, o peor aun ¿que pasa si la infraestructura que estamos auditando nos bloquea? ¿cuánto tiempo vamos a invertir en preparar un nuevo nodo desde donde podamos lanzar ataques y recibir shells?, para todo lo anterior llega docker al rescate 🙂
En este tutorial mostraré como ejecutar una de las herramientas de seguridad más populares utilizando docker: metasploit, específicamente utilizaremos el módulo exploit/multi/handler para recibir sesiones de meterpreter.
ojo: no voy a mostrar como dockerizar metasploit, eso lo dejamos para un siguiente tutorial donde veamos como dockerizar aplicaciones
Ejecutando metasploit desde un contenedor de docker
Para evitarte el problema de abrir los puertos en tu router y hacer un mapeo de puertos para exponer tu maquina a internet, puedes contratar un vps con algún proveedor de tu elección, hoy en día es muy sencillo contratar un vps y puedes tener uno en línea prácticamente en minutos, yo recomiendo digitalocean por qué sus vps son baratos y el soporte es muy bueno, con un nodo de 10 USD al mes es suficiente para correr una imagen de metasploit, puedes contratar el de 5 USD pero tendrás que habilitar el swap o si no quieres gastar dinero siempre puedes aprovechar la promoción que te ofrece Amazon Webservices (más o menos 1 año de uso gratuito de una instancia micro)
Sea cual sea el proveedor que hayas elegido el siguiente paso es instalar docker en tu instancia, para este tutorial lo haré sobre ubuntu / debian pero podrías instalarlo en el sistema operativo de tu elección, acá tienes una lista de sistemas operativos soportados
Desde la terminal de tu instancia y como root vamos a ejecutar algunos comandos para instalar herramientas necesarias como compiladores de gcc/g++, algunas librerías, utilidades, etc. al final vamos a instalar docker
Lo siguiente que vamos a hacer es crear un directorio en nuestra instancia, este directorio lo vamos a utilizar como un volumen persistente cuando ejecutemos metasploit desde el contenedor para poder almacenar ahí todo el loot, scripts y en general archivos que nos genere la herramienta.
mkdir /root/.msf4
Llego el momento, en el docker registry oficial existe una imagen llamada remnux/metasploit que contiene todo lo necesario para ejecutar la herramienta, ejecutamos el siguiente comando y docker comenzara a descargar la imagen y posteriormente procederá a correr el contenedor.
En el tutorial de docker anterior explicaba para que era cada parametro, en resumen -p nos permite mapear puertos y -v definir volúmenes persistentes (mapear una carpeta de nuestro sistema de archivos a una del sistema de archivos virtual del contenedor).
Una vez la imagen haya sido descargada el contenedor será creado y todas las dependencias necesarias comenzaran a ser instaladas, nos olvidamos de instalar todas las gemas y resolver conflictos y nos podemos ir por un café ya que es un proceso bastante automatizo 🙂
Después de unos minutos tenemos un nodo listo para recibir conexiones.
En el caso de necesitar más listeners no hay problema pues podemos ejecutar múltiples contenedores de metasploit en diferentes puertos y así tener nuestras shells organizadas, y si nuestro servidor es baneado rápidamente podemos desplegar otro ejecutando esos 6 comandos.
Como lo he comentado en varios artículos, docker es una herramienta muy poderosa que puede ser utilizada en varias situaciones además del desarrollo de software, como lo vimos en este tutorial. Puedes dockerizar casi cualquier cosa, yo en lo personal tengo una imagen con un set de herramientas que utilizo en mi día a día (fierce, dirb, sqlmap, nmap, enum4linux, hashcat, Responder, etc.)
En el artículo anterior comenzamos con una breve introducción a docker, vimos su instalación, configuración e incluso lanzamos un par de servidores web nginx usando contenedores, en esta ocasión explicare un poco más acerca de los puertos y los volúmenes.
Puertos
Ok, lo primero que explicare será el mapeo de puertos, abrimos una terminal y ejecutamos el siguiente comando:
$ sudo docker run --name servidor-web -p 80:80 nginx
El parametro –name sirve para asignarle un nombre al contenedor.
El parámetro -p sirve para realizar el mapeo de puertos y recibe una cadena en el formato PUERTO-HOST:PUERTO-CONTENEDOR, es decir, del lado izquierdo definimos el puerto que nuestro sistema operativo le asignara al contenedor de docker y del lado derecho el puerto en el que realmente se ejecuta el servicio dentro del contenedor, en este caso nginx (suena un poco confuso al inicio así que regresa y léelo de nuevo hasta que lo entiendas)
En el comando anterior estamos mapeando el puerto 80 de nuestra computadora con lo que sea que este corriendo en el puerto 80 del contenedor, es por eso que si vamos a http://localhost veremos el servidor web en ejecución 🙂
En la consola desde donde ejecutaste el comando podrás ver las peticiones hechas al servidor dentro del contenedor.
Al ejecutar el comando y correr el contenedor abras notado que la consola se queda bloqueada por el servidor web, para evitar eso podemos correr el contenedor en modo detach con el parámetro -d, esto ejecutara el contenedor en segundo plano.
$ sudo docker run -d --name servidor-web -p 80:80 nginx
Observa como tan pronto como ejecutamos el comando docker nos devuelve el control de la terminal, cuando ejecutas contenedores de esta forma no olvides que para eliminarlos primero tienes que recuperar su id, el cual puedes obtener haciendo:
$ sudo docker ps
y en la primera columna encontraras el ID del contenedor que después deberás de eliminar usando sudo docker rm [CONTAINER-ID], si lo prefieres un tip muy útil para borrar todos los contenedores que hayas creado es ejecutar:
$ sudo docker stop $(sudo docker ps -a -q)
$ sudo docker rm $(sudo docker ps -a -q)
El primer comando detiene todos los contenedores que estén en ejecución y el segundo los elimina todos (no puedes eliminar un contenedor que este en ejecución).
Puedes correr todas los contenedores que quieras (o necesites) de nginx en diferentes puertos y con diferentes nombres y cada uno será una instancia completamente diferente del servidor web 🙂
Observa como cada uno de los servidores web corren en un puerto diferente.
Volúmenes
Los volúmenes en docker pueden ser definidos con el parámetro -v y nos ayudan a resolver el problema de la persistencia de datos en los contenedores, un volumen puede ser visto como un mapeo entre un directorio de nuestra computadora y un directorio en el sistema de archivos del contenedor, regresemos a nuestro contenedor de nginx, ¿cómo le hacemos para mostrar un sitio web en nginx en lugar de la página por default?
Lo primero que haremos será crear una carpeta en donde colocaremos el código fuente de nuestro sitio web html (por ahora no trabajaremos con nada dinamico), por ejemplo website
Ejecutamos el siguiente comando mapeando el contenido de /home/alevsk/dev/sitio-web hacia /usr/share/nginx/html que es el directorio por default que utiliza nginx para servir contenido a Internet.
La próxima vez que visitemos http://localhost/ veremos nuestro sitio web corriendo.
Puedes replicar este contenedor con el contenido del sitio web tantas veces como quieras, es muy util en un escenario donde necesitas varios ambientes para pruebas, desarrollo, etc.
Eso es todo por ahora, en el siguiente tutorial aprenderemos a crear nuestras propias imágenes de docker (dockerizar aplicaciones), después de eso veremos otra herramienta bastante útil llamada docker-compose para facilitar la orquestación de aplicaciones que utilizan múltiples contenedores.
Saludos y happy hacking.
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.AcceptRead More
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.