Open Mobile Menu


Kali in EC2 with Docker

Views: 4481

Written By: Stephen Haywood October 13, 2016

We often have a need to run a Kali image in an EC2 environment and Offensive Security no longer maintains a Kali AMI. While it is possible to create a Kali image from a Debian image, it is not recommended nor is it supported. The officially supported method for running a current Kali box in EC2 is to use the Kali Docker image on the OS of your choice. I am a fan of Debian-based systems so I chose to build our Kali system on Ubuntu. Below are the steps we use to build the Kali system, along with a link to a script to make it easier, and the basic usage instructions. Since Kali is running in a container, using it is a bit different than you may be used to.

Building Docker

  1. Build a new Ubuntu 14.04 instance that has t2.medium specs or higher.
  2. Configure the root drive to be 40GB.
  3. Configure the Security Group and SSH key to match your normal settings.
  4. Access the new instance via SSH and copy this script to it.
  5. Run the script and when it is finished you will have a Kali Top 10 Docker image.

Running Docker

Once the Docker setup is complete, you can access the Kali server by running:

     sudo docker run --net=host -it kali:v1 /bin/bash.

This will give you a root shell in Kali just like you typically have. If you are doing any work that does not need to be saved on the Kali image, such as running fierce, theHarvester, dirb, etc, then you can exit the Docker image when you are finished and there is nothing else to do. Each time you need Kali, just run the above command.

However, if you are running a tool like Metasploit and loading Nmap scans into the database, you will want those changes to persist the next time you run the Kali image. To do that you will need to create an updated Kali image using the commands below. The next time you need Kali, you will run the same command as above but you will use the new image name you create. 

Saving an Image

If you need your data to persist, then immediately after exiting Docker, run the following command where N is simply the next highest number. This will create a new Docker image with the name kali:vN. This will take a bit of time and will produce a SHA256 hash of the new image when it is finished.

     sudo docker commit $(sudo docker ps -lq) kali:vN

To run this saved image, use the following command where N is the same number you used above, which will be the last version you created.

     sudo docker run --net=host -it kali:vN /bin/bash

Deleting an Image

Keep in mind that the base system you installed has a 40 GB hard drive and each Kali image you save will take up at least 4GBs so you may have to delete some older images. To do that, use the following commands:

     sudo docker images -a

The output will look something like this:

You can then delete an image using the following command:

     sudo docker rmi <image_id>

Mounting A Host Volume

Docker provides a way to copy files from a container (the latest run of an image) to the host using the cp command, which you can read about here:

The easiest thing to do is to mount a host volume into the container and save all of your data there. To do this:

  1. Create a new directory in the /home/ubuntu folder on the host:
  2. mkdir /home/ubuntu/client
  3. Run the Docker container as above but use the -v command to mount the volume:
     sudo docker run -v /home/ubuntu/client:/root/client --net=host -it kali:vN /bin/bash.

Using a mounted volume may prevent the need for saving images as often. For example, if you run an Nmap scan and save the data to the client folder, then there is no need to save the image of the container because you have the data saved on the host. If you are loading the data into Metasploit in the Docker container, then it would be necessary to save the image each time you exit to ensure the Metasploit database is persisted.

Quick Note on Metasploit

If you start the Docker image with --net=host, the su command will not work properly, which means the msfdb init command will not work properly. Start the Docker image without --net=host, run msfdb init, then save the image. After that you can launch Docker with --net=host, start the postgresql server, then launch msfconsole.

Stephen Haywood

Stephen Haywood, aka AverageSecurityGuy, is a Senior Penetration Tester with AppSec Consulting with 14 years of experience in the Information Technology field working as a programmer, technical trainer, network operations manager, and information security consultant. He holds a Bachelor of Science in Math, the Certified Information Systems Security Professional (CISSP) certification, the Offensive Security Certified Expert (OSCE) certification, and the Offensive Security Certified Professional (OSCP) certification. Over the last eight years, he has helped improve the network security of many small businesses ranging in size from ten employees to hundreds of employees by offering practical, time-tested information security advice.

In his off hours, Stephen created a number of security tools including the Prometheus firewall analysis tool and a set of penetration testing scripts used by testers worldwide. In addition, Stephen has made multiple contributions to the Metasploit exploitation framework including, auxiliary, exploitation, and post exploitation modules. Finally, Stephen created and delivered high-quality security training, spoke at multiple security conferences, and self-published an introduction to penetration testing book.

read more articles by Stephen Haywood