Skip to content

Instantly share code, notes, and snippets.

@paralax
Created November 2, 2018 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paralax/d644bfa364fd4107713e93707bd08333 to your computer and use it in GitHub Desktop.
Save paralax/d644bfa364fd4107713e93707bd08333 to your computer and use it in GitHub Desktop.
prototype code to convert a web client user-agent to a sequence of MITRE CPE strings
import re
import shlex
# application-specific
def tocpe(prodstring):
if prodstring.startswith('Mozilla') or prodstring.startswith('Gecko'):
return None
templ = 'cpe:/a:{0}:{1}:{2}'
vendor = '*'
application = '*'
version = '*'
try:
application, version = prodstring.lower().split('/')
return templ.format(vendor, application, version)
except ValueError:
return None
def extract_os(uastring):
cpes = []
# look for signs of an OS
vendor = '*'
version = '*'
ostmpl = 'cpe:/o:{0}:{1}:{2}'
if 'Windows' in uastring:
vendor = 'microsoft'
os = 'windows'
elif 'Linux' in uastring:
vendor = 'linux'
os = 'linux'
elif 'Mac OS X' in uastring:
vendor = 'apple'
os = 'mac_os_x'
try:
version = re.findall('Mac OS X (\d+_\d+_?\d+?)', uastring)[0].replace('_', '.')
except IndexError:
pass
if vendor != '*':
cpes.append(ostmpl.format(vendor, os, version))
return cpes
def extract_browser(uastring):
cpes = []
# opera and MSIE are odd, handle
apptmpl = 'cpe:/a:{0}:{1}:{2}'
if 'MSIE' in uastring:
vendor = 'microsoft'
application = 'internet_explorer'
try:
for version in re.findall('MSIE (\d+\.\d+)', uastring):
cpes.append(apptmpl.format(vendor, application, version))
except IndexError:
pass
if 'Opera' in uastring:
vendor = 'opera'
application = 'opera_browser'
try:
version = re.findall('Opera (\d+\.\d+)', uastring)[0]
except IndexError:
version = '*'
cpes.append(apptmpl.format(vendor, application, version))
return cpes
def parse_ua(uastring):
cpes = list(filter(None, map(tocpe, shlex.split(uastring))))
cpes.extend(extract_browser(uastring))
cpes.extend(extract_os(uastring))
return cpes
def test():
for ua in ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Mozilla/5.0 (Windows NT 6.1; rv:34.0) Gecko/20100101 Firefox/34.0",
"Morfeus Fucking Scanner",
"PycURL/7.43.0 libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3",
"Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.01 [en]"):
print(ua)
print(parse_ua(ua))
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment