mirror of
https://github.com/Pennyw0rth/NetExec
synced 2026-06-06 16:34:30 +00:00
151 lines
6.6 KiB
Python
151 lines
6.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
|
from impacket.dcerpc.v5 import rrp
|
|
from impacket.examples.secretsdump import RemoteOperations
|
|
|
|
|
|
class CMEModule:
|
|
name = 'reg-query'
|
|
description = 'Performs a registry query on the machine'
|
|
supported_protocols = ['smb']
|
|
opsec_safe = True
|
|
multiple_hosts = True
|
|
|
|
def options(self, context, module_options):
|
|
'''
|
|
PATH: Registry key path to query
|
|
KEY: Registry key value to retrieve
|
|
VALUE Registry key value to set (only used for modification). Will add a new regitry key if use on registry key that does not already exist
|
|
TYPE Type of registry to modify, add or delete. Default type : REG_SZ. Type supported : REG_NONE, REG_SZ, REG_EXPAND_SZ,REG_BINARY, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_LINK, REG_MULTI_SZ, REG_QWORD
|
|
DELETE If set to True, delete a registry key if it does exist
|
|
'''
|
|
|
|
self.context = context
|
|
self.path = None
|
|
self.key = None
|
|
self.value = None
|
|
self.type = None
|
|
self.delete = False
|
|
|
|
if module_options and 'PATH' in module_options:
|
|
self.path = module_options['PATH']
|
|
|
|
if module_options and 'KEY' in module_options:
|
|
self.key = module_options['KEY']
|
|
|
|
if 'VALUE' in module_options:
|
|
self.value = module_options['VALUE']
|
|
if 'TYPE' in module_options:
|
|
type_dict = {
|
|
'REG_NONE': rrp.REG_NONE,
|
|
'REG_SZ': rrp.REG_SZ,
|
|
'REG_EXPAND_SZ': rrp.REG_EXPAND_SZ,
|
|
'REG_BINARY': rrp.REG_BINARY,
|
|
'REG_DWORD': rrp.REG_DWORD,
|
|
'REG_DWORD_BIG_ENDIAN': rrp.REG_DWORD_BIG_ENDIAN,
|
|
'REG_LINK': rrp.REG_LINK,
|
|
'REG_MULTI_SZ': rrp.REG_MULTI_SZ,
|
|
'REG_QWORD': rrp.REG_QWORD
|
|
}
|
|
self.type = module_options['TYPE']
|
|
if "WORD" in self.type:
|
|
try :
|
|
self.value = int(self.value)
|
|
except:
|
|
context.log.error("Invalid registry value type specified: %s" % self.value)
|
|
sys.exit(1)
|
|
if self.type in type_dict:
|
|
self.type = type_dict[self.type]
|
|
else:
|
|
context.log.error("Invalid registry value type specified: %s" % self.type)
|
|
return
|
|
else:
|
|
self.type = 1
|
|
|
|
if module_options and 'DELETE' in module_options and module_options['DELETE'].lower() == 'true':
|
|
self.delete = True
|
|
|
|
def on_admin_login(self, context, connection):
|
|
if not self.path:
|
|
context.log.error("Please provide the path of the registry to query")
|
|
return
|
|
|
|
if not self.key:
|
|
context.log.error("Please provide the registry key to query")
|
|
return
|
|
|
|
remoteOps = RemoteOperations(connection.conn, False)
|
|
remoteOps.enableRegistry()
|
|
|
|
try:
|
|
if "HKLM" in self.path or "HKEY_LOCAL_MACHINE" in self.path:
|
|
self.path = (self.path).replace('HKLM\\', '')
|
|
ans = rrp.hOpenLocalMachine(remoteOps._RemoteOperations__rrp)
|
|
|
|
elif "HKCU" in self.path or "HKEY_CURRENT_USER" in self.path:
|
|
self.path = (self.path).replace('HKCU\\', '')
|
|
ans = rrp.hOpenCurrentUser(remoteOps._RemoteOperations__rrp)
|
|
|
|
elif "HKCR" in self.path or "HKEY_CLASSES_ROOT" in self.path:
|
|
self.path = (self.path).replace('HKCR\\', '')
|
|
ans = rrp.hOpenClassesRoot(remoteOps._RemoteOperations__rrp)
|
|
|
|
else:
|
|
context.log.error("Unsupported registry hive specified in path: %s" % self.path)
|
|
return
|
|
|
|
regHandle = ans['phKey']
|
|
ans = rrp.hBaseRegOpenKey(remoteOps._RemoteOperations__rrp, regHandle, self.path)
|
|
keyHandle = ans['phkResult']
|
|
|
|
if self.delete:
|
|
# Delete registry
|
|
try:
|
|
# Check if value exists
|
|
dataType, reg_value = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key)
|
|
except:
|
|
self.context.log.error("Registry key %s does not exist" % (self.key))
|
|
return
|
|
# Delete value
|
|
rrp.hBaseRegDeleteValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key)
|
|
self.context.log.success('Registry key %s has been deleted successfully' % (self.key))
|
|
rrp.hBaseRegCloseKey(remoteOps._RemoteOperations__rrp, keyHandle)
|
|
|
|
if self.value is not None:
|
|
# Check if value exists
|
|
try:
|
|
# Check if value exists
|
|
dataType, reg_value = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key)
|
|
self.context.log.highlight("Key %s exists with value %s" % (self.key, reg_value))
|
|
# Modification
|
|
rrp.hBaseRegSetValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key, self.type, self.value)
|
|
context.log.success("Key %s has been modified to %s" % (self.key, self.value))
|
|
except:
|
|
rrp.hBaseRegSetValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key, self.type, self.value)
|
|
self.context.log.success("New Key %s has been added with value %s" % (self.key, self.value))
|
|
rrp.hBaseRegCloseKey(remoteOps._RemoteOperations__rrp, keyHandle)
|
|
|
|
else:
|
|
# Query
|
|
try :
|
|
dataType, reg_value = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, self.key)
|
|
context.log.highlight("%s: %s" % (self.key, reg_value))
|
|
except:
|
|
if self.delete:
|
|
pass
|
|
else :
|
|
self.context.log.error("Registry key %s does not exist" % (self.key))
|
|
return
|
|
rrp.hBaseRegCloseKey(remoteOps._RemoteOperations__rrp, keyHandle)
|
|
|
|
except DCERPCException as e:
|
|
#context.log.error("DCERPC Error while querying or modifying registry: %s" % e)
|
|
pass
|
|
except Exception as e:
|
|
context.log.error("Error while querying or modifying registry: %s" % e)
|
|
|
|
finally:
|
|
remoteOps.finish()
|