Skip to content

User Guide

Hamed edited this page Jul 7, 2020 · 19 revisions

This user guide has been prepared for use in the Software Security Summer School (SSSS20), but can be generally used to install and use Confine.

There are three main sections in this guide.

  1. Seccomp profile generation
  2. Interpreting results
  3. Mapping Seccomp profile to mitigated CVEs
  4. Useful Docker commands

Each section has been described below.

1. Seccomp profile generation

The main script in this repo is the confine.py file which uses previously created call graphs for musl-libc and glibc, along with a list of images and creates respective SECCOMP profiles for each.

-l: glibc callgraph

-m: musl-libc callgraph

-i: input file containing JSON of images (more details provided below)

-o: path to store binaries and libraries extracted from container

-p: path to Docker default seccomp profile

-r: path to store results (seccomp profiles created)

-g: path to special cases containers like golang ones (more details provided below)

-d: debugging enabled or disabled

--skip: [Optional] In case you set this option, the script will not run the analysis for previously run images which have their results inserted into the profile.results.csv file.

-f: [Optional] glibc shared object

-n: [Optional] musl-libc shared object

--finegrain: [Optional] Passing this argument enables the fine grained policy generation. Using this feature is not advised, since it is under development.

--othercfgfolder: [Optional] In case you enable the fine grained analysis through setting --finegrain, you must set this option as well. This folder should contain the call graph for the other libraries used in the fine grained analysis.

--allbinaries: [Optional] Passing this argument causes the extraction of all binaries instead of only the ones run during the 30 seconds. This would cause an extremely more conservative filter.

python3.7 confine.py -l libc-callgraphs/glibc.callgraph -m libc-callgraphs/musllibc.callgraph -i images.json -o output/ -p default.seccomp.json -r results/ -g go.syscalls/

-i: The input file is in the JSON format. The images.json provided in the contains the images used for our paper. You can add or remove images as you need and see fit. The format for each image is as shown below::

{
    "nginx": {
        "enable": "false",
        "image-name": "nginx",
        "image-url": "nginx",
        "category": [
            "ApplicationInfrastructure"
        ],
        "options": "",
        "args": "",
        "dependencies": {}
    }
}

Note: The only keys which are required for any item in the JSON file are enable, image-name and image-url. The rest are optional. Some Docker images need a set of options to run correctly. Such as passing configuration options or setting environment variables. Docker supports two types of arguments, one is for options which are used by Docker and the other is args which are arguments passed directly to the application running in the container. For example the MySQL Docker image must be run with the options below: -e MYSQL_ROOT_PASSWORD=my-secret-pw These options are typically specified in the image page on Docker Hub.

-g: If the container uses languages such as Golang and we have extracted system calls which are required through a different mechanism such as CFG extraction at the source code level, we can create a file named [imagename].syscalls and place it in the path specified by -g.

2. Interpreting results

After you run the script to generate a Seccomp profile for your selected Docker image(s), multiple files are created in the folder you specified through the -r option (results by default). We will explain each file in this part.

Main Results

There two files which hold summarized information regarding all the hardened containers. There is also a JSON file created for each Docker image hardened successfully, which holds the generated Seccomp profile.

The Seccomp profile name follows the pattern:

[docker-image].seccomp.json

The summarized results are in:

profile.reports.csv
profile.reports.details.csv

Each line in profile.reports.csv shows the following information:

image-id;image-name;was-able-to-launch;remained-launched;deprecated;number-of-filtered-system-calls;deprecated;deprecated;deprecated;hardened-successfully;deprecated;deprecated;deprecated;time-taken-to-harden;languages-used;deprecated

For example the following line can be read as follows:

15;nginx;True;True;False;154;0;118;171;True;;0;0;400.30435395240784;{'CCPP'};16

Nginx hardening status:

a) ID: 15

b) Launched successfully: True

c) Did not die after launch: True

d) Number of filtered system calls: 154

e) Was hardened successfully: True

f) Time taken to harden (seconds): 400.30

