Forum Discussion

Stuart_Weenig's avatar
2 years ago

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.

3 Replies

  • I needed this as well some time ago, probably for the very same reason.  Did it this way.

    import com.santaba.agent.groovyapi.esx.ESX
    import com.vmware.vim25.mo.*

    def host = hostProps.get("system.hostname")
    def user = hostProps.get("esx.user")
    def pass = hostProps.get("esx.pass")
    def addr = hostProps.get("esx.url") ?: "https://${host}/sdk"

    def svc = new ESX()
    svc.open(addr, user, pass, 10 * 1000) // timeout in 10 seconds

    def si = svc.getServiceInstance()
    def rootFolder = si.getRootFolder()

    // Get resource clusters
    HostSystem esxHost = new InventoryNavigator(rootFolder).searchManagedEntities("HostSystem").first()


    println "auto.vcenter.fullname=${si.aboutInfo.fullName}"
    println "auto.vcenter.build=${si.aboutInfo.build}"
    println "auto.vcenter.licenseproductname=${si.aboutInfo.licenseProductName}"
    println "auto.vcenter.os.type=${si.aboutInfo.osType}"
    println "auto.vcenter.product.line=${si.aboutInfo.productLineId}"
    println "auto.vcenter.version=${si.aboutInfo.version}"


    return 0
  • And here’s another reason for LM to document their Groovy libraries. That’s definitely simpler and I’ll probably be pulling it in to go alongside or replace mine.