• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

Phyton Python tool to interact with WMI StdRegProv

dEEpEst

☣☣ In The Depths ☣☣
Staff member
Administrator
Super Moderator
Hacker
Specter
Crawler
Shadow
Joined
Mar 29, 2018
Messages
13,861
Solutions
4
Reputation
32
Reaction score
45,552
Points
1,813
Credits
55,350
‎7 Years of Service‎
 
56%
Python tool that leverages Impacket to interact with registry using WMI StdRegProv.

Source Code​

Python:
 import socket
import logging
import sys
import argparse
from impacket.examples import logger
from impacket.examples.utils import parse_target
from impacket.dcerpc.v5.dcom import wmi
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5.dcomrt import DCOMConnection, NULL



class WMI:
    def __init__(self, target, namespace, username='', password='', domain='', hashes=None, aesKey=None, doKerberos=False, kdcHost=None):
        self.dcom = None
        self.iWbemServices = None
        self.target = target
        self.namespace = namespace
        self.username = username
        self.password = password
        self.domain = domain
        self.lmhash = ''
        self.nthash = ''
        self.aesKey = aesKey
        self.doKerberos = doKerberos
        self.kdcHost = kdcHost
        if hashes is not None:
            self.lmhash, self.nthash = hashes.split(':')

    def connect(self):
        try:
            self.dcom = DCOMConnection(self.target, self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, oxidResolver=True, doKerberos=self.doKerberos, kdcHost=self.kdcHost)
            iInterface = self.dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
            iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
            self.iWbemServices = iWbemLevel1Login.NTLMLogin(self.namespace, NULL, NULL)
        except socket.error as e:
            logging.error(f"Couldn't connect {self.target}. Error: {str(e)}")
            exit(0)

    def get_reg_hive(self, hive):
        hive_map = {
            'HKCC': 0x80000005,
            'HKU': 0x80000003,
            'HKLM': 0x80000002,
            'HKCU': 0x80000001,
            'HKCR': 0x80000000,
        }
        return hive_map.get(hive, 0x80000002)

    def check_access(self, hive, key_path, check_type):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.CheckAccess(hive_num, key_path, check_type)
        return ret_vals.bGranted
    
    def create_key(self, hive, subkey):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.CreateKey(hive_num, subkey)
        return ret_vals.ReturnValue

    def delete_key(self, hive, subkey):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.DeleteKey(hive_num, subkey)
        return ret_vals.ReturnValue

    def delete_value(self, hive, subkey, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.DeleteValue(hive_num, subkey, value_name)
        return ret_vals.ReturnValue

    def enum_key(self, hive, key_path):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.EnumKey(hive_num, key_path)
        
        if ret_vals.ReturnValue == 0:
            return ret_vals.sNames or []
        return []

    def enum_values(self, hive, key_path):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.EnumValues(hive_num, key_path)
        
        if ret_vals.ReturnValue != 0:
            return {}

        type_map = {
            1: "REG_SZ",
            2: "REG_EXPAND_SZ",
            3: "REG_BINARY",
            4: "REG_DWORD",
            7: "REG_MULTI_SZ",
            11: "REG_QWORD"
        }

        results = {}
        value_names = ret_vals.sNames or []
        value_types = ret_vals.Types or []
        
        for name, type_num in zip(value_names, value_types):
            value = None
            if type_num == 1:  # String
                value = classObject.GetStringValue(hive_num, key_path, name)
            elif type_num == 2:  # Expanded String
                value = classObject.GetExpandedStringValue(hive_num, key_path, name)
            elif type_num == 3:  # Binary
                value = classObject.GetBinaryValue(hive_num, key_path, name)
            elif type_num == 4:  # DWORD
                value = classObject.GetDWORDValue(hive_num, key_path, name)
            elif type_num == 7:  # Multi-String
                value = classObject.GetMultiStringValue(hive_num, key_path, name)
            elif type_num == 11:  # QWORD
                value = classObject.GetQWORDValue(hive_num, key_path, name)
            
            results[name] = {
                'type': type_map.get(type_num, f"UNKNOWN_{type_num}"),
                'type_num': type_num,
                'value': value.sValue if value and hasattr(value, 'sValue') else value.uValue if value else None
            }
        
        return results

    def get_binary_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetBinaryValue(hive_num, key_path, value_name)
        
        if ret_vals.ReturnValue == 0:
            return bytes(ret_vals.uValue)
        return None

    def get_dword_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetDWORDValue(hive_num, key_path, value_name)
        if ret_vals.ReturnValue == 0:
            return ret_vals.uValue
        else:
            return None

    def get_expandedstring_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetExpandedStringValue(hive_num, key_path, value_name)
        if ret_vals.ReturnValue == 0:
            return ret_vals.sValue
        else:
            return None

    def get_multistring_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetMultiStringValue(hive_num, key_path, value_name)
        if ret_vals.ReturnValue == 0:
            return ret_vals.sValue
        else:
            return None

    def get_qword_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetQWORDValue(hive_num, key_path, value_name)
        if ret_vals.ReturnValue == 0:
            return ret_vals.uValue
        else:
            return None

    def get_security_descriptor(self, hive, key_path):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetSecurityDescriptor(hive_num, key_path)
        if ret_vals.ReturnValue == 0:
            return ret_vals.Descriptor
        else:
            return None
        
    def get_string_value(self, hive, key_path, value_name):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.GetStringValue(hive_num, key_path, value_name)
        
        if ret_vals.ReturnValue == 0:
            return ret_vals.sValue
        return None

    def set_binary_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetBinaryValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def set_dword_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetDWORDValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def set_expandedstring_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetExpandedStringValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def set_multistring_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetMultiStringValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def set_qword_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetQWORDValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def set_security_descriptor(self, hive, key_path):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetSecurityDescriptor(hive_num, key_path)
        return ret_vals.ReturnValue

    def set_string_value(self, hive, key_path, value_name, value):
        hive_num = self.get_reg_hive(hive)
        classObject, _ = self.iWbemServices.GetObject('StdRegProv')
        ret_vals = classObject.SetStringValue(hive_num, key_path, value_name, value)
        return ret_vals.ReturnValue

    def close(self):
        if self.iWbemServices:
            self.iWbemServices.RemRelease()
        if self.dcom:
            self.dcom.disconnect()

def get_hive(reg_key):
    hives = {
        'HKCU': 'HKCU',
        'HKEY_CURRENT_USER': 'HKCU',
        'HKLM': 'HKLM',
        'HKEY_LOCAL_MACHINE': 'HKLM',
        'HKU': 'HKU',
        'HKEY_USERS': 'HKU',
        'HKCR': 'HKCR',
        'HKEY_CLASSES_ROOT': 'HKCR'
    }
    if ':\\' in reg_key:
        parts = reg_key.split(':\\', 1)
    else:
        parts = reg_key.split('\\', 1)
        
    if len(parts) != 2:
        return None
        
    hive = parts[0].upper()
    key_path = parts[1]

    if hive in hives:
        return [hives[hive], key_path]
    return None

def str_to_bytes(data):
    try:
        data = data.replace(' ', '').replace('0x', '')
        if len(data) % 2 != 0:
            data = '0' + data
        byte_array = bytes.fromhex(data)
        return [b for b in byte_array]
    except ValueError:
        print(f"Error: Invalid hex string: {data}")
        return None

def str_to_dword(data):
    try:
        if data.startswith('0x'):
            return int(data, 16)
        return int(data)
    except ValueError:
        print(f"Error: Invalid DWORD value: {data}")
        return None

def str_to_qword(data):
    try:
        if data.startswith('0x'):
            value = int(data, 16)
        else:
            value = int(data)
        if 0 <= value <= 0xFFFFFFFFFFFFFFFF:
            return value
        else:
            print(f"Error: Value out of range for QWORD (0 to {0xFFFFFFFFFFFFFFFF})")
            return None
            
    except ValueError:
        print(f"Error: Invalid QWORD value: {data}")
        return None

def parse_security_descriptor(descriptor):
    access_rights = {
        0x10000: "DELETE",
        0x20000: "READ_CONTROL",
        0x40000: "WRITE_DAC",
        0x80000: "WRITE_OWNER",
        0x02000: "READ",
        0x04000: "WRITE",
        0x08000: "EXECUTE",
        0xF0000: "ALL_ACCESS"
    }
    ace_types = {
        0: "ACCESS_ALLOWED",
        1: "ACCESS_DENIED",
        2: "SYSTEM_AUDIT",
        3: "SYSTEM_ALARM"
    }
    results = []
    for ace in descriptor.DACL:
        rights = []
        for mask, right in access_rights.items():
            if ace.AccessMask & mask:
                rights.append(right)

        ace_info = {
            'trustee': f"{ace.Trustee.Domain}\\{ace.Trustee.Name}",
            'access_mask': f"0x{ace.AccessMask:08X}",
            'access_rights': rights,
            'ace_type': ace_types.get(ace.AceType, f"Unknown ({ace.AceType})")
        }
        results.append(ace_info)
    return results

def exec_reg(wmi, cmd, reg_key, reg_value, reg_content, access_num):
    print(f'\nAttempting to run {cmd}\n')
    if reg_key:
        reg_data = get_hive(reg_key)
        hive = reg_data[0]
        key_path = reg_data[1]
    else:
        print('Missing -subkey arg')
        return

    if cmd.lower() == 'checkaccess':
        try:
            rt = wmi.check_access(hive, key_path, int(access_num))
            if rt:
                print(f'\nAccess to {reg_key}: {rt}\n')
            else:
                print(f'Access to {reg_key}: {rt}')
                print(f'WMI returned: {rt}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'createkey':
        try:
            rt = wmi.create_key(hive, key_path)
            if rt:
                print(f'\nSuccessfully created {reg_key}\n')
            else:
                print(f'Failed to create {reg_key}')
                print(f'WMI returned: {rt}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'deletekey':
        try:
            rt = wmi.delete_key(hive, key_path)
            if rt == 0:
                print(f'\nSuccessfully deleted {reg_key}\n')
            else:
                print(f'Failed to delete {reg_key}')
                print(f'WMI returned: {rt}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'deletevalue':
        try:
            rt = wmi.delete_value(hive, key_path, reg_value)
            if rt == 0:
                print(f'\nSuccessfully deleted {reg_key}:{reg_value}\n')
            else:
                print(f'Failed to delete {reg_key}:{reg_value}')
                print(f'WMI returned: {rt}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'enumkey':
        try:
            rt = wmi.enum_key(hive, key_path)
            if len(rt) > 0:
                print(f'\nSubKeyNames for {reg_key}:')
                for keys in rt:
                    print(f'\t{keys}')
                print()
            else:
                print(f'No key data retuend for {reg_key}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'enumvalues':
        try:
            rt = wmi.enum_values(hive, key_path)
            if len(rt) > 0:
                print(f'\nSubKeyValues for {reg_key}:')
                print(f"\t{'Name':<30}{'Type':<20}Value")
                for name, data in rt.items():
                    print(f'\t{name:<30}{data['type']:<20}{data['value']}')
                print()
            else:
                print(f'No key data returned for {reg_key}')
        except Exception as e:
            print(e)
            return       

    elif cmd.lower() == 'getbinaryvalue':
        try:
            rt = wmi.get_binary_value(hive, key_path, reg_value)
            if rt:
                print(f'Binary value for {reg_key}:{reg_value}')
                print(f'\t{rt}')
            else:
                print(f'No binary value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getdwordvalue':
        try:
            rt = wmi.get_dword_value(hive, key_path, reg_value)
            if rt:
                print(f'DWORD value for {reg_key}:{reg_value}')
                print(f'\t{rt}')
            else:
                print(f'No DWORD value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getexpandedstringvalue':
        try:
            rt = wmi.get_expandedstring_value(hive, key_path, reg_value)
            if rt:
                print(f'ExpandedString value for {reg_key}:{reg_value}')
                print(f'\t{rt}')
            else:
                print(f'No ExpandedString value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getmultistringvalue':
        try:
            rt = wmi.get_multistring_value(hive, key_path, reg_value)
            if rt:
                print(f'MultiString value for {reg_key}:{reg_value}')
                for s in rt:
                    print(f'\t{s}')
            else:
                print(f'No MultiString value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getqwordvalue':
        try:
            rt = wmi.get_qword_value(hive, key_path, reg_value)
            if rt:
                print(f'QWORD value for {reg_key}:{reg_value}')
                for s in rt:
                    print(f'\t{s}')
            else:
                print(f'No QWORD value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getsecuritydescriptor':
        try:
            rt = wmi.get_security_descriptor(hive, key_path)
            if rt:
                print(f'Security Descriptor value for {reg_key}')
                desc = parse_security_descriptor(rt)
                for ace in desc:
                    print(f"Trustee: {ace['trustee']}")
                    print(f"Access Mask: {ace['access_mask']}")
                    print(f"Rights: {', '.join(ace['access_rights'])}")
                    print(f"ACE Type: {ace['ace_type']}")
                    print("---")
            else:
                print(f'No Security Descriptor value returned for {reg_key}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'getstringvalue':
        try:
            rt = wmi.get_qword_value(hive, key_path, reg_value)
            if rt:
                print(f'String value for {reg_key}:{reg_value}')
                print(f'\t{rt}')
            else:
                print(f'No String value returned for {reg_key}:{reg_value}\n')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'setbinaryvalue':
        try:
            bin_data = str_to_bytes(reg_content)
            rt = wmi.set_binary_value(hive, key_path, reg_value, bin_data)
            if rt == 0:
                print(f'\nSuccessfully set binary value{reg_key}:{reg_value} to {bytes(bin_data)}\n')
            else:
                print(f'WMI Returned: {rt}')
                print(f'Failed to set {reg_key}:{reg_value} to {reg_content}')
        except Exception as e:
            print(e)
            return

    elif cmd.lower() == 'setdwordvalue':
        try:
            dword_data = str_to_dword(reg_content)
            rt = wmi.set_dword_value(hive, key_path, reg_value, dword_data)
            if rt == 0:
                print(f'\nSuccessfully set DWORD value {reg_key}:{reg_value} to {dword_data}\n')
            else:
                print(f'WMI Returned: {rt}')
                print(f'Failed to set {reg_key}:{reg_value} to {dword_data}')
        except Exception as e:
            print(e)
            return
        
    elif cmd.lower() == 'setexpandedstringvalue':
        try:
            rt = wmi.set_expandedstring_value(hive, key_


Installation​

Code:
pip install impacket

Basic usage​


Python:
python reg_snake.py -command enumvalues -subkey "HKCU\SOFTWARE\Google\Chrome" ./admin:[email protected]

Like other Impacket tools, can use user/pass, hashes or kerberos for authentication.
 
Back
Top