Monday, February 25, 2019

Clair - A Container Image Security Analyzer

Clair - A Container Image Security Analyzer

Problem Statements:

"everyone is responsible for security" - But how in containers?

In container world, the first step in a Dockerfile is FROM statement. There you specify your base OS. Did you ever think if, the base OS is having any vulnerability? Are they from a trusted source? A docker image is composed of 1+n layers (also called intermediate images) and each layer is stored in a docker registry as a tar file blob. Therefore, whether you are building a Docker images from your own code or but also when using unmodified third party images, it’s important to identify and find any known vulnerabilities that may be present in those images. This process is known as container image scanning. The Docker build process follows a manifest (Dockerfile) that includes relevant security information that you can scan and evaluate including the base images, exposed ports, environment variables, entrypoint script, external installed binaries, etc. If a parent image is vulnerable, any other images built on top of that one will be vulnerable too. 

Clair:

Clair is an open source tool that does static analysis of vulnerabilities in a docker images made by CoreOS. It can be integrated with docker registry. Clair make use of static analysis for fast results. Clair doesn’t have a web UI or even a command-line tool; so the only way to work with it is via its REST API or a third-party CLI tool. As a source of vulnerabilities, it uses CVE (Common Vulnerabilities and Exposures) data sources like NIST NVD and other security bug trackers.

Clair components:
1. Clair - core product which has REST API server, CVE Updater and list of CVE data sources.
2. PostgreSQL 9.4+ - Storage of vulnerabilities database and results of analysis of uploaded docker image layers

How to build your own clair registry:

I am assuming you have a linux box which contain docker and docker-compose software installed. Next you need to check out the code from Git. The docker-compose.yml file has all you need to run this demo. It has the clair docker, postgres docker and a registry docker.

[root@apigateway opc]# docker-compose up -d

After starting Clair, the software starts downloading vulnerability information into the database. The download takes some time so I recommend to wait for 5 mins.

Okay, now I am going to test a nginx image. In this case, I will pull the latest nginx image from public repository and will tag and push to our local registry (which we have started just now using docker-compose)

[root@apigateway opc]# docker pull nginx:latest
[root@apigateway opc]# docker tag nginx localhost:5000/nginx-test
[root@apigateway opc]# docker push localhost:5000/nginx-test

Its the time to play with Clair.

The given below, is how to use clair with the local image registry
[root@apigateway opc]# CLAIR_ADDR=http://localhost:6060 CLAIR_OUTPUT=Low CLAIR_THRESHOLD=10 REGISTRY_INSECURE=TRUE klar localhost:5000/nginx-test
 
clair timeout 1m0s
docker timeout: 1m0s
no whitelist file
Analysing 3 layers
Got results from Clair API v1
Found 85 vulnerabilities
Unknown: 1
Negligible: 39
Low: 11
Medium: 22
High: 12
 
CVE-2016-2781: [Low]
Found in: coreutils [8.26-3]
Fixed By:
chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.
https://security-tracker.debian.org/tracker/CVE-2016-2781
-----------------------------------------
CVE-2017-15232: [Low]
Found in: libjpeg-turbo [1:1.5.1-2]
Fixed By:
libjpeg-turbo 1.5.2 has a NULL Pointer Dereference in jdpostct.c and jquant1.c via a crafted JPEG file.
https://security-tracker.debian.org/tracker/CVE-2017-15232
-----------------------------------------
CVE-2019-7317: [Low]
Found in: libpng1.6 [1.6.28-1]
Fixed By:
png_image_free in png.c in libpng 1.6.36 has a use-after-free because png_image_free_function is called under png_safe_execute.
https://security-tracker.debian.org/tracker/CVE-2019-7317
-----------------------------------------

Usage of Klar

[root@apigateway opc]# mv klar-2.4.0-linux-amd64 klar
[root@apigateway opc]# chmod 775 klar
[root@apigateway opc]# cp klar /bin

[root@apigateway opc]# CLAIR_ADDR=http://localhost:6060 CLAIR_OUTPUT=Low CLAIR_THRESHOLD=10 DOCKER_USER=oardccsi/oracleidentitycloudservice/shivin.vijai@mydomain.com DOCKER_PASSWORD="my_password"  klar iad.ocir.io/oardccsi/nginx-test
 
# For getting the result in JSON format
[root@apigateway opc]# CLAIR_ADDR=http://localhost:6060 CLAIR_OUTPUT=Low CLAIR_THRESHOLD=10 DOCKER_USER=oardccsi/oracleidentitycloudservice/shivin.vijai@mydomain.com DOCKER_PASSWORD="my_password"  JSON_OUTPUT=true klar iad.ocir.io/oardccsi/nginx-test | jq

The given below, is how to use clair to scan locally

For local scan, I used clair-local-scan api. You need to run docker version of clair-local-scan. In this case we don't need the above docker-compose. Follow the below steps only.

