def is_sudo_disabled(server: str, username: str, password: str, ssh_config: str = None) -> bool: """ Check if there's ``sudo`` or similar installed in ``os_linux``. :param server: URL or IP of host to test. :param username: User to connect to server. :param password: Password for given user. :param ssh_config: Path to SSH connection config file. """ result = True cmd = 'which sudo' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if out: show_close('{} server has "sudo" (or like) installed'.format(server), details=dict(paths=out.decode('utf-8'))) result = False else: show_open('{} server does not have "sudo" (or like) installed'.format( server), details=dict(paths=out.decode('utf-8'))) result = True return result
def are_compilers_installed(server: str, username: str, password: str, ssh_config: str = None) -> bool: """ Check if there is any compiler installed in ``os_linux``. :param server: URL or IP of host to test. :param username: User to connect to server. :param password: Password for given user. :param ssh_config: Path to SSH connection config file. """ result = True cmd = 'which cc gcc c++ g++ javac ld as nasm' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if not out: show_close( '{} server does not have compilers installed'.format(server), details=dict(paths=out.decode('utf-8'))) result = False else: show_open('{} server has compilers installed'.format(server), details=dict(paths=out.decode('utf-8'))) result = True return result
def is_min_priv_disabled(server: str, username: str, password: str, ssh_config: str = None) -> bool: """ Check if ``umask`` or similar is secure in ``os_linux``. :param server: URL or IP of host to test. :param username: User to connect to server. :param password: Password for given user. :param ssh_config: Path to SSH connection config file. """ result = True cmd = 'umask' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if out == b'0027': show_close('{} server has secure default privileges'.format(server), details=dict(umask=out.decode('utf-8'))) result = False else: show_open('{} server has insecure default privileges'.format(server), details=dict(umask=out.decode('utf-8'))) result = True return result
def are_syncookies_disabled(server: str, username: str, password: str, ssh_config: str = None) -> bool: """ Check if ``SynCookies`` or similar is enabled in ``os_linux``. :param server: URL or IP of host to test. :param username: User to connect to server. :param password: Password for given user. :param ssh_config: Path to SSH connection config file. """ result = True cmd = 'sysctl -q -n net.ipv4.tcp_syncookies' try: out, err = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if err: show_unknown('Error checking', details=dict(error=err.decode('utf-8'))) return False if out == b'1': show_close('{} server has syncookies enabled'.format(server), details=dict(result=out.decode('utf-8'))) result = False else: show_open('{} server has syncookies disabled'.format(server), details=dict(result=out.decode('utf-8'))) result = True return result
def is_remote_admin_enabled(server: str, username: str, password: str, ssh_config: str = None) -> bool: """ Check if admins can remotely log into ``os_linux``. :param server: URL or IP of host to test. :param username: User to connect to server. :param password: Password for given user. :param ssh_config: Path to SSH connection config file. """ result = True cmd = 'grep -i "^PermitRootLogin.*yes" /etc/ssh/sshd_config' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if not out: show_close('{} server does not have remote admin login enabled'.format( server), details=dict(result=out.decode('utf-8'))) result = False else: show_open('{} server has remote admin login enabled'.format(server), details=dict(result=out.decode('utf-8'))) result = True return result
def daemon_high_privileged(server: str, username: str, password: str, ssh_config: str = None) -> bool: """Check if current MySQL installation uses non-privileged user.""" cmds = [('ps -o user= -p $(pgrep mysql)', 'mysql'), ('grep -o ^mysql /etc/passwd', 'mysql'), ('stat -c %U /var/lib/mysql', 'mysql')] for cmd in cmds: try: out, _ = ssh_exec_command(server, username, password, cmd[0], ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False else: if out.decode() == cmd[1]: show_close('MySQL server is running with a \ non-privileged account', details=dict(server=server, process_owner=out.decode())) return False show_open('MySQL server is not running with a non-privileged account', details=dict(server=server, process_owner=out.decode())) return True
def has_insecure_shell(server: str, username: str, password: str, ssh_config: str = None) -> bool: """Check for mysql user with interactive shell.""" cmd = r'getent passwd mysql | cut -d: -f7 | grep -e nologin -e false' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if out.decode() != '': show_close('"mysql" user uses a non-interactive shell', details=dict(server=server, shell=out.decode())) return False show_open('"mysql" user uses an interactive shell', details=dict(server=server)) return True
def pwd_on_env(server: str, username: str, password: str, ssh_config: str = None) -> bool: """Check for MYSQL_PWD env var.""" cmd = r'grep -h MYSQL_PWD /proc/*/environ \ /home/*/.{bashrc,profile,bash_profile}' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if out.decode() == '': show_close('MYSQL_PWD not on environment', details=dict(server=server)) return False show_open('MYSQL_PWD found on environment', details=dict(server=server, values=out.decode())) return True
def history_enabled(server: str, username: str, password: str, ssh_config: str = None) -> bool: """Check for .mysql_history files.""" cmd = r'c=0; for i in $(find /home -name .mysql_history); \ do size=$(stat -c %b $i); c=$(($c+$size)); done; echo $c' try: out, _ = ssh_exec_command(server, username, password, cmd, ssh_config) except ConnError as exc: show_unknown('Could not connect', details=dict(server=server, username=username, error=str(exc))) return False if out.decode() == '0' or out.decode() == '': show_close('MySQL history files are empty', details=dict(server=server, size=out.decode())) return False show_open('MySQL history files are not empty', details=dict(server=server, size=out.decode())) return True