performing-agentless-vulnerability-scanning

配置并执行无代理漏洞扫描(agentless vulnerability scanning),利用网络协议、云快照分析和基于 API 的发现方式评估系统安全,无需在端点安装 Agent。

9 stars

Best use case

performing-agentless-vulnerability-scanning is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

配置并执行无代理漏洞扫描(agentless vulnerability scanning),利用网络协议、云快照分析和基于 API 的发现方式评估系统安全,无需在端点安装 Agent。

Teams using performing-agentless-vulnerability-scanning should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/performing-agentless-vulnerability-scanning/SKILL.md --create-dirs "https://raw.githubusercontent.com/killvxk/cybersecurity-skills-zh/main/skills/performing-agentless-vulnerability-scanning/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/performing-agentless-vulnerability-scanning/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How performing-agentless-vulnerability-scanning Compares

Feature / Agentperforming-agentless-vulnerability-scanningStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

配置并执行无代理漏洞扫描(agentless vulnerability scanning),利用网络协议、云快照分析和基于 API 的发现方式评估系统安全,无需在端点安装 Agent。

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 执行无代理漏洞扫描(Performing Agentless Vulnerability Scanning)

## 概述
无代理漏洞扫描(Agentless vulnerability scanning)无需在端点安装 Agent 即可评估系统安全弱点。该方法利用现有网络协议(Linux 使用 SSH、Windows 使用 WMI)、云服务商 API 进行基于快照的分析,以及经身份验证的远程检查。Microsoft Defender for Cloud、Wiz、Datadog 和 Tenable 等现代云平台通过获取磁盘快照并离线检查操作系统配置和已安装软件包,实现带外分析(out-of-band analysis)。开源工具 Vuls 基于 NVD 和 OVAL 数据为 Linux/FreeBSD 系统提供无代理扫描。本技能涵盖在本地、云端和容器化环境中配置无代理扫描。

## 前置条件
- 在 Linux/Unix 目标上配置基于 SSH 密钥的身份验证
- 在 Windows 目标上具有适当凭据的 WMI/WinRM 访问权限
- 云服务商 API 凭据(AWS IAM、Azure RBAC、GCP IAM)
- 扫描器到目标系统所需端口的网络访问权限
- 具有目标系统配置只读访问权限的服务账户
- Python 3.8+(用于自定义扫描自动化)

## 核心概念

### 无代理扫描 vs 基于 Agent 扫描

| 对比维度 | 无代理扫描 | 基于 Agent 扫描 |
|--------|-----------|-------------|
| 部署方式 | 无需安装软件 | 需在每个端点安装 Agent |
| 网络依赖 | 需要网络连接 | 可离线运行并通过云同步 |
| 性能影响 | 对目标系统影响极小 | 持续轻量级开销 |
| 覆盖深度 | 取决于协议/凭据 | 深度本地访问 |
| 云快照分析 | 原生支持 | 不适用 |
| 适用场景 | 云虚拟机、IoT、遗留系统、OT | 受管端点、笔记本电脑 |

### 无代理扫描方法

| 方法 | 协议 | 目标操作系统 | 端口 | 适用场景 |
|--------|----------|-----------|------|----------|
| SSH 远程命令 | SSH | Linux/Unix | 22 | 软件包枚举、配置审计 |
| WMI 远程查询 | WMI/DCOM | Windows | 135, 445 | 热补丁枚举、注册表检查 |
| WinRM PowerShell | WS-Man | Windows | 5985/5986 | 远程命令执行 |
| SNMP 团体字 | SNMP v2c/v3 | 网络设备 | 161 | 设备指纹识别、固件检查 |
| 云快照 | 云服务商 API | 云虚拟机 | N/A | 磁盘镜像分析 |
| 容器镜像仓库 | HTTPS | 容器镜像 | 443 | 镜像漏洞扫描 |
| 基于 API | REST/HTTPS | SaaS/Cloud | 443 | 配置评估 |

### 云快照分析流程
```
1. 扫描器通过云 API 请求磁盘快照
2. 云服务商为虚拟机根磁盘和数据磁盘创建快照
3. 扫描器在隔离分析环境中挂载快照
4. 扫描器检查操作系统软件包、配置和文件系统
5. 分析完成后删除快照(不保留持久副本)
6. 结果发送到中央管理控制台
```

## 实施步骤

### 步骤 1:基于 SSH 的无代理扫描(Linux)

