Open MrAnde7son opened 6 years ago
Hey @MrAnde7son
Yup.. bug in the DCOM class returned by the call (in particular ENCODING UNITS). Debugging and analysis needed. Welcome to [MS-WMIO]. Probably the security descriptor has a type that is not yet supported or wrongly parsed.
Confirmed.. this is because we still don't support CIM-TYPE-OBJECT as one of the attributes received by an ExecMethod
call.
Ok.. git pull first, give it a try and play with it.. it's just the first pass.. It allows to read data.. Sending objects as part of a WMI call is still not supported (maybe you can crack it ;) ). Example code, based on yours:
import socket
import logging
from impacket.dcerpc.v5.dcomrt import DCOMConnection, NULL
from impacket.dcerpc.v5.dcom import wmi
from impacket.examples import logger
address = '10.1.1.1'
username = 'Administrator'
password = 'Password'
domain = 'contoso.com'
lmhash = ''
nthash = ''
aesKey = None
namespace = '//./root/cimv2'
HKEY_LOCAL_MACHINE = 2147483650
logger.init()
logging.getLogger().setLevel(logging.DEBUG)
try:
dcom = DCOMConnection(address, username, password, domain, lmhash, nthash, aesKey, oxidResolver=False, doKerberos=False)
iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
iWbemServices = iWbemLevel1Login.NTLMLogin(namespace, NULL, NULL)
except socket.error, e:
logging.error("Couldn't connect %s. Error: %s" % (address, str(e)))
exit(0)
try:
classObject, _ = iWbemServices.GetObject('StdRegProv')
retVals = classObject.GetSecurityDescriptor(HKEY_LOCAL_MACHINE, 'SAM\\SAM\x00')
print "ReturnValue: %d" % retVals.ReturnValue
print "Descriptor Info:"
retVals.Descriptor.printInformation()
print "Owner Info:"
retVals.Descriptor.Owner.printInformation()
print "Accessing Descriptor.Owner.SIDString: %s" % retVals.Descriptor.Owner.SIDString
except Exception, e:
logging.error(str(e))
finally:
iWbemServices.RemRelease()
dcom.disconnect()
It would be great if you can check with other source (e.g. Powershell) if the data received is right.
Awesome @asolino, Thanks!
It would be great if you can check with other source (e.g. Powershell) if the data received is right.
Confirmed with Powershell, works like charm.
I will try to implement the support for sending objects.
Updated example code, showing how to get into the CIM_ARRAY_OBJECTs:
import socket
import logging
from impacket.dcerpc.v5.dcomrt import DCOMConnection, NULL
from impacket.dcerpc.v5.dcom import wmi
from impacket.examples import logger
address = '10.1.1.1'
username = 'Administrator'
password = 'Password'
domain = 'contoso.com'
lmhash = ''
nthash = ''
aesKey = None
namespace = '//./root/cimv2'
HKEY_LOCAL_MACHINE = 2147483650
logger.init()
logging.getLogger().setLevel(logging.DEBUG)
try:
dcom = DCOMConnection(address, username, password, domain, lmhash, nthash, aesKey, oxidResolver=False, doKerberos=False)
iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
iWbemServices = iWbemLevel1Login.NTLMLogin(namespace, NULL, NULL)
except socket.error, e:
logging.error("Couldn't connect %s. Error: %s" % (address, str(e)))
exit(0)
try:
classObject, _ = iWbemServices.GetObject('StdRegProv')
retVals = classObject.GetSecurityDescriptor(HKEY_LOCAL_MACHINE, 'SOFTWARE\x00')
print "ReturnValue: %d" % retVals.ReturnValue
print "Descriptor Info:"
retVals.Descriptor.printInformation()
print "Group Info:"
retVals.Descriptor.Group.printInformation()
print "Owner Info:"
retVals.Descriptor.Owner.printInformation()
print "Accessing Descriptor.Owner.SIDString: %s" % retVals.Descriptor.Owner.SIDString
print "DACLS: "
for dacl in retVals.Descriptor.DACL:
dacl.printInformation()
dacl.Trustee.printInformation()
except Exception, e:
logging.error(str(e))
finally:
iWbemServices.RemRelease()
dcom.disconnect()
Added the same thing on my side and was going to commit :) Now I'm trying to figure out how to send objects back so I can use SetSecurityDescriptor function.
Hi @asolino , When trying to use SetSecurityDescriptor I get E_FAIL error indicating an "Unspecified error". As 'Descriptor' parameter of the function, I'm using the one I received calling GetSecurityDescriptor, and I verified that the type is right (__SecurityDescriptor). tested the same with PowerShell, and it works. Any idea what to look for? The returned error does not suggest what's wrong, and I didn't find any good reference of using this function.
Hey @MrAnde7son
Yup.. you get E_FAIL
because, when the arguments of the function your are executed are marshaled, CIM_TYPE_OBJECT
are not processed :).
This is similar to what happened when receiving objects (the unmarshal part), but, in the opposite way.
Btw.. WMI involves a lot of meta-programming. It might be good for you to understand first that for every CIM object received, a class is created on the fly with its methods and properties.
Then, when you call any WMI method (for example GetSecurityDescriptor
) this method is called that marshals all the parameters and finally calls WMI IWbemServices::ExecMethod. How to marshal/unmarshal is detailed in [MS-WMIO] and [MS-WMI].
will do, thanks!
Hey @asolino , I had some free time, so I decided to get back and make the SetSecurityDescriptor function to work. According to [MS_WMIO], I understand that in order to process CIM_TYPE_OBJECT parameter, I should use ENCODED_UNIT structure. I tried to follow the same concept of your implementation for CIM_TYPE_STRING\CIM_TYPE_DATETIME\CIM_TYPE_REFERENCE parameters, and added the following code at line:
elif pType == CIM_TYPE_ENUM.CIM_TYPE_OBJECT.value:
# For now we just pack None
#
#valueTable += '\x00'*4
valueTable += pack('<L', curHeapPtr)
instanceHeap += str(inArg.encodingUnit)
curHeapPtr = len(instanceHeap)
However, I still get the same E_FAIL error. Isn't ENCODED_UNIT is the correct form for marshaled CIM_TYPE_OBJECT parameters? Your help will be much appreciated!
I was trying to query the security descriptor of a registry key from a remote machine using WMI interface (I'm not using winreg since Remote Registry service might be off), but I get 2147749917 as the return value, indicating WBEM_E_UNEXPECTED error. Digging a little more in the wmi.py, I figured there is an error when trying to parse the security descriptor returned by the remote machine (meaning I do get a response, but it does not parses correctly). In the process of parsing it, the following error is returned:
The remote machine is running Windows 10 Pro, and it was also tested on Windows Server 2012 Datacenter. Here's the code I'm using
Any clue?
Thanks.