def parse_sudo_list(self, sudo_list): """ Parse output from sudo -ll """ sudoers_info = [] fm = FileManager('') user = sudo_list[sudo_list.index('User '):].split(' ')[1] sudoers_entries = sudo_list.lower().split('sudoers entry') for sudo_rule in sudoers_entries: if not sudo_rule.startswith(':'): continue idx = sudo_rule.index('commands:\n') info = [ i.split(':')[1].strip() for i in sudo_rule[:idx].strip().split('\n') ] _, run_as_users, run_as_grp, options = info cmds = [ PathInFile(line=cmd.strip(), paths=fm.extract_paths_from_string(cmd.strip())) for cmd in sudo_rule[idx:].replace('commands:\n', '').split('\n') if cmd ] sudoers_info.append({ 'users': [user], 'runas': run_as_users, 'directives': options, 'cmds': cmds, }) self.all_rules += sudoers_info return sudoers_info
def parse_sudo_list(self, sudo_list): """ Parse output from sudo -l """ sudoers_info = [] user_rules = False login = None host = None fm = FileManager('') for line in sudo_list.split('\n'): if not line.strip(): continue if user_rules: m = self.sudoers_pattern.search(line.strip()) runas = m.group("runas") cmds = m.group("cmds") # cmds could be a list of many cmds with many path (split all cmd and check if writable path inside) commands = [ PathInFile(line=cmd.strip(), paths=fm.extract_paths_from_string(cmd.strip())) for cmd in cmds.split(',') if cmd.strip() ] sudoers_info.append({ 'users': [user], 'hosts': [host], 'runas': runas, 'directives': m.group("directives"), 'cmds': commands, }) if line.startswith('User'): # Next lines will contain user rules user_rules = True # Extract login and host on such kinf of line: "User test may run the following commands on xxxxx:" l = line.split() user = l[1] host = l[len(l) - 1][:-1] self.all_rules += sudoers_info return sudoers_info
def parse_sudo_list(self, sudo_list): """ Parse output from sudo -ll """ sudoers_info = [] fm = FileManager('') user = sudo_list[sudo_list.index('User '):].split(' ')[1] sudoers_entries = sudo_list.lower().split('sudoers entry') for sudo_rule in sudoers_entries: if not sudo_rule.startswith(':'): continue pattern = re.compile( r"\s*" + "runasusers:\s*(?P<runasusers>\w*)" + "\s*" + "(runasgroups:\s*(?P<runasgroups>\w*))*" + "\s*" + "(options:\s*(?P<options>[\!\w]*))*" + "\s*" + "(commands:\s*(?P<commands>.*))*", re.DOTALL) m = pattern.search(sudo_rule) # Default to empty string '' for values we didn't match data = m.groupdict('') # Remove whitespace and extra tabs from list of commands cmds = [ PathInFile(line=cmd.strip(), paths=fm.extract_paths_from_string(cmd.strip())) for cmd in data['commands'].strip().replace('\t', '').split('\n') ] sudoers_info.append({ 'users': [user], 'runas': data['runasusers'], 'directives': data['options'], 'cmds': cmds, }) self.all_rules += sudoers_info return sudoers_info