-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathRPC-Client1-Explicit-Auth-QOS.cpp
150 lines (133 loc) · 6.23 KB
/
RPC-Client1-Explicit-Auth-QOS.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// File Example1Client.cpp
#include <iostream>
#include "..\RPC-Interface1\Interface1-Explicit_h.h"
typedef enum _csENDPOINTTYPE {
TCP_IP,
NamedPipe,
LRPC
} CSENDPOINTTYPE;
int main()
{
wprintf(L"[*] Starting RPC Client!\n");
RPC_STATUS rpcStatus;
BOOL bSetBindingAuth = TRUE;
RPC_WSTR szStringBinding = NULL;
RPC_WSTR pszProtSeq;
RPC_WSTR pszTCPPort;
RPC_WSTR pszTCPHost = (RPC_WSTR)L"GSrv1.SafeAlliance.local";//(RPC_WSTR)L"Spaceland-SRV-1"; //L"WIN10-Client-2"; //reinterpret_cast<RPC_WSTR>(L"localhost");
RPC_WSTR pszHostSPN = (RPC_WSTR)L"Host/GSRV1";//(RPC_WSTR)L"Host/SPACELAND-SRV-1"; //L"Host/WIN10-CLIENT-2";//
CSENDPOINTTYPE pwsEndpointType = NamedPipe;
switch (pwsEndpointType)
{
case TCP_IP:
pszProtSeq = (RPC_WSTR)L"ncacn_ip_tcp";
pszTCPPort = (RPC_WSTR)L"8989";
break;
case NamedPipe:
pszProtSeq = (RPC_WSTR)L"ncacn_np"; //reinterpret_cast<RPC_WSTR>(L"ncacn_ip_tcp");
pszTCPPort = (RPC_WSTR)L"\\pipe\\FRPC-NP"; //reinterpret_cast<RPC_WSTR>(L"8989");
break;
case LRPC:
pszProtSeq = (RPC_WSTR)L"ncalrpc";
pszTCPPort = (RPC_WSTR)L"\\RPC Control\\FRPC-LRPC";
pszTCPHost = (RPC_WSTR)L""; // for LRPC we're always connect to a local RPC endpoint. If you add something here your might get error '1707'
pszHostSPN = (RPC_WSTR)L"LocalAdm"; // NEEDS ADJUSTMENT -- For LRPC set the user that runs the RPC endpoint here, this is a dummy value
break;
default:
pszProtSeq = (RPC_WSTR)L"";
pszTCPPort = (RPC_WSTR)L"";
break;
}
/* Set the quality of service structure */
RPC_SECURITY_QOS secQos;
secQos.Version = RPC_C_SECURITY_QOS_VERSION_1; // use version 1 as documented at https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/ns-rpcdce-rpc_security_qos
secQos.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; // set mutual authentication
secQos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; // Dynamic identitiy tracking
//secQos.ImpersonationType = RPC_C_IMP_LEVEL_ANONYMOUS; // ANONYMOUS Impersonation type, client does not provide authentication information, server can't obtain client's identity
//secQos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY; // IDENTIY Impersonation type, allowing the server to obtain the clien'ts identity and use it for example for ACL checks, but does not allow the server to impersonate the client
secQos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; // IMPERSONATE Impersonation type, allowing the server to fully impersonate the client on the server's local system but not on remote systems
//secQos.ImpersonationType = RPC_C_IMP_LEVEL_DELEGATE; // DELEGATE Impersonation type, allowing the server to fully impersonate the client on the server's local system and on remote systems
// Creates a string binding handle.
// Connection is not done here.
wprintf(L"[*] Create string binding to '%s:%s' using protocol '%s'.\n", pszTCPHost, pszTCPPort, pszProtSeq);
rpcStatus = RpcStringBindingCompose(
NULL, // UUID to bind to.
pszProtSeq, // Use TCP/IP protocol.
pszTCPHost, // TCP/IPww network address to use.
pszTCPPort, // TCP/IP port to use.
NULL, // Protocol dependent network options to use.
&szStringBinding); // String binding output.
if (rpcStatus != RPC_S_OK) {
wprintf(L"[-] RpcStringBindingCompose() failed with status: %d.\n", rpcStatus);
exit(rpcStatus);
}
handle_t hExplicitBinding = NULL;
// Create a valid binding handle from String
rpcStatus = RpcBindingFromStringBinding(
szStringBinding, // The string binding to validate.
&hExplicitBinding // Put the result in the implicit binding
); // handle defined in the IDL file.
if (rpcStatus != RPC_S_OK) {
wprintf(L"[-] RpcBindingFromStringBinding() failed with status: %d.\n", rpcStatus);
exit(rpcStatus);
}
if (bSetBindingAuth) {
wprintf(L"[*] Set Binding authentication info to SPN '%s' with an ImpersonationType of '%d'.\n", pszHostSPN, secQos.ImpersonationType);
rpcStatus = RpcBindingSetAuthInfoEx(
hExplicitBinding, // the client's binding handle
pszHostSPN, // the server's service principale name (SPN)
RPC_C_AUTHN_LEVEL_PKT, // authentication level as defined at https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-level-constants
RPC_C_AUTHN_WINNT, // using NTLM as authentication service provider as defined at https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-service-constants
NULL, // use current thread credentials
RPC_C_AUTHZ_NAME, // authorization based on the provided SPN as defined at https://docs.microsoft.com/en-us/windows/win32/com/com-authorization-constants
&secQos // Quality of Service structure
);
if (rpcStatus != RPC_S_OK) {
wprintf(L"[-] RpcBindingSetAuthInfoEx() failed with status: %d.\n", rpcStatus);
exit(rpcStatus);
}
}
printf("[*] Trying to connect...\n");
RpcTryExcept
{
// Calls the RPC function.
int retValue = Output(hExplicitBinding, "Hello From Client!");
//ret = Output(hExplicitBinding, "Triggering Remote Shutdown now...");
wprintf(L"[+] Value returned from Server is: %d\n", retValue);
//wprintf(L"[*] Trigger remote Shutdown now...\n");
//Shutdown(hExplicitBinding);
}
RpcExcept(1)
{
wprintf(L"Runtime reported exception: %d.\n", RpcExceptionCode());
}
RpcEndExcept
wprintf(L"[*] Shuting down client...\n");
// Free the memory allocated by a string.
rpcStatus = RpcStringFree(&szStringBinding);
if (rpcStatus != RPC_S_OK) {
wprintf(L"[-] RpcStringFree() failed with status: %d.\n", rpcStatus);
exit(rpcStatus);
}
// Releases binding handle resources and disconnects from the server.
rpcStatus = RpcBindingFree(&hExplicitBinding);
if (rpcStatus != RPC_S_OK) {
wprintf(L"[-] RpcBindingFree() failed with status: %d.\n", rpcStatus);
exit(rpcStatus);
}
// exit successfully
return 0;
}
/******************************************************/
/* MIDL allocate and free */
/* The runtime uses these two functions for */
/* allocating / deallocating */
/******************************************************/
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}