Skip to content

Commit

Permalink
splitting up Nmap2CVE-Search.py
Browse files Browse the repository at this point in the history
  • Loading branch information
PidgeyL committed Nov 30, 2015
1 parent 71d693b commit fa05323
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 143 deletions.
51 changes: 8 additions & 43 deletions bin/Nmap2CVE-Search.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
from lib.Config import Configuration
from lib.WebDisplay import WebDisplay
from lib.TermDisplay import TermDisplay
from lib.Toolkit import enhance

from bin.converter import parseNMap
from bin.analyzer import enhance
from bin.visualizer import filtersFromArgs, displayTypeFromArgs, visualize

description='''Read Nmap scans of services or systems and use the
cve-search core to get information about these cpes.'''
Expand All @@ -45,34 +48,6 @@
parser.add_argument('-xN', metavar='xml', type=str, help='Read NMap XML file' )
args = parser.parse_args()

def parseNMap(file=None, string=None):
try:
if file: report = NmapParser.parse_fromfile(file)
if string: report = NmapParser.parse_fromstring(string)
except:
exit("Invalid Nmap xml!")
systems = []
for h in report.hosts:
system = {'mac':h.mac, 'ip':h.address, 'status':h.status, 'hostnames': h.hostnames,
'vendor':h.vendor, 'distance':h.distance}
cpeList = []
for c in h.os_match_probabilities():
for x in c.get_cpe():
cpeList.append(x)
cpeList=list(set(cpeList))
if len(cpeList)>0:
system['cpes']=cpeList
services = []
for s in h.services:
service={'port':s.port, 'banner':s.banner, 'protocol':s.protocol, 'name':s.service,
'state':s.state, 'reason':s.reason}
if s.cpelist:
service['cpe'] = s.cpelist[0].cpestring
services.append(service)
system['services']=services
systems.append(system)
return systems

if __name__ == '__main__':
# intakes
if not args.xN and not args.jN and not args.sN:
Expand All @@ -96,22 +71,12 @@ def parseNMap(file=None, string=None):
os.remove(args.j)
with open(args.j, 'w') as dump:
json.dump(syslist, dump)
#filters
filters={'access':[],'impact':[]}
if args.fL: filters['access'].append('LOCAL')
if args.fAN: filters['access'].append('ADJECENT_NETWORK')
if args.fN: filters['access'].append('NETWORK')
if args.fC: filters['impact'].append('confidentiality')
if args.fI: filters['impact'].append('integrity')
if args.fA: filters['impact'].append('availability')

#CVE-Scan magic
try:
syslist=enhance(syslist,exploitsOnly=args.e,filters=filters)
syslist=enhance(syslist)
except:
sys.exit("Could not connect to the CVE-Search API on %s:%s"%(Configuration.getCVESearch()))
#server
if not args.s and not args.t:
WebDisplay.start(systems=syslist)
elif args.t:
TermDisplay.start(systems=syslist)
filters=filtersFromArgs(args)
display=displayTypeFromArgs(args)
visualize(syslist, args.e, filters, display)
64 changes: 17 additions & 47 deletions bin/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,7 @@

from lib.Config import Configuration
from lib.Toolkit import writeJson

description='''Read input from NMap and use the information from
cve-search to find potential vulnerabilities in the
recognized systems and their services'''

parser = argparse.ArgumentParser(description=description)
parser.add_argument('-j', metavar='json', type=str, help='Dump output to json file' )
parser.add_argument('-jN', metavar='json', type=str, help='Read Json file in Nmap2CVE format' )
parser.add_argument('-xN', metavar='xml', type=str, help='Read NMap XML file' )
parser.add_argument('out', metavar='output', type=str, help='Output file')
args = parser.parse_args()

def parseNMap(file=None, string=None):
try:
if file: report = NmapParser.parse_fromfile(file)
if string: report = NmapParser.parse_fromstring(string)
except:
exit("Invalid Nmap xml!")
# TO-DO: Add scan info: date, scan type... and change format to {scandate: x, scantype: y, systems: z}
systems = []
for h in report.hosts:
system = {'mac':h.mac, 'ip':h.address, 'status':h.status, 'hostnames': h.hostnames,
'vendor':h.vendor, 'distance':h.distance}
cpeList = []
for c in h.os_match_probabilities():
for x in c.get_cpe():
cpeList.append(x)
cpeList=list(set(cpeList))
if len(cpeList)>0:
system['cpes']=cpeList
services = []
for s in h.services:
service={'port':s.port, 'banner':s.banner, 'protocol':s.protocol, 'name':s.service,
'state':s.state, 'reason':s.reason}
if s.cpelist:
service['cpe'] = s.cpelist[0].cpestring
services.append(service)
system['services']=services
systems.append(system)
return systems
from bin.converter import parseNMap

def enhance(systems):
host,port=Configuration.getCVESearch()
Expand All @@ -87,6 +48,16 @@ def enhance(systems):


if __name__ == '__main__':
# argument parser
description='''Read input from NMap and use the information from
cve-search to find potential vulnerabilities in the
recognized systems and their services'''
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-jN', metavar='json', type=str, help='Read Json file in Nmap2CVE format' )
parser.add_argument('-xN', metavar='xml', type=str, help='Read NMap XML file' )
parser.add_argument('out', metavar='output', type=str, help='Output file')
args = parser.parse_args()

