Software con CVE críticos por dispositivo
Lista por computadora el software con vulnerabilidades críticas, cuántas tienen exploit público y qué actualización se recomienda, para priorizar parches.
Ejemplo en México
Maquiladora de electrónicos en Ciudad Juárez, 400 personas con tres turnos
Las ventanas para parchar son cortas porque las líneas no paran. Hay que elegir qué actualizar en el siguiente cambio de turno.
.\get-vulnerabilidades-criticas.ps1 -RutaCsv .\vulnerabilidades.csvObtiene la lista priorizada y aprovecha la ventana para parchar primero lo que ya tiene exploit público.
Cómo implementarlo
- Instala el módulo si no lo tienes: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser.
- Corre el script e inicia sesión con una cuenta con el rol Lector de seguridad.
- Abre el CSV: arriba quedan las filas con Urgente: hay exploit público.
- Actualiza ese software con la columna Actualizaciones y vuelve a correr el script para confirmar que bajó.
Ver el código completo de get-vulnerabilidades-criticas.ps1
<#
.SYNOPSIS
¿Qué software tiene CVE críticos en cada computadora y cuál actualizo primero?
.DESCRIPTION
Consulta las tablas de Microsoft Defender Vulnerability Management con búsqueda avanzada y
lista, por dispositivo y software, los CVE de severidad crítica, cuántos tienen exploit público
y qué actualización se recomienda. Pone primero lo que ya se puede explotar.
Solo lectura: el POST a runHuntingQuery es una consulta.
.PARAMETER RutaCsv
Ruta del CSV de salida. Si se omite, solo se muestra en pantalla.
.EXAMPLE
.\get-vulnerabilidades-criticas.ps1 -RutaCsv .\vulnerabilidades.csv
.NOTES
Permisos: ThreatHunting.Read.All
Rol mínimo: Lector de seguridad
Licencia: Microsoft Defender for Endpoint Plan 2 o Microsoft Defender Vulnerability Management (complemento o independiente), o Microsoft Defender for Servers. Microsoft 365 Business Premium por sí solo no alcanza: Defender for Business no incluye búsqueda avanzada
Licencia del código: MIT. Se entrega TAL CUAL, sin garantía. Pruébalo primero en un tenant de pruebas.
#>
[CmdletBinding()]
param(
[string]$RutaCsv
)
$ErrorActionPreference = 'Stop'
$permisos = @('ThreatHunting.Read.All')
if (-not (Get-Command Connect-MgGraph -ErrorAction SilentlyContinue)) {
throw 'Falta el módulo. Instálalo con: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser'
}
Connect-MgGraph -Scopes $permisos -NoWelcome
$consulta = @'
DeviceTvmSoftwareVulnerabilities
| where VulnerabilitySeverityLevel =~ "Critical"
| join kind=leftouter (DeviceTvmSoftwareVulnerabilitiesKB | project CveId, CvssScore, IsExploitAvailable) on CveId
| summarize CveCriticos = dcount(CveId), ConExploit = countif(IsExploitAvailable == 1), CvssMaximo = max(todouble(CvssScore)),
ListaCve = make_set(CveId), Actualizaciones = make_set(RecommendedSecurityUpdate)
by DeviceName, OSPlatform, SoftwareVendor, SoftwareName, SoftwareVersion
'@
$respuesta = Invoke-MgGraphRequest -Method POST -Uri 'https://graph.microsoft.com/v1.0/security/runHuntingQuery' -Body (@{ Query = $consulta } | ConvertTo-Json) -ContentType 'application/json; charset=utf-8'
if (@($respuesta.results).Count -ge 100000) { Write-Warning 'Se alcanzó el tope de 100,000 filas de la consulta: pueden faltar resultados. Reduce el periodo o filtra más.' }
$filas = foreach ($r in $respuesta.results) {
[pscustomobject]@{
Prioridad = if ([int]$r.ConExploit -gt 0) { 'Urgente: hay exploit público' } else { 'Alta' }
Dispositivo = $r.DeviceName
Sistema = $r.OSPlatform
Fabricante = $r.SoftwareVendor
Software = $r.SoftwareName
Version = $r.SoftwareVersion
CveCriticos = [int]$r.CveCriticos
ConExploit = [int]$r.ConExploit
CvssMaximo = $r.CvssMaximo
ListaCve = @($r.ListaCve) -join ', '
Actualizaciones = @($r.Actualizaciones | Where-Object { $_ }) -join ', '
}
}
$filas = $filas | Sort-Object @{ Expression = 'ConExploit'; Descending = $true }, @{ Expression = 'CveCriticos'; Descending = $true }, Dispositivo
$equipos = @($filas | Select-Object -ExpandProperty Dispositivo -Unique).Count
$urgentes = @($filas | Where-Object ConExploit -GT 0).Count
Write-Host "Software con CVE críticos: $(@($filas).Count) registros en $equipos dispositivos. Con exploit público: $urgentes"
if ($RutaCsv) {
# UTF-8 con BOM para que Excel en español muestre bien los acentos.
$filas | Export-Csv -Path $RutaCsv -NoTypeInformation -Encoding utf8BOM
Write-Host "CSV guardado en $RutaCsv"
} else {
$filas | Format-Table -AutoSize
}