Skip to content

Impacket wmipersist.py

Back to the category index / Back to the command index

Creates or deletes WMI event filters, consumers, and bindings to run VBScript when an event occurs.

ItemDetails
Implementationexamples/wmipersist.py
CategoryRemote execution / WMI / services
Size246 lines
DistributionInstalled as a script through scripts=examples/*.py in setup.py

Run python examples/wmipersist.py -h for the current option definitions.

Subcommands: install, remove

ArgumentDescription
target[domain/][username[:password]@]
-debugEnable debug output
-tsAdd a timestamp to each log message
-com-versionDCOM version in MAJOR_VERSION:MINOR_VERSION format, for example 5.7
-nameEvent name; required
-vbsVBS file containing the script to run; required
-filterWQL filter string that triggers the script
-timerMilliseconds before the script is triggered
-hashesNTLM hashes in LMHASH:NTHASH format
-no-passDo not prompt for a password (useful with -k)
-kUse Kerberos authentication. Look for matching credentials in the ccache file named by KRB5CCNAME; if none are valid, use those specified on the command line
-aesKeyAES key for Kerberos authentication (128 or 256 bits)
-dc-ipDomain controller IP address; if omitted, use the domain name (FQDN) from the target parameter

The tool connects to root\subscription through DCOM/WMI. install creates a named event filter, ActiveScript consumer, and binding between them, rolling back objects it has created if an operation fails. remove finds and deletes the associated objects by name.

A permanent WMI event subscription consists of three objects: an __EventFilter describing the event condition, a consumer holding the action to run, and a binding linking them. This command connects to the root\subscription namespace, creates all three with install, and finds and deletes objects linked to the same name with remove.

A filter contains a WQL event query or timer reference, while the consumer stores VBScript text. Until the binding is created, the filter and consumer are unconnected, so a failure midway may leave orphaned objects. Consider rollback in reverse creation order, and do not delete another subscription if its name collides.

A permanent subscription remains in the repository after the command process exits. Success therefore means the consumer can run whenever the trigger condition is met in the future, rather than that the script ran once. Check the filter query syntax, namespace, consumer engine availability, and references left after deletion separately.

SymbolLocationWhere to trace its responsibility
WMIPERSISTENCE64__init__(), checkError(), run()
ModuleMain names used
impacket.exampleslogger
impacket.examples.utilsparse_target
impacketversion
impacket.dcerpc.v5.dcomrtCOMVERSION, DCOMConnection
impacket.dcerpc.v5.dcomwmi
impacket.dcerpc.v5.dtypesNULL
impacket.dcerpc.v5.dcom.wmiWBEMSTATUS

Output, side effects, and required privileges

Section titled “Output, side effects, and required privileges”
  • Some operations change the target’s state. Check the target name, SID, and path before making changes.
  • On failure, use protocol status codes to determine whether name resolution, connection, authentication, service state, or permissions caused the stop.

The code depends on dcerpc.v5.dcomrt and dcom.wmi; WMIPERSISTENCE.run() handles actions. Change the lifecycle of the three objects, name collisions, and rollback together.