
Building Vulnerability Scanning Workflow
- 207 installs
- 27.3k repo stars
- Updated August 2, 2026
- mukul975/anthropic-cybersecurity-skills
building-vulnerability-scanning-workflow is a Claude Code skill that builds recurring Nessus/Qualys/OpenVAS scanning with risk-based prioritization and SLA remediation tracking.
About
building-vulnerability-scanning-workflow is a Claude Code skill that builds a recurring vulnerability scanning workflow using Nessus, Qualys or OpenVAS. It covers scan scheduling, risk-based prioritization beyond raw CVSS using asset criticality and CISA KEV, SIEM integration and SLA-based remediation tracking dashboards. A SOC team uses it to run and formalize continuous vulnerability assessment across infrastructure. The current catalog stage (ship) understates its ongoing operational nature.
- Nessus, Qualys and OpenVAS scan configuration
- Risk-based prioritization with asset context and CISA KEV
- SIEM integration for correlation
- SLA-based remediation tracking
Building Vulnerability Scanning Workflow by the numbers
- 207 all-time installs (skills.sh)
- +7 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #762 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
building-vulnerability-scanning-workflow capabilities & compatibility
free skill; requires a licensed scanner (Nessus/Qualys) and its API credentials
- Capabilities
- vulnerability scanning · risk based prioritization · cisa kev check · siem integration · remediation tracking
- Works with
- splunk
- Use cases
- security audit
- Pricing
- Bring your own API key
- Requires keys
- NESSUS_ACCESS_KEY · NESSUS_SECRET_KEY · QUALYS_API_PASSWORD
What building-vulnerability-scanning-workflow says it does
Do not use** for penetration testing or active exploitation — vulnerability scanning identifies weaknesses, penetration testing validates exploitability.
SOC teams need to establish or improve recurring vulnerability scanning programs
npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill building-vulnerability-scanning-workflowAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 207 |
|---|---|
| repo stars | ★ 27.3k |
| Last updated | August 2, 2026 |
| Repository | mukul975/anthropic-cybersecurity-skills ↗ |
How do I run recurring vulnerability scans and prioritize remediation beyond raw CVSS?
security-audit
Who is it for?
SOC teams running continuous vulnerability management across infrastructure.
Skip if: Penetration testing or active exploitation; vulnerability scanning identifies weaknesses, penetration testing validates exploitability.
When should I use this skill?
When SOC teams need to establish recurring vulnerability assessment processes, integrate scan results with SIEM alerting, and build remediation tracking dashboards.
What you get
A scheduled scanning workflow with risk-scored findings, SIEM integration and SLA-tracked remediation.
- Recurring scan policies
- Prioritized remediation dashboard with SLAs
By the numbers
- Supports Nessus, Qualys and OpenVAS
- SLA tiers P1 24h to lower priorities
- boosts risk score 1.5x for CISA KEV CVEs
Files
Building Vulnerability Scanning Workflow
When to Use
Use this skill when:
- SOC teams need to establish or improve recurring vulnerability scanning programs
- Scan results require prioritization beyond raw CVSS scores using asset context and threat intelligence
- Vulnerability data must be integrated into SIEM for correlation with exploitation attempts
- Remediation tracking needs formalization with SLA-based dashboards and reporting
Do not use for penetration testing or active exploitation — vulnerability scanning identifies weaknesses, penetration testing validates exploitability.
Prerequisites
- Vulnerability scanner (Tenable Nessus Professional, Qualys VMDR, or OpenVAS/Greenbone)
- Asset inventory with criticality classifications (business-critical, standard, development)
- Network access from scanner to all target segments (agent-based or network scan)
- SIEM integration for scan result ingestion and correlation
- Patch management system (WSUS, SCCM, Intune) for remediation tracking
Workflow
Step 1: Define Scan Scope and Scheduling
Create scan policies covering all asset types:
Nessus Scan Configuration (API):
import requests
nessus_url = "https://nessus.company.com:8834"
headers = {"X-ApiKeys": f"accessKey={access_key};secretKey={secret_key}"}
# Create scan policy
policy = {
"uuid": "advanced",
"settings": {
"name": "SOC Weekly Infrastructure Scan",
"description": "Weekly credentialed scan of all server and workstation segments",
"scanner_id": 1,
"policy_id": 0,
"text_targets": "10.0.0.0/16, 172.16.0.0/12",
"launch": "WEEKLY",
"starttime": "20240315T020000",
"rrules": "FREQ=WEEKLY;INTERVAL=1;BYDAY=SA",
"enabled": True
},
"credentials": {
"add": {
"Host": {
"Windows": [{
"domain": "company.local",
"username": "nessus_svc",
"password": "SCAN_SERVICE_PASSWORD",
"auth_method": "Password"
}],
"SSH": [{
"username": "nessus_svc",
"private_key": "/path/to/nessus_key",
"auth_method": "public key"
}]
}
}
}
}
response = requests.post(f"{nessus_url}/scans", headers=headers, json=policy,
verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true") # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
scan_id = response.json()["scan"]["id"]
print(f"Scan created: ID {scan_id}")Qualys VMDR Scan via API:
import qualysapi
conn = qualysapi.connect(
hostname="qualysapi.qualys.com",
username="api_user",
password="API_PASSWORD"
)
# Launch vulnerability scan
params = {
"action": "launch",
"scan_title": "Weekly_Infrastructure_Scan",
"ip": "10.0.0.0/16",
"option_id": "123456", # Scan profile ID
"iscanner_name": "Internal_Scanner_01",
"priority": "0"
}
response = conn.request("/api/2.0/fo/scan/", params)
print(f"Scan launched: {response}")Step 2: Process and Prioritize Scan Results
Download results and apply risk-based prioritization:
import requests
import csv
# Export Nessus results
response = requests.get(
f"{nessus_url}/scans/{scan_id}/export",
headers=headers,
params={"format": "csv"},
verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
)
# Parse and prioritize
vulns = []
reader = csv.DictReader(response.text.splitlines())
for row in reader:
cvss = float(row.get("CVSS v3.0 Base Score", 0))
asset_criticality = get_asset_criticality(row["Host"]) # From asset inventory
# Risk-based priority calculation
risk_score = cvss * asset_criticality_multiplier(asset_criticality)
# Boost score if actively exploited (check CISA KEV)
if row.get("CVE") in cisa_kev_list:
risk_score *= 1.5
vulns.append({
"host": row["Host"],
"plugin_name": row["Name"],
"severity": row["Risk"],
"cvss": cvss,
"cve": row.get("CVE", "N/A"),
"risk_score": round(risk_score, 1),
"asset_criticality": asset_criticality,
"kev": row.get("CVE") in cisa_kev_list
})
# Sort by risk score
vulns.sort(key=lambda x: x["risk_score"], reverse=True)CISA KEV (Known Exploited Vulnerabilities) Check:
import requests
kev_response = requests.get(
"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
)
kev_data = kev_response.json()
cisa_kev_list = {v["cveID"] for v in kev_data["vulnerabilities"]}
# Check if vulnerability is actively exploited
def is_actively_exploited(cve_id):
return cve_id in cisa_kev_listStep 3: Define Remediation SLAs
Apply SLA-based remediation timelines:
| Priority | CVSS Range | Asset Type | SLA | Examples |
|---|---|---|---|---|
| P1 Critical | 9.0-10.0 + KEV | All assets | 24 hours | Log4Shell, EternalBlue on prod servers |
| P2 High | 7.0-8.9 or 9.0+ non-KEV | Business-critical | 7 days | RCE without known exploit |
| P3 Medium | 4.0-6.9 | Business-critical | 30 days | Authenticated privilege escalation |
| P4 Low | 0.1-3.9 | Standard | 90 days | Information disclosure, low-impact DoS |
| P5 Informational | 0.0 | Development | Next cycle | Best practice findings, config hardening |
Step 4: Integrate with SIEM for Exploitation Detection
Correlate vulnerability scan data with SIEM alerts to detect active exploitation:
index=vulnerability sourcetype="nessus:scan"
| eval vuln_key = Host.":".CVE
| join vuln_key type=left [
search index=ids_ips sourcetype="snort" OR sourcetype="suricata"
| eval vuln_key = dest_ip.":".cve_id
| stats count AS exploit_attempts, latest(_time) AS last_exploit_attempt by vuln_key
]
| where isnotnull(exploit_attempts)
| eval risk = "CRITICAL — Vulnerability being actively exploited"
| sort - exploit_attempts
| table Host, CVE, plugin_name, cvss_score, exploit_attempts, last_exploit_attempt, riskAlert when KEV vulnerabilities are detected on critical assets:
index=vulnerability sourcetype="nessus:scan" severity="Critical"
| lookup cisa_kev_lookup.csv cve_id AS CVE OUTPUT kev_status, due_date
| where kev_status="active"
| lookup asset_criticality_lookup.csv ip AS Host OUTPUT criticality
| where criticality IN ("business-critical", "mission-critical")
| table Host, CVE, plugin_name, cvss_score, kev_status, due_date, criticalityStep 5: Build Remediation Tracking Dashboard
Splunk Dashboard for Vulnerability Metrics:
-- Open vulnerabilities by severity
index=vulnerability sourcetype="nessus:scan" status="open"
| stats count by severity
| eval order = case(severity="Critical", 1, severity="High", 2, severity="Medium", 3,
severity="Low", 4, 1=1, 5)
| sort order
-- SLA compliance tracking
index=vulnerability sourcetype="nessus:scan" status="open"
| eval sla_days = case(
severity="Critical", 1,
severity="High", 7,
severity="Medium", 30,
severity="Low", 90
)
| eval days_open = round((now() - first_detected) / 86400)
| eval sla_status = if(days_open > sla_days, "OVERDUE", "Within SLA")
| stats count by severity, sla_status
-- Remediation trend over 90 days
index=vulnerability sourcetype="nessus:scan"
| eval is_open = if(status="open", 1, 0)
| eval is_closed = if(status="fixed", 1, 0)
| timechart span=1w sum(is_open) AS opened, sum(is_closed) AS remediatedStep 6: Automate Remediation Ticketing
Create tickets automatically for high-priority findings:
import requests
servicenow_url = "https://company.service-now.com/api/now/table/incident"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {snow_token}"
}
for vuln in vulns:
if vuln["risk_score"] >= 8.0:
ticket = {
"short_description": f"[VULN] {vuln['cve']} — {vuln['plugin_name']} on {vuln['host']}",
"description": (
f"Vulnerability: {vuln['plugin_name']}\n"
f"CVE: {vuln['cve']}\n"
f"CVSS: {vuln['cvss']}\n"
f"Host: {vuln['host']}\n"
f"Asset Criticality: {vuln['asset_criticality']}\n"
f"CISA KEV: {'YES' if vuln['kev'] else 'NO'}\n"
f"Risk Score: {vuln['risk_score']}\n"
f"Remediation SLA: {'24 hours' if vuln['kev'] else '7 days'}"
),
"urgency": "1" if vuln["kev"] else "2",
"impact": "1" if vuln["asset_criticality"] == "business-critical" else "2",
"assignment_group": "IT Infrastructure",
"category": "Vulnerability"
}
response = requests.post(servicenow_url, headers=headers, json=ticket)
print(f"Ticket created: {response.json()['result']['number']}")Key Concepts
| Term | Definition |
|---|---|
| CVSS | Common Vulnerability Scoring System — standardized severity rating (0-10) for vulnerabilities |
| CISA KEV | Known Exploited Vulnerabilities catalog — CISA-maintained list of vulnerabilities with confirmed active exploitation |
| Credentialed Scan | Vulnerability scan using authenticated access for deeper detection than network-only scanning |
| Asset Criticality | Business impact classification determining remediation priority (mission-critical, business-critical, standard) |
| Remediation SLA | Service Level Agreement defining maximum time allowed to patch vulnerabilities by severity |
| EPSS | Exploit Prediction Scoring System — ML-based probability score predicting likelihood of exploitation |
Tools & Systems
- Tenable Nessus / Tenable.io: Enterprise vulnerability scanner with 200,000+ plugin checks and compliance auditing
- Qualys VMDR: Cloud-based vulnerability management with asset discovery, prioritization, and patching integration
- OpenVAS (Greenbone): Open-source vulnerability scanner with community-maintained vulnerability feed
- CISA KEV Catalog: US government maintained list of actively exploited vulnerabilities requiring mandatory remediation
- Rapid7 InsightVM: Vulnerability management platform with live dashboards and remediation project tracking
Common Scenarios
- Zero-Day Response: New CVE published — run targeted scan for affected software, cross-reference with KEV and exploit databases
- Compliance Audit Prep: Generate PCI DSS or HIPAA vulnerability report showing scan coverage and remediation status
- Post-Patch Verification: Rescan patched systems to confirm vulnerability closure and update tracking dashboard
- Network Expansion: New subnet added to infrastructure — onboard to scan scope with appropriate policy
- Third-Party Risk: Scan externally-facing assets to validate vendor patch compliance before integration
Output Format
VULNERABILITY SCAN REPORT — Weekly Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Scan Date: 2024-03-16 02:00 UTC
Scan Scope: 10.0.0.0/16 (1,247 hosts scanned)
Duration: 4h 23m
Coverage: 98.7% (16 hosts unreachable)
Findings:
Severity Count New CISA KEV
Critical 23 5 3
High 187 34 12
Medium 892 78 0
Low 1,456 112 0
Info 3,891 201 0
Top Priority (P1 — 24hr SLA):
CVE-2024-21762 FortiOS RCE 3 hosts KEV: YES
CVE-2024-1709 ConnectWise RCE 1 host KEV: YES
CVE-2024-3400 Palo Alto PAN-OS RCE 2 hosts KEV: YES
SLA Compliance:
Critical: 82% within SLA (4 overdue)
High: 91% within SLA (17 overdue)
Medium: 88% within SLA (107 overdue)
Tickets Created: 39 (ServiceNow)
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
API Reference: Vulnerability Scanning Workflow Agent
Overview
Orchestrates vulnerability scanning using Nmap and Nessus, enriches findings with CISA KEV data, applies risk-based prioritization, and generates remediation reports.
Dependencies
| Package | Version | Purpose |
|---|---|---|
| python-nmap | >=0.7.1 | Nmap scan orchestration |
| requests | >=2.28 | REST API communication |
CLI Usage
python agent.py --targets 192.168.1.0/24 --ports 1-1024 --output report.json
python agent.py --targets 10.0.0.0/16 --nessus-url https://nessus:8834 --nessus-keys "access;secret"Key Functions
run_nmap_vuln_scan(targets, ports)
Runs Nmap with -sV --script=vulners,vulscan for service version detection and vulnerability matching.
fetch_cisa_kev()
Downloads the CISA Known Exploited Vulnerabilities JSON catalog and returns a set of CVE IDs.
launch_nessus_scan(nessus_url, api_keys, scan_name, targets)
Creates and launches a vulnerability scan via the Nessus REST API.
prioritize_vulnerabilities(vulns, kev_set, asset_criticality_map)
Applies risk scoring: risk_score = CVSS * asset_criticality * (1.5 if KEV). Assigns P1-P4 priority.
create_servicenow_ticket(snow_url, token, vuln)
Creates ServiceNow incident tickets for high-priority vulnerability findings.
generate_report(vulns)
Produces a formatted vulnerability scan summary with priority breakdown.
External APIs Used
| API | Endpoint | Purpose |
|---|---|---|
| CISA KEV | https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json | Known exploited vulns |
| Nessus | /scans, /scans/{id}/launch | Scan management |
| ServiceNow | /api/now/table/incident | Ticket creation |
#!/usr/bin/env python3
"""Vulnerability Scanning Workflow Agent - Automates scan orchestration and prioritization."""
import json
import logging
import os
import argparse
from datetime import datetime
import requests
import nmap
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
def run_nmap_vuln_scan(targets, ports="1-1024"):
"""Run Nmap vulnerability scan against target hosts."""
scanner = nmap.PortScanner()
logger.info("Starting Nmap vuln scan on %s ports %s", targets, ports)
scanner.scan(hosts=targets, ports=ports, arguments="-sV --script=vulners,vulscan")
results = []
for host in scanner.all_hosts():
for proto in scanner[host].all_protocols():
for port in scanner[host][proto]:
service = scanner[host][proto][port]
results.append({
"host": host,
"port": port,
"protocol": proto,
"state": service["state"],
"service": service.get("name", ""),
"version": service.get("version", ""),
"scripts": service.get("script", {}),
})
logger.info("Nmap scan complete: %d service entries", len(results))
return results
def fetch_cisa_kev():
"""Fetch the CISA Known Exploited Vulnerabilities catalog."""
url = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
resp = requests.get(url, timeout=30)
resp.raise_for_status()
kev_data = resp.json()
kev_set = {v["cveID"] for v in kev_data["vulnerabilities"]}
logger.info("Loaded %d CISA KEV entries", len(kev_set))
return kev_set
def launch_nessus_scan(nessus_url, api_keys, scan_name, targets):
"""Launch a vulnerability scan via Nessus REST API."""
headers = {"X-ApiKeys": api_keys, "Content-Type": "application/json"}
scan_config = {
"uuid": "advanced",
"settings": {
"name": scan_name,
"text_targets": targets,
"launch": "ON_DEMAND",
"enabled": True,
},
}
resp = requests.post(
f"{nessus_url}/scans", headers=headers, json=scan_config,
verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30 # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
)
resp.raise_for_status()
scan_id = resp.json()["scan"]["id"]
logger.info("Nessus scan created: ID %d", scan_id)
requests.post(
f"{nessus_url}/scans/{scan_id}/launch", headers=headers,
verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30 # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
)
logger.info("Nessus scan %d launched", scan_id)
return scan_id
def prioritize_vulnerabilities(vulns, kev_set, asset_criticality_map):
"""Apply risk-based prioritization to vulnerability findings."""
for vuln in vulns:
cvss = vuln.get("cvss", 0.0)
cve = vuln.get("cve", "")
host = vuln.get("host", "")
criticality = asset_criticality_map.get(host, 1.0)
risk_score = cvss * criticality
if cve in kev_set:
risk_score *= 1.5
vuln["kev"] = True
else:
vuln["kev"] = False
vuln["risk_score"] = round(risk_score, 1)
vuln["priority"] = (
"P1" if risk_score >= 13.5 else
"P2" if risk_score >= 7.0 else
"P3" if risk_score >= 4.0 else
"P4"
)
vulns.sort(key=lambda x: x["risk_score"], reverse=True)
return vulns
def create_servicenow_ticket(snow_url, token, vuln):
"""Create a ServiceNow incident ticket for a high-priority vulnerability."""
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}
ticket = {
"short_description": f"[VULN] {vuln.get('cve', 'N/A')} on {vuln['host']}",
"description": (
f"CVE: {vuln.get('cve', 'N/A')}\n"
f"CVSS: {vuln.get('cvss', 0)}\n"
f"Host: {vuln['host']}\n"
f"Risk Score: {vuln['risk_score']}\n"
f"CISA KEV: {'YES' if vuln.get('kev') else 'NO'}"
),
"urgency": "1" if vuln.get("kev") else "2",
"category": "Vulnerability",
}
resp = requests.post(
f"{snow_url}/api/now/table/incident", headers=headers, json=ticket, timeout=30
)
logger.info("ServiceNow ticket created: %s", resp.json().get("result", {}).get("number"))
return resp.json()
def generate_report(vulns):
"""Generate vulnerability scan summary report."""
p1 = [v for v in vulns if v.get("priority") == "P1"]
p2 = [v for v in vulns if v.get("priority") == "P2"]
lines = [
"VULNERABILITY SCAN REPORT",
"=" * 40,
f"Date: {datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC')}",
f"Total Findings: {len(vulns)}",
f"P1 Critical: {len(p1)}",
f"P2 High: {len(p2)}",
"",
"TOP PRIORITY FINDINGS:",
]
for v in p1[:10]:
lines.append(f" {v.get('cve', 'N/A'):20s} {v['host']:15s} Score: {v['risk_score']}")
print("\n".join(lines))
return lines
def main():
parser = argparse.ArgumentParser(description="Vulnerability Scanning Workflow Agent")
parser.add_argument("--targets", required=True, help="Target hosts/CIDR")
parser.add_argument("--ports", default="1-1024", help="Port range to scan")
parser.add_argument("--nessus-url", help="Nessus API URL")
parser.add_argument("--nessus-keys", help="Nessus API keys (accessKey;secretKey)")
parser.add_argument("--output", default="vuln_report.json")
args = parser.parse_args()
kev_set = fetch_cisa_kev()
results = run_nmap_vuln_scan(args.targets, args.ports)
if args.nessus_url and args.nessus_keys:
launch_nessus_scan(args.nessus_url, args.nessus_keys, "Agent Scan", args.targets)
prioritized = prioritize_vulnerabilities(results, kev_set, {})
generate_report(prioritized)
with open(args.output, "w") as f:
json.dump(prioritized, f, indent=2)
logger.info("Report saved to %s", args.output)
if __name__ == "__main__":
main()
Related skills
FAQ
Which scanners does it support?
Tenable Nessus Professional, Qualys VMDR, and OpenVAS/Greenbone, configured via their APIs.
How does it prioritize findings?
By risk score combining CVSS with asset criticality and a 1.5x boost for CVEs in the CISA Known Exploited Vulnerabilities list.