# input
if not args.xN and not args.jN and not args.sN: sys.exit("No input selected!")
if args.xN:
Expand All @@ -97,12 +68,11 @@ def enhance(systems):
except:
sys.exit("Invalid JSon format!")
#output
if args.j: writeJson(args.j, syslist)

#CVE-Scan magic
# try:
syslist=enhance(syslist)
writeJson(args.out, syslist)
# except Exception as e:
# print(e)
# sys.exit("Could not connect to the CVE-Search API on %s:%s"%(Configuration.getCVESearch()))
try:
syslist=enhance(syslist)
writeJson(args.out, syslist)
except Exception as e:
print(e)
sys.exit("Could not connect to the CVE-Search API on %s:%s"%(Configuration.getCVESearch()))
28 changes: 14 additions & 14 deletions bin/visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@
from lib.WebDisplay import WebDisplay
from lib.TermDisplay import TermDisplay

description='''Visualizes the enhanced nmap results'''

parser = argparse.ArgumentParser(description=description)
parser.add_argument('-t', action='store_true', help='Use terminal GUI')
parser.add_argument('-e', action='store_true', help='Show only CVEs with known exploitation scripts')
parser.add_argument('-fN', action='store_true', help='Filter: Exploitable via network')
parser.add_argument('-fL', action='store_true', help='Filter: Exploitable locally')
parser.add_argument('-fAN',action='store_true', help='Filter: Exploitable via adjecent network')
parser.add_argument('-fC', action='store_true', help='Filter: Impacts Confidentiality')
parser.add_argument('-fI', action='store_true', help='Filter: Impacts Integrity')
parser.add_argument('-fA', action='store_true', help='Filter: Impacts Availability')
parser.add_argument('inp', metavar='input', help='output file from analyzer' )
args = parser.parse_args()

def filtersFromArgs(args):
# populate filters
filters={'access':[],'impact':[]}
Expand Down Expand Up @@ -71,6 +57,20 @@ def visualize(data, exploitOnly=False, filters={}, display="web"):
else: sys.exit("Could not visualize: Unknown display (%s)"%display)

if __name__ == '__main__':
# argument parser
description='''Visualizes the enhanced nmap results'''
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-t', action='store_true', help='Use terminal GUI')
parser.add_argument('-e', action='store_true', help='Show only CVEs with known exploitation scripts')
parser.add_argument('-fN', action='store_true', help='Filter: Exploitable via network')
parser.add_argument('-fL', action='store_true', help='Filter: Exploitable locally')
parser.add_argument('-fAN',action='store_true', help='Filter: Exploitable via adjecent network')
parser.add_argument('-fC', action='store_true', help='Filter: Impacts Confidentiality')
parser.add_argument('-fI', action='store_true', help='Filter: Impacts Integrity')
parser.add_argument('-fA', action='store_true', help='Filter: Impacts Availability')
parser.add_argument('inp', metavar='input', help='output file from analyzer' )
args = parser.parse_args()

# intakes
try:
syslist=json.loads(open(args.inp).read())
Expand Down
39 changes: 0 additions & 39 deletions lib/Toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def toLocalTime(utc):
output = output.strftime('%d-%m-%Y - %H:%M')
return output


def toHuman(cpe):
cpe = cpe[7:]
result = cpe.split(':')[0] + " - "
Expand All @@ -59,43 +58,5 @@ def toHuman(cpe):
result = result.title()
return result

def filter(vulns, exploitsOnly=False, filters={}):
if 'access' in filters and len(filters['access'])!=0:
vulns=[x for x in vulns if x['access']['vector'] in filters['access']]
if 'impact' in filters and len(filters['impact'])!=0:
for fil in filters['impact']: vulns=[x for x in vulns if x['impact'][fil] !='NONE']
# exploits only
if exploitsOnly: vulns=[x for x in vulns if ('map_cve_exploitdb' in x or 'map_cve_msf' in x)]
return vulns

def enhance(systems, exploitsOnly=False, filters={}):
host,port=Configuration.getCVESearch()
# deal with filters
for system in systems:
cpe=system['cpes'] if 'cpes' in system else None
if cpe:
cpes=[]
for c in cpe:
cEnc=c.lower()
data = (urlopen('http://%s:%s/api/cvefor/%s'%(host,port,cEnc)).read()).decode('utf8')
vulns=json.loads(str(data))
# apply filter
vulns=filter(vulns, exploitsOnly, filters)
# done
cpes.append({'cpe':c, 'cves':vulns})
system['cpes']=cpes
#TODO get possible dpe info and store in dpe
for service in system['services']:
if 'cpe' in service:
c=service['cpe'].lower()
data = (urlopen('http://%s:%s/api/cvefor/%s'%(host,port,c)).read()).decode('utf8')
vulns=json.loads(str(data))
# apply filter
vulns=filter(vulns, exploitsOnly, filters)
service['cves']=vulns

#TODO get dpe info for service
return systems

def splitByLength(string, size=50):
return [string[i:i+size] for i in range(0,len(string),size)]

0 comments on commit fa05323

Please sign in to comment.