Exemplo n.º 1
0
    def load_auth_data(self, **kwargs):
        def parse_auth(auth_type, line):
            items = filter(I, map(lambda x: x.strip(), line.split(' ')))
            tfmt = '%Y-%m-%d %H:%M:%S'
            time = items[0]+' '+items[1]
            time = datetime.strptime(time, tfmt)
            if auth_type == 'local':
                return{
                    'user': items[8][1:len(items[8])-1],
                    'ip': None,
                    'time': time,
                }
            elif auth_type == 'ssh':
                return{
                    'user': items[9],
                    'ip': items[11],
                    'time': time,
                }
                
        try:
            authf_local, bad = pcall('syslog -F \'$((Time)(J)) $Host $(Sender)[$(PID)]<$((Level)(str))>: $Message\' | grep \'Failed to authenticate\'')
            if bad:
                raise OSError()
            authf_ssh, bad = pcall('syslog -F \'$((Time)(J)) $Host $(Sender)[$(PID)]<$((Level)(str))>: $Message\' | grep \'PAM: authentication error\'')
            if bad:
                raise OSError()
            self.authf['local'] = [parse_auth('local',l) for l in authf_local]

            self.authf['ssh'] = [parse_auth('ssh',l)  for l in authf_ssh]
        except OSError:
            raise Exception('`syslog` fails. Backend not supported.')
Exemplo n.º 2
0
    def __init__(self):
        out, err = pcall('which opensnoop')
        if not out:
            raise Exception('opensnoop not installed!')
        self.logs = []

        out, err = pcall('dscl . -list /Users UniqueID')
        out = map(lambda l: filter(I, l.split(' ')), out)
        self.users = {int(uid): user for user, uid in out}
Exemplo n.º 3
0
    def snoop(self, timeout=10, output_file=None):
        """ Snoop open's for a while

        Args:
            timeout (int): how long to snoop

            output_file (optional[str]): if specified, save log to file.
        """
        out, err = pcall('opensnoop -v', timeout)
        if len(err) > 0 and 'additional privileges' in err[0]:
            raise Exception(err[0])
        if len(out) > 0:
            out = out[1:]

        self.logs = []
        for line in out:
            line = filter(I, line.split(' '))
            time = datetime.strptime(' '.join(line[:4]), '%Y %b %d %H:%M:%S')
            user = self.users[int(line[4])]
            # TODO: this is problematic for cmd/path with space in it
            cmd = line[6]
            fpath = line[-1]
            self.logs.append({
                'time': time,
                'user': user,
                'cmd':  cmd,
                'fpath': fpath,
            })

        if output_file is not None:
            with open(output_file, 'w') as f:
                pickle.dump(self.logs, f)
Exemplo n.º 4
0
    def load(self, **kwargs):
        """ Load the system log

        It loads log(s) from default location. If they are not in the
        default location, specify in **kwargs.

        Args:
            **kwargs: specifies custom config for sys logs.
                None for this backend.
        """
        def parse(line):
            items = filter(I, map(lambda x: x.strip(), line.split(' ')))
            # special case
            if items[1] == 'system' and items[2] == 'boot':
                items[1] = 'system boot'
                items.pop(2)

            # time format
            tfmt = '%a %b %d %H:%M:%S %Y'
            # parse tin
            if len(items[5]) == 1:
                items[5] = '0' + items[5]  # pad zero before day
            tin = ' '.join(items[3:8])
            tin = datetime.strptime(tin, tfmt)
            # parse tout
            if items[8] == '-':
                if len(items[10]) == 1:
                    items[10] = '0' + items[10]
                if items[9] == 'crash':
                    tout = None
                else:
                    tout = ' '.join(items[9:14])
                    tout = datetime.strptime(tout, tfmt)
            else:
                tout = None

            return {
                'user': items[0],
                'terminal': items[1],
                'ip': items[2],
                'time_in': tin,
                'time_out': tout,
            }

        try:
            last, bad = pcall('last -Fi')
            if bad:
                raise OSError()
            else:
                self.last = [parse(l) for l in last[:-1]]
        except OSError:
            raise Exception('`last -Fi` fails. Backend not supported.')

        try:
            lastb, bad = pcall('lastb -Fi')
            if bad:
                warnings.warn(
                    '`lastb -Fi` fails, which requires sudo permission.'
                    'Continue if you don\'t need authfailures')
            else:
                self.lastb = [parse(l) for l in lastb[:-1]]
        except OSError:
            raise Exception('`lastb -Fi` fails. Backend not supported.')
