File size: 6,207 Bytes
7c89ed7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# Copyright (c) 2014 Mozilla Corporation

import netaddr


def isIPv4(ip):
    try:
        return netaddr.valid_ipv4(ip)
    except:
        return False


def isIPv6(ip):
    try:
        return netaddr.valid_ipv6(ip)
    except:
        return False


def addError(message, error):
    '''add an error note to a message'''
    if 'errors' not in message:
        message['errors'] = list()
    if isinstance(message['errors'], list):
        message['errors'].append(error)


class message(object):
    def __init__(self):
        '''register our criteria for being passed a message
           as a list of lower case strings or values to match with an event's dictionary of keys or values
           set the priority if you have a preference for order of plugins to run.
           0 goes first, 100 is assumed/default if not sent
        '''
        # ask for anything that could house an IP address
        self.registration = ['sourceipaddress', 'destinationipaddress', 'src', 'dst', 'srcip', 'dstip', 'http_x_forwarded_for']
        self.priority = 15

    def onMessage(self, message, metadata):
        '''
        Examine possible ip addresses for the following:
          ipv6 in an ipv4 field
          ipv4 in another field
          '-' or other invalid ip in the ip field
        Also sets ipv4 in two fields:
            ipaddress (decimal mapping IP)
            ipv4address (string mapping)
            While the IP field-type serves for IPv4 or IPv6,
            it is not quite mature yet as kibana lacks filtering
            to differentiate between IPv4 and IPv6, so always
            having a string version is the most flexible option.
        '''

        if 'details' in message:
            # forwarded header can be spoofed, so try it first,
            # but override later if we've a better field.
            if 'http_x_forwarded_for' in message['details']:
                # should be a comma delimited list of ips with the original client listed first
                ipText = message['details']['http_x_forwarded_for'].split(',')[0]
                if isIPv4(ipText) and 'sourceipaddress' not in message['details']:
                    message['details']['sourceipaddress'] = ipText
                if isIPv4(ipText) and 'sourceipv4address' not in message['details']:
                    message['details']['sourceipv4address'] = ipText
                if isIPv6(ipText) and 'sourceipv6address' not in message['details']:
                    message['details']['sourceipv6address'] = ipText

            if 'sourceipaddress' in message['details']:
                ipText = message['details']['sourceipaddress']
                if isIPv6(ipText):
                    message['details']['sourceipv6address'] = ipText
                    message['details']['sourceipaddress'] = '0.0.0.0'
                    addError(message, 'plugin: {0} error: {1}'.format('ipFixUp.py', 'sourceipaddress is ipv6, moved'))
                elif isIPv4(ipText):
                    message['details']['sourceipv4address'] = ipText
                else:
                    # Smells like a hostname, let's save it as source field
                    message['details']['source'] = message['details']['sourceipaddress']
                    message['details']['sourceipaddress'] = None

            if 'destinationipaddress' in message['details']:
                ipText = message['details']['destinationipaddress']
                if isIPv6(ipText):
                    message['details']['destinationipv6address'] = ipText
                    message['details']['destinationipaddress'] = '0.0.0.0'
                    addError(message, 'plugin: {0} error: {1}'.format('ipFixUp.py', 'destinationipaddress is ipv6, moved'))
                elif isIPv4(ipText):
                    message['details']['destinationipv4address'] = ipText
                else:
                    # Smells like a hostname, let's save it as destination field
                    message['details']['destination'] = message['details']['destinationipaddress']
                    message['details']['destinationipaddress'] = None

            if 'src' in message['details']:
                ipText = message['details']['src']
                if isIPv4(ipText):
                    message['details']['sourceipaddress'] = ipText
                    message['details']['sourceipv4address'] = ipText
                if isIPv6(ipText):
                    message['details']['sourceipv6address'] = ipText

            if 'srcip' in message['details']:
                ipText = message['details']['srcip']
                if isIPv4(ipText):
                    message['details']['sourceipaddress'] = ipText
                    message['details']['sourceipv4address'] = ipText
                if isIPv6(ipText):
                    message['details']['sourceipv6address'] = ipText
            if 'dst' in message['details']:
                ipText = message['details']['dst']
                if isIPv4(ipText):
                    message['details']['destinationipaddress'] = ipText
                    message['details']['destinationipv4address'] = ipText
                if isIPv6(ipText):
                    message['details']['destinationipv6address'] = ipText

            if 'dstip' in message['details']:
                ipText = message['details']['dstip']
                if isIPv4(ipText):
                    message['details']['destinationipaddress'] = ipText
                    message['details']['destinationipv4address'] = ipText
                if isIPv6(ipText):
                    message['details']['destinationipv6address'] = ipText

            if 'cluster_client_ip' in message['details']:
                ipText = message['details']['cluster_client_ip']
                if isIPv4(ipText):
                    message['details']['sourceipaddress'] = ipText
                if isIPv6(ipText):
                    message['details']['sourceipv6address'] = ipText

        return (message, metadata)