NetExec/cme/protocols/ssh.py

97 lines
4.2 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import paramiko
2017-10-21 23:24:09 +00:00
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
2019-11-10 21:42:04 +00:00
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])
2020-05-09 11:59:53 +00:00
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)")
ssh_parser.add_argument("--continue-on-success", action='store_true', help="continues authentication attempts even after successes")
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)
2021-11-17 12:37:14 +00:00
return True
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
2017-10-21 23:24:09 +00:00
except socket.error:
return False
2020-04-28 10:11:16 +00:00
def client_close(self):
self.conn.close()
def check_if_admin(self):
stdin, stdout, stderr = self.conn.exec_command('id')
2020-04-28 10:11:16 +00:00
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=passwd, 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,
2022-02-06 22:56:41 +00:00
password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
2018-03-01 19:36:17 +00:00
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))
if not self.args.continue_on_success:
return True
except Exception as e:
2019-11-10 23:12:35 +00:00
self.logger.error(u'{}:{} {}'.format(username,
2022-02-07 21:19:46 +00:00
password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
e))
2020-04-28 10:11:16 +00:00
self.client_close()
return False
def execute(self, payload=None, get_output=False):
2020-04-28 10:11:16 +00:00
try:
stdin, stdout, stderr = self.conn.exec_command(self.args.execute)
except AttributeError:
return ''
self.logger.success('Executed command')
for line in stdout:
2019-11-10 23:12:35 +00:00
self.logger.highlight(line.strip())
return stdout