The given below, is how to use clair to scan locally

For local scan, I used clair-local-scan api. You need to run docker version of clair-local-scan. In this case we don't need the above docker-compose. Follow the below steps only.

docker run -p 5432:5432 -d --name db arminc/clair-db:2017-09-18
docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.6

Now you are ready to scan.

[opc@oo-pipeline ~]$ sudo ./clair-scanner --ip 172.17.0.1 openjdk:8-jre-alpine
2019/02/22 05:02:40 [INFO] ¿ Start clair-scanner
2019/02/22 05:02:41 [INFO] ¿ Server listening on port 9279
2019/02/22 05:02:41 [INFO] ¿ Analyzing 69970c11d5e148aad8020cbe98433478ca5144d56579b2c1cd1185d628560839
2019/02/22 05:02:41 [INFO] ¿ Analyzing b0c9657887cd2f5749a8a745d94b056755c3130a25d8b018fe6ac3b9e4be9b27
2019/02/22 05:02:41 [INFO] ¿ Analyzing 044bbcd416d4d815fa63411e8eec1604562ee127ca03e303f5fa2442302508dd
2019/02/22 05:02:41 [INFO] ¿ Image [openjdk:8-jre-alpine] contains NO unapproved vulnerabilities
[opc@oo-pipeline ~]$
 
[opc@oo-pipeline ~]$ sudo ./clair-scanner --ip 172.17.0.1 nginx:latest
2019/02/22 05:08:52 [INFO] ¿ Start clair-scanner
2019/02/22 05:08:54 [INFO] ¿ Server listening on port 9279
2019/02/22 05:08:54 [INFO] ¿ Analyzing 4bba18425451a6d1c39814a92f3c352aa59eab1637e8e32ee659c9b34322ae4a
2019/02/22 05:08:55 [INFO] ¿ Analyzing 4411730c73b8d6d1032c2b9b43f7b456beb380383efd2d8bc5bec60a91f71f2b
2019/02/22 05:08:55 [INFO] ¿ Analyzing 042e7cad15354418b4e0cc72626443fe9db951f72306e91cc2bd4a80072999b3
2019/02/22 05:08:55 [WARN] ¿ Image [nginx:latest] contains 57 total vulnerabilities
2019/02/22 05:08:55 [ERRO] ¿ Image [nginx:latest] contains 57 unapproved vulnerabilities
+------------+-----------------------------+--------------+------------------------+--------------------------------------------------------------+
| STATUS     | CVE SEVERITY                | PACKAGE NAME | PACKAGE VERSION        | CVE DESCRIPTION                                              |
+------------+-----------------------------+--------------+------------------------+--------------------------------------------------------------+
| Unapproved | High CVE-2017-12424         | shadow       | 1:4.4-4.1              | In shadow before 4.5, the newusers tool could be             |
|            |                             |              |                        | made to manipulate internal data structures in ways          |
|            |                             |              |                        | unintended by the authors. Malformed input may lead          |
|            |                             |              |                        | to crashes (with a buffer overflow or other memory           |
|            |                             |              |                        | corruption) or other unspecified behaviors. This             |
|            |                             |              |                        | crosses a privilege boundary infor example, certain        |
|            |                             |              |                        | web-hosting environments in which a Control Panel allows     |
|            |                             |              |                        | an unprivileged user account to create subaccounts.          |
|            |                             |              |                        | https://security-tracker.debian.org/tracker/CVE-2017-12424   |
+------------+-----------------------------+--------------+------------------------+--------------------------------------------------------------+
| Unapproved | High CVE-2016-2779          | util-linux   | 2.29.2-1+deb9u1        | runuser in util-linux allows local users to escape to        |
|            |                             |              |                        | the parent session via a crafted TIOCSTI ioctl call,         |
|            |                             |              |                        | which pushes characters to the terminal's input buffer.      |
|            |                             |              |                        | https://security-tracker.debian.org/tracker/CVE-2016-2779    |
+------------+-----------------------------+--------------+------------------------+--------------------------------------------------------------+

You can easily whitelist if you're not concern about that vulnerability. You need to create a file "generalwhitelist". Add the following

[opc@oo-pipeline DockerScanning]$ cat generalwhitelist
generalwhitelist: #Approve CVE for any image
  CVE-2017-6055: XML
  CVE-2017-5586: OpenText
images:
  ubuntu: #Apprive CVE only for ubuntu image, regardles of the version
    CVE-2017-5230: Java
    CVE-2017-5230: XSX
  alpine:
    CVE-2017-3261: SE
  nginx:
    CVE-2016-2779: util-linux
    CVE-2017-10684: ncurses
    CVE-2017-8804: glibc
[opc@oo-pipeline DockerScanning]$
 
 
# Scan local using whitelist
opc@oo-pipeline ~]$ sudo ./clair-scanner -w generalwhitelist --ip 172.17.0.1 nginx:latest