CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/metsvc/src/metsvc.cpp
Views: 11780
1
/* Copyright (c) 2007, Determina Inc.
2
* All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of Determina Inc. nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
* POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33
#include <windows.h>
34
35
#include "metsvc.h"
36
37
//
38
// Globals
39
//
40
41
SERVICE_STATUS status;
42
SERVICE_STATUS_HANDLE hStatus;
43
44
//
45
// Listen for incoming connections and start the Meterpreter
46
//
47
48
int start_meterpreter()
49
{
50
SOCKET sock = INVALID_SOCKET;
51
DWORD err = 0;
52
53
// Get the current module directory
54
55
char path[MAX_PATH];
56
char* p;
57
58
if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
59
err = GetLastError();
60
printf("Cannot get module file name (0x%08x)\n", err);
61
goto cleanup;
62
}
63
64
if ((p = strrchr(path, '\\')) == NULL) {
65
err = -1;
66
printf("Cannot find directory in module name %s (0x%08x)\n", path, err);
67
goto cleanup;
68
}
69
70
*p = '\0';
71
72
// Build the server filename
73
74
if (sizeof(path) - strlen(path) < sizeof(METSVC_SERVER)+1) {
75
err = -1;
76
printf("Cannot build server filename (0x%08x)\n", err);
77
goto cleanup;
78
}
79
80
strncat(path, "\\", 1);
81
strncat(path, METSVC_SERVER, sizeof(METSVC_SERVER)-1);
82
83
// Initialize Winsock
84
85
WSADATA wsa_data;
86
87
err = WSAStartup(MAKEWORD(2, 2), &wsa_data);
88
if (err != 0) {
89
printf("Cannot initialize Winsock (0x%08x)\n", err);
90
goto cleanup;
91
}
92
93
// Create socket
94
95
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
96
err = WSAGetLastError();
97
printf("Cannot create socket (0x%08x)\n", err);
98
goto cleanup;
99
}
100
101
// Bind to 0.0.0.0
102
103
struct sockaddr_in sockaddr;
104
105
sockaddr.sin_family = AF_INET;
106
sockaddr.sin_port = htons(PORT);
107
sockaddr.sin_addr.s_addr = INADDR_ANY;
108
109
if (bind(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) {
110
err = WSAGetLastError();
111
printf("Cannot bind to port %d (0x%08x)\n", PORT, err);
112
goto cleanup;
113
}
114
115
// Listen for incoming connections
116
117
if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
118
err = WSAGetLastError();
119
printf("Cannot listen for incoming connections (0x%08x)\n", err);
120
goto cleanup;
121
}
122
123
printf("Meterpreter service listening on port %d\n", PORT);
124
fflush(stdout);
125
126
// Accept incoming connections
127
128
while (TRUE) {
129
130
SOCKET conn;
131
sockaddr_in peer;
132
int peer_len = sizeof(peer);
133
134
if ((conn = accept(sock, (struct sockaddr*)&peer, &peer_len)) == INVALID_SOCKET) {
135
if ((err = WSAGetLastError()) == WSAECONNRESET)
136
continue;
137
printf("Cannot accept an incomming connection (0x%08x)\n", err);
138
goto cleanup;
139
}
140
141
printf("Received connection from %s\n",
142
inet_ntoa(peer.sin_addr));
143
fflush(stdout);
144
145
// Build the metsrv server command line
146
147
char cmd[MAX_PATH];
148
int len = _snprintf(cmd, sizeof(cmd), "\"%s\" %d", path, conn);
149
150
if (len < 0 || len == sizeof(cmd)) {
151
err = -1;
152
printf("Cannot build the metsrv server command line (0x%08x)\n", err);
153
goto cleanup;
154
}
155
156
// Start the metsrv server
157
158
STARTUPINFO startup_info;
159
PROCESS_INFORMATION process_information;
160
161
ZeroMemory(&startup_info, sizeof(startup_info));
162
startup_info.cb = sizeof(startup_info);
163
164
ZeroMemory(&process_information, sizeof(process_information));
165
166
if (CreateProcess(path, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL,
167
NULL, &startup_info, &process_information) == 0)
168
{
169
err = GetLastError();
170
printf("Cannot start the metsrv server %s (0x%08x)\n", path, err);
171
goto cleanup;
172
}
173
174
// Close our copy of the socket
175
176
closesocket(conn);
177
}
178
179
cleanup:
180
181
// Cleanup
182
183
if (sock != INVALID_SOCKET)
184
closesocket(sock);
185
186
return err;
187
}
188
189
190
//
191
// Process control requests from the Service Control Manager
192
//
193
194
VOID WINAPI ServiceCtrlHandler(DWORD fdwControl)
195
{
196
switch (fdwControl) {
197
case SERVICE_CONTROL_STOP:
198
case SERVICE_CONTROL_SHUTDOWN:
199
status.dwCurrentState = SERVICE_STOPPED;
200
break;
201
202
default:
203
break;
204
}
205
206
if (SetServiceStatus(hStatus, &status) == 0) {
207
printf("Cannot set service status (0x%08x)\n", GetLastError());
208
exit(1);
209
}
210
211
return;
212
}
213
214
215
//
216
// Main function of service
217
//
218
219
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
220
{
221
// Register the service handler
222
223
hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
224
225
if (hStatus == 0) {
226
printf("Cannot register service handler (0x%08x)\n", GetLastError());
227
exit(1);
228
}
229
230
// Initialize the service status structure
231
232
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
233
status.dwCurrentState = SERVICE_RUNNING;
234
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
235
status.dwWin32ExitCode = NO_ERROR;
236
status.dwServiceSpecificExitCode = 0;
237
status.dwCheckPoint = 0;
238
status.dwWaitHint = 0;
239
240
if (SetServiceStatus(hStatus, &status) == 0) {
241
printf("Cannot set service status (0x%08x)\n", GetLastError());
242
return;
243
}
244
245
// Start the Meterpreter
246
247
DWORD err = start_meterpreter();
248
249
if (err != 0) {
250
status.dwCurrentState = SERVICE_STOPPED;
251
status.dwWin32ExitCode = err;
252
status.dwServiceSpecificExitCode = 0;
253
254
if (SetServiceStatus(hStatus, &status) == 0) {
255
printf("Cannot set service status (0x%08x)\n", GetLastError());
256
}
257
}
258
259
return;
260
}
261
262
263
//
264
// Installs and starts the Meterpreter service
265
//
266
267
BOOL install_service()
268
{
269
SC_HANDLE hSCManager;
270
SC_HANDLE hService;
271
272
char path[MAX_PATH];
273
274
// Get the current module name
275
276
if (!GetModuleFileName(NULL, path, MAX_PATH)) {
277
printf("Cannot get module name (0x%08x)\n", GetLastError());
278
return FALSE;
279
}
280
281
// Build the service command line
282
283
char cmd[MAX_PATH];
284
int len = _snprintf(cmd, sizeof(cmd), "\"%s\" service", path);
285
286
if (len < 0 || len == sizeof(cmd)) {
287
printf("Cannot build service command line (0x%08x)\n", -1);
288
return FALSE;
289
}
290
291
// Open the service manager
292
293
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
294
295
if (hSCManager == NULL) {
296
printf("Cannot open service manager (0x%08x)\n", GetLastError());
297
return FALSE;
298
}
299
300
printf(" * Installing service %s\n", SERVICE_NAME);
301
fflush(stdout);
302
303
// Create the service
304
305
hService = CreateService(
306
hSCManager,
307
SERVICE_NAME,
308
DISPLAY_NAME,
309
SERVICE_ALL_ACCESS,
310
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
311
SERVICE_AUTO_START,
312
SERVICE_ERROR_NORMAL,
313
cmd,
314
NULL,
315
NULL,
316
NULL,
317
NULL, /* LocalSystem account */
318
NULL
319
);
320
321
if (hService == NULL) {
322
printf("Cannot create service (0x%08x)\n", GetLastError());
323
324
CloseServiceHandle(hSCManager);
325
return FALSE;
326
}
327
328
// Start the service
329
330
printf(" * Starting service\n");
331
fflush(stdout);
332
333
char* args[] = { path, "service" };
334
335
if (StartService(hService, 2, (const char**)&args) == 0) {
336
DWORD err = GetLastError();
337
338
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
339
printf("Cannot start service %s (0x%08x)\n", SERVICE_NAME, err);
340
341
CloseServiceHandle(hService);
342
CloseServiceHandle(hSCManager);
343
return FALSE;
344
}
345
}
346
347
// Cleanup
348
349
CloseServiceHandle(hService);
350
CloseServiceHandle(hSCManager);
351
352
printf("Service %s successfully installed.\n", SERVICE_NAME);
353
fflush(stdout);
354
355
return TRUE;
356
}
357
358
359
//
360
// Stops and removes the Meterpreter service
361
//
362
363
BOOL remove_service()
364
{
365
SC_HANDLE hSCManager;
366
SC_HANDLE hService;
367
SERVICE_STATUS status;
368
DWORD err;
369
370
// Open the service manager
371
372
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
373
374
if (hSCManager == NULL) {
375
printf("Cannot open service manager (0x%08x)\n", GetLastError());
376
return FALSE;
377
}
378
379
// Open the service
380
381
hService = OpenService(hSCManager, SERVICE_NAME, SERVICE_STOP | DELETE);
382
383
if (hService == NULL) {
384
printf("Cannot open service %s (0x%08x)\n", SERVICE_NAME, GetLastError());
385
386
CloseServiceHandle(hSCManager);
387
return FALSE;
388
}
389
390
// Stop the service
391
392
printf(" * Stopping service %s\n", SERVICE_NAME);
393
fflush(stdout);
394
395
if (ControlService(hService, SERVICE_CONTROL_STOP, &status) == 0) {
396
err = GetLastError();
397
398
if (err != ERROR_SERVICE_NOT_ACTIVE) {
399
printf("Cannot stop service %s (0x%08x)\n", SERVICE_NAME, err);
400
401
CloseServiceHandle(hSCManager);
402
return FALSE;
403
}
404
}
405
406
// Delete the service
407
408
printf(" * Removing service\n");
409
fflush(stdout);
410
411
if (DeleteService(hService) == 0) {
412
printf("Cannot delete service %s (0x%08x)\n", SERVICE_NAME);
413
414
CloseServiceHandle(hSCManager);
415
return FALSE;
416
}
417
418
// Cleanup
419
420
CloseServiceHandle(hService);
421
CloseServiceHandle(hSCManager);
422
423
printf("Service %s successfully removed.\n", SERVICE_NAME);
424
fflush(stdout);
425
426
return TRUE;
427
}
428
429
430
//
431
// Start the service
432
//
433
434
void start_service()
435
{
436
SERVICE_TABLE_ENTRY ServiceTable[] =
437
{
438
{ SERVICE_NAME, &ServiceMain },
439
{ NULL, NULL }
440
};
441
442
if (StartServiceCtrlDispatcher(ServiceTable) == 0) {
443
printf("Cannot start the service control dispatcher (0x%08x)\n",
444
GetLastError());
445
exit(1);
446
}
447
}
448
449
450
//
451
// Main function
452
//
453
454
int main(int argc, char *argv[])
455
{
456
if (argc == 2) {
457
458
if (strcmp(argv[1], "install-service") == 0) {
459
460
// Installs and starts the service
461
462
install_service();
463
return 0;
464
}
465
else if (strcmp(argv[1], "remove-service") == 0) {
466
467
// Stops and removes the service
468
469
remove_service();
470
return 0;
471
}
472
else if (strcmp(argv[1], "service") == 0) {
473
474
// Starts the Meterpreter as a service
475
476
start_service();
477
return 0;
478
}
479
}
480
481
// Starts the Meterpreter as a normal application
482
483
start_meterpreter();
484
485
return 0;
486
}
487
488