Finding VMware's most recent vulnerability
I woke up this morning to an email pointing me to this: https://www.vmware.com/security/advisories/VMSA-2021-0002.html
My boss - Can LM tell us which ones need attention? We’d like to notify our customers proactively.
Me - Sure! Oh wait, I only have version info for the ESX servers. I’ll have to build out something to grab the vCenter versions.
So, I built a custom property source. AppliesTo:
system.virtualization =~ "VMware ESX vcenter"
&& (vcsa.user || esx.user)
&& (vcsa.pass || esx.pass)
Then the script looks like this:
/*******************************************************************************
* © 2023 Aqueduct Technologies Inc.
*
* External Resources:
* - https://developer.vmware.com/apis/vsphere-automation/v7.0U1/appliance/rest/appliance/system/version/get/
*
******************************************************************************/
import groovy.json.JsonSlurper
user = hostProps.get("vcsa.user")?: hostProps.get("esx.user")
pass = hostProps.get("vcsa.pass")?: hostProps.get("esx.pass")
host = hostProps.get("system.hostname")
session_endpoint = "/rest/com/vmware/cis/session" //endpoint for establishing an ssl session
vsphere_version_endpoint = "/rest/appliance/system/version" //endpoint for determining vsphere version
jSlurp = new JsonSlurper()
globalHeaders = [:]
genSessionId()//get session ID for future API requests
try{
def resp = httpRequest(vsphere_version_endpoint)
if (!resp) {return 1}
println("auto.vcenter.version=${resp.version}")
}
finally{deleteSessionId()}
return 0
def genSessionId(){
String auth = "Basic " + "$user:$pass".getBytes().encodeBase64().toString()
def headers = ["Authorization": (auth)]
def resp = httpRequest(session_endpoint, headers, 'POST')
globalHeaders.put('Cookie', "vmware-api-session-id=${resp as String}")
}
def deleteSessionId(){
httpRequest(session_endpoint, [:], 'DELETE')
}
def httpRequest(def endpoint, Map<String, String> headers = [:], def method = 'GET', String query = null){
URI _uri = new URI('https', null, host, 443, endpoint, query, null)
def _session = _uri.toURL().openConnection()
_session.setRequestMethod(method)
(headers + globalHeaders).each { k, v ->
_session.setRequestProperty(k, v)
}
def response = _session.getInputStream().getText()
_session.disconnect()
return (response) ? jSlurp.parseText(response).value : null
}
If you don’t have one under /Devices by Type, create a dynamic group for ESX hosts and another dynamic group for vCenter. We called ours “VMware Hosts” (AppliesTo system.virtualization =~ "VMware ESX host") and “VMware vCenters” (AppliesTo system.virtualization =~ "VMware ESX vcenter") respectively.
Then create a Resource Inventory report where the Resource Group is “Devices by Type/VMware*”. Add the system.virtualization, auto.vcenter.version, and system.version properties and run it.
Voila, you now know the version numbers of your ESX and vCenter resources and you can compare that to the versions in the VMware Advisory.