```bash
# 创建专用扫描 SSH 密钥对
ssh-keygen -t ed25519 -f /opt/scanner/.ssh/scan_key -N "" \
  -C "vuln-scanner@security.local"

# 通过 Ansible 将公钥部署到目标
# ansible-playbook deploy_scan_key.yml

# 测试与目标的连通性
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 的 Linux 系统无代理漏洞扫描器。"""

    def __init__(self, key_path):
        self.key_path = key_path

    def connect(self, hostname, username="scanner", port=22):
        """与目标建立 SSH 连接。"""
        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):
        """检测操作系统类型和版本。"""
        _, 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):
        """枚举已安装的软件包。"""
        # 尝试 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

        # 尝试 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):
        """获取运行中的内核版本。"""
        _, stdout, _ = client.exec_command("uname -r", timeout=10)
        return stdout.read().decode().strip()

    def check_listening_ports(self, client):
        """枚举正在监听的网络服务。"""
        _, 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"):
        """对主机执行完整的无代理扫描。"""
        print(f"[*] 正在扫描 {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"  [+] 在 {hostname} 上发现 {len(result['packages'])} 个软件包")
        return result
```

### 步骤 2:基于 WinRM 的无代理扫描(Windows)

```python
import winrm

class AgentlessWindowsScanner:
    """基于 WinRM 的 Windows 系统无代理漏洞扫描器。"""

    def __init__(self, username, password, domain=None):
        self.username = username
        self.password = password
        self.domain = domain

    def connect(self, hostname, use_ssl=True):
        """创建 WinRM 会话。"""
        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):
        """获取已安装的 Windows 更新/热补丁。"""
        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):
        """从注册表枚举已安装的软件。"""
        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):
        """获取 Windows 操作系统详情。"""
        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):
        """对 Windows 主机执行完整的无代理扫描。"""
        print(f"[*] 通过 WinRM 扫描 {hostname}...")
        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"  [+] 发现 {len(result['hotfixes'])} 个热补丁,"
              f"{len(result['software'])} 个软件条目")
        return result
```

### 步骤 3:云快照扫描(AWS)

```python
import boto3
import time

class AWSSnapshotScanner:
    """基于 AWS EC2 EBS 快照的无代理漏洞扫描器。"""

    def __init__(self, region="us-east-1"):
        self.ec2 = boto3.client("ec2", region_name=region)

    def create_snapshot(self, volume_id, description="安全扫描快照"):
        """创建用于分析的 EBS 快照。"""
        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"  [*] 正在从 {volume_id} 创建快照 {snapshot_id}...")

        waiter = self.ec2.get_waiter("snapshot_completed")
        waiter.wait(SnapshotIds=[snapshot_id])
        print(f"  [+] 快照 {snapshot_id} 已就绪")
        return snapshot_id

    def delete_snapshot(self, snapshot_id):
        """分析完成后清理快照。"""
        self.ec2.delete_snapshot(SnapshotId=snapshot_id)
        print(f"  [+] 已删除快照 {snapshot_id}")

    def scan_instance(self, instance_id):
        """通过快照分析扫描 EC2 实例。"""
        print(f"[*] 对实例 {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("  [!] 未找到根卷")
            return None

        snapshot_id = self.create_snapshot(root_volume)
        try:
            # 此处执行分析
            # 挂载快照,检查软件包,核查配置
            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)
```

### 步骤 4:Vuls 开源无代理扫描器

```toml
# /etc/vuls/config.toml - 无代理扫描的 Vuls 配置

[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
# 运行 Vuls 无代理扫描
vuls scan

# 生成报告
vuls report -format-json -to-localfile

# 查看结果
vuls tui
```

## 最佳实践
1. 对 Linux 扫描使用基于 SSH 密钥的身份验证,而非密码
2. 为扫描创建具有最小只读权限的专用服务账户
3. 分析完成后始终清理云快照,以避免存储成本和数据暴露
4. 结合无代理扫描与 Agent 扫描以实现全面覆盖
5. 在低活动期安排扫描,以最小化性能影响
6. 定期轮换扫描凭据并存储在 Secrets Vault 中
7. 在安排生产扫描前测试扫描器连通性
8. 对网络设备扫描使用带身份验证和加密的 SNMPv3

## 常见陷阱
- 在未正确隔离的多个环境中使用共享凭据
- 未清理云环境中的临时快照
- 假设无代理扫描对性能完全无影响(网络和 CPU 仍会被使用)
- 新部署上缺少 WinRM/SSH 防火墙规则导致扫描失败
- 未考虑 SSH 主机密钥变更导致身份验证失败
- 使用 OT/ICS 设备无法安全处理的协议扫描这些设备

