About the AWS EC2 Mac AMI Scan
The Veertu AWS EC2 Mac AMI Scan software solution scans for vulnerabilities in your Mac AMIs using an NVD database. The scanner identifies vulnerabilities in third-party dependencies, packages, and libraries, including Brew, Golang, Javascript, Java, Ruby, Python, Rust, etc.
AWS EC2 Mac AMI Scan software can be installed on an Amazon Linux EC2 instance. AWS EC2 Mac AMI Scan detects vulnerabilities in the Mac AMIs without the need to start instances. It will instead mount the EC2 Mac AMI snapshot as a volume.
Scanned languages/packages:
- Ruby Gems
- Python Packages
- Javascript Node/NPM Packages
- Java Packages
- Golang Modules
- Rust Cargo
- Brew Formula
- MacOS Applications
- Cocoapods
sh-4.2$ ./ec2-mac-ami-scan
A vulnerability scanner for MacOS AMIs.
Supported commands:
ec2-mac-ami-scan ami-id | Read and scan using an AWS AMI-ID
Usage:
ec2-mac-ami-scan ami-id [flags]
ec2-mac-ami-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:
--ami-license-file string unique AMI add-on license file path
-c, --config string application config file
-u, --disable-db-update disable updating scanner DB automatically
-h, --help help for ec2-mac-ami-scan
-i, --ignore-system-volume do not scan the system volume
-l, --license-file string license file path (default "scanner.lic")
--min-score float32 do not show vulnerabilities with lesser score
--min-severity string do not show vulnerabilities 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
Use "ec2-mac-ami-scan [command] --help" for more information about a command.
Getting Started
- Start an Amazon Linux EC2 Instance and prepare it with your credentials.
- Install the AWS EC2 Mac AMI Scan binary.
- Obtain a license and license the scanner.
- Review the usage guide.
You cannot scan AMIs without having access to their snapshot. Because of this, the scanner will not scan marketplace AMIs or Community/public AMIs without a public snapshot.
You must have access to the AMI snapshot in the same region as your EC2 instance in order to scan it. You also cannot currently scan across regions. You can, however, deploy instances of EC2 Mac AMI Scanner in multiple regions.
Currently, we only provide a scanner binary for Amazon Linux x86_64. It is archived into a tar.gz and available on our site or at https://downloads.veertu.com/#ec2-mac-ami-scan/.
Preparing an EC2 instance
-
Create an x86_64 Amazon Linux EC2 instance with a minimum of 1 CPU, 0.5GiB of RAM, and ~1GB of space for storage of the vulnerability database.
-
In order to have the permissions necessary for mounting AMI volumes and scanning them, you can either:
-
Create and attach an ec2 service policy to the instance and ensure it has the following permissions.
-
Configure the instance with
sudo aws configure(scanning requires and will run as root) through SSH using an Access key and secret for a user that has the following permissions.- ec2.DescribeVolumes
- ec2.DescribeInstanceAttribute
- ec2.CreateVolume
- ec2.DeleteVolume
- ec2.AttachVolume
- ec2.DetachVolume
- ec2.DescribeImages
- ec2.CreateTags
-
Installation
- Download the latest Linux x86_64 package.
FULL_FILE_NAME=$(echo $(curl -Ls -r 0-1 -o /dev/null -w %{url_effective} https://veertu.com/downloads/ec2-mac-ami-scan-linux) | cut -d/ -f5)PARTIAL_FILE_NAME=$(echo $FULL_FILE_NAME | awk -F'.tar.gz' '{print $1}')curl -Ls https://veertu.com/downloads/ec2-mac-ami-scan-linux -o $FULL_FILE_NAMEtar -xzvf $FULL_FILE_NAMErm -f $FULL_FILE_NAMEcd $PARTIAL_FILE_NAME
- Place the binary under /usr/local/bin (or just execute with
./in-place).
Licensing
How to License
You need two different licenses to scan an AMI.
- The "Platform" license for the specific host to use the binary.
- The "AMI Add-On" license for the specific AMI[s] you want to scan.
Here is the step by step:
-
Set up the AWS CLI and make sure the ~/.aws/credentials file is set up with the correct credentials for the root user.
-
Obtain licenses: Trial - or email [email protected] to get a non-trial license
-
Execute the license CLI to activate it:
sh-4.2$ ./ec2-mac-ami-scan licenseLicense show/activateUsage:ec2-mac-ami-scan license [command]Available Commands:activate Activate the licenseshow Show the licenseFlags:-h, --help help for licenseGlobal Flags:--ami-license-file string unique AMI add-on license file path-c, --config string application config file-l, --license-file string license file path (default "scanner.lic")Use "ec2-mac-ami-scan license [command] --help" for more information about a command.sh-4.2$ ./ec2-mac-ami-scan ami-0b117cb41d1dcb87fError: failed to validate the license 'scanner.lic': No such file or directorysh-4.2$ ./ec2-mac-ami-scan license activate XXXX-XXXX-XXXX-XXXXActivatedsh-4.2$ ./ec2-mac-ami-scan license showProduct: com.veertu.macami.scanVersion: 1.0Expiration Date: 31-dec-2022sh-4.2$ ./ec2-mac-ami-scan license activate --helpActivate the licenseUsage:ec2-mac-ami-scan license activate {activation-key} [flags]Flags:--ami-count activate Unique AMI add-on license-h, --help help for activate-o, --overwrite overwrite license file if already existsGlobal Flags:--ami-license-file string unique AMI add-on license file path-c, --config string application config file-l, --license-file string license file path (default "scanner.lic")sh-4.2$ ./ec2-mac-ami-scan ami-XXXXXXXXXXXXXXXXXError: unique AMI Scan license is required for this scansh-4.2$ ./ec2-mac-ami-scan license activate --ami-count XXXX-XXXX-XXXX-XXXXActivated
By default the scanner.lic file is created in the directory where you execute license activate. If you execute the scanner in a directory outside of the location with the scanner.lic, it will not see the file and fail. You can however set the path the scanner looks for the license file in by modifying the config-example.yaml and the license-file: 'scanner.lic' to a different location.
Usage
Features / Examples
The scanner is very simple. You can set the ami-id as your first argument and the scanner will find the snapshot, mount it as a volume, and then perform the scan inside of it.
sh-4.2$ sudo ./ec2-mac-ami-scan ami-07eec7bea34f42837
✔ Vulnerability DB Update [completed]
✔ Attaching an AMI [attached vol-077126acd2775d6e1]
✔ Cataloged packages [266 packages]
✔ Indexed Data Volume
✔ Cataloged packages [335 packages]
✔ Indexed System Volume
✔ Detaching an AMI [detached vol-077126acd2775d6e1]
✔ Analyzed packages [138 vulnerabilities]
TYPE NAME VERSION VULNERABILITY SCORE SEVERITY
brew [email protected] 1.1.1o CVE-2022-2068 10.0 critical
brew [email protected] 1.1.1o CVE-2022-2097 7.5 high
brew [email protected] 3.9.12_1 CVE-2015-20107 10.0 critical
gem bundler 1.17.2 CVE-2019-3881 7.8 high
gem bundler 1.17.2 CVE-2020-36327 9.3 critical
gem bundler 1.17.2 CVE-2021-43809 9.3 critical
gem date 2.0.0 CVE-2012-1626 6.0 medium
gem date 2.0.0 CVE-2021-41817 7.5 high
. . .
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.
sh-4.2$ sudo ./ec2-mac-ami-scan ami-07eec7bea34f42837 --report-format json --quiet
{
"matches": [
{
"vulnerability": {
"id": "CVE-2019-3881",
"base-score": 7.8,
"severity": "high",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-3881"
},
"matchDetails": [
{
"matched-cpe": "cpe:/a:bundler:bundler:::~~~ruby~~",
"matched-version": "1.17.2",
"matched-constraint": "< 2.1.0",
"match-type": "Semantic"
}
],
"artifact": {
"name": "bundler",
"version": "1.17.2",
"type": "gem",
"locations": [
{
"path": "/Library/Ruby/Gems/2.6.0/specifications/default/bundler-1.17.2.gemspec"
}
],
"language": "ruby",
"licenses": [
"MIT"
],
"cpes": [
"cpe:2.3:a:jessica-lynn-suttles:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:jessica_lynn_suttles:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:david-rodr\\\ufffd\\\ufffdguez:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:andr\\\ufffd\\\ufffd-medeiros:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:david_rodr\\\ufffd\\\ufffdguez:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:stephanie-morillo:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:andr\\\ufffd\\\ufffd_medeiros:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:stephanie_morillo:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:hiroshi-shibata:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:colby-swandale:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:hiroshi_shibata:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:samuel-giddins:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:andr\\\ufffd\\\ufffd-arko:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:colby_swandale:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:samuel_giddins:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:andr\\\ufffd\\\ufffd_arko:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:chris-morris:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:carl-lerche:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:chris_morris:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:terence-lee:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:yehuda-katz:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:carl_lerche:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:grey-baker:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:terence_lee:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:yehuda_katz:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:grey_baker:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:james-wen:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby-lang:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:tim-moore:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:james_wen:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby_lang:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:tim_moore:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:bundler:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:ruby:bundler:1.17.2:*:*:*:*:*:*:*",
"cpe:2.3:a:*:bundler:1.17.2:*:*:*:*:*:*:*"
],
"purl": "pkg:gem/[email protected]",
"metadata": null
}
},
. . .
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.yml
ignore-cves:
- "CVE-2020-7791"
sh-4.2$ sudo ./ec2-mac-ami-scan ami-07eec7bea34f42837 --report-format json --config /tmp/customConfig.yaml --report-file /tmp/report_i18n_python.json
✔ Vulnerability DB Update [completed]
✔ Attaching an AMI [attached vol-0e25f5c07490615a4]
✔ Cataloged packages [266 packages]
✔ Indexed Data Volume
✔ Cataloged packages [335 packages]
✔ Indexed System Volume
✔ Detaching an AMI [detached vol-0e25f5c07490615a4]
✔ Analyzed packages [357 vulnerabilities]
Report written to "/tmp/report_i18n_python.json"
FAQs
- Why do I need two licenses?
- The "Platform" license is for the specific host to use the binary.
- The "AMI Add-On" license is for the specific AMI[s] you want to scan.
- Why do I need to set up the AWS CLI?
- The AWS CLI is used to get the AMI snapshot and mount it as a volume.
- For the AMI Add-On license, can I scan multiple AMIs with the same license?
- Yes, you can scan multiple AMIs with the same license as long as you've paid for the amount of AMIs you want to scan.
Release Notes
2.0.0 - Apr 24th, 2026
- Complete rewrite of the scanner for a new license structure.