smbRpc 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +11 -0
- data/examples/enumLsa.rb +44 -0
- data/examples/enumSmbPipe.rb +16 -0
- data/lib/smbRpc.rb +33 -0
- data/lib/smbRpc/epmapper.rb +13 -0
- data/lib/smbRpc/epmapper/constants.rb +28 -0
- data/lib/smbRpc/epmapper/epmLookup.rb +98 -0
- data/lib/smbRpc/lsarpc.rb +22 -0
- data/lib/smbRpc/lsarpc/close.rb +48 -0
- data/lib/smbRpc/lsarpc/constants.rb +54 -0
- data/lib/smbRpc/lsarpc/enumerateAccounts.rb +55 -0
- data/lib/smbRpc/lsarpc/enumeratePrivilegesAccount.rb +49 -0
- data/lib/smbRpc/lsarpc/lookupNames.rb +74 -0
- data/lib/smbRpc/lsarpc/lookupPrivilegeName.rb +37 -0
- data/lib/smbRpc/lsarpc/lookupSids.rb +96 -0
- data/lib/smbRpc/lsarpc/openAccount.rb +49 -0
- data/lib/smbRpc/lsarpc/openPolicy.rb +52 -0
- data/lib/smbRpc/lsarpc/queryInformationPolicy.rb +92 -0
- data/lib/smbRpc/lsarpc/querySecurityObject.rb +75 -0
- data/lib/smbRpc/rpc.rb +5 -0
- data/lib/smbRpc/rpc/connection.rb +34 -0
- data/lib/smbRpc/rpc/constants.rb +64 -0
- data/lib/smbRpc/rpc/endpoints.rb +38 -0
- data/lib/smbRpc/rpc/ndrep.rb +24 -0
- data/lib/smbRpc/rpc/pdu.rb +40 -0
- data/lib/smbRpc/samr.rb +40 -0
- data/lib/smbRpc/samr/addMemberToAlias.rb +43 -0
- data/lib/smbRpc/samr/addMemberToGroup.rb +36 -0
- data/lib/smbRpc/samr/changePasswordUser.rb +64 -0
- data/lib/smbRpc/samr/closeHandle.rb +50 -0
- data/lib/smbRpc/samr/connect.rb +46 -0
- data/lib/smbRpc/samr/constants.rb +114 -0
- data/lib/smbRpc/samr/createAliasInDomain.rb +45 -0
- data/lib/smbRpc/samr/createGroupInDomain.rb +46 -0
- data/lib/smbRpc/samr/createUserInDomain.rb +48 -0
- data/lib/smbRpc/samr/deleteAlias.rb +35 -0
- data/lib/smbRpc/samr/deleteGroup.rb +35 -0
- data/lib/smbRpc/samr/deleteUser.rb +35 -0
- data/lib/smbRpc/samr/enumerateAliasesInDomain.rb +61 -0
- data/lib/smbRpc/samr/enumerateDomainsInSamServer.rb +52 -0
- data/lib/smbRpc/samr/enumerateGroupsInDomain.rb +60 -0
- data/lib/smbRpc/samr/enumerateUsersInDomain.rb +67 -0
- data/lib/smbRpc/samr/getMembersInAlias.rb +41 -0
- data/lib/smbRpc/samr/getMembersInGroup.rb +45 -0
- data/lib/smbRpc/samr/lookupDomainInSamServer.rb +41 -0
- data/lib/smbRpc/samr/lookupIdsInDomain.rb +52 -0
- data/lib/smbRpc/samr/lookupNamesInDomain.rb +55 -0
- data/lib/smbRpc/samr/openAlias.rb +39 -0
- data/lib/smbRpc/samr/openDomain.rb +48 -0
- data/lib/smbRpc/samr/openGroup.rb +39 -0
- data/lib/smbRpc/samr/openUser.rb +39 -0
- data/lib/smbRpc/samr/queryInformationUser.rb +182 -0
- data/lib/smbRpc/samr/removeMemberFromAlias.rb +43 -0
- data/lib/smbRpc/samr/removeMemberFromGroup.rb +34 -0
- data/lib/smbRpc/samr/setInformationUser.rb +53 -0
- data/lib/smbRpc/srvsvc.rb +12 -0
- data/lib/smbRpc/srvsvc/netShareEnum.rb +104 -0
- data/lib/smbRpc/srvsvc/serverGetInfo.rb +57 -0
- data/lib/smbRpc/svcctl.rb +20 -0
- data/lib/smbRpc/svcctl/closeService.rb +48 -0
- data/lib/smbRpc/svcctl/constants.rb +88 -0
- data/lib/smbRpc/svcctl/controlService.rb +48 -0
- data/lib/smbRpc/svcctl/createService.rb +68 -0
- data/lib/smbRpc/svcctl/deleteService.rb +31 -0
- data/lib/smbRpc/svcctl/enumServicesStatus.rb +96 -0
- data/lib/smbRpc/svcctl/openScm.rb +37 -0
- data/lib/smbRpc/svcctl/openService.rb +36 -0
- data/lib/smbRpc/svcctl/queryServiceConfig.rb +67 -0
- data/lib/smbRpc/svcctl/startService.rb +35 -0
- data/lib/smbRpc/updateRuby_smb.rb +3 -0
- data/lib/smbRpc/updateRuby_smb/client.rb +29 -0
- data/lib/smbRpc/updateRuby_smb/dcerpc.rb +30 -0
- data/lib/smbRpc/updateRuby_smb/ioctl_request.rb +53 -0
- data/lib/smbRpc/updateString.rb +3 -0
- data/lib/smbRpc/updateString/raise_not_error_success.rb +11 -0
- data/lib/smbRpc/updateString/to_des_ecb_lm.rb +34 -0
- data/smbRpc.gemspec +16 -0
- metadata +148 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
module SmbRpc
|
|
2
|
+
class Srvsvc < Rpc
|
|
3
|
+
|
|
4
|
+
class Share_info_0 < BinData::Record
|
|
5
|
+
endian :little
|
|
6
|
+
uint32 :ref_id_shi0_netname, :initial_value => 1
|
|
7
|
+
uint32 :max_count
|
|
8
|
+
array :ref_id_array, :type => :uint32, :initial_length => :max_count
|
|
9
|
+
array :conformantandVaryingStringsArray, :type => :conformantandVaryingStrings, :initial_length => :max_count
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class Share_info_0_container < BinData::Record
|
|
13
|
+
endian :little
|
|
14
|
+
uint32 :entriesRead
|
|
15
|
+
choice :share_info_entries, :selection => :entriesRead do
|
|
16
|
+
uint32 0
|
|
17
|
+
share_info_0 :default
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class NetnameRemark < BinData::Record
|
|
22
|
+
endian :little
|
|
23
|
+
conformantandVaryingStrings :netname
|
|
24
|
+
conformantandVaryingStrings :remark
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Share_info_1 < BinData::Record
|
|
28
|
+
endian :little
|
|
29
|
+
uint32 :ref_id_shi1_netname, :initial_value => 1
|
|
30
|
+
uint32 :max_count
|
|
31
|
+
array :ref_id_netname, :type => :uint32, :initial_length => :max_count
|
|
32
|
+
array :shi1_type, :type => :uint32, :initial_length => :max_count
|
|
33
|
+
array :ref_id_remark, :type => :uint32, :initial_length => :max_count
|
|
34
|
+
array :netname_remark, :type => :netnameRemark, :initial_length => :max_count
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Share_info_1_container < BinData::Record
|
|
38
|
+
endian :little
|
|
39
|
+
uint32 :entriesRead, :initial_value => 0
|
|
40
|
+
choice :share_info_entries, :selection => :entriesRead do
|
|
41
|
+
uint32 0
|
|
42
|
+
share_info_1 :default
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class Share_enum_struct < BinData::Record
|
|
47
|
+
endian :little
|
|
48
|
+
uint32 :level
|
|
49
|
+
uint32 :share_enum_union_tag, :initial_value => :level
|
|
50
|
+
uint32 :ref_id_share_info_container, :initial_value => 1
|
|
51
|
+
choice :share_info_container, :selection => :level do
|
|
52
|
+
share_info_0_container 0
|
|
53
|
+
share_info_1_container 1
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class NetShareEnumReq < BinData::Record
|
|
58
|
+
endian :little
|
|
59
|
+
request :request
|
|
60
|
+
uint32 :ref_id_unc, :value => 1
|
|
61
|
+
conformantandVaryingStrings :serverName
|
|
62
|
+
share_enum_struct :share_enum_struct
|
|
63
|
+
uint32 :max_buffer, :initial_value => 0xffffffff
|
|
64
|
+
uint32 :ref_id_resume, :initial_value => 1 #unique pointer(can have null)
|
|
65
|
+
uint32 :resume_handle, :initial_value => 0
|
|
66
|
+
|
|
67
|
+
def initialize_instance
|
|
68
|
+
super
|
|
69
|
+
serverName.str = "\\\\#{get_parameter(:srvName)}\x00".bytes.pack("v*")
|
|
70
|
+
request.pduHead.frag_length = self.num_bytes
|
|
71
|
+
request.opnum.value = 15
|
|
72
|
+
share_enum_struct.level = get_parameter(:shareLevel)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class NetShareEnumRes < BinData::Record
|
|
77
|
+
endian :little
|
|
78
|
+
response :response
|
|
79
|
+
share_enum_struct :share_enum_struct
|
|
80
|
+
uint32 :totalEntries
|
|
81
|
+
uint32 :ref_id_resume
|
|
82
|
+
uint32 :resume_handle
|
|
83
|
+
uint32 :windowsError
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def netShareEnum(serverName:@ip)
|
|
87
|
+
shareEnumReq = NetShareEnumReq.new(:srvName=> serverName, shareLevel:1)
|
|
88
|
+
shareEnumRes = @file.ioctl_send_recv(shareEnumReq).buffer
|
|
89
|
+
shares = NetShareEnumRes.read(shareEnumRes)
|
|
90
|
+
out = []
|
|
91
|
+
numShare = shares.share_enum_struct.share_info_container.entriesRead
|
|
92
|
+
shi1_container = shares.share_enum_struct.share_info_container
|
|
93
|
+
numShare.times do |i|
|
|
94
|
+
type = shi1_container.share_info_entries.shi1_type[i]
|
|
95
|
+
shareName = shi1_container.share_info_entries.netname_remark[i].netname.str.unpack("v*").pack("c*").chop
|
|
96
|
+
remark = shi1_container.share_info_entries.netname_remark[i].remark.str.unpack("v*").pack("c*").chop
|
|
97
|
+
out << {shareName:shareName, remark:remark, type:type}
|
|
98
|
+
end
|
|
99
|
+
return out
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module SmbRpc
|
|
2
|
+
class Srvsvc < Rpc
|
|
3
|
+
|
|
4
|
+
class NetrServerGetInfoReq < BinData::Record
|
|
5
|
+
endian :little
|
|
6
|
+
request :request
|
|
7
|
+
uint32 :ref_id_unc, :value => 1
|
|
8
|
+
conformantandVaryingStrings :serverName
|
|
9
|
+
uint32 :level, :value => 101
|
|
10
|
+
|
|
11
|
+
def initialize_instance
|
|
12
|
+
super
|
|
13
|
+
serverName.str = "\\\\#{get_parameter(:srvName)}\x00".bytes.pack("v*")
|
|
14
|
+
request.pduHead.frag_length = self.num_bytes
|
|
15
|
+
request.opnum.value = 21 #NetrServerGetInfo
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Server_info_101 < BinData::Record
|
|
20
|
+
endian :little
|
|
21
|
+
uint32 :sv101_platform_id
|
|
22
|
+
uint32 :ref_id_name
|
|
23
|
+
uint32 :sv101_version_major
|
|
24
|
+
uint32 :sv101_version_minor
|
|
25
|
+
uint32 :serverType
|
|
26
|
+
uint32 :ref_id_comment
|
|
27
|
+
conformantandVaryingStrings :nameNdr
|
|
28
|
+
conformantandVaryingStrings :commentNdr
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class NetrServerGetInfoRes < BinData::Record
|
|
32
|
+
endian :little
|
|
33
|
+
response :response
|
|
34
|
+
uint32 :switch
|
|
35
|
+
uint32 :ref_id_infoStruct
|
|
36
|
+
server_info_101 :infoStruct
|
|
37
|
+
uint32 :windowsError
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def serverGetInfo(serverName:@ip)
|
|
41
|
+
netrServerGetInfoReq = NetrServerGetInfoReq.new(:srvName=> serverName)
|
|
42
|
+
netrServerGetInfoRes = @file.ioctl_send_recv(netrServerGetInfoReq).buffer
|
|
43
|
+
netrServerGetInfoRes.raise_not_error_success("serverGetInfo")
|
|
44
|
+
netrServerGetInfoRes = NetrServerGetInfoRes.read(netrServerGetInfoRes)
|
|
45
|
+
info = netrServerGetInfoRes.infoStruct
|
|
46
|
+
h = { :platform_id => info.sv101_platform_id,
|
|
47
|
+
:version_major => info.sv101_version_major,
|
|
48
|
+
:version_minor => info.sv101_version_minor,
|
|
49
|
+
:type => info.serverType,
|
|
50
|
+
:name => info.nameNdr.str.unpack("v*").pack("c*").chop,
|
|
51
|
+
:comment => info.commentNdr.str.unpack("v*").pack("c*").chop
|
|
52
|
+
}
|
|
53
|
+
return h
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require"smbRpc/svcctl/closeService"
|
|
2
|
+
require"smbRpc/svcctl/controlService"
|
|
3
|
+
require"smbRpc/svcctl/deleteService"
|
|
4
|
+
require"smbRpc/svcctl/openScm"
|
|
5
|
+
require"smbRpc/svcctl/queryServiceConfig"
|
|
6
|
+
require"smbRpc/svcctl/constants"
|
|
7
|
+
require"smbRpc/svcctl/createService"
|
|
8
|
+
require"smbRpc/svcctl/enumServicesStatus"
|
|
9
|
+
require"smbRpc/svcctl/openService"
|
|
10
|
+
require"smbRpc/svcctl/startService"
|
|
11
|
+
|
|
12
|
+
module SmbRpc
|
|
13
|
+
class Svcctl < Rpc
|
|
14
|
+
def initialize(**argv)
|
|
15
|
+
super(argv)
|
|
16
|
+
self.connect
|
|
17
|
+
self.bind(pipe:"svcctl")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module SmbRpc
|
|
2
|
+
class Svcctl < Rpc
|
|
3
|
+
class CloseServiceHandleReq < BinData::Record #use to close BOTH SC and service handle
|
|
4
|
+
endian :little
|
|
5
|
+
request :request
|
|
6
|
+
string :serviceHandle, :length => 20
|
|
7
|
+
|
|
8
|
+
def initialize_instance
|
|
9
|
+
super
|
|
10
|
+
serviceHandle.value = get_parameter(:handle)
|
|
11
|
+
request.pduHead.frag_length = self.num_bytes
|
|
12
|
+
request.opnum.value = 0 #RCloseServiceHandle
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class CloseServiceHandleRes < BinData::Record
|
|
17
|
+
endian :little
|
|
18
|
+
request :request
|
|
19
|
+
string :serviceHandle, :length => 20
|
|
20
|
+
uint32 :windowsError
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def closeService()
|
|
24
|
+
if !@serviceHandle.nil? #close service handle if exist
|
|
25
|
+
closeServiceHandleReq = CloseServiceHandleReq.new(handle:@serviceHandle)
|
|
26
|
+
closeServiceHandleRes = @file.ioctl_send_recv(closeServiceHandleReq).buffer
|
|
27
|
+
closeServiceHandleRes.raise_not_error_success("closeService")
|
|
28
|
+
@serviceHandle = nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def closeScm()
|
|
33
|
+
if !@scHandle.nil? #close SC handle if exist
|
|
34
|
+
closeServiceHandleReq = CloseServiceHandleReq.new(handle:@scHandle)
|
|
35
|
+
closeServiceHandleRes = @file.ioctl_send_recv(closeServiceHandleReq).buffer
|
|
36
|
+
closeServiceHandleRes.raise_not_error_success("closeScm")
|
|
37
|
+
@serviceHandle = nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def close()
|
|
42
|
+
closeService()
|
|
43
|
+
closeScm()
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
|
|
2
|
+
#[MS-SCMR] Specific access types for Service Control Manager object
|
|
3
|
+
SVCCTL_SC_ACCESS_MASK = {
|
|
4
|
+
"SC_MANAGER_LOCK" => 0x00000008, #Required to lock the SCM database.
|
|
5
|
+
"SC_MANAGER_CREATE_SERVICE" => 0x00000002, #Required for a service to be created
|
|
6
|
+
"SC_MANAGER_ENUMERATE_SERVICE" => 0x00000004, #Required to enumerate a service
|
|
7
|
+
"SC_MANAGER_CONNECT" => 0x00000001, #Required to connect to the SCM
|
|
8
|
+
"SC_MANAGER_QUERY_LOCK_STATUS" => 0x00000010, #Required to query the lock status of the SCM database
|
|
9
|
+
"SC_MANAGER_MODIFY_BOOT_CONFIG" => 0x0020, #Required to call the RNotifyBootConfigStatus method
|
|
10
|
+
#https://docs.microsoft.com/en-us/windows/desktop/Services/service-security-and-access-rights
|
|
11
|
+
"SC_MANAGER_ALL_ACCESS" => 0xF003F
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#[MS-SCMR]
|
|
15
|
+
SVCCTL_SERVICE_ACCESS_MASK = {
|
|
16
|
+
"SERVICE_ALL_ACCESS" => 0x000F01FF,
|
|
17
|
+
"SERVICE_CHANGE_CONFIG" => 0x00000002,
|
|
18
|
+
"SERVICE_ENUMERATE_DEPENDENTS" => 0x00000008,
|
|
19
|
+
"SERVICE_INTERROGATE" => 0x00000080,
|
|
20
|
+
"SERVICE_PAUSE_CONTINUE" => 0x00000040,
|
|
21
|
+
"SERVICE_QUERY_CONFIG" => 0x00000001,
|
|
22
|
+
"SERVICE_QUERY_STATUS" => 0x00000004,
|
|
23
|
+
"SERVICE_START" => 0x00000010,
|
|
24
|
+
"SERVICE_STOP" => 0x00000020,
|
|
25
|
+
"SERVICE_USER_DEFINED_CONTROL" => 0x00000100,
|
|
26
|
+
"SERVICE_SET_STATUS" => 0x00008000
|
|
27
|
+
}
|
|
28
|
+
#[MS-SCMR] This MUST be one or a combination of the following values
|
|
29
|
+
SVCCTL_SERVICE_TYPE = {
|
|
30
|
+
"SERVICE_KERNEL_DRIVER" => 0x00000001,
|
|
31
|
+
"SERVICE_FILE_SYSTEM_DRIVER" => 0x00000002,
|
|
32
|
+
"SERVICE_WIN32_OWN_PROCESS" => 0x00000010,
|
|
33
|
+
"SERVICE_WIN32_SHARE_PROCESS" => 0x00000020,
|
|
34
|
+
"ALL" => 0x33
|
|
35
|
+
}
|
|
36
|
+
#[MS-SCMR] This MUST be one of the following values
|
|
37
|
+
SVCCTL_SERVICE_STATE = {
|
|
38
|
+
"SERVICE_ACTIVE" => 0x01, #get ServiceStatus.dwCurrentState = SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, and SERVICE_PAUSED
|
|
39
|
+
"SERVICE_INACTIVE" => 0x02, #SERVICE_STOPPED
|
|
40
|
+
"SERVICE_STATE_ALL" => 0x03 #SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED, and SERVICE_STOPPED
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[MS-SCMR] Only SERVICE_WIN32_OWN_PROCESS and SERVICE_INTERACTIVE_PROCESS OR SERVICE_WIN32_SHARE_PROCESS and SERVICE_INTERACTIVE_PROCESS can be combined
|
|
44
|
+
SVCCTL_SERVICE_STATUS_SERVICE_TYPE = {
|
|
45
|
+
"SERVICE_KERNEL_DRIVER" => 0x00000001,
|
|
46
|
+
"SERVICE_FILE_SYSTEM_DRIVER" => 0x00000002,
|
|
47
|
+
"SERVICE_WIN32_OWN_PROCESS" => 0x00000010,
|
|
48
|
+
"SERVICE_WIN32_SHARE_PROCESS" => 0x00000020,
|
|
49
|
+
"SERVICE_INTERACTIVE_PROCESS" => 0x00000100,
|
|
50
|
+
"SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS" => 0x00000110,
|
|
51
|
+
"SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS" => 0x00000120
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
SVCCTL_SERVICE_STATUS_CURRENT_STATE = {
|
|
55
|
+
0x00000005 => "SERVICE_CONTINUE_PENDING",
|
|
56
|
+
0x00000006 => "SERVICE_PAUSE_PENDING",
|
|
57
|
+
0x00000007 => "SERVICE_PAUSED",
|
|
58
|
+
0x00000004 => "SERVICE_RUNNING",
|
|
59
|
+
0x00000002 => "SERVICE_START_PENDING",
|
|
60
|
+
0x00000003 => "SERVICE_STOP_PENDING",
|
|
61
|
+
0x00000001 => "SERVICE_STOPPED"
|
|
62
|
+
}
|
|
63
|
+
SVCCTL_SERVICE_START_TYPE = {
|
|
64
|
+
"SERVICE_BOOT_START" => 0x00000000,
|
|
65
|
+
"SERVICE_SYSTEM_START" => 0x00000001,
|
|
66
|
+
"SERVICE_AUTO_START" => 0x00000002,
|
|
67
|
+
"SERVICE_DEMAND_START" => 0x00000003,
|
|
68
|
+
"SERVICE_DISABLED" => 0x00000004
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
SVCCTL_SERVICE_ERROR_CONTROL = {
|
|
72
|
+
"SERVICE_ERROR_IGNORE" => 0x00000000,
|
|
73
|
+
"SERVICE_ERROR_NORMAL" => 0x00000001,
|
|
74
|
+
"SERVICE_ERROR_SEVERE" => 0x00000002,
|
|
75
|
+
"SERVICE_ERROR_CRITICAL" => 0x00000003
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
SVCCTL_SERVICE_CONTROL = {
|
|
79
|
+
"SERVICE_CONTROL_CONTINUE" => 0x00000003,
|
|
80
|
+
"SERVICE_CONTROL_INTERROGATE" => 0x00000004,
|
|
81
|
+
"SERVICE_CONTROL_NETBINDADD" => 0x00000007,
|
|
82
|
+
"SERVICE_CONTROL_NETBINDDISABLE" => 0x0000000A,
|
|
83
|
+
"SERVICE_CONTROL_NETBINDENABLE" => 0x00000009,
|
|
84
|
+
"SERVICE_CONTROL_NETBINDREMOVE" => 0x00000008,
|
|
85
|
+
"SERVICE_CONTROL_PARAMCHANGE" => 0x00000006,
|
|
86
|
+
"SERVICE_CONTROL_PAUSE" => 0x00000002,
|
|
87
|
+
"SERVICE_CONTROL_STOP" => 0x00000001,
|
|
88
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module SmbRpc
|
|
2
|
+
class Svcctl < Rpc
|
|
3
|
+
|
|
4
|
+
class ControlServiceReq < BinData::Record
|
|
5
|
+
endian :little
|
|
6
|
+
request :request
|
|
7
|
+
string :serviceHandle, :length => 20
|
|
8
|
+
uint32 :control
|
|
9
|
+
|
|
10
|
+
def initialize_instance
|
|
11
|
+
super
|
|
12
|
+
serviceHandle.value = get_parameter(:handle)
|
|
13
|
+
control.value = get_parameter(:serviceControl)
|
|
14
|
+
request.pduHead.frag_length = self.num_bytes
|
|
15
|
+
request.opnum.value = 1 #RControlService
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class ControlServiceRes < BinData::Record
|
|
20
|
+
endian :little
|
|
21
|
+
request :response
|
|
22
|
+
uint32 :serviceType
|
|
23
|
+
uint32 :currentState
|
|
24
|
+
uint32 :controlsAccepted
|
|
25
|
+
uint32 :win32ExitCode
|
|
26
|
+
uint32 :serviceSpecificExitCode
|
|
27
|
+
uint32 :checkPoint
|
|
28
|
+
uint32 :waitHint
|
|
29
|
+
uint32 :windowsError
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def controlService(control:SVCCTL_SERVICE_CONTROL["SERVICE_CONTROL_INTERROGATE"]) #default to do RQueryServiceStatus
|
|
33
|
+
controlServiceReq = ControlServiceReq.new(handle:@serviceHandle, serviceControl:control)
|
|
34
|
+
controlServiceRes = @file.ioctl_send_recv(controlServiceReq).buffer
|
|
35
|
+
controlServiceRes.raise_not_error_success("controlService")
|
|
36
|
+
controlServiceRes = ControlServiceRes.read(controlServiceRes)
|
|
37
|
+
return {
|
|
38
|
+
serviceType:controlServiceRes.serviceType, currentState:controlServiceRes.currentState,
|
|
39
|
+
controlsAccepted:controlServiceRes.controlsAccepted,
|
|
40
|
+
win32ExitCode:controlServiceRes.win32ExitCode,
|
|
41
|
+
serviceSpecificExitCode:controlServiceRes.serviceSpecificExitCode,
|
|
42
|
+
checkPoint:controlServiceRes.checkPoint,
|
|
43
|
+
waitHint:controlServiceRes.waitHint
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module SmbRpc
|
|
2
|
+
class Svcctl < Rpc
|
|
3
|
+
class CreateServiceReq < BinData::Record
|
|
4
|
+
endian :little
|
|
5
|
+
request :request
|
|
6
|
+
string :scHandle, :length => 20
|
|
7
|
+
conformantandVaryingStrings :serviceName
|
|
8
|
+
uint32 :ref_id_displayName, :value => 1, :onlyif => lambda { displayLen > 0 }
|
|
9
|
+
choice :displayName, :selection => lambda { displayLen } do
|
|
10
|
+
conformantandVaryingStrings :default
|
|
11
|
+
uint32 0
|
|
12
|
+
end
|
|
13
|
+
uint32 :desiredAccess
|
|
14
|
+
uint32 :serviceType
|
|
15
|
+
uint32 :startType
|
|
16
|
+
uint32 :errorControl
|
|
17
|
+
conformantandVaryingStrings :binaryPathName
|
|
18
|
+
uint32 :loadOrderGroup #might implement this, tagId, and dependencies later
|
|
19
|
+
uint32 :tagId
|
|
20
|
+
uint32 :dependencies
|
|
21
|
+
uint32 :dependSize
|
|
22
|
+
uint32 :serviceStartName #not going to implement this cause ncacn_np may require password encryption
|
|
23
|
+
uint32 :password #and default service account is LocalSystem anyway
|
|
24
|
+
uint32 :pwSize
|
|
25
|
+
|
|
26
|
+
def initialize_instance
|
|
27
|
+
super
|
|
28
|
+
scHandle.value = get_parameter(:handle)
|
|
29
|
+
serviceName.str = "#{get_parameter(:name)}\x00".bytes.pack("v*")
|
|
30
|
+
displayName.str = "#{get_parameter(:display)}\x00".bytes.pack("v*") if displayLen > 0 #if display not empty
|
|
31
|
+
binaryPathName.str = "#{get_parameter(:path)}\x00".bytes.pack("v*")
|
|
32
|
+
desiredAccess.value = get_parameter(:access)
|
|
33
|
+
serviceType.value = get_parameter(:type)
|
|
34
|
+
startType.value = get_parameter(:start)
|
|
35
|
+
errorControl.value = get_parameter(:error)
|
|
36
|
+
request.pduHead.frag_length = self.num_bytes
|
|
37
|
+
request.opnum.value = 12 #RCreateServiceW
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def displayLen #helper method to get displayname length
|
|
41
|
+
get_parameter(:display).bytesize
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class CreateServiceRes < BinData::Record
|
|
46
|
+
endian :little
|
|
47
|
+
request :response
|
|
48
|
+
uint32 :tagId
|
|
49
|
+
string :serviceHandle, :length => 20
|
|
50
|
+
uint32 :windowsError
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def createService(serviceName:, displayName:"", binaryPathName:,
|
|
54
|
+
desiredAccess:SVCCTL_SERVICE_ACCESS_MASK["SERVICE_ALL_ACCESS"],
|
|
55
|
+
serviceType:SVCCTL_SERVICE_STATUS_SERVICE_TYPE["SERVICE_WIN32_OWN_PROCESS"],
|
|
56
|
+
startType:SVCCTL_SERVICE_START_TYPE["SERVICE_DEMAND_START"],
|
|
57
|
+
errorControl:SVCCTL_SERVICE_ERROR_CONTROL["SERVICE_ERROR_NORMAL"])
|
|
58
|
+
createServiceReq = CreateServiceReq.new(handle:@scHandle, name:serviceName, display:displayName, path:binaryPathName,
|
|
59
|
+
access:desiredAccess, type:serviceType, start:startType, error:errorControl)
|
|
60
|
+
createServiceRes = @file.ioctl_send_recv(createServiceReq).buffer
|
|
61
|
+
createServiceRes.raise_not_error_success("createService")
|
|
62
|
+
createServiceRes = CreateServiceRes.read(createServiceRes)
|
|
63
|
+
@serviceHandle = createServiceRes.serviceHandle
|
|
64
|
+
return self
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end
|