<commit_before>import paramiko
import socket
from cme.connection import *
from cme.helpers.logger import highlight
from cme.logger import CMEAdapter
from paramiko.ssh_exception import AuthenticationException, NoValidConnectionsError, SSHException
import configparser


class ssh(connection):

    @staticmethod
    def proto_args(parser, std_parser, module_parser):
        ssh_parser = parser.add_parser('ssh', help="own stuff using SSH", parents=[std_parser, module_parser])
        ssh_parser.add_argument("--no-bruteforce", action='store_true', help='No spray when using file for username and password (user1 => password1, user2 => password2')
        #ssh_parser.add_argument("--key-file", type=str, help="Authenticate using the specified private key")
        ssh_parser.add_argument("--port", type=int, default=22, help="SSH port (default: 22)")

        cgroup = ssh_parser.add_argument_group("Command Execution", "Options for executing commands")
        cgroup.add_argument('--no-output', action='store_true', help='do not retrieve command output')
        cgroup.add_argument("-x", metavar="COMMAND", dest='execute', help="execute the specified command")

        return parser

    def proto_logger(self):
        self.logger = CMEAdapter(extra={'protocol': 'SSH',
                                        'host': self.host,
                                        'port': self.args.port,
                                        'hostname': self.hostname})

    def print_host_info(self):
        self.logger.info(self.remote_version)

    def enum_host_info(self):
        self.remote_version = self.conn._transport.remote_version

    def create_conn_obj(self):
        self.conn = paramiko.SSHClient()
        self.conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        try:
            self.conn.connect(self.host, port=self.args.port)
        except AuthenticationException:
            return True
        except SSHException:
            return True
        except NoValidConnectionsError:
            return False
        except socket.error:
            return False

    def client_close(self):
        self.conn.close()

    def check_if_admin(self):
        stdin, stdout, stderr = self.conn.exec_command('id')
        if stdout.read().decode('utf-8').find('uid=0(root)') != -1:
            self.admin_privs = True

    def plaintext_login(self, username, password):
        try:
            self.conn.connect(self.host, port=self.args.port, username=username, password=password)
            self.check_if_admin()

            self.logger.success(u'{}:{} {}'.format(username,
                                                   password,
                                                   highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))

            return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(username,
                                                 password,
                                                 e))
            self.client_close()
            return False

    def execute(self, payload=None, get_output=False):
        try:
            stdin, stdout, stderr = self.conn.exec_command(self.args.execute)
        except AttributeError:
            return ''
        self.logger.success('Executed command')
        for line in stdout:
            self.logger.highlight(line.strip())

        return stdout
<commit_msg>feat(ssh): Add support for publickey authentication.<commit_after>import paramiko
import socket
from cme.connection import *
from cme.helpers.logger import highlight
from cme.logger import CMEAdapter
from paramiko.ssh_exception import AuthenticationException, NoValidConnectionsError, SSHException
import configparser


class ssh(connection):

    @staticmethod
    def proto_args(parser, std_parser, module_parser):
        ssh_parser = parser.add_parser('ssh', help="own stuff using SSH", parents=[std_parser, module_parser])
        ssh_parser.add_argument("--no-bruteforce", action='store_true', help='No spray when using file for username and password (user1 => password1, user2 => password2')
        ssh_parser.add_argument("--key-file", type=str, help="Authenticate using the specified private key. Treats the password parameter as the key's passphrase.")
        ssh_parser.add_argument("--port", type=int, default=22, help="SSH port (default: 22)")

        cgroup = ssh_parser.add_argument_group("Command Execution", "Options for executing commands")
        cgroup.add_argument('--no-output', action='store_true', help='do not retrieve command output')
        cgroup.add_argument("-x", metavar="COMMAND", dest='execute', help="execute the specified command")

        return parser

    def proto_logger(self):
        self.logger = CMEAdapter(extra={'protocol': 'SSH',
                                        'host': self.host,
                                        'port': self.args.port,
                                        'hostname': self.hostname})

    def print_host_info(self):
        self.logger.info(self.remote_version)

    def enum_host_info(self):
        self.remote_version = self.conn._transport.remote_version

    def create_conn_obj(self):
        self.conn = paramiko.SSHClient()
        self.conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        try:
            self.conn.connect(self.host, port=self.args.port)
        except AuthenticationException:
            return True
        except SSHException:
            return True
        except NoValidConnectionsError:
            return False
        except socket.error:
            return False

    def client_close(self):
        self.conn.close()

    def check_if_admin(self):
        stdin, stdout, stderr = self.conn.exec_command('id')
        if stdout.read().decode('utf-8').find('uid=0(root)') != -1:
            self.admin_privs = True

    def plaintext_login(self, username, password):
        try:
            if self.args.key_file:
                passwd = password
                password = u'{} (keyfile: {})'.format(passwd, self.args.key_file)
                self.conn.connect(self.host, port=self.args.port, username=username, passphrase=<PASSWORD>, key_filename=self.args.key_file, look_for_keys=False, allow_agent=False)
            else:
                self.conn.connect(self.host, port=self.args.port, username=username, password=password, look_for_keys=False, allow_agent=False)

            self.check_if_admin()
            self.logger.success(u'{}:{} {}'.format(username.decode('utf-8'),
                                                   password.decode('utf-8'),
                                                   highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))

            return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(username,
                                                 password,
                                                 e))
            self.client_close()
            return False

    def execute(self, payload=None, get_output=False):
        try:
            stdin, stdout, stderr = self.conn.exec_command(self.args.execute)
        except AttributeError:
            return ''
        self.logger.success('Executed command')
        for line in stdout:
            self.logger.highlight(line.strip())

        return stdout

{'fraction_non_alphanumeric': 0.10857296425692019, 'fraction_numerical': 0.0034936844934157483, 'mean_word_length': 2.2248700173310225, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5482822', 'n_tokens_mistral': 1995, 'n_tokens_neox': 1935, 'n_words': 430}