Exemplo n.º 5
0
    def load(self, **kwargs):
        """ Load the system log

        It loads log(s) from default location. If they are not in the
        default location, specify in **kwargs.

        Args:
            **kwargs: specifies custom config for sys logs.
                None for this backend.
        """

        def parse(line):
            items = filter(I, map(lambda x: x.strip(), line.split(' ')))

            if items[0] == 'reboot' or items[0] == 'shutdown':
                return

            # time format
            tfmt = '%a %b %d %H:%M'

            if len(items) == 10:
                # parse tin
                if len(items[5]) == 1:
                    items[5] = '0' + items[5]  # pad zero before day
                tin = ' '.join(items[3:7])
                tin = datetime.strptime(tin, tfmt)
                now = datetime.now()
                now_month = now.month
                now_day = now.day
                tin = tin.replace(year=now.year)
                if tin.month > now_month:
                    if tin.day > now_day:
                        tin = tin - relativedelta(years = 1)

                # parse tout
                if items[7] == '-':

                    if items[8] == 'shutdown' or items[8] == 'crash' :
                        duration = items[9][1:-1]
                        if '+' in duration:
                            time = duration.split('+')
                            hours_mins = time[1].split(':')
                            tout = tin + timedelta(days=int(time[0]),
                                                   hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                        else:
                            hours_mins = duration.split(':')
                            tout = tin + timedelta(hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                    else:
                        duration = items[9][1:-1]
                        # logout_time = items[8]
                        # logout_time = datetime.strptime(logout_time, "%H:%M")
                        if '+' in duration:
                            time = duration.split('+')
                            hours_mins = time[1].split(':')
                            tout = tin + timedelta(days=int(time[0]),
                                                   hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                        else:
                            hours_mins = duration.split(':')
                            tout = tin + timedelta(hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                else:
                    tout = None

                return {
                    'user': items[0],
                    'terminal': items[1],
                    'ip': items[2],
                    'time_in': tin,
                    'time_out': tout,
                }

            else:
                # parse tin
                if len(items[4]) == 1:
                    items[4] = '0' + items[4]  # pad zero before day
                tin = ' '.join(items[2:6])
                tin = datetime.strptime(tin, tfmt)
                now = datetime.now()
                now_month = now.month
                now_day = now.day
                tin = tin.replace(year=now.year)
                if tin.month > now_month:
                    if tin.day > now_day:
                        tin = tin - relativedelta(years = 1)
                # parse tout
                if items[6] == '-':
                    # tout = ' '.join(items[7:9])
                    if items[7] == 'shutdown' or items[7] == 'crash':
                        duration = items[8][1:-1]
                        if '+' in duration:
                            time = duration.split('+')
                            hours_mins = time[1].split(':')
                            tout = tin + timedelta(days=int(time[0]),
                                                   hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                        else:
                            hours_mins = duration.split(':')
                            tout = tin + timedelta(hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                    else:

                        duration = items[8][1:-1]
                        # logout_time = items[7]

                        # logout_time = datetime.strptime(logout_time, "%H:%M")
                        if '+' in duration:
                            time = duration.split('+')
                            hours_mins = time[1].split(':')
                            tout = tin + timedelta(days=int(time[0]),
                                                   hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                        else:
                            hours_mins = duration.split(':')
                            tout = tin + timedelta(hours=int(hours_mins[0]),
                                                   seconds=int(hours_mins[1]) * 60)
                else:
                    tout = None

                return {
                    'user': items[0],
                    'terminal': items[1],
                    'ip': 'Local',
                    'time_in': tin,
                    'time_out': tout,
                }

        try:
            last, bad = pcall('last')
            if bad:
                raise OSError()
            else:
                self.last = filter(I, [parse(l) for l in last[:-1]])

            self.load_auth_data()
        except OSError:
            raise Exception('`last` fails. Backend not supported.')
Exemplo n.º 6
0
    def load(self, **kwargs):
        """ Load the system log

        It loads log(s) from default location. If they are not in the
        default location, specify in **kwargs.

        Args:
            **kwargs: specifies custom config for sys logs.
                None for this backend.
        """
        def parse(line):
            items = filter(I, map(lambda x: x.strip(), line.split(' ')))
            # special case
            if items[1] == 'system' and items[2] == 'boot':
                items[1] = 'system boot'
                items.pop(2)

            # time format
            tfmt = '%a %b %d %H:%M:%S %Y'
            # parse tin
            if len(items[5]) == 1:
                items[5] = '0' + items[5]  # pad zero before day
            tin = ' '.join(items[3:8])
            tin = datetime.strptime(tin, tfmt)
            # parse tout
            if items[8] == '-':
                if len(items[10]) == 1:
                    items[10] = '0' + items[10]
                if items[9] == 'crash':
                    tout = None
                else:
                    tout = ' '.join(items[9:14])
                    tout = datetime.strptime(tout, tfmt)
            else:
                tout = None

            return {
                'user':     items[0],
                'terminal': items[1],
                'ip':       items[2],
                'time_in':  tin,
                'time_out': tout,
            }

        try:
            last, bad = pcall('last -Fi')
            if bad:
                raise OSError()
            else:
                self.last = [parse(l) for l in last[:-1]]
        except OSError:
            raise Exception('`last -Fi` fails. Backend not supported.')

        try:
            lastb, bad = pcall('lastb -Fi')
            if bad:
                warnings.warn('`lastb -Fi` fails, which requires sudo permission.'
                              'Continue if you don\'t need authfailures')
            else:
                self.lastb = [parse(l) for l in lastb[:-1]]
        except OSError:
            raise Exception('`lastb -Fi` fails. Backend not supported.')