Sharing a little programming know-how…

Archive for August, 2011

McAfee ePO Logs

The McAfee ePO logs made available by the McAfee ePolicy Orchestrator agent can be easily queried and parsed to obtain the version number. The code below is a simple script for obtaining the current version of McAfee running on the target machine. I built the tool as a way to obtain information on infected hosts identified by network sensors. I was not using the ePO server and had absolutely no interest in manually opening the server UI to obtain this information.

Of course, this would be useful if you are doing penetration tests. You get the bonus of identifying online hosts AND vulnerable hosts with outdated virus definitions. The script as is will take an IP address, NetBios name or a fully-qualified domain name.

I’ve not tested this beyond the environment I wrote it for, so depending on the enterprise environment this tool may fail. It assumes the agent is configured with the default listening port of 8081 and also expects no authentication or challenge to the query. I believe the agent can be configured to only respond to the ePO server, which would provide your enterprise with an added layer of defense against network mapping tools.


import socket
import argparse
import httplib
import xml.dom.minidom

def initArgParser():
	description = 'Automated script to capture ePO version from network host.'
	parser = argparse.ArgumentParser(description=description)
	parser.add_argument('address',help='The address or name of the host to analyze.')
	return parser

def get_element(node,tag):
	try:
		root,tail = tag.split('.',1)
		nl = node.getElementsByTagName(root)
		if len(nl) > 0:
			return get_element(nl[0],tail)
	except ValueError:
		nl = node.getElementsByTagName(tag)
		if len(nl) > 0:
			return nl[0]
	return None
	
def get_version(fqdn):
	version = ''
	try:
		conn = httplib.HTTPConnection(fqdn,8081)
		name = fqdn.split(".")[0]
		get_request = "/Agent_{0}.xml".format(name)
		conn.request("GET",get_request)
		r = conn.getresponse()
		conn.close()
		data = r.read()
	
		dom = xml.dom.minidom.parseString(data)
		e = get_element(dom,'naLog.version')
		version = str(e.childNodes[0].data)
	except:
		pass
	return version
	
	
if __name__ == "__main__":
	parser = initArgParser()
	args = parser.parse_args()
	print get_version(socket.getfqdn(args.address))