## 相关技能
- implementing-rapid7-insightvm-for-scanning
- implementing-wazuh-for-vulnerability-detection
- deploying-osquery-for-endpoint-monitoring
- performing-remediation-validation-scanning

Related Skills

testing-api-for-mass-assignment-vulnerability

9
from killvxk/cybersecurity-skills-zh

测试 API 是否存在批量赋值(mass assignment,自动绑定)漏洞——攻击者可在 API 请求中附加额外参数,从而修改本不应被访问的对象属性。测试人员识别可写端点,向请求体注入未公开字段(role、isAdmin、price、balance),验证服务器是否在未过滤的情况下将这些字段绑定到数据模型。属于 OWASP API3:2023 Broken Object Property Level Authorization 范畴。适用于批量赋值测试、参数绑定滥用、自动绑定漏洞或 API 过度发布(over-posting)相关请求。

scanning-network-with-nmap-advanced

9
from killvxk/cybersecurity-skills-zh

使用 Nmap 的脚本引擎、时序控制、规避技术和输出解析,对授权目标网络执行高级网络侦察, 发现主机、枚举服务、检测漏洞并识别操作系统。

scanning-kubernetes-manifests-with-kubesec

9
from killvxk/cybersecurity-skills-zh

使用 Kubesec 对 Kubernetes 资源清单执行安全风险分析,识别错误配置、权限提升风险以及与安全最佳实践的偏差。

scanning-infrastructure-with-nessus

9
from killvxk/cybersecurity-skills-zh

Tenable Nessus 是业界领先的漏洞扫描器,用于识别网络基础设施(包括服务器、工作站、网络设备和操作系统)中的安全弱点。

scanning-docker-images-with-trivy

9
from killvxk/cybersecurity-skills-zh

Trivy 是 Aqua Security 开源的综合性漏洞扫描器,用于检测容器镜像中操作系统软件包、语言特定依赖项的漏洞、错误配置、密钥和许可证违规,并集成到 CI/CD 流水线,支持 SARIF、CycloneDX 和 SPDX 等多种输出格式。

scanning-containers-with-trivy-in-cicd

9
from killvxk/cybersecurity-skills-zh

本技能涵盖将 Aqua Security 的 Trivy 扫描器集成到 CI/CD 流水线中,用于全面的容器镜像漏洞检测。包括扫描 Docker 镜像中的操作系统包和应用依赖 CVE、检测 Dockerfile 中的错误配置、扫描文件系统和 Git 仓库,以及建立基于严重性的质量门禁以阻止有漏洞的镜像部署。

scanning-container-images-with-grype

9
from killvxk/cybersecurity-skills-zh

使用 Anchore Grype 扫描容器镜像的已知漏洞(Vulnerability),支持基于 SBOM 的匹配和可配置的严重性阈值。

performing-yara-rule-development-for-detection

9
from killvxk/cybersecurity-skills-zh

通过识别可执行文件中的唯一字节模式、字符串和行为指标,开发精准的 YARA 恶意软件检测规则,同时将误报率降至最低。

performing-wireless-security-assessment-with-kismet

9
from killvxk/cybersecurity-skills-zh

使用 Kismet 通过被动射频监控进行无线网络安全评估,检测流氓接入点(Rogue AP)、隐藏 SSID、弱加密和未授权客户端。

performing-wireless-network-penetration-test

9
from killvxk/cybersecurity-skills-zh

执行无线网络渗透测试,通过捕获握手包、破解 WPA2/WPA3 密钥、检测流氓接入点以及使用 Aircrack-ng 和相关工具测试无线网络分段,评估 WiFi 安全性。

performing-windows-artifact-analysis-with-eric-zimmerman-tools

9
from killvxk/cybersecurity-skills-zh

使用 Eric Zimmerman 的开源 EZ Tools 套件(包括 KAPE、MFTECmd、PECmd、LECmd、JLECmd 和 Timeline Explorer)执行全面的 Windows 取证制品分析,解析注册表 hive、预取文件、事件日志和文件系统元数据。

performing-wifi-password-cracking-with-aircrack

9
from killvxk/cybersecurity-skills-zh

在授权无线安全评估中捕获 WPA/WPA2 握手包,并使用 aircrack-ng、hashcat 和字典攻击进行离线密码破解, 以评估密码短语强度和无线网络安全状况。