I can't take credit for this, a co-worker helped me solve it and suggested this fix.
Problem: Sometimes the line-continuance character \ is parsed as a sudoers command.
Given this line in a sudoers file...
neko ALL=(root) NOPASSWD: REPAIRDISK, /bin/mount, /bin/umount, /usr/bin/iotop, /usr/sbin/lsof, /usr/sbin/iotop, /bin/cat /var/log/messages, \
/some/path/to/a/command/somewhere/that/i_want_to_run.sh
The scan_sudoers.py plugin parses the entry as:
{
"commands": [
"REPAIRDISK",
"/bin/mount",
"/bin/umount",
"/usr/bin/iotop",
"/usr/sbin/lsof",
"/usr/sbin/iotop",
"/bin/cat /var/log/messages",
"\\"
],
"hosts": [
"ALL"
],
"operators": [
"root"
],
"tags": [
"NOPASSWD"
],
"users": [
"neko"
]
},
Which completely skips the wrapped line.
The suggested fix we came up with is in the def get_config_lines(path, params): function.
Just before iterating through the all_lines read from the sudoers file ( ~ line 223 ) we suggest "unfolding" wrapped lines with re.sub like this...
# "Unfold" lines with a continuance character '\' followed by 0 or more spaces or tabs
# a newline '\' and again 0 or more spaces or tabs.
unfolded_lines = re.sub(r'\\\s*\n\s*', '', all_lines)
# Work on each line of sudoers file
for sline in unfolded_lines.strip().split("\n"):
line = sline.replace("\n", "").replace(
"\t", " "
) # cleaning up chars we don't want
I can't take credit for this, a co-worker helped me solve it and suggested this fix.
Problem: Sometimes the line-continuance character
\is parsed as a sudoers command.Given this line in a sudoers file...
The scan_sudoers.py plugin parses the entry as:
Which completely skips the wrapped line.
The suggested fix we came up with is in the
def get_config_lines(path, params):function.Just before iterating through the
all_linesread from the sudoers file ( ~ line 223 ) we suggest "unfolding" wrapped lines with re.sub like this...