@@ -11,12 +11,47 @@ module Exploit::Remote::DCERPC_SERVICES
11
11
12
12
SC_MANAGER_ALL_ACCESS = 0xF003F
13
13
SERVICE_ALL_ACCESS = 0x0F01FF
14
+
14
15
ERROR_SUCCESS = 0x0
15
16
ERROR_FILE_NOT_FOUND = 0x2
16
17
ERROR_ACCESS_DENIED = 0x5
17
18
ERROR_SERVICE_REQUEST_TIMEOUT = 0x41D
18
19
ERROR_SERVICE_EXISTS = 0x431
19
20
21
+ CLOSE_SERVICE_HANDLE = 0x00
22
+ CONTROL_SERVICE = 0x01
23
+ DELETE_SERVICE = 0x02
24
+ QUERY_SERVICE_STATUS = 0x05
25
+ CHANGE_SERVICE_CONFIG_W = 0x0b
26
+ CREATE_SERVICE_W = 0x0c
27
+ OPEN_SC_MANAGER_W = 0x0f
28
+ OPEN_SERVICE_W = 0x10
29
+ CHANGE_SERVICE_CONFIG2_W = 0x25
30
+
31
+ SERVICE_WIN32_OWN_PROCESS = 0x10
32
+ SERVICE_INTERACTIVE_PROCESS = 0x100
33
+
34
+ SERVICE_BOOT_START = 0x00
35
+ SERVICE_SYSTEM_START = 0x01
36
+ SERVICE_AUTO_START = 0x02
37
+ SERVICE_DEMAND_START = 0x03
38
+ SERVICE_DISABLED = 0x04
39
+
40
+ SERVICE_ERROR_IGNORE = 0x0
41
+
42
+ SERVICE_CONFIG_DESCRIPTION = 0x01
43
+
44
+ SERVICE_CONTROL_STOP = 0x01
45
+
46
+ # Returns the Windows Error Code in numeric format
47
+ #
48
+ # @param raw_error [String] the raw error code in binary format.
49
+ #
50
+ # @return [Integer] the Windows Error Code integer.
51
+ def error_code ( raw_error )
52
+ raw_error . unpack ( 'V' ) . first
53
+ end
54
+
20
55
# Calls OpenSCManagerW() to obtain a handle to the service control manager.
21
56
#
22
57
# @param dcerpc [Rex::Proto::DCERPC::Client] the DCERPC client to use.
@@ -33,9 +68,9 @@ def dce_openscmanagerw(dcerpc, rhost, access = SC_MANAGER_ALL_ACCESS)
33
68
NDR . long ( 0 ) +
34
69
NDR . long ( access )
35
70
begin
36
- response = dcerpc . call ( 0x0f , stubdata )
71
+ response = dcerpc . call ( OPEN_SC_MANAGER_W , stubdata )
37
72
if response
38
- scm_status = response [ 20 , 4 ] . unpack ( 'V' ) . first
73
+ scm_status = error_code ( response [ 20 , 4 ] )
39
74
if scm_status == ERROR_SUCCESS
40
75
scm_handle = response [ 0 , 20 ]
41
76
end
@@ -74,10 +109,10 @@ def dce_openscmanagerw(dcerpc, rhost, access = SC_MANAGER_ALL_ACCESS)
74
109
# error code.
75
110
def dce_createservicew ( dcerpc , scm_handle , service_name , display_name , binary_path , opts )
76
111
default_opts = {
77
- :access => SERVICE_ALL_ACCESS , # Maximum access.
78
- :type => 0x00000110 , # Interactive, own process.
79
- :start => 0x00000003 , # Start on demand.
80
- :errors => 0x00000000 , # Ignore errors.
112
+ :access => SERVICE_ALL_ACCESS ,
113
+ :type => SERVICE_WIN32_OWN_PROCESS || SERVICE_INTERACTIVE_PROCESS ,
114
+ :start => SERVICE_DEMAND_START ,
115
+ :errors => SERVICE_ERROR_IGNORE ,
81
116
:load_order_group => 0 ,
82
117
:dependencies => 0 ,
83
118
:service_start => 0 ,
@@ -105,9 +140,9 @@ def dce_createservicew(dcerpc, scm_handle, service_name, display_name, binary_pa
105
140
NDR . long ( default_opts [ :password3 ] ) +
106
141
NDR . long ( default_opts [ :password4 ] )
107
142
begin
108
- response = dcerpc . call ( 0x0c , stubdata )
143
+ response = dcerpc . call ( CREATE_SERVICE_W , stubdata )
109
144
if response
110
- svc_status = response [ 24 , 4 ] . unpack ( 'V' ) . first
145
+ svc_status = error_code ( response [ 24 , 4 ] )
111
146
112
147
if svc_status == ERROR_SUCCESS
113
148
svc_handle = response [ 4 , 20 ]
@@ -131,14 +166,14 @@ def dce_changeservicedescription(dcerpc, svc_handle, service_description)
131
166
svc_status = nil
132
167
stubdata =
133
168
svc_handle +
134
- NDR . long ( 1 ) + # dwInfoLevel = SERVICE_CONFIG_DESCRIPTION
169
+ NDR . long ( SERVICE_CONFIG_DESCRIPTION ) +
135
170
NDR . long ( 1 ) + # lpInfo -> *SERVICE_DESCRIPTION
136
171
NDR . long ( 0x0200 ) + # SERVICE_DESCRIPTION struct
137
172
NDR . long ( 0x04000200 ) +
138
173
NDR . wstring ( service_description )
139
174
begin
140
- response = dcerpc . call ( 0x25 , stubdata ) # ChangeServiceConfig2
141
- svc_status = response . unpack ( 'V' ) . first
175
+ response = dcerpc . call ( CHANGE_SERVICE_CONFIG2_W , stubdata ) # ChangeServiceConfig2
176
+ svc_status = error_code ( response )
142
177
rescue Rex ::Proto ::DCERPC ::Exceptions ::Fault => e
143
178
print_error ( "#{ peer } - Error changing service description : #{ e } " )
144
179
end
@@ -156,9 +191,9 @@ def dce_changeservicedescription(dcerpc, svc_handle, service_description)
156
191
def dce_closehandle ( dcerpc , handle )
157
192
svc_status = nil
158
193
begin
159
- response = dcerpc . call ( 0x0 , handle )
194
+ response = dcerpc . call ( CLOSE_SERVICE_HANDLE , handle )
160
195
if response
161
- svc_status = response [ 20 , 4 ] . unpack ( 'V' ) . first
196
+ svc_status = error_code ( response [ 20 , 4 ] )
162
197
end
163
198
rescue Rex ::Proto ::DCERPC ::Exceptions ::Fault => e
164
199
print_error ( "#{ peer } - Error closing service handle: #{ e } " )
@@ -180,9 +215,9 @@ def dce_openservicew(dcerpc, scm_handle, service_name, access = SERVICE_ALL_ACCE
180
215
svc_status = nil
181
216
stubdata = scm_handle + NDR . wstring ( service_name ) + NDR . long ( access )
182
217
begin
183
- response = dcerpc . call ( 0x10 , stubdata )
218
+ response = dcerpc . call ( OPEN_SERVICE_W , stubdata )
184
219
if response
185
- svc_status = response [ 20 , 4 ]
220
+ svc_status = error_code ( response [ 20 , 4 ] )
186
221
if svc_status == ERROR_SUCCESS
187
222
svc_handle = response [ 0 , 20 ]
188
223
end
@@ -211,7 +246,7 @@ def dce_startservice(dcerpc, svc_handle, magic1 = 0, magic2 = 0)
211
246
begin
212
247
response = dcerpc . call ( 0x13 , stubdata )
213
248
if response
214
- svc_status = response [ 0 , 4 ] . unpack ( 'V' ) . first
249
+ svc_status = error_code ( response )
215
250
end
216
251
rescue Rex ::Proto ::DCERPC ::Exceptions ::Fault => e
217
252
print_error ( "#{ peer } - Error starting service: #{ e } " )
@@ -228,7 +263,7 @@ def dce_startservice(dcerpc, svc_handle, magic1 = 0, magic2 = 0)
228
263
#
229
264
# @return [Integer] Windows error code
230
265
def dce_stopservice ( dcerpc , svc_handle )
231
- return dce_controlservice ( dcerpc , svc_handle , 1 )
266
+ return dce_controlservice ( dcerpc , svc_handle , SERVICE_CONTROL_STOP )
232
267
end
233
268
234
269
# Controls an existing service.
@@ -243,9 +278,9 @@ def dce_stopservice(dcerpc, svc_handle)
243
278
def dce_controlservice ( dcerpc , svc_handle , operation )
244
279
svc_status = nil
245
280
begin
246
- response = dcerpc . call ( 0x01 , svc_handle + NDR . long ( operation ) )
281
+ response = dcerpc . call ( CONTROL_SERVICE , svc_handle + NDR . long ( operation ) )
247
282
if response
248
- svc_status = dcerpc . last_response . stub_data [ 28 , 4 ] . unpack ( 'V' ) . first
283
+ svc_status = error_code ( response [ 28 , 4 ] )
249
284
end
250
285
rescue Rex ::Proto ::DCERPC ::Exceptions ::Fault => e
251
286
print_error ( "#{ peer } - Error controlling service: #{ e } " )
@@ -264,9 +299,9 @@ def dce_controlservice(dcerpc, svc_handle, operation)
264
299
def dce_deleteservice ( dcerpc , svc_handle )
265
300
svc_status = nil
266
301
begin
267
- response = dcerpc . call ( 0x02 , svc_handle )
302
+ response = dcerpc . call ( DELETE_SERVICE , svc_handle )
268
303
if response
269
- svc_status = response [ 0 , 4 ] . unpack ( 'V' ) . first
304
+ svc_status = error_code ( response )
270
305
end
271
306
rescue Rex ::Proto ::DCERPC ::Exceptions ::Fault => e
272
307
print_error ( "#{ peer } - Error deleting service: #{ e } " )
@@ -288,7 +323,7 @@ def dce_queryservice(dcerpc, svc_handle)
288
323
ret = 0
289
324
290
325
begin
291
- response = dcerpc . call ( 0x06 , svc_handle )
326
+ response = dcerpc . call ( QUERY_SERVICE_STATUS , svc_handle )
292
327
if response [ 0 , 9 ] == "\x10 \x00 \x00 \x00 \x04 \x00 \x00 \x00 \x01 "
293
328
ret = 1
294
329
elsif response [ 0 , 9 ] == "\x10 \x00 \x00 \x00 \x01 \x00 \x00 \x00 \x00 "
0 commit comments