Vulnerability Management
- Vulnerability Management
Finding and fixing weaknesses, continuously
Vulnerability management is the continuous process of identifying, classifying, prioritizing, remediating, and reporting on security vulnerabilities in systems and software. It spans the full lifecycle from dependency scanning in CI to runtime scanning of production infrastructure.
ℹ️ The hard part is rarely finding vulnerabilities — scanners produce more findings than any team can fix. The discipline is prioritization: using CVSS, exploitability, and asset value to fix the few that matter before attackers reach them. Most critical CVEs are exploited within days of disclosure, so this connects directly to threat modeling and patch cadence.
Vulnerability Scanning Fundamentals
A vulnerability scanner probes systems and software against databases of known weaknesses (CVEs, misconfigurations, CIS benchmarks). Scanners fall into several categories:
| Category | What it scans | Examples |
|---|---|---|
| Network scanner | Open ports, running services, banners | Nmap, Nessus, OpenVAS |
| Web application scanner | HTTP endpoints, forms, parameters | Burp Suite, OWASP ZAP, Nikto |
| Container/image scanner | OS packages, language libraries in images | Trivy, Grype, Clair |
| Infrastructure scanner | Cloud configurations, IaC files | Checkov, tfsec, Prowler |
| Dependency scanner | Language package dependencies | Safety, Dependabot, Snyk |
Vulnerability scanning is a point-in-time activity. Continuous scanning — integrated into CI/CD and scheduled against production — is required for an effective program.
Nmap
Nmap is the standard open-source network discovery and security auditing tool. It discovers hosts, open ports, running services, and their versions.
Basic scanning
# Host discovery (ping scan — no port scan)
nmap -sn 192.168.1.0/24
# TCP SYN scan (default; requires root/sudo)
sudo nmap -sS 192.168.1.100
# Full TCP connect scan (no root required)
nmap -sT 192.168.1.100
# UDP scan (slow; important — many services run on UDP)
sudo nmap -sU 192.168.1.100
# Scan specific ports
nmap -p 22,80,443,8080 192.168.1.100
# Scan all 65535 ports
nmap -p- 192.168.1.100
Service and version detection
# Service version detection
nmap -sV 192.168.1.100
# OS detection (requires root)
sudo nmap -O 192.168.1.100
# Aggressive scan: OS, version, scripts, traceroute
sudo nmap -A 192.168.1.100
# Default NSE scripts (safe reconnaissance)
nmap -sC 192.168.1.100
Nmap Scripting Engine (NSE)
# Run specific NSE scripts
nmap --script http-title 192.168.1.100
nmap --script ssl-enum-ciphers -p 443 192.168.1.100
nmap --script vuln 192.168.1.100 # run all vulnerability scripts
# Check for specific vulnerabilities
nmap --script smb-vuln-ms17-010 192.168.1.100 # EternalBlue
nmap --script http-shellshock 192.168.1.100
nmap --script ssh-brute --script-args userdb=users.txt 192.168.1.100
# List available scripts
ls /usr/share/nmap/scripts/
ls /usr/share/nmap/scripts/ | grep http
Output formats
# Normal output to file
nmap -oN scan-results.txt 192.168.1.0/24
# XML output (for parsing and import into tools)
nmap -oX scan-results.xml 192.168.1.0/24
# Grepable output
nmap -oG scan-results.gnmap 192.168.1.0/24
# All formats simultaneously
nmap -oA scan-results 192.168.1.0/24
# Parse Nmap XML output with python-nmap
import nmap
nm = nmap.PortScanner()
nm.scan('192.168.1.0/24', '22,80,443', arguments='-sV')
for host in nm.all_hosts():
print(f"\nHost: {host} ({nm[host].hostname()})")
print(f"State: {nm[host].state()}")
for proto in nm[host].all_protocols():
ports = nm[host][proto].keys()
for port in ports:
state = nm[host][proto][port]['state']
service = nm[host][proto][port]['name']
version = nm[host][proto][port].get('version', '')
print(f" {proto}/{port}: {state} ({service} {version})")
Worked example — audit a web server for security issues:
# Comprehensive web server assessment
sudo nmap -sV -sC -p 80,443,8080,8443 \
--script "http-*,ssl-*" \
-oA webserver-audit \
192.168.1.100
# Key things to check in output:
# - SSL/TLS protocol versions (reject SSLv3, TLS 1.0, TLS 1.1)
# - Cipher suite strength (reject RC4, DES, 3DES, EXPORT)
# - HTTP methods allowed (DELETE, PUT, TRACE should be disabled)
# - Server version disclosure (hide with server_tokens off in nginx)
# - Missing security headers
OpenVAS / Greenbone
OpenVAS (Open Vulnerability Assessment System) is a full-featured network vulnerability scanner, now part of the Greenbone Community Edition. It maintains a continuously updated database of Network Vulnerability Tests (NVTs).
# Install Greenbone Community Edition (Docker-based)
curl -f -L https://greenbone.github.io/docs/latest/_static/setup-and-start-greenbone-community-edition.sh \
| bash
# Or with docker compose directly
docker compose -f greenbone-community-edition.yml up -d
# Access the web interface
# https://localhost:9392
# Default credentials: admin / admin (change immediately)
# gvm-cli: command-line interface to OpenVAS/Greenbone
pip install gvm-tools
# List available scan configurations
gvm-cli --gmp-username admin --gmp-password admin socket \
--xml "<get_scan_configs/>"
# Create and start a scan via XML GMP protocol
gvm-cli socket --xml "
<create_task>
<name>Weekly Scan</name>
<config id='daba56c8-73ec-11df-a475-002264764cea'/>
<target id='TARGET-UUID'/>
</create_task>"
# Python: interact with OpenVAS via python-gvm
from gvm.connections import UnixSocketConnection
from gvm.protocols.gmp import Gmp
from gvm.transforms import EtreeTransform
connection = UnixSocketConnection(path='/run/gvmd/gvmd.sock')
transform = EtreeTransform()
with Gmp(connection, transform=transform) as gmp:
gmp.authenticate('admin', 'admin')
# List all tasks
tasks = gmp.get_tasks()
for task in tasks.findall('task'):
name = task.find('name').text
status = task.find('status').text
print(f"{name}: {status}")
Nessus / Qualys
Nessus (Tenable) and Qualys are commercial vulnerability scanners widely used in enterprise environments. They provide the same core function as OpenVAS with vendor support, compliance reporting, and cloud integrations.
Nessus basics
# Nessus runs as a web service
# Access: https://localhost:8834
# Nessus CLI via the API
curl -k -X POST https://localhost:8834/session \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}' \
| python3 -m json.tool
# Python: automate Nessus scans via REST API
import requests
import json
NESSUS_URL = 'https://localhost:8834'
SESSION = requests.Session()
SESSION.verify = False # self-signed cert on Nessus server
# Authenticate
resp = SESSION.post(f'{NESSUS_URL}/session',
json={'username': 'admin', 'password': 'password'})
token = resp.json()['token']
SESSION.headers.update({'X-Cookie': f'token={token}'})
# List scans
scans = SESSION.get(f'{NESSUS_URL}/scans').json()
for scan in scans.get('scans', []):
print(f"{scan['id']}: {scan['name']} — {scan['status']}")
# Get vulnerabilities from a completed scan
scan_id = 5
detail = SESSION.get(f'{NESSUS_URL}/scans/{scan_id}').json()
for vuln in detail.get('vulnerabilities', []):
print(f"CVSS {vuln['severity']}: {vuln['plugin_name']} ({vuln['count']} hosts)")
Qualys integration
# Python: Qualys VMDR API
import requests
from base64 import b64encode
QUALYS_URL = 'https://qualysapi.qualys.com'
credentials = b64encode(b'username:password').decode()
headers = {
'Authorization': f'Basic {credentials}',
'X-Requested-With': 'Python',
}
# Launch a vulnerability scan
resp = requests.post(
f'{QUALYS_URL}/api/2.0/fo/scan/',
headers=headers,
data={
'action': 'launch',
'scan_title': 'Weekly Production Scan',
'target_from': 'assets',
'asset_group_ids': '12345',
'option_id': '67890',
}
)
Burp Suite
Burp Suite is the professional-grade web application security testing platform. The Community Edition is free; Pro adds an automated scanner and more tools.
Setting up Burp as a proxy
# Launch Burp Suite (GUI)
java -jar burpsuite_community.jar
# Configure browser to use Burp proxy: 127.0.0.1:8080
# Install Burp's CA certificate in browser to intercept HTTPS:
# Navigate to: http://burpsuite (while proxy is active)
# Download and install the cacert.der
# Command-line: use Burp with curl
curl -x http://127.0.0.1:8080 --proxy-insecure https://target.example.com
Burp Suite tools
| Tool | Purpose |
|---|---|
| Proxy | Intercept, inspect, and modify HTTP/HTTPS traffic |
| Repeater | Replay and modify individual requests |
| Intruder | Automated payload injection (brute force, fuzzing) |
| Scanner | Automated vulnerability scanning (Pro only) |
| Decoder | Encode/decode Base64, URL, HTML, hex, etc. |
| Comparer | Diff two requests or responses |
| Logger | Full traffic log with filtering |
Burp REST API (Pro)
# Burp Suite Professional REST API
import requests
BURP_API = 'http://localhost:1337/v0.1'
# Start a scan
resp = requests.post(f'{BURP_API}/scan', json={
'urls': ['https://target.example.com'],
'scan_configurations': [{'name': 'Audit checks - all issues'}],
'application_logins': [{
'username': 'testuser',
'password': 'testpass',
}],
})
task_id = resp.json()['task_id']
# Poll for completion
import time
while True:
status = requests.get(f'{BURP_API}/scan/{task_id}').json()
if status['scan_metrics']['crawl_and_audit_progress'] == 100:
break
time.sleep(30)
# Get issues
issues = requests.get(f'{BURP_API}/scan/{task_id}/issues').json()
for issue in issues:
print(f"{issue['severity']}: {issue['issue_type']['name']} at {issue['path']}")
Infrastructure as Code Security Scanning
IaC files (Terraform, Kubernetes manifests, Dockerfile, CloudFormation) contain configuration that can introduce security vulnerabilities.
Checkov
Checkov scans IaC files for misconfigurations against hundreds of built-in checks aligned to CIS Benchmarks and cloud provider best practices:
# Install
pip install checkov
# Scan a Terraform directory
checkov -d infrastructure/
# Scan a specific file
checkov -f kubernetes/deployment.yaml
# Scan a Docker file
checkov -f Dockerfile
# Output as JSON
checkov -d infrastructure/ -o json > checkov-report.json
# Fail on HIGH severity only
checkov -d infrastructure/ --compact --soft-fail-on MEDIUM,LOW
# Skip specific checks (with documented justification)
checkov -d infrastructure/ --skip-check CKV_AWS_18,CKV_AWS_21
# Parse Checkov JSON output
import subprocess
import json
result = subprocess.run(
['checkov', '-d', 'infrastructure/', '-o', 'json'],
capture_output=True, text=True
)
data = json.loads(result.stdout)
passed = data['summary']['passed']
failed = data['summary']['failed']
print(f"Passed: {passed}, Failed: {failed}")
for check in data.get('results', {}).get('failed_checks', []):
print(f"FAIL {check['check_id']}: {check['check_result']['result']} — "
f"{check['resource']} in {check['file_path']}:{check['file_line_range']}")
tfsec
tfsec is a Terraform-specific security scanner. Aqua has folded tfsec into
Trivy, which now performs the same checks via trivy config <dir> (or
trivy fs); tfsec itself is in maintenance mode, so prefer Trivy for new work
and treat the commands below as legacy:
# Install
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash
# Scan Terraform files
tfsec .
# Show only HIGH and CRITICAL
tfsec . --minimum-severity HIGH
# JSON output
tfsec . --format json > tfsec-report.json
# Ignore a specific rule inline
resource "aws_s3_bucket" "logs" {
bucket = "my-logs"
# tfsec:ignore:aws-s3-enable-bucket-logging
}
Automated patching
Keeping systems and dependencies patched is the single most effective vulnerability management activity. Most critical vulnerabilities are exploited in the wild within days of public disclosure.
# Debian/Ubuntu: configure unattended security upgrades
apt install unattended-upgrades
dpkg-reconfigure --priority=low unattended-upgrades
# /etc/apt/apt.conf.d/50unattended-upgrades
# Unattended-Upgrade::Allowed-Origins {
# "${distro_id}:${distro_codename}-security";
# };
# Unattended-Upgrade::Automatic-Reboot "false";
# Unattended-Upgrade::Mail "ops@example.com";
# Check what would be upgraded
unattended-upgrade --dry-run --debug
# FreeBSD: apply security patches
freebsd-update fetch && freebsd-update install
# Python dependencies: use Dependabot or Renovate
# .github/dependabot.yml
# version: 2
# updates:
# - package-ecosystem: pip
# directory: /
# schedule:
# interval: weekly
# open-pull-requests-limit: 10
# Python: check for outdated packages and CVEs
import subprocess
import json
# List outdated pip packages
result = subprocess.run(
['pip', 'list', '--outdated', '--format', 'json'],
capture_output=True, text=True
)
outdated = json.loads(result.stdout)
for pkg in outdated:
print(f"{pkg['name']}: {pkg['version']} → {pkg['latest_version']}")
# Check for CVEs with safety
result = subprocess.run(
['safety', 'check', '--json'],
capture_output=True, text=True
)
vulns = json.loads(result.stdout)
for v in vulns.get('vulnerabilities', []):
print(f"CVE {v['vulnerability_id']}: {v['package_name']} {v['analyzed_version']} "
f"— fix in {v['safe_versions']}")
Key takeaways
- Vulnerability management is a continuous lifecycle — identify, classify, prioritize, remediate, report — not a one-off scan. Point-in-time scans are necessary but not sufficient.
- Match the scanner to the target: network (Nmap, OpenVAS/Greenbone, Nessus), web app (Burp, ZAP, Nikto), container/image (Trivy, Grype), IaC/cloud (Checkov, tfsec, Prowler), dependencies (Safety, Dependabot).
- Nmap is the foundational tool — host discovery, port/service/version detection, and the NSE (
--script vuln,ssl-enum-ciphers,smb-vuln-ms17-010); machine-readable output (-oA) feeds the rest of the pipeline. - Shift IaC scanning left: Checkov and tfsec catch misconfigurations in Terraform/Kubernetes/Dockerfiles in CI, before they ever reach production.
- Patching is the highest-leverage activity — unattended security upgrades,
freebsd-update, and Dependabot/Renovate close the window before disclosed CVEs are weaponized. - Prioritize with CVSS plus context (exploitability, exposure, asset value); a scanner’s raw severity is a starting point, not the final ranking.
References
- Nmap Reference Guide. https://nmap.org/book/man.html
- Greenbone Community Edition documentation. https://greenbone.github.io/docs/latest/
- OWASP ZAP documentation. https://www.zaproxy.org/docs/
- Checkov — IaC misconfiguration scanning. https://www.checkov.io/1.Welcome/Quick%20Start.html
- Trivy — container and dependency scanning. https://trivy.dev/latest/
- NIST National Vulnerability Database. https://nvd.nist.gov/
- FIRST — CVSS v3.1 calculator. https://www.first.org/cvss/calculator/3.1
- CIS Benchmarks. https://www.cisecurity.org/cis-benchmarks
Related course pages: Introduction to Recon · Threat Modeling · DevSecOps Fundamentals
🛠️ Maintenance note: scanner tooling churns — Nessus/Qualys API shapes shift between versions, and the Python
safetyCLI now requires account auth (safety checkwas replaced bysafety scan). Re-verify the install commands and JSON field names against current releases each term, and note CVSS v4.0 now coexists with v3.1 in the NVD.