g) Languages identified being used in container: C/C++

The profile.reports.details.csv also reports the filtered system calls as well. This file is used in the mapping the system calls to their CVEs. (Explained in section 3).

Statistics

There are three files which mainly contain statistics about the hardened containers. Such as the languages used in the Docker images used, the total number of successfully launched and hardened containers and the number of filtered system calls based on their category.

These files are named container.language.stats.csv, container.stats.csv and syscall.categorized.csv.

You do not need to interpret these files.

3. Mapping Seccomp profile to mitigated CVEs

In the evaluation section of our paper we have shown how hardening the container through applying our SECCOMP profiles can mitigate previously disclosed Linux kernel CVEs. This can serve as a sign as how effective our approach can be in limiting the attacker's capabilities.

You can use the filterToCveProfile.py script to map the generated SECCOMP profile to the mitigated CVEs.

python3.7 filterProfileToCve.py -c cve.files/cveToStartNodes.csv.validated -f results/profile.report.details.csv -o results -v cve.files/cveToFile.json.type.csv --manualcvefile cve.files/cve.to.syscall.manual --manualtypefile cve.files/cve.to.vulntype.manual -d

-c: Path to the file containing a map between each CVE and all the starting nodes which can reach the vulnerable point in the kernel call graph

-f: This file is generated after you run Confine for a set of containers. It can be found in the results path in the root of the repository.

-o: Name of the prefix of the file you would like to store the results in.

-v: A CSV file containing the mapping of CVEs to their vulnerability type.

--manualcvefile: Some CVEs have been gathered manually which can be specified using this option.

--manualtypefile: A file containing the mapping of CVEs identified manually to their respective vulnerability type.

-d: Enable/disable debug mode which prints much more log messages.

Note: The scripts required to generate the mapping between the kernel functions and their CVEs are in a separate repository. You do not need to recreate those results.

Interpreting the output

After you run the script above a single file will be created named [results].container.csv. You can change the prefix through the -o option. Each line corresponds to a CVE mitigated in at least one of the Docker images provided in the profile.report.details.csv file.

Line format:

cveid;system call names(can be more than one);cve-type(can be more than
one);was-it-mitigated-by-the-default-seccomp-policies;number-of-docker-images-affected;
name of docker images
CVE-2015-8539;add_key, keyctl;Denial Of Service, Gain privileges;True;1;nginx

4. Useful Docker commands

a) Run a container with the default Seccomp profile:

sudo docker run --name [any-name] -td [docker-image-name]

example:

sudo docker run --name nginx-container -td nginx

b) Run a container without any Seccomp profile:

sudo docker run --name [any-name] --security-opt seccomp=unconfined -td [docker-image-name]

example:

sudo docker run --name nginx-container-free --security-opt seccomp=unconfined -td nginx

c) Run a container with custom Seccomp profile:

sudo docker run --name [any-name] --security-opt seccomp=[path-to-seccomp-profile] -td [docker-image-name]

example:

sudo docker run --name nginx-container-hardened --security-opt seccomp=results/nginx.seccomp.json -td nginx

d) Connect to a running container instance and launch bash/sh/...:

sudo docker exec -it [container-name] [any-shell]

example:

sudo docker exec -it nginx-container /bin/bash

e) Extract IP address of running container:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container-name]

example:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-container-hardened

f) View list of running containers:

sudo docker container ls -a

g) Kill a running container:

sudo docker kill [container-name]

h) Delete a container instance (Must be killed first):

sudo docker rm [container-name]

Statistics Creator

After running the confine.py script we can generate different statistics by running the createStats script. -r: Path to the main summarized results -e: Path to the detailed results -i: Path to the image list used (to extract extra information which might not exist in results) -o: path to store output -c: file specifying system call for each cve -b: path to where binaries and libraries for all containers exist (this should be the same as -o in confine.py)

python3.7 createStats.py -r results/profile.report.csv -e results/profile.report.details.csv -i images.list -o stats/ -c cveToSyscall.csv -b output/