Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions impacket/dcerpc/v5/dcom/wmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2359,9 +2359,9 @@ def setClassName(self, value):
else:
raise Exception("Cannot set class name for an instance object.")

def addNewAttribute(self, name, type, default_value=None):
def addNewAttribute(self, name, type, default_value=None, qualifiers=None):
if not self.encodingUnit['ObjectBlock'].isInstance():
self.__new_attributes.append((name, type, default_value))
self.__new_attributes.append((name, type, default_value, qualifiers or []))
setattr(self, name, default_value)
else:
raise Exception("Cannot add new attribute to an instance object.")
Expand Down Expand Up @@ -2428,24 +2428,38 @@ def __ndEntry(index, null_default, inherited_default):
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wmio/ed436785-40fc-425e-ad3d-f9200eb1a122
return (bool(null_default) << 1 | bool(inherited_default)) << (2 * index)

def __createCimTypeQualifierSet(self, heap, propertyInfo):
def __createCimTypeQualifierSet(self, heap, propertyInfo, qualifiers=None):
propertyInfo['PropertyQualifierSet'] = b''

# CIMTYPE qualifier (mandatory)
qualifierSet = QUALIFIER_SET()
qualifier = QUALIFIER()
qualifier['QualifierName'] = DICTIONARY_REFERENCE_TO_VALUE['CIMTYPE'] | 0x80000000
qualifier['QualifierFlavor'] = 0 #WBEM_FLAVOR_FLAG_PROPAGATE_O_INSTANCE | WBEM_FLAVOR_FLAG_PROPAGATE_O_DERIVED_CLASS
qualifier['QualifierType'] = CIM_TYPE_ENUM.CIM_TYPE_STRING.value
qualifier.structure = (('QualifierValue', CIM_TYPES_REF[qualifier['QualifierType'] & (~CIM_ARRAY_FLAG)]),)

qualifierSet['Qualifier'] = qualifier.getData() # for EncodingLength calculation
cimtype_qual = QUALIFIER()
cimtype_qual['QualifierName'] = DICTIONARY_REFERENCE_TO_VALUE['CIMTYPE'] | 0x80000000
cimtype_qual['QualifierFlavor'] = 0 #WBEM_FLAVOR_FLAG_PROPAGATE_O_INSTANCE | WBEM_FLAVOR_FLAG_PROPAGATE_O_DERIVED_CLASS
cimtype_qual['QualifierType'] = CIM_TYPE_ENUM.CIM_TYPE_STRING.value
cimtype_qual.structure = (
('QualifierValue', CIM_TYPES_REF[cimtype_qual['QualifierType'] & (~CIM_ARRAY_FLAG)]),
)

# Extra qualifiers
extra_data = b''
for qname in (qualifiers or []):
q = QUALIFIER()
q['QualifierName'] = DICTIONARY_REFERENCE_TO_VALUE[qname] | 0x80000000
q['QualifierFlavor'] = 0
q['QualifierType'] = CIM_TYPE_ENUM.CIM_TYPE_BOOLEAN.value
q.structure = (
('QualifierValue', CIM_TYPES_REF[CIM_TYPE_ENUM.CIM_TYPE_BOOLEAN.value & (~CIM_ARRAY_FLAG)]),
)
q['QualifierValue'] = 0xFFFF
extra_data += q.getData()

# Assemble QUALIFIER_SET
qualifierSet['Qualifier'] = cimtype_qual.getData() + extra_data
qualifierSet['EncodingLength'] = len(qualifierSet.getData())

# now we set real value for QualifierValue
qualifier['QualifierValue'] = len(heap) + len(propertyInfo) + len(qualifierSet.getData())

# set the final qualifier to QUALIFIER_SET
qualifierSet['Qualifier'] = qualifier.getData()
cimtype_qual['QualifierValue'] = len(heap) + len(propertyInfo) + len(qualifierSet.getData())
qualifierSet['Qualifier'] = cimtype_qual.getData() + extra_data

cimTypeString = ENCODED_STRING()
cimTypeString['Character'] = CIM_TYPE_TO_NAME[propertyInfo['PropertyType']]
Expand All @@ -2471,7 +2485,8 @@ def marshalMe(self):
propRecord = properties[propName]
itemValue = getattr(self, propName)
propIsInherited = propRecord['inherited']
print("PropName %r, Value: %r" % (propName,itemValue))
if logging.getLogger().level == logging.DEBUG:
LOG.debug(f"PropName {propName!r}, Value: {itemValue!r}")

pType = propRecord['type'] & (~(CIM_ARRAY_FLAG|Inherited))
if propRecord['type'] & CIM_ARRAY_FLAG:
Expand Down Expand Up @@ -2590,7 +2605,7 @@ def marshalMe(self):

sorted_attrs = sorted(self.__new_attributes, key=lambda x:x[0])
for i, attr in enumerate(sorted_attrs):
attribute_name, attribute_type, attribute_default_value = attr
attribute_name, attribute_type, attribute_default_value, attribute_qualifiers = attr
propIndex = existingPropCount + i

# property name
Expand All @@ -2606,7 +2621,7 @@ def marshalMe(self):
propertyInfo['DeclarationOrder'] = propIndex
propertyInfo['ValueTableOffset'] = len(valueTable)
propertyInfo['ClassOfOrigin'] = 0 # TODO
qualifierSet, cimType = self.__createCimTypeQualifierSet(cHeap, propertyInfo)
qualifierSet, cimType = self.__createCimTypeQualifierSet(cHeap, propertyInfo, attribute_qualifiers)
propertyInfo['PropertyQualifierSet'] = qualifierSet
cHeap += propertyInfo.getData()
cHeap += cimType.getData()
Expand Down
6 changes: 3 additions & 3 deletions tests/SMB_RPC/test_wmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def test_IWbemServices_PutClass(self):
try:
dummyClass, _ = iWbemServices.GetObject('')
dummyClass.setClassName(className)
dummyClass.addNewAttribute(attrName, wmi.CIM_TYPE_ENUM.CIM_TYPE_STRING, attrValue)
dummyClass.addNewAttribute(attrName, wmi.CIM_TYPE_ENUM.CIM_TYPE_STRING, attrValue, qualifiers=["key", "read", "write"])

_ = iWbemServices.PutClass(dummyClass.marshalMe(), wmi.WBEM_FLAG_CREATE_ONLY)
createdClass,_ = iWbemServices.GetObject(className)
Expand All @@ -244,11 +244,11 @@ def test_IWbemServices_PutClass_update_adds_property(self):
try:
dummyClass, _ = iWbemServices.GetObject('')
dummyClass.setClassName(className)
dummyClass.addNewAttribute("Code", wmi.CIM_TYPE_ENUM.CIM_TYPE_STRING, "EN")
dummyClass.addNewAttribute("Code", wmi.CIM_TYPE_ENUM.CIM_TYPE_STRING, "EN", qualifiers=["key", "read", "write"])
iWbemServices.PutClass(dummyClass.marshalMe(), wmi.WBEM_FLAG_CREATE_ONLY)

fetchedClass, _ = iWbemServices.GetObject(className)
fetchedClass.addNewAttribute("Number", wmi.CIM_TYPE_ENUM.CIM_TYPE_UINT32, 123)
fetchedClass.addNewAttribute("Number", wmi.CIM_TYPE_ENUM.CIM_TYPE_UINT32, 123, qualifiers=["read", "write"])
iWbemServices.PutClass(fetchedClass.marshalMe(), wmi.WBEM_FLAG_UPDATE_ONLY)

roundTrip, _ = iWbemServices.GetObject(className)
Expand Down
Loading