NetExec/cme/protocols/ssh.py

118 lines
4.4 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import paramiko
from cme.connection import *
from cme.helpers.logger import highlight
from cme.logger import CMEAdapter
from paramiko.ssh_exception import AuthenticationException, NoValidConnectionsError, SSHException
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.display(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")
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 = f"{passwd} (keyfile: {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,
password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
highlight(f'({self.config.get("CME", "pwn3d_label")})' if self.admin_privs else '')
)
)
if not self.args.continue_on_success:
return True
except Exception as e:
self.logger.fail(
f"{username}:{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