Dockers
Basic Intro To Dockers
Dockers containers are used for virtualization purposes for speed, flexibility, and security. They are much like virtual machines in that they run separately, but with the exception that dockers use the same kernel as the main OS in addition to the same RAM and CPU resources.
Containerization
By definition, it is the process of packaging an application and the necessary resources (such as libraries and packages) required into one package named a container to make it portable and run faster.
Benefits of Containerization
Security: by isolating the application and its dependencies into a single package or container, if a container is compromised other containers will stay unaffected.
Convenience: applications packaged into containers will have their dependencies and necessary components packaged with them which means they will run on any OS as long as the OS supports containerization engine or #Dockers.
The role of Dockers
Dockers form a platform for these containers, which are packaged with applications to be deployed, managed, and shared easily.
Definitions
#DockerEngine is essentially an API that runs on the host operating system, which communicates between the operating system and containers to access the system's hardware (such as CPU, RAM, networking, and disk). Docker Engines allow you to connect Dockers together, export and import containers, and transfer files between the containers and the main OS.
#DockerContainer: Containers are made to run independently of other processes, using only the resources they need. This means that containers only use the amount of memory, processing time, and disk space required for the program and do not interact with one another or the host operating system.
#DockerHub: Users can create, store, manage, test, and distribute Docker images using the cloud-based registry known as Docker Hub.
#DockerImages : A Docker image serves as a template for constructing containers. Using the build command, one can produce Docker images. Compared to virtual machines, Docker images are smaller and more efficient.
Docker significantly more quickly and use a lot less storage.
#DockerRegistry : All Docker images are kept in the Docker Registry. Users can utilize a public registry like Docker Hub or a local registry on their computer.
How Dockers Are Built?
Docker uses the programming syntax YAML. to allow developers to instruct how a container should be built and what is run. This is a significant reason why Docker is so portable and easy to debug. By sharing the instructions and the commands, dockers can be built and run on any device. All instructions are stored in the images which dictate how the container will be built and deployed that's why docker containers are shared using images
Building a Docker Container
To build a docker container, we need the docker image which we can either pull or build by eventually building what's called the DockerFile which contains the instructions that the docker executes when it's run.
Creating a DockerFile
To get started with Dockerfiles, we need to know some basic syntax and instructions. Dockerfiles are formatted in the following way:
INSTRUCTION argument
#Example-DockerFile The below dockerfile does the below
Use the "Ubuntu" (version 22.04) operating system as the base.
Set the working directory to be the root of the container.
Update the APT repository
Install apache2
Run Apache2 web server'.
FROM
specifies the operating system that we want to use WORKDIR
sets the working directory of the docker RUN
executes a command EXPOSE
Specifies the port CMD
specifies what command is run when the container starts.
Building The Docker with the Image
After we have created an image, we can then proceed and build a docker container
-t
is used to name the docker container
.
specifies the path to the Dockerfile that we built above.
Running Docker Containers
Back to the above example, we can run Docker after we have built it with the below command
Running Docker Containers
Back to the above example, we can run the docker after we have built it with the below command
-d
specifies a name for the docker.
Now lets go back to basics and understand the basics of running docker containers
The general syntax to run a docker container is below
#example
The command above runs the container named nginx by using the options -it
to interact with the container and the command /bin/bash
to spawn a shell once the container is run. We can verify that we have successfully launched a shell because our prompt will change to another user account and hostname. The hostname of a container is the container ID (which can be found by using docker ps
).
The below command runs the container in the background which is called the detached mode
The below command binds a port for the docker to listen on. You would use this instruction if you are running an application or service (such as a web server) in the container and wish to access the application/service by navigating to the IP address.
The below command removes the docker once it has finished running.
Once you finished running the container, you can view a list of the running and stopped containers using the below command
The above command reveals the following about a running container
The container's ID
What command is the container running
When was the container created
How long has the container been running
What ports are mapped
The name of the container
Downloading and running a ready docker image file
We need two items:
The container image name: for example an image name could be nginx
The tag: the tag is used to specify different variations of an image. For example, an image can have the same name but different tags to indicate a different version. When specifying a tag, you must include a colon
:
between the image name and tag
For example:
The above command retrieves a container image name ubuntu with its tag latest to specify the latest version
This command will pull version 22.04 of the “ubuntu” image.
Then you follow the above steps to build and run the docker image.
Auditing Docker Images
To list all images stored on the local system in addition to verifying if an image has been downloaded correctly and to view a little bit more information about it, we use the below command
Removing a docker image
The output of the list command above will help you in determining the name and tag of the image that you want to remove.
Running and Building Multiple Containers Together
Docker Compose allows us to create multiple containers as "microservices" as one singular "service" to run more dynamic and complex applications such as an apache webserver and a mysql database because more often than not, applications require additional services to run, which we cannot do in a single container. Docker Compose is the solution for that.
Installing Docker Compose
Please check the documentation below to view to install Docker Compose
docker-compose.yml_
This file is extremely important for efficient deployment, management and running of multiple docker containers all together at once. Check out the documentation below on examples and instructions on creating this file
It is important to note that YAML requires indentation (a good practice is two spaces which must be consistent).
Scenario
Lets assume we want to run an ecommerce website that uses mysql database. We need more than one container therefore we choose docker-compose.
First we care the YAML config file docker-compose.yml
Version This is placed at the top of the file and is used to identify what version of Compose the docker-compose.yml is written for. Services This instruction marks the beginning of the containers to be managed. build This instruction defines the directory containing the Dockerfile for this container/service. In the above file the Dockerfile name is apache2 networks This instruction defines what networks the container will be a part of. ports This instruction publishes ports to the exposed ports (this depends on the image/Dockerfile).
Once finished creating the docker-compose, we can proceed and run with the command below
Or both can be run in one command.
To stop the containers
To stop and delete
Dockers vs Virtual Machines
Docker looks similar to virtual machines, but the difference is that it runs directly on the kernel of the host by virtualising the OS and not on the hardware. Docker Service runs on the host itself and Containers runs on top of it. Virtual machines are considered more secure since they are more isolated and have their own operation system. environment
This instruction is used to pass environment variables i.e. passwords,usernames,etc.
The concept of Docker Penetration Testing
How Dockers Get Compromised?
Usually attackers will compromise a container through the external facing application. If it is a web application, it can be exploited in the same way as other web applications. So basically attackers will compromise the software/service/application running within a specific container using traditional tools(attack methods/procedures and then leverage the attack by little modification to exploit the internals of an application.
If an attacker managed to exploit a web application running inside a container and get a shell access, the exploitation and access will be limited to that container environment alone and may not lead to the exploitation of the container's host. Sometimes this single/monolithic environment will provide post-exploitation opportunities for the attackers just like how they will do it in the traditional network.
Important remarks before you start
Every docker container has an ID and you will need this ID when you want to enumerate the container
Indications of a docker container
Usually we get shell on a system we wanna know if we landed on a docker environment.
.dockerenv
file in the root file systemThe user/directory of the user, permissions showing ls instead of names
In the user's home directory, some of them or all of them, don't exist in /etc/passwd which means that the home directory was mounted from the host. You can confirm by issuing the below command
You find docker in the process list
The word docker exists when you display the contents of cgroups
Enumeration of the docker containers
Local Dockers
These type dockers you find when you first get a foothold on the machine. Usually the below methods are used to escalate your privileges.
Writable docker socket
We check if /var/run/docker.sock is writable and by whom. Also we check the running processes and see if the docker is listening on a port. The aim is to escape the docker and dump the root file system
listing docker images
executing commands
executing reverse shell
Basic Info Gathering
This includes version of the docker, settings, networking information, processes running the containers and listing docker images
Check Docker Version:
This command displays the Docker version along with client and server information. It helps in identifying the installed version of Docker to ensure compatibility with Docker images and containers.
Display Docker System Information:
This command provides a comprehensive overview of the Docker system, including the number of containers and images, storage driver, kernel version, system status, and more. It's useful for getting a snapshot of the current Docker environment.
List Docker Networks:
This command lists all networks created on the Docker host. Docker networks facilitate communication between containers, and viewing existing networks can help manage container connectivity.
List All Containers:
This command shows all Docker containers, both running and stopped. It provides details such as container ID, image used, creation time, and status. This is crucial for container management, allowing users to see the state of all containers on the system.
List Docker Images:
This command lists all Docker images available on the local system. Docker images are the basis of containers, and this command helps in managing images, including identifying unused or old images that may need cleanup.
Basic Docker Operations
This includes installing a docker (downloading the docker images, getting a shell inside a specific container, updating a container, exporting a container, exporting an image, stop running a certain container, removing a container, and removing an image and
Install Docker:
Enable Docker to start on boot:
Start Docker service:
Download the Alpine image from a private registry:
Access the shell inside a running container:
Replace
<containerid>
with the actual ID of your container.Commit changes made in a container to create a new image:
Replace
<containerid>
with the container's ID andname-container
with your chosen name for the new image.Export an existing Docker image to a tar file:
Replace
<image>
with the name or ID of the image you wish to export.Stop a running container:
Replace
<containerID>
with the ID of the container you want to stop.Remove a container by its ID:
Replace
<containerID>
with the ID of the container you wish to remove.Remove a Docker Container:
Replace
<containerID>
with the actual ID of the container you wish to remove. This command deletes a stopped container from your system. It's important to note that you cannot remove a running container without stopping it first or using the-f
(force) option withdocker rm
.
Find IP Addresses of docker containers
To find the docker ip address, you need to perform a quick ping sweep scan on the main interface ip address
Port scan for docker containers
Perform a quick port scan on the docker ip
Enumerating the docker image
Inside every container image is a [manifest.json] file which represents the container image layers. It also
contains configuration information that were used when the container image was first built.we can view this file using the [jq] tool for neat printing of its contents. Make sure you are inside the directory to which you have extracted the image container file [tar]
You can inspect other configuration files you found in the manifest.json using the same method with [jq]. The configuration files can be found at the same directory where you have extracted the [tar] file.
Retrieving potential secrets from environment variables
Once inside the container, you can enumerate values stored inside the environment variable as it may contain secrets.
Docker Containers Vulnerabilities Docker Registry Exploitation
Goal
The goal of exploiting docker registries is grabbing the manifest file which contains valuable information about the application such as size, layers in addition to the [history] section that may reveal commands and credentials that were used when the docker image was first built and run.
Definition
At their core, Docker Registries serve as repositories for published Docker images. Creators of Docker images can easily switch between different iterations of their apps and share them with others by using
repositories. Although there are public registries like DockerHub, many Docker-using organizations have their own "private" registry.
Discovery
Docker registries run on port 5000/7000 by default but this can be changed. If you found these ports in your Nmap scan it means Docker registry is running on the target.
Enumeration
We can interact with Docker registry using several tools
1- Postman[https://www.postman.com/downloads/]
2- Insomnia[https://insomnia.rest/download/]
Listing all stored repos in the docker registry We send a GET request to the target domain on the port the docker registry is listening on.
Listing the associated tags with the selected repo
From the last step, we will have listed all the repositories published on the Docker registry of the target. In order to interact with a specific repository we need its tag that specifies version requirements.
Lets say one of the repositories name is [web/app]. then to list the tags we send the below GET request.
Grabbing the Manifest File
The manifest file contains various pieces of information about the application, such as size, layers and other information so it forms a useful piece of information to get a hold of. We can retrieve the manifest file with the below GET request after having selected the repository and the tag. We are assuming that the tag name is [tag1]
In the manifests file, you will be able to extract useful information about the commands that were executed with the docker first was published and run. These command may contain sensitive information such as passwords, database creds, etc.
Docker Images Reverse Engineering
Goal
The goal of reverse engineering docker images is to obtain information on the commands and instructions used to build the image in a detailed fashion. This could reveal useful information such as credentials and commands.
Pulling The Image
First we pull the target image from its repository
Then make sure to obtain the image id by running
Last updated