mirror of
https://github.com/XiaoliChan/wmiexec-Pro.git
synced 2026-10-21 00:37:59 +08:00
18220b679f
Signed-off-by: XiaoliChan <30458572+XiaoliChan@users.noreply.github.com>
76 lines
3.5 KiB
Python
76 lines
3.5 KiB
Python
import sys
|
|
import logging
|
|
|
|
from io import StringIO
|
|
from impacket.dcerpc.v5.dtypes import NULL
|
|
from impacket.dcerpc.v5.dcom.wmi import CIM_TYPE_ENUM, WBEM_FLAG_CREATE_ONLY
|
|
|
|
|
|
class class_MethodEx():
|
|
def __init__(self, iWbemLevel1Login):
|
|
self.iWbemLevel1Login = iWbemLevel1Login
|
|
self.logger = logging.getLogger("wmiexec-pro")
|
|
|
|
def create_Class(self, ClassName, iWbemServices_Cimv2=None, iWbemServices_Subscription=None, return_iWbemServices=False):
|
|
self.logger.info(f"Creating class: {ClassName}")
|
|
|
|
if not iWbemServices_Cimv2:
|
|
iWbemServices_Cimv2 = self.iWbemLevel1Login.NTLMLogin("//./root/Cimv2", NULL, NULL)
|
|
self.iWbemLevel1Login.RemRelease()
|
|
|
|
# Login into subscription namespace (still needed by callers for script execution)
|
|
if not iWbemServices_Subscription:
|
|
iWbemServices_Subscription = self.iWbemLevel1Login.NTLMLogin("//./root/subscription", NULL, NULL)
|
|
self.iWbemLevel1Login.RemRelease()
|
|
|
|
# Use native PutClass instead of VBS workaround
|
|
newClass, _ = iWbemServices_Cimv2.GetObject('')
|
|
newClass.setClassName(ClassName)
|
|
newClass.addNewAttribute("CreationClassName", CIM_TYPE_ENUM.CIM_TYPE_STRING, "", qualifiers=["key", "read", "write"])
|
|
newClass.addNewAttribute("DebugOptions", CIM_TYPE_ENUM.CIM_TYPE_STRING, "", qualifiers=["read", "write"])
|
|
iWbemServices_Cimv2.PutClass(newClass.marshalMe(), WBEM_FLAG_CREATE_ONLY)
|
|
|
|
self.logger.info(f"Class: {ClassName} has been created!")
|
|
|
|
# Return cimv2
|
|
if return_iWbemServices:
|
|
return iWbemServices_Cimv2, iWbemServices_Subscription
|
|
|
|
def check_ClassStatus(self, ClassName, iWbemServices_Cimv2=None, iWbemServices_Subscription=None, return_iWbemServices=False):
|
|
if not iWbemServices_Cimv2:
|
|
iWbemServices_Cimv2 = self.iWbemLevel1Login.NTLMLogin("//./root/Cimv2", NULL, NULL)
|
|
self.iWbemLevel1Login.RemRelease()
|
|
|
|
try:
|
|
iWbemServices_Cimv2.GetObject(ClassName)
|
|
except Exception as e:
|
|
# GetObject on a class path raises WBEM_E_NOT_FOUND when missing;
|
|
# WBEM_E_INVALID_CLASS shows up on instance-path lookups. Accept both.
|
|
msg = str(e)
|
|
if "WBEM_E_NOT_FOUND" in msg or "WBEM_E_INVALID_CLASS" in msg:
|
|
self.logger.info(f"Class {ClassName} didn't exist, start creating class.")
|
|
iWbemServices_Cimv2, iWbemServices_Subscription = self.create_Class(ClassName, iWbemServices_Cimv2=iWbemServices_Cimv2, iWbemServices_Subscription=iWbemServices_Subscription,return_iWbemServices=True)
|
|
else:
|
|
self.logger.error(f"Unexpected error: {e!s}")
|
|
else:
|
|
self.logger.info(f"Class: {ClassName} has been created!")
|
|
|
|
# Return cimv2
|
|
if return_iWbemServices:
|
|
return iWbemServices_Cimv2, iWbemServices_Subscription
|
|
|
|
def remove_Class(self, ClassName, iWbemServices_Cimv2=None, return_iWbemServices_Cimv2=False):
|
|
if not iWbemServices_Cimv2:
|
|
iWbemServices_Cimv2 = self.iWbemLevel1Login.NTLMLogin("//./root/Cimv2", NULL, NULL)
|
|
self.iWbemLevel1Login.RemRelease()
|
|
|
|
self.logger.info(f"Remove wmi class: {ClassName}")
|
|
# Don't output verbose
|
|
current=sys.stdout
|
|
sys.stdout = StringIO()
|
|
iWbemServices_Cimv2.DeleteClass(ClassName)
|
|
sys.stdout = current
|
|
|
|
# Return cimv2
|
|
if return_iWbemServices_Cimv2:
|
|
return iWbemServices_Cimv2 |