2022-07-18 23:59:14 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2017-07-10 05:44:58 +00:00
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
2017-10-25 02:08:19 +00:00
2017-07-10 05:44:58 +00:00
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 ' )
2019-11-18 17:39:17 +00:00
ssh_parser . add_argument ( " --key-file " , type = str , help = " Authenticate using the specified private key. Treats the password parameter as the key ' s passphrase. " )
2017-07-10 05:44:58 +00:00
ssh_parser . add_argument ( " --port " , type = int , default = 22 , help = " SSH port (default: 22) " )
2020-06-20 10:10:05 +00:00
ssh_parser . add_argument ( " --continue-on-success " , action = ' store_true ' , help = " continues authentication attempts even after successes " )
2017-07-10 05:44:58 +00:00
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 ) :
2023-03-30 03:59:22 +00:00
self . logger = CMEAdapter (
extra = {
' protocol ' : ' SSH ' ,
' host ' : self . host ,
' port ' : self . args . port ,
' hostname ' : self . hostname
}
)
2017-07-10 05:44:58 +00:00
def print_host_info ( self ) :
2023-03-30 03:59:22 +00:00
self . logger . display ( self . remote_version )
2021-11-17 12:37:14 +00:00
return True
2017-07-10 05:44:58 +00:00
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
2017-07-10 05:44:58 +00:00
2020-04-28 10:11:16 +00:00
def client_close ( self ) :
self . conn . close ( )
2017-07-10 05:44:58 +00:00
def check_if_admin ( self ) :
2023-04-12 04:25:38 +00:00
stdin , stdout , stderr = self . conn . exec_command ( " id " )
if stdout . read ( ) . decode ( " utf-8 " ) . find ( " uid=0(root) " ) != - 1 :
2017-07-10 05:44:58 +00:00
self . admin_privs = True
def plaintext_login ( self , username , password ) :
try :
2019-11-18 17:39:17 +00:00
if self . args . key_file :
passwd = password
2023-03-30 03:59:22 +00:00
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
)
2019-11-18 17:39:17 +00:00
else :
2023-03-30 03:59:22 +00:00
self . conn . connect (
self . host ,
port = self . args . port ,
username = username ,
password = password ,
look_for_keys = False ,
allow_agent = False
)
2017-07-10 05:44:58 +00:00
2019-11-18 17:39:17 +00:00
self . check_if_admin ( )
2023-03-30 03:59:22 +00:00
self . logger . success (
2023-04-12 04:25:38 +00:00
u " {} : {} {} " . format (
2023-03-30 03:59:22 +00:00
username ,
password if not self . config . get ( ' CME ' , ' audit_mode ' ) else self . config . get ( ' CME ' , ' audit_mode ' ) * 8 ,
2023-04-12 04:25:38 +00:00
highlight ( f ' ( { self . config . get ( " CME " , " pwn3d_label " ) } ) ' if self . admin_privs else ' ' )
2023-03-30 03:59:22 +00:00
)
)
2020-06-20 10:10:05 +00:00
if not self . args . continue_on_success :
return True
2017-07-10 05:44:58 +00:00
except Exception as e :
2023-04-21 10:20:47 +00:00
self . logger . fail (
2023-04-12 04:25:38 +00:00
f " { username } : { password if not self . config . get ( ' CME ' , ' audit_mode ' ) else self . config . get ( ' CME ' , ' audit_mode ' ) * 8 } { e } "
2023-03-30 03:59:22 +00:00
)
2020-04-28 10:11:16 +00:00
self . client_close ( )
2017-07-10 05:44:58 +00:00
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 :
2023-04-12 04:25:38 +00:00
return " "
self . logger . success ( " Executed command " )
2017-07-10 05:44:58 +00:00
for line in stdout :
2019-11-10 23:12:35 +00:00
self . logger . highlight ( line . strip ( ) )
2017-07-10 05:44:58 +00:00
return stdout