xml_utils.py
5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'eduardo'
from lxml import etree
import model.computer
import model.printer
import model.host
class NmapXML(object):
"""
Classe para realizar o parsing do arquivo XML do NMAP
"""
def __init__(self,
xml):
self.xml = xml
self.hosts = dict()
def parse_xml(self):
"""
Parse XML file
"""
infile = open(self.xml, 'r')
for _, element in etree.iterparse(infile, events=('start', 'end'), tag='host'):
addr_list = element.findall('address')
# MAC e IP
for addr in addr_list:
if addr.get('addrtype') == 'ipv4':
host = addr.get('addr')
elif addr.get('addrtype') == 'mac':
mac = {
'address': addr.get('addr'),
'vendor': addr.get('vendor')
}
# A chave do dicionário é o IP
self.hosts[host] = dict()
if 'mac' in locals():
self.hosts[host]['mac'] = mac
# Hostname
self.hosts[host]['hostname'] = dict()
for tag in element.find('hostnames').findall('hostname'):
self.hosts[host]['hostname'][tag.get('type')] = tag.get('name')
# Open ports
ports = element.find('ports')
self.hosts[host]['ports'] = dict()
for port_xml in ports.findall('port'):
self.hosts[host]['ports'][port_xml.get('portid')] = {
'protocol': port_xml.get('protocol'),
'state': port_xml.find('state').get('state'),
'service': port_xml.find('service').get('name'),
}
# OS Matches
os = element.find('os')
if os is not None:
self.hosts[host]['os'] = dict()
for osmatch in os.findall('osmatch'):
self.hosts[host]['os'][osmatch.get('name')] = dict()
self.hosts[host]['os'][osmatch.get('name')]['accuracy'] = osmatch.get('accuracy')
for osclass in osmatch.findall('osclass'):
self.hosts[host]['os'][osmatch.get('name')]['osclass'] = {
'type': osclass.get('type'),
'vendor': osclass.get('vendor'),
'osfamily': osclass.get('osfamily'),
'accuracy': osclass.get('accuracy'),
'cpe': osclass.findtext('cpe')
}
# General attributes
self.hosts[host]['starttime'] = element.get('starttime')
self.hosts[host]['endtime'] = element.get('endtime')
status = element.find('status')
self.hosts[host]['state'] = status.get('state')
return True
def identify_host(self, hostname):
if not self.hosts:
raise AttributeError("It is necessary do load XML file first")
# Ordena os sistemas operacionais por accuracy
host = self.hosts[hostname]
accuracy = 0
if host.get('os'):
# Nesse caso já sei que é computador. Precisa identificar o OS
for os in host['os'].keys():
if int(host['os'][os]['accuracy']) > accuracy:
os_final = os
scantime = int(host.get('endtime')) - int(host.get('starttime'))
computer = model.computer.Computer(
ip_address=hostname,
mac_address=host.get('mac'),
hostname=host.get('hostname'),
inclusion_date=host.get('endtime'),
scantime=scantime,
open_ports=host.get('ports'),
so=host['os'][os_final]
)
return computer
elif host.get('ports'):
scantime = int(host.get('endtime')) - int(host.get('starttime'))
#FIXME: Tem que encontrar uma forma melhor de identificar a impressora
for value in ['9100']:
if value in host['ports'].keys():
# Regra temporária!!! As impressoras serão identificadas pela porta 9100
printer = model.printer.Printer(
ip_address=hostname,
mac_address=host.get('mac'),
hostname=host.get('hostname'),
inclusion_date=host.get('endtime'),
scantime=scantime,
open_ports=host['ports'],
)
return printer
else:
host = model.host.Host(
ip_address=hostname,
mac_address=host.get('mac'),
hostname=host.get('hostname'),
inclusion_date=host.get('endtime'),
scantime=scantime,
open_ports=host['ports'],
)
return host
else:
# Não foi possível identificar. Só gera um host genérico
scantime = int(host.get('endtime')) - int(host.get('starttime'))
host = model.host.Host(
ip_address=hostname,
mac_address=host.get('mac'),
hostname=host.get('hostname'),
inclusion_date=host.get('endtime'),
scantime=scantime,
open_ports=host['ports'],
)
return host