2022-07-18 23:59:14 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2022-02-28 22:18:53 +00:00
import asyncio
2023-03-30 03:59:22 +00:00
import os
from datetime import datetime
2023-02-01 11:04:13 +00:00
from os import getenv
2023-03-30 03:59:22 +00:00
from impacket . krb5 . ccache import CCache
2022-02-28 22:18:53 +00:00
from cme . connection import *
2023-03-30 03:59:22 +00:00
from cme . helpers . bloodhound import add_user_bh
2022-02-28 22:18:53 +00:00
from cme . logger import CMEAdapter
2023-02-05 20:23:40 +00:00
from aardwolf . connection import RDPConnection
2022-10-20 18:53:36 +00:00
from aardwolf . commons . queuedata . constants import VIDEO_FORMAT
2022-07-06 15:17:24 +00:00
from aardwolf . commons . iosettings import RDPIOSettings
2023-03-30 03:59:22 +00:00
from aardwolf . commons . target import RDPTarget
2022-07-06 15:17:24 +00:00
from aardwolf . protocol . x224 . constants import SUPP_PROTOCOLS
2023-02-05 20:23:40 +00:00
from asyauth . common . credentials . ntlm import NTLMCredential
from asyauth . common . credentials . kerberos import KerberosCredential
from asyauth . common . constants import asyauthSecret
from asysocks . unicomm . common . target import UniTarget , UniProto
2023-03-30 03:59:22 +00:00
2022-02-28 22:18:53 +00:00
class rdp ( connection ) :
def __init__ ( self , args , db , host ) :
self . domain = None
self . server_os = None
self . iosettings = RDPIOSettings ( )
2022-03-13 12:01:04 +00:00
self . iosettings . channels = [ ]
2022-10-20 18:53:36 +00:00
self . iosettings . video_out_format = VIDEO_FORMAT . RAW
self . iosettings . clipboard_use_pyperclip = False
2023-05-02 15:17:59 +00:00
self . protoflags_nla = [
SUPP_PROTOCOLS . SSL | SUPP_PROTOCOLS . RDP ,
SUPP_PROTOCOLS . SSL ,
SUPP_PROTOCOLS . RDP ,
]
self . protoflags = [
SUPP_PROTOCOLS . SSL | SUPP_PROTOCOLS . RDP ,
SUPP_PROTOCOLS . SSL ,
SUPP_PROTOCOLS . RDP ,
SUPP_PROTOCOLS . SSL | SUPP_PROTOCOLS . HYBRID ,
SUPP_PROTOCOLS . SSL | SUPP_PROTOCOLS . HYBRID_EX ,
]
width , height = args . res . upper ( ) . split ( " X " )
2022-03-13 12:01:04 +00:00
height = int ( height )
width = int ( width )
self . iosettings . video_width = width
self . iosettings . video_height = height
2023-03-30 03:59:22 +00:00
# servers dont support 8 any more :/
self . iosettings . video_bpp_min = 15
2022-03-13 12:01:04 +00:00
self . iosettings . video_bpp_max = 32
2023-03-30 03:59:22 +00:00
# PIL produces incorrect picture for some reason?! TODO: check bug
self . iosettings . video_out_format = VIDEO_FORMAT . PNG #
2022-02-28 22:18:53 +00:00
self . output_filename = None
self . domain = None
self . server_os = None
2022-03-13 12:01:04 +00:00
self . url = None
2022-04-20 08:34:49 +00:00
self . nla = True
2022-04-01 14:02:34 +00:00
self . hybrid = False
2023-02-05 20:23:40 +00:00
self . target = None
self . auth = None
2022-02-28 22:18:53 +00:00
2023-05-03 20:36:13 +00:00
self . rdp_error_status = {
" 0xc0000071 " : " STATUS_PASSWORD_EXPIRED " ,
" 0xc0000234 " : " STATUS_ACCOUNT_LOCKED_OUT " ,
" 0xc0000072 " : " STATUS_ACCOUNT_DISABLED " ,
" 0xc0000193 " : " STATUS_ACCOUNT_EXPIRED " ,
" 0xc000006E " : " STATUS_ACCOUNT_RESTRICTION " ,
" 0xc000006F " : " STATUS_INVALID_LOGON_HOURS " ,
" 0xc0000070 " : " STATUS_INVALID_WORKSTATION " ,
" 0xc000015B " : " STATUS_LOGON_TYPE_NOT_GRANTED " ,
" 0xc0000224 " : " STATUS_PASSWORD_MUST_CHANGE " ,
" 0xc0000022 " : " STATUS_ACCESS_DENIED " ,
" 0xc000006d " : " STATUS_LOGON_FAILURE " ,
" 0xc000006a " : " STATUS_WRONG_PASSWORD " ,
" KDC_ERR_CLIENT_REVOKED " : " KDC_ERR_CLIENT_REVOKED " ,
" KDC_ERR_PREAUTH_FAILED " : " KDC_ERR_PREAUTH_FAILED " ,
}
2022-02-28 22:18:53 +00:00
connection . __init__ ( self , args , db , host )
@staticmethod
def proto_args ( parser , std_parser , module_parser ) :
2023-05-08 18:39:36 +00:00
rdp_parser = parser . add_parser ( " rdp " , help = " own stuff using RDP " , parents = [ std_parser , module_parser ] )
2023-05-02 15:17:59 +00:00
rdp_parser . add_argument (
" -H " ,
" --hash " ,
metavar = " HASH " ,
dest = " hash " ,
nargs = " + " ,
default = [ ] ,
help = " NTLM hash(es) or file(s) containing NTLM hashes " ,
)
rdp_parser . add_argument (
" --no-bruteforce " ,
action = " store_true " ,
2023-05-08 18:39:36 +00:00
help = ( " No spray when using file for username and password (user1 => " " password1, user2 => password2 " ) ,
2023-05-02 15:17:59 +00:00
)
rdp_parser . add_argument (
" --continue-on-success " ,
action = " store_true " ,
help = " continues authentication attempts even after successes " ,
)
2023-05-08 18:39:36 +00:00
rdp_parser . add_argument ( " --port " , type = int , default = 3389 , help = " Custom RDP port " )
2023-05-02 15:17:59 +00:00
rdp_parser . add_argument (
" --rdp-timeout " ,
type = int ,
default = 1 ,
help = " RDP timeout on socket connection " ,
)
rdp_parser . add_argument (
" --nla-screenshot " ,
action = " store_true " ,
help = " Screenshot RDP login prompt if NLA is disabled " ,
)
2022-11-02 17:47:32 +00:00
2022-02-28 22:18:53 +00:00
dgroup = rdp_parser . add_mutually_exclusive_group ( )
2023-05-02 15:17:59 +00:00
dgroup . add_argument (
" -d " ,
metavar = " DOMAIN " ,
dest = " domain " ,
type = str ,
default = None ,
help = " domain to authenticate to " ,
)
dgroup . add_argument (
" --local-auth " ,
action = " store_true " ,
help = " authenticate locally to each target " ,
)
2022-02-28 22:18:53 +00:00
2023-05-08 18:39:36 +00:00
egroup = rdp_parser . add_argument_group ( " Screenshot " , " Remote Desktop Screenshot " )
2023-05-02 15:17:59 +00:00
egroup . add_argument (
" --screenshot " ,
action = " store_true " ,
help = " Screenshot RDP if connection success " ,
)
2023-05-08 18:39:36 +00:00
egroup . add_argument ( " --screentime " , type = int , default = 10 , help = " Time to wait for desktop image " )
2023-05-02 15:17:59 +00:00
egroup . add_argument (
" --res " ,
default = " 1024x768 " ,
help = ' Resolution in " WIDTHxHEIGHT " format. Default: " 1024x768 " ' ,
)
2022-03-12 11:54:40 +00:00
2022-02-28 22:18:53 +00:00
return parser
2023-01-04 17:26:37 +00:00
# def proto_flow(self):
# if self.create_conn_obj():
# self.proto_logger()
# self.print_host_info()
# if self.login() or (self.username == '' and self.password == ''):
# if hasattr(self.args, 'module') and self.args.module:
# self.call_modules()
# else:
# self.call_cmd_args()
2022-02-28 22:18:53 +00:00
def proto_logger ( self ) :
2023-03-30 03:59:22 +00:00
self . logger = CMEAdapter (
extra = {
2023-04-12 04:25:38 +00:00
" protocol " : " RDP " ,
" host " : self . host ,
" port " : self . args . port ,
2023-05-02 15:17:59 +00:00
" hostname " : self . hostname ,
2023-03-30 03:59:22 +00:00
}
)
2022-02-28 22:18:53 +00:00
def print_host_info ( self ) :
2023-03-30 03:59:22 +00:00
if self . domain is None :
2023-05-08 18:39:36 +00:00
self . logger . display ( " Probably old, doesn ' t not support HYBRID or HYBRID_EX " f " (nla: { self . nla } ) " )
2022-04-01 14:02:34 +00:00
else :
2023-05-08 18:39:36 +00:00
self . logger . display ( f " { self . server_os } (name: { self . hostname } ) (domain: { self . domain } ) " f " (nla: { self . nla } ) " )
2023-01-04 17:26:37 +00:00
return True
2022-02-28 22:18:53 +00:00
def create_conn_obj ( self ) :
2023-05-08 18:39:36 +00:00
self . target = RDPTarget ( ip = self . host , domain = " FAKE " , timeout = self . args . rdp_timeout )
self . auth = NTLMCredential ( secret = " pass " , username = " user " , domain = " FAKE " , stype = asyauthSecret . PASS )
2023-02-05 20:23:40 +00:00
2022-11-02 19:39:14 +00:00
self . check_nla ( )
2023-02-05 20:23:40 +00:00
2022-11-02 19:39:14 +00:00
for proto in reversed ( self . protoflags ) :
2022-04-01 14:02:34 +00:00
try :
self . iosettings . supported_protocols = proto
2023-05-02 15:17:59 +00:00
self . conn = RDPConnection (
iosettings = self . iosettings ,
target = self . target ,
credentials = self . auth ,
)
2023-02-05 20:23:40 +00:00
asyncio . run ( self . connect_rdp ( ) )
2022-04-01 14:02:34 +00:00
except OSError as e :
if " Errno 104 " not in str ( e ) :
return False
except Exception as e :
2022-04-20 07:41:15 +00:00
if " TCPSocket " in str ( e ) :
return False
2022-04-01 14:02:34 +00:00
if " Reason: " not in str ( e ) :
info_domain = self . conn . get_extra_info ( )
2023-04-12 04:25:38 +00:00
self . domain = info_domain [ " dnsdomainname " ]
self . hostname = info_domain [ " computername " ]
2023-05-08 18:39:36 +00:00
self . server_os = info_domain [ " os_guess " ] + " Build " + str ( info_domain [ " os_build " ] )
self . output_filename = os . path . expanduser ( f " ~/.cme/logs/ { self . hostname } _ { self . host } _ { datetime . now ( ) . strftime ( ' % Y- % m- %d _ % H % M % S ' ) } " )
2022-04-01 14:02:34 +00:00
self . output_filename = self . output_filename . replace ( " : " , " - " )
break
if self . args . domain :
self . domain = self . args . domain
2023-05-02 15:17:59 +00:00
2022-04-01 14:02:34 +00:00
if self . args . local_auth :
2022-06-21 19:38:25 +00:00
self . domain = self . hostname
2022-03-06 15:55:24 +00:00
2023-05-02 15:17:59 +00:00
self . target = RDPTarget (
ip = self . host ,
hostname = self . hostname ,
domain = self . domain ,
dc_ip = self . domain ,
timeout = self . args . rdp_timeout ,
)
2023-02-05 20:23:40 +00:00
2022-04-01 14:02:34 +00:00
return True
2022-02-28 22:18:53 +00:00
2022-11-02 19:39:14 +00:00
def check_nla ( self ) :
for proto in self . protoflags_nla :
try :
self . iosettings . supported_protocols = proto
2023-05-02 15:17:59 +00:00
self . conn = RDPConnection (
iosettings = self . iosettings ,
target = self . target ,
credentials = self . auth ,
)
2023-02-05 20:23:40 +00:00
asyncio . run ( self . connect_rdp ( ) )
2023-05-08 18:39:36 +00:00
if str ( proto ) == " SUPP_PROTOCOLS.RDP " or str ( proto ) == " SUPP_PROTOCOLS.SSL " or str ( proto ) == " SUPP_PROTOCOLS.SSL|SUPP_PROTOCOLS.RDP " :
2022-11-02 19:39:14 +00:00
self . nla = False
return
2023-02-05 20:23:40 +00:00
except Exception as e :
2022-11-02 19:39:14 +00:00
pass
2023-02-05 20:23:40 +00:00
async def connect_rdp ( self ) :
2022-02-28 22:18:53 +00:00
_ , err = await self . conn . connect ( )
if err is not None :
raise err
2023-05-02 15:17:59 +00:00
def kerberos_login (
self ,
domain ,
username ,
password = " " ,
ntlm_hash = " " ,
aesKey = " " ,
kdcHost = " " ,
useCache = False ,
) :
2023-01-02 11:37:37 +00:00
try :
2023-05-02 15:17:59 +00:00
lmhash = " "
nthash = " "
2023-03-30 03:59:22 +00:00
# This checks to see if we didn't provide the LM Hash
2023-05-02 15:17:59 +00:00
if ntlm_hash . find ( " : " ) != - 1 :
lmhash , nthash = ntlm_hash . split ( " : " )
2023-01-02 11:37:37 +00:00
self . hash = nthash
else :
nthash = ntlm_hash
self . hash = ntlm_hash
2023-03-30 03:59:22 +00:00
if lmhash :
self . lmhash = lmhash
if nthash :
self . nthash = nthash
2023-01-02 11:37:37 +00:00
2023-05-02 15:17:59 +00:00
if not all ( " " == s for s in [ nthash , password , aesKey ] ) :
2023-02-01 11:04:13 +00:00
kerb_pass = next ( s for s in [ nthash , password , aesKey ] if s )
else :
2023-05-02 15:17:59 +00:00
kerb_pass = " "
2023-02-01 11:04:13 +00:00
2023-01-02 11:37:37 +00:00
fqdn_host = self . hostname + " . " + self . domain
password = password if password else nthash
2023-02-05 20:23:40 +00:00
2023-02-01 11:04:13 +00:00
if useCache :
2023-02-05 20:23:40 +00:00
stype = asyauthSecret . CCACHE
2023-02-01 11:04:13 +00:00
if not password :
2023-05-02 15:17:59 +00:00
password = getenv ( " KRB5CCNAME " ) if not password else password
2023-02-01 11:04:13 +00:00
if " / " in password :
2023-05-08 18:39:36 +00:00
self . logger . fail ( " Kerberos ticket need to be on the local directory " )
2023-02-01 11:04:13 +00:00
return False
2023-05-02 15:17:59 +00:00
ccache = CCache . loadFile ( getenv ( " KRB5CCNAME " ) )
2023-02-01 11:04:13 +00:00
ticketCreds = ccache . credentials [ 0 ]
2023-05-08 18:39:36 +00:00
username = ticketCreds [ " client " ] . prettyPrint ( ) . decode ( ) . split ( " @ " ) [ 0 ]
2023-02-05 20:23:40 +00:00
else :
stype = asyauthSecret . PASS if not nthash else asyauthSecret . NT
2023-03-30 03:59:22 +00:00
kerberos_target = UniTarget (
self . domain ,
88 ,
UniProto . CLIENT_TCP ,
proxies = None ,
dns = None ,
2023-05-02 15:17:59 +00:00
dc_ip = self . domain ,
2023-03-30 03:59:22 +00:00
)
self . auth = KerberosCredential (
target = kerberos_target ,
secret = password ,
username = username ,
domain = domain ,
2023-05-02 15:17:59 +00:00
stype = stype ,
2023-03-30 03:59:22 +00:00
)
2023-05-08 18:39:36 +00:00
self . conn = RDPConnection ( iosettings = self . iosettings , target = self . target , credentials = self . auth )
2023-02-05 20:23:40 +00:00
asyncio . run ( self . connect_rdp ( ) )
2023-02-01 11:04:13 +00:00
2023-01-02 11:37:37 +00:00
self . admin_privs = True
2023-04-12 04:25:38 +00:00
self . logger . success (
2023-05-02 15:17:59 +00:00
" {} \\ {} {} {} " . format (
domain ,
username ,
2023-05-07 22:51:01 +00:00
(
# Show what was used between cleartext, nthash, aesKey and ccache
" from ccache "
if useCache
2023-05-08 18:39:36 +00:00
else " : %s " % ( kerb_pass if not self . config . get ( " CME " , " audit_mode " ) else self . config . get ( " CME " , " audit_mode " ) * 8 )
2023-05-02 15:17:59 +00:00
) ,
2023-05-03 20:38:46 +00:00
self . mark_pwned ( ) ,
2023-05-02 15:17:59 +00:00
)
2023-03-30 03:59:22 +00:00
)
2023-01-02 11:37:37 +00:00
if not self . args . local_auth :
add_user_bh ( username , domain , self . logger , self . config )
if not self . args . continue_on_success :
return True
except Exception as e :
2023-02-01 11:04:13 +00:00
if " KDC_ERR " in str ( e ) :
reason = None
2023-05-03 20:36:13 +00:00
for word in self . rdp_error_status . keys ( ) :
2023-02-01 11:04:13 +00:00
if word in str ( e ) :
2023-05-03 20:36:13 +00:00
reason = self . rdp_error_status [ word ]
2023-04-12 04:25:38 +00:00
self . logger . fail (
2023-05-08 18:39:36 +00:00
( f " { domain } \\ { username } { ' from ccache ' if useCache else ' : %s ' % ( kerb_pass if not self . config . get ( ' CME ' , ' audit_mode ' ) else self . config . get ( ' CME ' , ' audit_mode ' ) * 8 ) } { f ' ( { reason } ) ' if reason else str ( e ) } " ) ,
color = ( " magenta " if ( ( reason or " CredSSP " in str ( e ) ) and reason != " KDC_ERR_C_PRINCIPAL_UNKNOWN " ) else " red " ) ,
2023-03-30 03:59:22 +00:00
)
2023-02-01 11:04:13 +00:00
elif " Authentication failed! " in str ( e ) :
2023-05-08 18:39:36 +00:00
self . logger . success ( f " { domain } \\ { username } : { password } { self . mark_pwned ( ) } " )
2023-02-01 11:04:13 +00:00
elif " No such file " in str ( e ) :
2023-04-12 04:25:38 +00:00
self . logger . fail ( e )
2023-01-02 11:37:37 +00:00
else :
reason = None
2023-05-03 20:36:13 +00:00
for word in self . rdp_error_status . keys ( ) :
2023-01-02 11:37:37 +00:00
if word in str ( e ) :
2023-05-03 20:36:13 +00:00
reason = self . rdp_error_status [ word ]
2023-01-02 11:37:37 +00:00
if " cannot unpack non-iterable NoneType object " == str ( e ) :
reason = " User valid but cannot connect "
2023-04-06 00:09:07 +00:00
self . logger . fail (
2023-05-08 18:39:36 +00:00
( f " { domain } \\ { username } { ' from ccache ' if useCache else ' : %s ' % ( kerb_pass if not self . config . get ( ' CME ' , ' audit_mode ' ) else self . config . get ( ' CME ' , ' audit_mode ' ) * 8 ) } { f ' ( { reason } ) ' if reason else ' ' } " ) ,
color = ( " magenta " if ( ( reason or " CredSSP " in str ( e ) ) and reason != " STATUS_LOGON_FAILURE " ) else " red " ) ,
2023-03-30 03:59:22 +00:00
)
2023-01-02 11:37:37 +00:00
return False
2022-04-01 14:02:34 +00:00
def plaintext_login ( self , domain , username , password ) :
2022-02-28 22:18:53 +00:00
try :
2023-05-02 15:17:59 +00:00
self . auth = NTLMCredential (
secret = password ,
username = username ,
domain = domain ,
stype = asyauthSecret . PASS ,
)
2023-05-08 18:39:36 +00:00
self . conn = RDPConnection ( iosettings = self . iosettings , target = self . target , credentials = self . auth )
2023-02-05 20:23:40 +00:00
asyncio . run ( self . connect_rdp ( ) )
2022-02-28 22:18:53 +00:00
self . admin_privs = True
2023-05-04 13:21:17 +00:00
self . logger . success ( f " { domain } \\ { username } : { password } { self . mark_pwned ( ) } " )
2022-03-06 15:55:24 +00:00
if not self . args . local_auth :
add_user_bh ( username , domain , self . logger , self . config )
2022-02-28 22:18:53 +00:00
if not self . args . continue_on_success :
return True
except Exception as e :
2022-11-02 19:39:14 +00:00
if " Authentication failed! " in str ( e ) :
2023-05-08 18:39:36 +00:00
self . logger . success ( f " { domain } \\ { username } : { password } { self . mark_pwned ( ) } " )
2022-11-02 19:39:14 +00:00
else :
reason = None
2023-05-03 20:36:13 +00:00
for word in self . rdp_error_status . keys ( ) :
2022-11-02 19:39:14 +00:00
if word in str ( e ) :
2023-05-03 20:36:13 +00:00
reason = self . rdp_error_status [ word ]
2022-11-08 08:25:59 +00:00
if " cannot unpack non-iterable NoneType object " == str ( e ) :
reason = " User valid but cannot connect "
2023-04-06 00:09:07 +00:00
self . logger . fail (
2023-05-08 18:39:36 +00:00
( f " { domain } \\ { username } : { password } { f ' ( { reason } ) ' if reason else ' ' } " ) ,
color = ( " magenta " if ( ( reason or " CredSSP " in str ( e ) ) and reason != " STATUS_LOGON_FAILURE " ) else " red " ) ,
2023-03-30 03:59:22 +00:00
)
2022-02-28 22:18:53 +00:00
return False
def hash_login ( self , domain , username , ntlm_hash ) :
try :
2023-05-02 15:17:59 +00:00
self . auth = NTLMCredential (
secret = ntlm_hash ,
username = username ,
domain = domain ,
stype = asyauthSecret . NT ,
)
2023-05-08 18:39:36 +00:00
self . conn = RDPConnection ( iosettings = self . iosettings , target = self . target , credentials = self . auth )
2023-02-05 20:23:40 +00:00
asyncio . run ( self . connect_rdp ( ) )
2022-02-28 22:18:53 +00:00
self . admin_privs = True
2023-05-08 18:39:36 +00:00
self . logger . success ( f " { self . domain } \\ { username } : { ntlm_hash } { self . mark_pwned ( ) } " )
2022-03-06 15:55:24 +00:00
if not self . args . local_auth :
2023-05-02 15:17:59 +00:00
add_user_bh ( username , domain , self . logger , self . config )
2022-02-28 22:18:53 +00:00
if not self . args . continue_on_success :
return True
except Exception as e :
2022-11-02 19:39:14 +00:00
if " Authentication failed! " in str ( e ) :
2023-05-08 18:39:36 +00:00
self . logger . success ( f " { domain } \\ { username } : { ntlm_hash } { self . mark_pwned ( ) } " )
2022-11-02 19:39:14 +00:00
else :
reason = None
2023-05-03 20:36:13 +00:00
for word in self . rdp_error_status . keys ( ) :
2022-11-02 19:39:14 +00:00
if word in str ( e ) :
2023-05-03 20:36:13 +00:00
reason = self . rdp_error_status [ word ]
2022-11-02 19:39:14 +00:00
if " cannot unpack non-iterable NoneType object " == str ( e ) :
reason = " User valid but cannot connect "
2023-05-02 15:17:59 +00:00
2023-04-06 00:09:07 +00:00
self . logger . fail (
2023-05-08 18:39:36 +00:00
( f " { domain } \\ { username } : { ntlm_hash } { f ' ( { reason } ) ' if reason else ' ' } " ) ,
color = ( " magenta " if ( ( reason or " CredSSP " in str ( e ) ) and reason != " STATUS_LOGON_FAILURE " ) else " red " ) ,
2023-03-30 03:59:22 +00:00
)
2022-02-28 22:18:53 +00:00
return False
2022-03-12 11:54:40 +00:00
2022-03-13 12:01:04 +00:00
async def screen ( self ) :
2023-01-04 17:26:37 +00:00
try :
2023-05-08 18:39:36 +00:00
self . conn = RDPConnection ( iosettings = self . iosettings , target = self . target , credentials = self . auth )
2023-02-05 20:23:40 +00:00
await self . connect_rdp ( )
except Exception as e :
2023-01-04 17:26:37 +00:00
return
2022-03-13 12:01:04 +00:00
2023-02-05 20:23:40 +00:00
await asyncio . sleep ( int ( 5 ) )
2022-03-13 12:01:04 +00:00
if self . conn is not None and self . conn . desktop_buffer_has_data is True :
buffer = self . conn . get_desktop_buffer ( VIDEO_FORMAT . PIL )
2023-05-08 18:39:36 +00:00
filename = os . path . expanduser ( f " ~/.cme/screenshots/ { self . hostname } _ { self . host } _ { datetime . now ( ) . strftime ( ' % Y- % m- %d _ % H % M % S ' ) } .png " )
2023-04-12 04:25:38 +00:00
buffer . save ( filename , " png " )
self . logger . highlight ( f " Screenshot saved { filename } " )
2022-03-13 12:01:04 +00:00
2022-03-12 11:54:40 +00:00
def screenshot ( self ) :
2022-03-13 12:01:04 +00:00
asyncio . run ( self . screen ( ) )
2023-05-02 15:17:59 +00:00
2022-11-02 17:47:32 +00:00
async def nla_screen ( self ) :
# Otherwise it crash
self . iosettings . supported_protocols = None
2023-05-08 18:39:36 +00:00
self . auth = NTLMCredential ( secret = " " , username = " " , domain = " " , stype = asyauthSecret . PASS )
self . conn = RDPConnection ( iosettings = self . iosettings , target = self . target , credentials = self . auth )
2023-02-05 20:23:40 +00:00
await self . connect_rdp_old ( self . url )
2022-11-02 17:47:32 +00:00
await asyncio . sleep ( int ( self . args . screentime ) )
if self . conn is not None and self . conn . desktop_buffer_has_data is True :
buffer = self . conn . get_desktop_buffer ( VIDEO_FORMAT . PIL )
2023-05-08 18:39:36 +00:00
filename = os . path . expanduser ( f " ~/.cme/screenshots/ { self . hostname } _ { self . host } _ { datetime . now ( ) . strftime ( ' % Y- % m- %d _ % H % M % S ' ) } .png " )
2023-04-12 04:25:38 +00:00
buffer . save ( filename , " png " )
self . logger . highlight ( f " NLA Screenshot saved { filename } " )
2022-11-02 17:47:32 +00:00
def nla_screenshot ( self ) :
if not self . nla :
2022-11-08 08:25:59 +00:00
asyncio . run ( self . nla_screen ( ) )