About
The Veertu Anka Scan software solution scans for vulnerabilities in Anka images used for CI building and testing of iOS or macOS applications. Using an NVD database to generate a report, the scanner identifies vulnerabilities in Brew, Golang, Javascript, Java, Ruby, Python, and Rust. It does not require installation inside of the Anka VM/image or host.
We are also working to increase the scope of the Veertu Anka Scan to also scan and report vulnerabilities in AWS EC2 macOS AMIs and not just Anka images.
Currently in beta.
❯ anka-scan --help
A vulnerability scanner for Anka VMs and images.
Supported commands/types:
anka-scan registry_template:uuid[:tag] | Read and scan from registry Anka VM using the UUID and optional tag
- [:tag] defaults to latest tag
anka-scan ank_image:/path/to/image.ank | Read and scan using an Anka VM ank image/file at the specified path
anka-scan dir:/path/to/folder | Scan from the specified path
Usage:
anka-scan type:source [flags]
anka-scan [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
license License show/activate
version Show the version
Flags:
-c, --config string application config file
-u, --disable-db-update Disable updating scanner DB automatically
-h, --help help for anka-scan
-i, --ignore-system-volume do not scan the system volume (for anka VM)
-l, --license-file string license file path (default "scanner.lic")
--min-score float32 Don't show vulnerabilites with lesser score
--min-severity string Don't show vulnerabilites with lesser severity
-q, --quiet suppress all console output
-o, --report-file string write report to file
-f, --report-format string report output format, formats=[json table] (default "table")
-p, --show-packages do not scan and only show packages
-s, --storage-dir string the location of the registry storage containing *_lib directories (default "/mnt")
Use "anka-scan [command] --help" for more information about a command.
Usage (Linux/Docker)
Download the package:
FULL_FILE_NAME=$(echo $(curl -Ls -r 0-1 -o /dev/null -w %{url_effective} https://veertu.com/downloads/anka-scan-linux) | cut -d/ -f5)
PARTIAL_FILE_NAME=$(echo $FULL_FILE_NAME | awk -F'.tar.gz' '{print $1}')
mkdir -p $PARTIAL_FILE_NAME
cd $PARTIAL_FILE_NAME
curl -Ls https://veertu.com/downloads/anka-scan-linux -o $FULL_FILE_NAME
tar -xzvf $FULL_FILE_NAME
rm -f $FULL_FILE_NAME
Prerequisites
- Access to the Anka Registry storage directory
- (optional) Install Docker
- ~200MBs of space
- 16GB of RAM or more
Docker
If using docker, be sure that the docker service itself has access to more than 8GBs of memory.
If you decide to use docker, you’ll need to build the tag locally using a Dockerfile. It must be built with the configuration included inside to allow mounting of the anka-scan.db file from the host (else, it will download the .db each time you need to run the scan and cause delays/networking costs):
cd anka-scan-linux-*
*
Manually edit the example-config.yaml and change 'db-path: anka-scan.db' to 'db-path: /tmp/anka-scan.db'
You can also modify the anka-scan.log location to /tmp as well
*
cat << SCRIPT > Dockerfile
FROM debian:stable-slim
ARG license
RUN apt -qq update && apt install --yes ca-certificates
COPY anka-scan_linux_amd64 anka-scan
COPY example-config.yaml anka-scan.yaml
ENTRYPOINT ["/anka-scan"]
SCRIPT
docker build --force-rm --tag anka-scan:latest .
Once built, you can then run the following to start the scan:
❯ docker run -it --rm -v /Library/Application\ Support/Veertu/Anka/registry:/mnt -v $PWD:/tmp anka-scan:latest registry_template:c12ccfa5-8757-411e-9505-128190e9854e
✔ Vulnerability DB Updates [Completed]
. . .
Features / Examples
There are two different commands/types available in the scanner:
Anka Registry VM
This type will automatically scan the registry storage directory you’ve mounted and find the proper .ank file to scan. It’s essentially anka_image
under the hood.
Let’s say I have three tags for an Anka VM Template: vanilla
, vanilla+port-forward-22
, and vanilla+port-forward-22+brew-git
. If I wanted to scan vanilla
, I would run:
export REGISTRY_PATH="/Library/Application Support/Veertu/Anka/registry" # this location is where my macOS registry is running; it may differ if you're running on linux or have configured it differently.
❯ docker run -it --rm -v "${REGISTRY_PATH}:/mnt" anka-scan:latest registry_template:ea663a61-0e5c-4419-8194-697104fb693a:vanilla
✔ Indexed Data Volume ✔ Cataloged packages [10 packages]
✔ Indexed System Volume ✔ Cataloged packages [344 packages]
TYPE NAME VERSION VULNERABILITY SCORE SEVERITY
macos-app python 2.7.18 CVE-2017-17522 8.8 high
macos-app python 2.7.18 CVE-2021-23336 5.9 medium
macos-app python 2.7.18 CVE-2015-5652 7.2 high
macos-app python 2.7.18 CVE-2017-18207 6.5 medium
macos-app python 2.7.18 CVE-2019-20907 7.5 high
macos-app python 2.7.18 CVE-2019-9674 7.5 high
python cryptography 2.9.2 CVE-2020-36242 9.1 critical
python numpy 1.8.0rc1 CVE-2014-1859 5.5 medium
python numpy 1.8.0rc1 CVE-2014-1858 5.5 medium
python numpy 1.8.0rc1 CVE-2017-12852 7.5 high
python numpy 1.8.0rc1 CVE-2019-6446 9.8 critical
Or, write the report to a file:
❯ docker run -it --rm -v "${REGISTRY_PATH}:/mnt" -v "$(pwd):/reports" anka-scan:latest registry_template:ea663a61-0e5c-4419-8194-697104fb693a:vanilla --report-file /reports/report-$(date +"%m_%d_%Y_%H:%M")
✔ Indexed Data Volume ✔ Cataloged packages [10 packages]
✔ Indexed System Volume ✔ Cataloged packages [344 packages]
Report written to "/reports/report-12_06_2021_16:44"
❯ cat report-12_06_2021_16:44
TYPE NAME VERSION VULNERABILITY SCORE SEVERITY
macos-app python 2.7.18 CVE-2019-20907 7.5 high
macos-app python 2.7.18 CVE-2019-9674 7.5 high
macos-app python 2.7.18 CVE-2021-23336 5.9 medium
macos-app python 2.7.18 CVE-2017-17522 8.8 high
macos-app python 2.7.18 CVE-2015-5652 7.2 high
macos-app python 2.7.18 CVE-2017-18207 6.5 medium
python cryptography 2.9.2 CVE-2020-36242 9.1 critical
python numpy 1.8.0rc1 CVE-2014-1859 5.5 medium
python numpy 1.8.0rc1 CVE-2014-1858 5.5 medium
python numpy 1.8.0rc1 CVE-2017-12852 7.5 high
python numpy 1.8.0rc1 CVE-2019-6446 9.8 critical
Ank Image
If you’re a more advanced user, you can determine the root .ank file inside of the metadata yaml for your VM/Template. This allows you to scan on your registry but also on an Anka host machine as well.
I’m going to track down the hard_drives > controller > file
value first:
❯ cat "$(anka config vm_lib_dir)/ea663a61-0e5c-4419-8194-697104fb693a/ea663a61-0e5c-4419-8194-697104fb693a.yaml" | grep -5 hard_drives
width: 1024
ram: 8G
uuid: ea663a61-0e5c-4419-8194-697104fb693a
creation_date: '2021-10-25T22:21:58.406768Z'
nvram: true
hard_drives:
- controller: ablk
file: ce87816df16f4661a1be0684add6ca2f.ank
pci_slot: 4
network_cards:
- mode: shared
❯ docker run -it --rm -v "$(anka config img_lib_dir)/..:/mnt" anka-scan:latest ank_image:/mnt/img_lib/ce87816df16f4661a1be0684add6ca2f.ank
✔ Indexed Data Volume ✔ Cataloged packages [214 packages]
✔ Indexed System Volume ✔ Cataloged packages [344 packages]
TYPE NAME VERSION VULNERABILITY SCORE SEVERITY
gem i18n 0.9.5 CVE-2020-7791 7.5 high
gem i18n 1.8.10 CVE-2020-7791 7.5 high
gem parallel 1.21.0 CVE-2015-4156 3.6 low
gem parallel 1.21.0 CVE-2015-4155 3.6 low
gem webrick 1.7.0 CVE-2008-1145 5.0 medium
macos-app python 3.8.9 CVE-2021-29921 9.8 critical
macos-app python 2.7.18 CVE-2021-23336 5.9 medium
macos-app python 2.7.18 CVE-2019-20907 7.5 high
macos-app python 2.7.18 CVE-2017-18207 6.5 medium
macos-app python 2.7.18 CVE-2015-5652 7.2 high
macos-app python 2.7.18 CVE-2019-9674 7.5 high
macos-app python 2.7.18 CVE-2017-17522 8.8 high
python cryptography 2.9.2 CVE-2020-36242 9.1 critical
python numpy 1.8.0rc1 CVE-2014-1858 5.5 medium
python numpy 1.8.0rc1 CVE-2017-12852 7.5 high
python numpy 1.8.0rc1 CVE-2019-6446 9.8 critical
python numpy 1.8.0rc1 CVE-2014-1859 5.5 medium
Report Formats
By default the human readable table output does not include paths or other information about how the vulnerability was found. Fortunately, we allow you to produce verbose JSON output with that information.
The use of --quiet
here is important to avoid any output which is not json parsable.
❯ docker run -it --rm -v "$(anka config img_lib_dir)/..:/mnt" anka-scan:latest ank_image:/mnt/img_lib/c2deedc229ae4e8b967aef0ddf4b2813.ank --report-format json --quiet
{
"matches": [
{
"vulnerability": {
"id": "CVE-2020-7791",
"base-score": 7.5,
"severity": "high"
},
"matchDetails": [
{
"matched-cpe": "cpe:/a:i18n_project:i18n:::~~~asp.net~~",
"matched-version": "0.9.5",
"matched-constraint": "< 2.1.15",
"match-type": "Semantic"
}
],
"artifact": {
"name": "i18n",
"version": "0.9.5",
"type": "gem",
"locations": [
{
"path": "/usr/local/Homebrew/docs/Gemfile.lock"
}
],
"language": "ruby",
"licenses": [],
"cpes": [
"cpe:2.3:a:ruby-lang:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby_lang:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:i18n:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:*:i18n:0.9.5:*:*:*:*:*:*:*"
],
"purl": "pkg:gem/[email protected]",
"metadata": null
}
},
{
"vulnerability": {
"id": "CVE-2020-7791",
"base-score": 7.5,
"severity": "high"
},
"matchDetails": [
{
"matched-cpe": "cpe:/a:i18n_project:i18n:::~~~asp.net~~",
"matched-version": "0.9.5",
"matched-constraint": "< 2.1.15",
"match-type": "Semantic"
}
],
"artifact": {
"name": "i18n",
"version": "0.9.5",
"type": "gem",
"locations": [
{
"path": "/usr/local/Homebrew/docs/Gemfile.lock"
}
],
"language": "ruby",
"licenses": [],
"cpes": [
"cpe:2.3:a:ruby-lang:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby_lang:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:i18n:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby:i18n:0.9.5:*:*:*:*:*:*:*",
"cpe:2.3:a:*:i18n:0.9.5:*:*:*:*:*:*:*"
],
"purl": "pkg:gem/[email protected]",
"metadata": null
}
},
{
"vulnerability": {
"id": "CVE-2020-7791",
"base-score": 7.5,
"severity": "high"
},
"matchDetails": [
{
"matched-cpe": "cpe:/a:i18n_project:i18n:::~~~asp.net~~",
"matched-version": "1.8.11",
"matched-constraint": "< 2.1.15",
"match-type": "Semantic"
}
],
"artifact": {
"name": "i18n",
"version": "1.8.11",
"type": "gem",
"locations": [
{
"path": "/usr/local/Homebrew/Library/Homebrew/Gemfile.lock"
}
],
"language": "ruby",
"licenses": [],
"cpes": [
"cpe:2.3:a:ruby-lang:i18n:1.8.11:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby_lang:i18n:1.8.11:*:*:*:*:*:*:*",
"cpe:2.3:a:i18n:i18n:1.8.11:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby:i18n:1.8.11:*:*:*:*:*:*:*",
"cpe:2.3:a:*:i18n:1.8.11:*:*:*:*:*:*:*"
],
"purl": "pkg:gem/[email protected]",
"metadata": null
}
},
. . .
],
"source": {
"type": "anka image",
"target": "/Users/veertu/Library/Application Support/Veertu/Anka/img_lib/c2deedc229ae4e8b967aef0ddf4b2813.ank"
}
}
Ignoring Vulnerabilities
Using a custom config (--config customConfig.yaml
), you can specify a list of CPEs to ignore.
You need to specify the “matched-cpe” or URI binding representation in the packages to ignore. Wildcards will not work.
❯ cat /tmp/customConfig.yaml
ignore-packages:
- "cpe:/a:i18n_project:i18n:::~~~asp.net~~"
- "cpe:/a:python:python"
By default, if you don’t specify a custom config, we automatically exclude
cpe:/a:apple:icloud:1.0
as there are several hundred vulnerabilities from it. You can use an empty custom config:ignore-packages: - ""
Or, you can ignore specific CVEs:
❯ cat /tmp/customConfig.yaml
ignore-cves:
- "CVE-2020-7791"
❯ docker run -it --rm -v "$(anka config img_lib_dir)/..:/mnt" -v "/tmp:/mnt/config" public.ecr.aws/veertu/anka-scan:latest ank_image:/mnt/img_lib/c2deedc229ae4e8b967aef0ddf4b2813.ank --report-format json --config /mnt/config/customConfig.yml --report-file /mnt/config/report_i18n_python.txt
✔ Indexed Data Volume ✔ Cataloged packages [220 packages]
✔ Indexed System Volume ✔ Cataloged packages [345 packages]
Report written to "/mnt/config/report_i18n_python.txt"
Usage (macOS)
Download the latest macOS package
The instructions for using the macOS package are identical in many ways to docker. The major differences are that the default --storage-dir
for the binary is /mnt
and likely not where your registry storage is located on macOS. You also of course do not include docker commands when executing the binary.
❯ ./_release/anka-scan --storage-dir "/Library/Application Support/Veertu/Anka/registry" registry_template:c12ccfa5-8757-411e-9505-128190e9854e
✔ Indexed Data Volume
✔ Cataloged packages [222 packages]
✔ Indexed System Volume
✔ Cataloged packages [345 packages]
TYPE NAME VERSION VULNERABILITY SCORE SEVERITY
gem i18n 0.9.5 CVE-2020-7791 7.5 high
gem i18n 1.8.11 CVE-2020-7791 7.5 high
gem parallel 1.21.0 CVE-2015-4155 3.6 low
gem parallel 1.21.0 CVE-2015-4156 3.6 low
gem webrick 1.7.0 CVE-2008-1145 5.0 medium
macos-app python 3.8.9 CVE-2021-29921 9.8 critical
macos-app python 2.7.18 CVE-2019-20907 7.5 high
macos-app python 2.7.18 CVE-2019-9674 7.5 high
macos-app python 2.7.18 CVE-2021-23336 5.9 medium
macos-app python 2.7.18 CVE-2015-5652 7.2 high
macos-app python 2.7.18 CVE-2017-17522 8.8 high
macos-app python 2.7.18 CVE-2017-18207 6.5 medium
python numpy 1.8.0rc1 CVE-2014-1858 5.5 medium
python numpy 1.8.0rc1 CVE-2014-1859 5.5 medium
python numpy 1.8.0rc1 CVE-2017-12852 7.5 high
python numpy 1.8.0rc1 CVE-2019-6446 9.8 critical
python numpy 1.8.0rc1 CVE-2021-41496 7.5 high
python numpy 1.8.0rc1 CVE-2021-41495 7.5 high
python numpy 1.8.0rc1 CVE-2021-34141 5.3 medium