mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-11 10:03:42 +03:00
399 lines
15 KiB
Markdown
399 lines
15 KiB
Markdown
---
|
|
name: performing-agentless-vulnerability-scanning
|
|
description: Configure and execute agentless vulnerability scanning using network protocols, cloud snapshot analysis, and API-based discovery to assess systems without installing endpoint agents.
|
|
domain: cybersecurity
|
|
subdomain: vulnerability-management
|
|
tags: [agentless-scanning, vulnerability-assessment, cloud-security, ssh, wmi, snapshot-analysis, vuls, tenable]
|
|
version: "1.0"
|
|
author: mahipal
|
|
license: Apache-2.0
|
|
---
|
|
# Performing Agentless Vulnerability Scanning
|
|
|
|
## Overview
|
|
Agentless vulnerability scanning assesses systems for security weaknesses without requiring endpoint agent installation. This approach leverages existing network protocols (SSH for Linux, WMI for Windows), cloud provider APIs for snapshot-based analysis, and authenticated remote checks. Modern cloud platforms like Microsoft Defender for Cloud, Wiz, Datadog, and Tenable perform out-of-band analysis by taking disk snapshots and examining OS configurations and installed packages offline. The open-source tool Vuls provides agentless scanning based on NVD and OVAL data for Linux/FreeBSD systems. This skill covers configuring agentless scans across on-premises, cloud, and containerized environments.
|
|
|
|
|
|
## When to Use
|
|
|
|
- When conducting security assessments that involve performing agentless vulnerability scanning
|
|
- When following incident response procedures for related security events
|
|
- When performing scheduled security testing or auditing activities
|
|
- When validating security controls through hands-on testing
|
|
|
|
## Prerequisites
|
|
- SSH key-based authentication configured on Linux/Unix targets
|
|
- WMI/WinRM access on Windows targets with appropriate credentials
|
|
- Cloud provider API credentials (AWS IAM, Azure RBAC, GCP IAM)
|
|
- Network access from scanner to target systems on required ports
|
|
- Service account with read-only access to target system configurations
|
|
- Python 3.8+ for custom scanning automation
|
|
|
|
## Core Concepts
|
|
|
|
### Agentless vs Agent-Based Scanning
|
|
|
|
| Aspect | Agentless | Agent-Based |
|
|
|--------|-----------|-------------|
|
|
| Deployment | No software installation needed | Agent install on every endpoint |
|
|
| Network dependency | Requires network connectivity | Works offline with cloud sync |
|
|
| Performance impact | Minimal on target systems | Light continuous overhead |
|
|
| Coverage depth | Depends on protocol/credentials | Deep local access |
|
|
| Cloud snapshot analysis | Native capability | Not applicable |
|
|
| Ideal for | Cloud VMs, IoT, legacy systems, OT | Managed endpoints, laptops |
|
|
|
|
### Agentless Scanning Methods
|
|
|
|
| Method | Protocol | Target OS | Port | Use Case |
|
|
|--------|----------|-----------|------|----------|
|
|
| SSH Remote Commands | SSH | Linux/Unix | 22 | Package enumeration, config audit |
|
|
| WMI Remote Query | WMI/DCOM | Windows | 135, 445 | Hotfix enumeration, registry checks |
|
|
| WinRM PowerShell | WS-Man | Windows | 5985/5986 | Remote command execution |
|
|
| SNMP Community | SNMP v2c/v3 | Network devices | 161 | Device fingerprinting, firmware check |
|
|
| Cloud Snapshot | Provider API | Cloud VMs | N/A | Disk image analysis |
|
|
| Container Registry | HTTPS | Container images | 443 | Image vulnerability scanning |
|
|
| API-Based | REST/HTTPS | SaaS/Cloud | 443 | Configuration assessment |
|
|
|
|
### Cloud Snapshot Analysis Flow
|
|
```
|
|
1. Scanner requests disk snapshot via cloud API
|
|
2. Cloud provider creates snapshot of VM root + data disks
|
|
3. Scanner mounts snapshot in isolated analysis environment
|
|
4. Scanner examines OS packages, configurations, file system
|
|
5. Snapshot is deleted after analysis (no persistent copies)
|
|
6. Results sent to central management console
|
|
```
|
|
|
|
## Workflow
|
|
|
|
### Step 1: SSH-Based Agentless Scanning (Linux)
|
|
|
|
```bash
|
|
# Create dedicated scan SSH key pair
|
|
ssh-keygen -t ed25519 -f /opt/scanner/.ssh/scan_key -N "" \
|
|
-C "vuln-scanner@security.local"
|
|
|
|
# Deploy public key to targets via Ansible
|
|
# ansible-playbook deploy_scan_key.yml
|
|
|
|
# Test connectivity to target
|
|
ssh -i /opt/scanner/.ssh/scan_key -o ConnectTimeout=10 \
|
|
scanner@target-host "cat /etc/os-release && dpkg -l 2>/dev/null || rpm -qa"
|
|
```
|
|
|
|
```python
|
|
import paramiko
|
|
import json
|
|
|
|
class AgentlessLinuxScanner:
|
|
"""SSH-based agentless vulnerability scanner for Linux systems."""
|
|
|
|
def __init__(self, key_path):
|
|
self.key_path = key_path
|
|
|
|
def connect(self, hostname, username="scanner", port=22):
|
|
"""Establish SSH connection to target."""
|
|
client = paramiko.SSHClient()
|
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
key = paramiko.Ed25519Key.from_private_key_file(self.key_path)
|
|
client.connect(hostname, port=port, username=username, pkey=key,
|
|
timeout=30, banner_timeout=30)
|
|
return client
|
|
|
|
def get_os_info(self, client):
|
|
"""Detect OS type and version."""
|
|
_, stdout, _ = client.exec_command("cat /etc/os-release", timeout=10)
|
|
os_release = stdout.read().decode()
|
|
info = {}
|
|
for line in os_release.strip().split("\n"):
|
|
if "=" in line:
|
|
key, val = line.split("=", 1)
|
|
info[key] = val.strip('"')
|
|
return info
|
|
|
|
def get_installed_packages(self, client):
|
|
"""Enumerate installed packages."""
|
|
# Try dpkg (Debian/Ubuntu)
|
|
_, stdout, _ = client.exec_command(
|
|
"dpkg-query -W -f='${Package}|${Version}|${Architecture}\\n'",
|
|
timeout=30
|
|
)
|
|
output = stdout.read().decode().strip()
|
|
if output:
|
|
packages = []
|
|
for line in output.split("\n"):
|
|
parts = line.split("|")
|
|
if len(parts) >= 2:
|
|
packages.append({
|
|
"name": parts[0],
|
|
"version": parts[1],
|
|
"arch": parts[2] if len(parts) > 2 else "",
|
|
"manager": "dpkg"
|
|
})
|
|
return packages
|
|
|
|
# Try rpm (RHEL/CentOS/Fedora)
|
|
_, stdout, _ = client.exec_command(
|
|
"rpm -qa --queryformat '%{NAME}|%{VERSION}-%{RELEASE}|%{ARCH}\\n'",
|
|
timeout=30
|
|
)
|
|
output = stdout.read().decode().strip()
|
|
packages = []
|
|
for line in output.split("\n"):
|
|
parts = line.split("|")
|
|
if len(parts) >= 2:
|
|
packages.append({
|
|
"name": parts[0],
|
|
"version": parts[1],
|
|
"arch": parts[2] if len(parts) > 2 else "",
|
|
"manager": "rpm"
|
|
})
|
|
return packages
|
|
|
|
def check_kernel_version(self, client):
|
|
"""Get running kernel version."""
|
|
_, stdout, _ = client.exec_command("uname -r", timeout=10)
|
|
return stdout.read().decode().strip()
|
|
|
|
def check_listening_ports(self, client):
|
|
"""Enumerate listening network services."""
|
|
_, stdout, _ = client.exec_command(
|
|
"ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null",
|
|
timeout=10
|
|
)
|
|
return stdout.read().decode().strip()
|
|
|
|
def scan_host(self, hostname, username="scanner"):
|
|
"""Perform full agentless scan of a host."""
|
|
print(f"[*] Scanning {hostname}...")
|
|
client = self.connect(hostname, username)
|
|
|
|
result = {
|
|
"hostname": hostname,
|
|
"os_info": self.get_os_info(client),
|
|
"kernel": self.check_kernel_version(client),
|
|
"packages": self.get_installed_packages(client),
|
|
"listening_ports": self.check_listening_ports(client),
|
|
}
|
|
|
|
client.close()
|
|
print(f" [+] Found {len(result['packages'])} packages on {hostname}")
|
|
return result
|
|
```
|
|
|
|
### Step 2: WinRM-Based Agentless Scanning (Windows)
|
|
|
|
```python
|
|
import winrm
|
|
|
|
class AgentlessWindowsScanner:
|
|
"""WinRM-based agentless vulnerability scanner for Windows."""
|
|
|
|
def __init__(self, username, password, domain=None):
|
|
self.username = username
|
|
self.password = password
|
|
self.domain = domain
|
|
|
|
def connect(self, hostname, use_ssl=True):
|
|
"""Create WinRM session."""
|
|
port = 5986 if use_ssl else 5985
|
|
transport = "ntlm"
|
|
user = f"{self.domain}\\{self.username}" if self.domain else self.username
|
|
session = winrm.Session(
|
|
f"{'https' if use_ssl else 'http'}://{hostname}:{port}/wsman",
|
|
auth=(user, self.password),
|
|
transport=transport,
|
|
server_cert_validation="ignore"
|
|
)
|
|
return session
|
|
|
|
def get_installed_hotfixes(self, session):
|
|
"""Get installed Windows updates/hotfixes."""
|
|
cmd = "Get-HotFix | Select-Object HotFixID,InstalledOn,Description | ConvertTo-Json"
|
|
result = session.run_ps(cmd)
|
|
if result.status_code == 0:
|
|
return json.loads(result.std_out.decode())
|
|
return []
|
|
|
|
def get_installed_software(self, session):
|
|
"""Enumerate installed software from registry."""
|
|
cmd = """
|
|
$paths = @(
|
|
'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*',
|
|
'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'
|
|
)
|
|
Get-ItemProperty $paths -ErrorAction SilentlyContinue |
|
|
Where-Object {$_.DisplayName} |
|
|
Select-Object DisplayName, DisplayVersion, Publisher |
|
|
ConvertTo-Json
|
|
"""
|
|
result = session.run_ps(cmd)
|
|
if result.status_code == 0:
|
|
return json.loads(result.std_out.decode())
|
|
return []
|
|
|
|
def get_os_info(self, session):
|
|
"""Get Windows OS details."""
|
|
cmd = "Get-CimInstance Win32_OperatingSystem | Select-Object Caption,Version,BuildNumber,OSArchitecture | ConvertTo-Json"
|
|
result = session.run_ps(cmd)
|
|
if result.status_code == 0:
|
|
return json.loads(result.std_out.decode())
|
|
return {}
|
|
|
|
def scan_host(self, hostname):
|
|
"""Perform full agentless scan of Windows host."""
|
|
print(f"[*] Scanning {hostname} via WinRM...")
|
|
session = self.connect(hostname)
|
|
|
|
result = {
|
|
"hostname": hostname,
|
|
"os_info": self.get_os_info(session),
|
|
"hotfixes": self.get_installed_hotfixes(session),
|
|
"software": self.get_installed_software(session),
|
|
}
|
|
|
|
print(f" [+] Found {len(result['hotfixes'])} hotfixes, "
|
|
f"{len(result['software'])} software entries")
|
|
return result
|
|
```
|
|
|
|
### Step 3: Cloud Snapshot Scanning (AWS)
|
|
|
|
```python
|
|
import boto3
|
|
import time
|
|
|
|
class AWSSnapshotScanner:
|
|
"""AWS EC2 agentless snapshot-based vulnerability scanner."""
|
|
|
|
def __init__(self, region="us-east-1"):
|
|
self.ec2 = boto3.client("ec2", region_name=region)
|
|
|
|
def create_snapshot(self, volume_id, description="Security scan snapshot"):
|
|
"""Create EBS snapshot for analysis."""
|
|
snapshot = self.ec2.create_snapshot(
|
|
VolumeId=volume_id,
|
|
Description=description,
|
|
TagSpecifications=[{
|
|
"ResourceType": "snapshot",
|
|
"Tags": [
|
|
{"Key": "Purpose", "Value": "VulnScan"},
|
|
{"Key": "AutoDelete", "Value": "true"},
|
|
]
|
|
}]
|
|
)
|
|
snapshot_id = snapshot["SnapshotId"]
|
|
print(f" [*] Creating snapshot {snapshot_id} from {volume_id}...")
|
|
|
|
waiter = self.ec2.get_waiter("snapshot_completed")
|
|
waiter.wait(SnapshotIds=[snapshot_id])
|
|
print(f" [+] Snapshot {snapshot_id} ready")
|
|
return snapshot_id
|
|
|
|
def delete_snapshot(self, snapshot_id):
|
|
"""Clean up snapshot after analysis."""
|
|
self.ec2.delete_snapshot(SnapshotId=snapshot_id)
|
|
print(f" [+] Deleted snapshot {snapshot_id}")
|
|
|
|
def scan_instance(self, instance_id):
|
|
"""Scan an EC2 instance via snapshot analysis."""
|
|
print(f"[*] Agentless scan of instance {instance_id}")
|
|
|
|
instance = self.ec2.describe_instances(
|
|
InstanceIds=[instance_id]
|
|
)["Reservations"][0]["Instances"][0]
|
|
|
|
root_volume = None
|
|
for bdm in instance.get("BlockDeviceMappings", []):
|
|
if bdm["DeviceName"] == instance.get("RootDeviceName"):
|
|
root_volume = bdm["Ebs"]["VolumeId"]
|
|
break
|
|
|
|
if not root_volume:
|
|
print(" [!] No root volume found")
|
|
return None
|
|
|
|
snapshot_id = self.create_snapshot(root_volume)
|
|
try:
|
|
# Analysis would be performed here
|
|
# Mount snapshot, examine packages, check configs
|
|
result = {
|
|
"instance_id": instance_id,
|
|
"snapshot_id": snapshot_id,
|
|
"root_volume": root_volume,
|
|
"platform": instance.get("Platform", "linux"),
|
|
"state": instance["State"]["Name"],
|
|
}
|
|
return result
|
|
finally:
|
|
self.delete_snapshot(snapshot_id)
|
|
```
|
|
|
|
### Step 4: Vuls Open-Source Agentless Scanner
|
|
|
|
```toml
|
|
# /etc/vuls/config.toml - Vuls configuration for agentless scanning
|
|
|
|
[servers]
|
|
|
|
[servers.web-server-01]
|
|
host = "192.168.1.10"
|
|
port = "22"
|
|
user = "vuls"
|
|
keyPath = "/opt/vuls/.ssh/scan_key"
|
|
scanMode = ["fast"]
|
|
|
|
[servers.db-server-01]
|
|
host = "192.168.1.20"
|
|
port = "22"
|
|
user = "vuls"
|
|
keyPath = "/opt/vuls/.ssh/scan_key"
|
|
scanMode = ["fast-root"]
|
|
[servers.db-server-01.optional]
|
|
[servers.db-server-01.optional.sudo]
|
|
password = ""
|
|
|
|
[servers.container-host-01]
|
|
host = "192.168.1.30"
|
|
port = "22"
|
|
user = "vuls"
|
|
keyPath = "/opt/vuls/.ssh/scan_key"
|
|
scanMode = ["fast"]
|
|
containersIncluded = ["${running}"]
|
|
```
|
|
|
|
```bash
|
|
# Run Vuls agentless scan
|
|
vuls scan
|
|
|
|
# Generate report
|
|
vuls report -format-json -to-localfile
|
|
|
|
# View results
|
|
vuls tui
|
|
```
|
|
|
|
## Best Practices
|
|
1. Use SSH key-based authentication instead of passwords for Linux scanning
|
|
2. Create dedicated service accounts with minimal read-only privileges for scanning
|
|
3. Always clean up cloud snapshots after analysis to avoid storage costs and data exposure
|
|
4. Combine agentless scanning with agent-based for comprehensive coverage
|
|
5. Schedule scans during low-activity periods to minimize any performance impact
|
|
6. Rotate scanning credentials regularly and store in a secrets vault
|
|
7. Test scanner connectivity before scheduling production scans
|
|
8. Use SNMPv3 with authentication and encryption for network device scanning
|
|
|
|
## Common Pitfalls
|
|
- Using shared credentials across multiple environments without proper segmentation
|
|
- Not cleaning up temporary snapshots in cloud environments
|
|
- Assuming agentless scanning has zero performance impact (network and CPU are used)
|
|
- Missing WinRM/SSH firewall rules causing scan failures on new deployments
|
|
- Not accounting for SSH host key changes causing authentication failures
|
|
- Scanning OT/ICS devices with protocols they cannot safely handle
|
|
|
|
## Related Skills
|
|
- implementing-rapid7-insightvm-for-scanning
|
|
- implementing-wazuh-for-vulnerability-detection
|
|
- deploying-osquery-for-endpoint-monitoring
|
|
- performing-remediation-validation-scanning
|