diff --git a/backend/backend/settings/base.py b/backend/backend/settings/base.py index 85edd79f7..d213b4da6 100644 --- a/backend/backend/settings/base.py +++ b/backend/backend/settings/base.py @@ -35,7 +35,7 @@ def check_ip_range(ipr): with open(spam_networks_list_path) as f: read_data = f.read() spam_networks_list = re.findall(r'^(\d{1,3}\.\d{1,3}\.\d{1,3}\.0/\d{1,2}).*', read_data, re.MULTILINE) -SPAM_NETWORKS = list(filter(check_ip_range, spam_networks_list)) +SPAM_NETWORKS = [[addr, False] for addr in filter(check_ip_range, spam_networks_list)] # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ diff --git a/backend/device_registry/api_views.py b/backend/device_registry/api_views.py index f09f56b61..8cdfb7b20 100644 --- a/backend/device_registry/api_views.py +++ b/backend/device_registry/api_views.py @@ -14,6 +14,7 @@ from rest_framework.decorators import api_view, renderer_classes, permission_classes from rest_framework.renderers import JSONRenderer from rest_framework.response import Response +from netaddr import IPAddress from device_registry import ca_helper from device_registry.serializers import DeviceInfoSerializer @@ -265,6 +266,11 @@ def mtls_ping_view(request, format=None): scan_info = request.data.get('scan_info', []) if isinstance(scan_info, str): scan_info = json.loads(scan_info) + # Add missing IP protocol version info. + for record in scan_info: + if 'ip_version' not in record: + ipaddr = IPAddress(record['host']) + record['ip_version'] = ipaddr.version portscan_object.scan_info = scan_info portscan_object.netstat = request.data.get('netstat', []) block_networks = portscan_object.block_networks.copy() diff --git a/backend/device_registry/migrations/0035_fix_missing_protocol_version.py b/backend/device_registry/migrations/0035_fix_missing_protocol_version.py new file mode 100644 index 000000000..785ac457e --- /dev/null +++ b/backend/device_registry/migrations/0035_fix_missing_protocol_version.py @@ -0,0 +1,46 @@ +# Generated by Django 2.1.7 on 2019-05-27 10:29 + +from django.db import migrations + +from netaddr import IPAddress + + +def fix_missing_protocol_version(apps, schema_editor): + PortScan = apps.get_model('device_registry', 'PortScan') + for instance in PortScan.objects.all(): + # Fix `block_ports`. + block_ports = instance.block_ports + for record in block_ports: + ipaddr = IPAddress(record[0]) + # Check if it's IPv6 address or not. + is_v6 = ipaddr.version == 6 + if len(record) == 3: + record.append(is_v6) + # Fix `scan_info`. + scan_info = instance.scan_info + for record in scan_info: + if 'ip_version' not in record: + ipaddr = IPAddress(record['host']) + record['ip_version'] = ipaddr.version + # Fix `block_networks`. + block_networks = instance.block_networks + block_networks_list = [] + for record in block_networks: + if not isinstance(record, list): + ipaddr = IPAddress(record) + block_networks_list.append([record, ipaddr.version == 6]) + else: + block_networks_list.append(record) + instance.block_networks = block_networks_list + + instance.save(update_fields=['block_ports', 'scan_info', 'block_networks']) + + +class Migration(migrations.Migration): + dependencies = [ + ('device_registry', '0034_device_name'), + ] + + operations = [ + migrations.RunPython(fix_missing_protocol_version), + ] diff --git a/backend/device_registry/models.py b/backend/device_registry/models.py index 46bb9bbb6..53f3a3473 100644 --- a/backend/device_registry/models.py +++ b/backend/device_registry/models.py @@ -273,11 +273,11 @@ def ports_form_data(self): Build 3 lists: 1) list of choices for the ports form (gonna be split in a template by '/' separator): - [[0, '192.168.1.178/22/TCP'], [0, '192.168.1.178/33/UDP']] + [[0, '::ffff:192.168.1.178/22/TCP/6'], [0, '192.168.1.178/33/UDP/4']] 2) list of initial values for the ports form: [0, 1] 3) list of choices for saving to the block list: - [['192.168.1.178', 22, 'tcp'], ['192.168.1.178', 33, 'udp']] + [['::ffff:192.168.1.178', 22, 'tcp', True], ['192.168.1.178', 33, 'udp', False]] """ initial_data = [] choices_data = [] @@ -285,17 +285,20 @@ def ports_form_data(self): port_record_index = 0 # 1st - take ports from the block list. for port_record in self.block_ports: - choices_data.append((port_record_index, '%s/%s/%s' % ( - port_record[0], port_record[2], port_record[1].upper()))) + choices_data.append((port_record_index, '%s/%s/%s/%d' % ( + port_record[0], port_record[2], port_record[1].upper(), 6 if port_record[3] else 4))) ports_data.append(port_record) initial_data.append(port_record_index) port_record_index += 1 # 2nd - take ports from the open ports list (only the ones missing in the block list). for port_record in self.scan_info: - if [port_record['host'], port_record['proto'], port_record['port']] not in self.block_ports: - choices_data.append((port_record_index, '%s/%s/%s' % ( - port_record['host'], port_record['port'], port_record['proto'].upper()))) - ports_data.append([port_record['host'], port_record['proto'], port_record['port']]) + if [port_record['host'], port_record['proto'], port_record['port'], port_record['ip_version'] == 6] \ + not in self.block_ports: + choices_data.append((port_record_index, '%s/%s/%s/%d' % ( + port_record['host'], port_record['port'], port_record['proto'].upper(), + port_record['ip_version']))) + ports_data.append([port_record['host'], port_record['proto'], port_record['port'], + port_record['ip_version'] == 6]) port_record_index += 1 return choices_data, initial_data, ports_data @@ -304,11 +307,11 @@ def connections_form_data(self): Build 3 lists: 1) list of choices for the open connections form (gonna be split in a template by '/' separator):: - [[0, '192.168.1.20/4567/192.168.1.178/80/v4/TCP/open/3425']] + [[0, '192.168.1.20/4567/192.168.1.178/80/4/TCP/open/3425']] 2) list of initial values for the open connections form: [0] 3) list of choices for saving to the block list: - ['192.168.1.20'] + [['192.168.1.20', False], ['::ffff:192.168.1.25', True]] """ initial_data = [] choices_data = [] @@ -318,25 +321,28 @@ def connections_form_data(self): # 1st - take addresses from the block list. for connection_record in self.block_networks: - if connection_record not in unique_addresses: - unique_addresses.add(connection_record) - choices_data.append((connection_record_index, '%s////v4///' % connection_record)) + if tuple(connection_record) not in unique_addresses: + unique_addresses.add(tuple(connection_record)) + choices_data.append((connection_record_index, '%s////%d///' % (connection_record[0], + 6 if connection_record[1] else 4))) connections_data.append(connection_record) initial_data.append(connection_record_index) connection_record_index += 1 # 2nd - take addresses from the open connections list (only the ones missing in the block list). for connection_record in self.netstat: - if connection_record['remote_address'] and connection_record['remote_address'][0] not in unique_addresses: - unique_addresses.add(connection_record['remote_address'][0]) + if connection_record['remote_address'] and (connection_record['remote_address'][0], + connection_record['ip_version'] == 6) not in unique_addresses: + unique_addresses.add((connection_record['remote_address'][0], connection_record['ip_version'] == 6)) choices_data.append(( - connection_record_index, '%s/%s/%s/%s/v%s/%s/%s/%s' % + connection_record_index, '%s/%s/%s/%s/%d/%s/%s/%s' % (connection_record['remote_address'][0], connection_record['remote_address'][1], connection_record['local_address'][0] if connection_record['local_address'] else '', connection_record['local_address'][1] if connection_record['local_address'] else '', connection_record['ip_version'], connection_record['type'].upper(), connection_record['status'], connection_record['pid']))) - connections_data.append(connection_record['remote_address'][0]) + connections_data.append([connection_record['remote_address'][0], + connection_record['ip_version'] == 6]) connection_record_index += 1 return choices_data, initial_data, connections_data diff --git a/backend/device_registry/templates/device_info_security.html b/backend/device_registry/templates/device_info_security.html index ceac954c3..150adb463 100644 --- a/backend/device_registry/templates/device_info_security.html +++ b/backend/device_registry/templates/device_info_security.html @@ -139,6 +139,7 @@