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,31 @@
|
|
1
|
+
module SmbRpc
|
2
|
+
class Svcctl < Rpc
|
3
|
+
|
4
|
+
class DeleteServiceReq < BinData::Record
|
5
|
+
endian :little
|
6
|
+
request :request
|
7
|
+
string :serviceHandle, :length => 20
|
8
|
+
|
9
|
+
def initialize_instance
|
10
|
+
super
|
11
|
+
serviceHandle.value = get_parameter(:handle)
|
12
|
+
request.pduHead.frag_length = self.num_bytes
|
13
|
+
request.opnum.value = 2 #RDeleteService
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class DeleteServiceRes < BinData::Record
|
18
|
+
endian :little
|
19
|
+
request :response
|
20
|
+
uint32 :windowsError
|
21
|
+
end
|
22
|
+
|
23
|
+
def deleteService()
|
24
|
+
deleteServiceReq = DeleteServiceReq.new(handle:@serviceHandle)
|
25
|
+
deleteServiceRes = @file.ioctl_send_recv(deleteServiceReq).buffer
|
26
|
+
deleteServiceRes.raise_not_error_success("deleteService")
|
27
|
+
return 0
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module SmbRpc
|
2
|
+
class Svcctl < Rpc
|
3
|
+
class EnumServicesStatusReq < BinData::Record
|
4
|
+
default_parameter :bytesNeeded => 0
|
5
|
+
endian :little
|
6
|
+
request :request
|
7
|
+
string :scHandle, :length => 20
|
8
|
+
uint32 :serviceType
|
9
|
+
uint32 :serviceState
|
10
|
+
uint32 :bufSize
|
11
|
+
uint32 :ref_id_resume, :value => 1
|
12
|
+
uint32 :resume_handle
|
13
|
+
|
14
|
+
def initialize_instance
|
15
|
+
super
|
16
|
+
scHandle.value = get_parameter(:handle)
|
17
|
+
bufSize.value = get_parameter(:bytesNeeded)
|
18
|
+
serviceType.value = get_parameter(:type)
|
19
|
+
serviceState.value = get_parameter(:state)
|
20
|
+
request.pduHead.frag_length = self.num_bytes
|
21
|
+
request.opnum.value = 14 #REnumServicesStatusW
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Service_status < BinData::Record
|
26
|
+
endian :little
|
27
|
+
uint32 :ref_id_serviceName
|
28
|
+
uint32 :ref_id_displayName
|
29
|
+
uint32 :serviceType #SERVICE_STATUS nested struct begin
|
30
|
+
uint32 :currentState #different from SmbRpc::Svcctl::SERVICE_STATE
|
31
|
+
uint32 :controlsAccepted
|
32
|
+
uint32 :win32ExitCode
|
33
|
+
uint32 :serviceSpecificExitCode
|
34
|
+
uint32 :checkPoint
|
35
|
+
uint32 :waitHint #SERVICE_STATUS nested struct ends
|
36
|
+
string :serviceName
|
37
|
+
string :displayName
|
38
|
+
end
|
39
|
+
|
40
|
+
class Enum_service_statusw < BinData::Record
|
41
|
+
array :service_status_array, :type => :service_status, :initial_length => :servicesReturned
|
42
|
+
end
|
43
|
+
|
44
|
+
class EnumServicesStatusRes < BinData::Record
|
45
|
+
endian :little
|
46
|
+
request :response
|
47
|
+
uint32 :buffLen
|
48
|
+
string :buffer, :onlyif => lambda{ buffLen > 0 }, :read_length => :buffLen
|
49
|
+
uint32 :bytesNeeded
|
50
|
+
uint32 :servicesReturned
|
51
|
+
uint32 :ref_id_resumeIndex
|
52
|
+
uint32 :resumeIndex
|
53
|
+
uint32 :windowsError
|
54
|
+
|
55
|
+
def getService
|
56
|
+
enum_service_statusw = Enum_service_statusw.new(:servicesReturned => self.servicesReturned)
|
57
|
+
enum_service_statusw.read(self.buffer)
|
58
|
+
num = self.servicesReturned * 36
|
59
|
+
serviceStr = self.buffer[num..-1 ].scan(/\w.+?\x00\x00\x00/)
|
60
|
+
len = enum_service_statusw.service_status_array.length - 1 #get service array index
|
61
|
+
len.downto(0).each do |idx| #lopp backward b/c MS thaough it was cool to add a buffer in the middle of struct :(
|
62
|
+
enum_service_statusw.service_status_array[idx].displayName = serviceStr.pop.unpack("v*").pack("C*").chop
|
63
|
+
enum_service_statusw.service_status_array[idx].serviceName = serviceStr.pop.unpack("v*").pack("C*").chop
|
64
|
+
end
|
65
|
+
return enum_service_statusw.service_status_array
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#[MS-SCMR] SC_MANAGER_ENUMERATE_SERVICE access right MUST have been granted to the caller when the RPC context handle
|
70
|
+
#to the service record was created
|
71
|
+
def enumServicesStatus(type:SVCCTL_SERVICE_TYPE["ALL"], state:SVCCTL_SERVICE_STATE["SERVICE_STATE_ALL"])
|
72
|
+
services = []
|
73
|
+
response = ""
|
74
|
+
idx = 0
|
75
|
+
loop do
|
76
|
+
enumServicesStatusReq = EnumServicesStatusReq.new(handle:@scHandle, bytesNeeded:512, type:type, state:state)
|
77
|
+
enumServicesStatusReq.resume_handle = idx
|
78
|
+
enumServicesStatusRes = @file.ioctl_send_recv(enumServicesStatusReq).buffer
|
79
|
+
response = enumServicesStatusRes
|
80
|
+
enumServicesStatusRes = EnumServicesStatusRes.read(enumServicesStatusRes)
|
81
|
+
idx = enumServicesStatusRes.resumeIndex
|
82
|
+
enumServicesStatusRes.getService.each do |i|
|
83
|
+
services << { serviceType:i.serviceType, currentState:i.currentState,
|
84
|
+
controlsAccepted:i.controlsAccepted, win32ExitCode:i.win32ExitCode,
|
85
|
+
serviceSpecificExitCode:i.serviceSpecificExitCode, checkPoint:i.checkPoint,
|
86
|
+
waitHint:i.waitHint, serviceName:i.serviceName, displayName:i.displayName
|
87
|
+
}
|
88
|
+
end
|
89
|
+
break if enumServicesStatusRes.windowsError == 0 || enumServicesStatusRes.windowsError != 234
|
90
|
+
end
|
91
|
+
response.raise_not_error_success("enumServicesStatus")
|
92
|
+
return services
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SmbRpc
|
2
|
+
class Svcctl < Rpc
|
3
|
+
|
4
|
+
class OpenScmReq < BinData::Record
|
5
|
+
endian :little
|
6
|
+
request :request
|
7
|
+
uint32 :ref_id_machine_name, :value => 1
|
8
|
+
conformantandVaryingStrings :machine_name
|
9
|
+
uint32 :databaseName
|
10
|
+
uint32 :desiredAccess
|
11
|
+
|
12
|
+
def initialize_instance
|
13
|
+
super
|
14
|
+
machine_name.str = "\\\\#{get_parameter(:serverName)}\x00".bytes.pack("v*")
|
15
|
+
desiredAccess.value = get_parameter(:accessMask)
|
16
|
+
request.pduHead.frag_length = self.num_bytes
|
17
|
+
request.opnum.value = 15 #ROpenSCManagerW
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class OpenScmRes < BinData::Record
|
22
|
+
endian :little
|
23
|
+
response :response
|
24
|
+
string :scHandle, :length => 20
|
25
|
+
uint32 :windowsError
|
26
|
+
end
|
27
|
+
|
28
|
+
def openScm(scAccessMask:)
|
29
|
+
openScmReq = OpenScmReq.new(serverName:@ip, accessMask:scAccessMask)
|
30
|
+
openScmRes = @file.ioctl_send_recv(openScmReq).buffer
|
31
|
+
openScmRes.raise_not_error_success("openScm")
|
32
|
+
openScmRes = OpenScmRes.read(openScmRes)
|
33
|
+
@scHandle = openScmRes.scHandle
|
34
|
+
return self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SmbRpc
|
2
|
+
class Svcctl < Rpc
|
3
|
+
class OpenServiceReq < BinData::Record
|
4
|
+
endian :little
|
5
|
+
request :request
|
6
|
+
string :scHandle, :length => 20
|
7
|
+
conformantandVaryingStrings :serviceName
|
8
|
+
uint32 :desiredAccess
|
9
|
+
|
10
|
+
def initialize_instance
|
11
|
+
super
|
12
|
+
scHandle.value = get_parameter(:handle)
|
13
|
+
serviceName.str = "#{get_parameter(:svcName)}\x00".bytes.pack("v*")
|
14
|
+
desiredAccess.value = get_parameter(:access)
|
15
|
+
request.pduHead.frag_length = self.num_bytes
|
16
|
+
request.opnum.value = 16 #ROpenServiceW
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class OpenServiceRes < BinData::Record
|
21
|
+
endian :little
|
22
|
+
request :request
|
23
|
+
string :serviceHandle, :length => 20
|
24
|
+
uint32 :windowsError
|
25
|
+
end
|
26
|
+
|
27
|
+
def openService(serviceName:, serviceAccessMask:)
|
28
|
+
openServiceReq = OpenServiceReq.new(svcName:serviceName, handle:@scHandle, access:serviceAccessMask)
|
29
|
+
openServiceRes = @file.ioctl_send_recv(openServiceReq).buffer
|
30
|
+
openServiceRes.raise_not_error_success("openService")
|
31
|
+
openServiceRes = OpenServiceRes.read(openServiceRes)
|
32
|
+
@serviceHandle = openServiceRes.serviceHandle
|
33
|
+
return self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
module SmbRpc
|
3
|
+
class Svcctl < Rpc
|
4
|
+
|
5
|
+
class QueryServiceConfigReq < BinData::Record
|
6
|
+
mandatory_parameter :handle
|
7
|
+
endian :little
|
8
|
+
request :request
|
9
|
+
string :serviceHandle, :length => 20
|
10
|
+
uint32 :bufSize
|
11
|
+
|
12
|
+
def initialize_instance
|
13
|
+
super
|
14
|
+
serviceHandle.value = get_parameter(:handle)
|
15
|
+
bufSize.value = get_parameter(:bytesNeeded)
|
16
|
+
request.pduHead.frag_length = self.num_bytes
|
17
|
+
request.opnum.value = 17 #RQueryServiceConfigW
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Query_service_configw < BinData::Record
|
22
|
+
endian :little
|
23
|
+
uint32 :serviceType
|
24
|
+
uint32 :startType
|
25
|
+
uint32 :errorControl
|
26
|
+
uint32 :ref_id_binaryPathName
|
27
|
+
uint32 :ref_id_loadOrderGroup
|
28
|
+
uint32 :tagId
|
29
|
+
uint32 :ref_id_dependencies
|
30
|
+
uint32 :ref_id_serviceStartName
|
31
|
+
uint32 :ref_id_displayName
|
32
|
+
conformantandVaryingStrings :binaryPathName
|
33
|
+
conformantandVaryingStrings :loadOrderGroup
|
34
|
+
conformantandVaryingStrings :dependencies
|
35
|
+
conformantandVaryingStrings :serviceStartName
|
36
|
+
conformantandVaryingStrings :displayName
|
37
|
+
end
|
38
|
+
|
39
|
+
class QueryServiceConfigRes < BinData::Record
|
40
|
+
endian :little
|
41
|
+
request :response
|
42
|
+
query_service_configw :serviceConfig
|
43
|
+
uint32 :bytesNeeded #bytes needed to return all data if function fail
|
44
|
+
uint32 :windowsError
|
45
|
+
end
|
46
|
+
|
47
|
+
def queryServiceConfig()
|
48
|
+
queryServiceConfigReq = QueryServiceConfigReq.new(handle:@serviceHandle, bytesNeeded:512)
|
49
|
+
queryServiceConfigRes = @file.ioctl_send_recv(queryServiceConfigReq).buffer
|
50
|
+
queryServiceConfigRes.raise_not_error_success("queryServiceConfig")
|
51
|
+
queryServiceConfigRes = QueryServiceConfigRes.read(queryServiceConfigRes)
|
52
|
+
config = queryServiceConfigRes.serviceConfig
|
53
|
+
return {
|
54
|
+
serviceType:config.serviceType,
|
55
|
+
startType:config.startType,
|
56
|
+
errorControl:config.errorControl,
|
57
|
+
tagId:config.tagId,
|
58
|
+
binaryPathName:config.binaryPathName.str.unpack("v*").pack("C*").chop,
|
59
|
+
loadOrderGroup:config.loadOrderGroup.str.unpack("v*").pack("C*").chop,
|
60
|
+
dependencies:config.dependencies.str.unpack("v*").pack("C*").chop,
|
61
|
+
serviceStartName:config.serviceStartName.str.unpack("v*").pack("C*").chop,
|
62
|
+
displayName:config.displayName.str.unpack("v*").pack("C*").chop
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SmbRpc
|
2
|
+
class Svcctl < Rpc
|
3
|
+
|
4
|
+
class StartServiceReq < BinData::Record
|
5
|
+
mandatory_parameter :handle
|
6
|
+
endian :little
|
7
|
+
request :request
|
8
|
+
string :serviceHandle, :length => 20
|
9
|
+
uint32 :argc
|
10
|
+
uint32 :argv
|
11
|
+
|
12
|
+
def initialize_instance
|
13
|
+
super
|
14
|
+
serviceHandle.value = get_parameter(:handle)
|
15
|
+
request.pduHead.frag_length = self.num_bytes
|
16
|
+
request.opnum.value = 19 #RStartServiceW
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class StartServiceRes < BinData::Record
|
21
|
+
endian :little
|
22
|
+
request :response
|
23
|
+
uint32 :windowsError
|
24
|
+
end
|
25
|
+
|
26
|
+
def startService()
|
27
|
+
startServiceReq = StartServiceReq.new(handle:@serviceHandle)
|
28
|
+
startServiceRes = @file.ioctl_send_recv(startServiceReq).buffer
|
29
|
+
startServiceRes.raise_not_error_success("startService")
|
30
|
+
return 0
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RubySMB
|
2
|
+
class Client
|
3
|
+
|
4
|
+
def send_recv(packet)
|
5
|
+
case packet.packet_smb_version
|
6
|
+
when 'SMB1'
|
7
|
+
packet.smb_header.uid = user_id if user_id
|
8
|
+
packet = smb1_sign(packet)
|
9
|
+
when 'SMB2'
|
10
|
+
packet = increment_smb_message_id(packet)
|
11
|
+
packet.smb2_header.session_id = session_id
|
12
|
+
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
13
|
+
packet = smb2_sign(packet)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
packet = packet
|
17
|
+
end
|
18
|
+
dispatcher.send_packet(packet)
|
19
|
+
raw_response = dispatcher.recv_packet
|
20
|
+
|
21
|
+
#fix ioctl_send_recv() raise error when receive STATUS_PENDING
|
22
|
+
#force repeat read request if server sends NtStatus STATUS_PENDING
|
23
|
+
raw_response = dispatcher.recv_packet if raw_response[8,4].unpack("V")[0] == WindowsError::NTStatus::STATUS_PENDING.value
|
24
|
+
|
25
|
+
self.sequence_counter += 1 if signing_required && !session_key.empty?
|
26
|
+
raw_response
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB2
|
3
|
+
module Dcerpc
|
4
|
+
|
5
|
+
def ioctl_send_recv(action, options={})
|
6
|
+
#update ioctl_send_recv to use the new RubySMB::SMB2::Packet::IoctlRequest2 structure and avoid `ioctl_send_recv': STATUS_BUFFER_OVERFLOW
|
7
|
+
request = set_header_fields(RubySMB::SMB2::Packet::IoctlRequest2.new(options))
|
8
|
+
request.ctl_code = 0x0011C017
|
9
|
+
request.flags.is_fsctl = 0x00000001
|
10
|
+
request.buffer = action.to_binary_s
|
11
|
+
ioctl_raw_response = @tree.client.send_recv(request)
|
12
|
+
ioctl_response = RubySMB::SMB2::Packet::IoctlResponse.read(ioctl_raw_response)
|
13
|
+
unless ioctl_response.valid?
|
14
|
+
raise RubySMB::Error::InvalidPacket.new(
|
15
|
+
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
16
|
+
expected_cmd: RubySMB::SMB2::Packet::IoctlRequest::COMMAND,
|
17
|
+
received_proto: ioctl_response.smb2_header.protocol,
|
18
|
+
received_cmd: ioctl_response.smb2_header.command
|
19
|
+
)
|
20
|
+
end
|
21
|
+
unless ioctl_response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
22
|
+
raise RubySMB::Error::UnexpectedStatusCode, ioctl_response.status_code.name
|
23
|
+
end
|
24
|
+
ioctl_response
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB2
|
3
|
+
module Packet
|
4
|
+
# An SMB2 Ioctl Request Packet as defined in
|
5
|
+
# [2.2.31 SMB2 IOCTL Request](https://msdn.microsoft.com/en-us/library/cc246545.aspx)
|
6
|
+
class IoctlRequest2 < RubySMB::GenericPacket
|
7
|
+
#copy IoctlRequest to IoctlRequest2 to change max_output_response initial_value
|
8
|
+
COMMAND = RubySMB::SMB2::Commands::IOCTL
|
9
|
+
|
10
|
+
endian :little
|
11
|
+
|
12
|
+
smb2_header :smb2_header
|
13
|
+
uint16 :structure_size, label: 'Structure Size', initial_value: 57
|
14
|
+
uint16 :reserved1, label: 'Reserved Space'
|
15
|
+
uint32 :ctl_code, label: 'Control Code'
|
16
|
+
smb2_fileid :file_id, label: 'File Id'
|
17
|
+
uint32 :input_offset, label: 'Input Offset', initial_value: -> { calc_input_offset }
|
18
|
+
uint32 :input_count, label: 'Input Count', initial_value: -> { buffer.do_num_bytes }
|
19
|
+
uint32 :max_input_response, label: 'Max Input Response'
|
20
|
+
uint32 :output_offset, label: 'Output Offset', initial_value: -> { input_offset + output_count }
|
21
|
+
uint32 :output_count, label: 'Output Count'
|
22
|
+
#change initial_value from 2014 to 0x2000 to avoid /lib/ruby_smb/smb2/dcerpc.rb:67:in `ioctl_send_recv': STATUS_BUFFER_OVERFLOW
|
23
|
+
uint32 :max_output_response, label: 'Max Output response', initial_value: 0x2000
|
24
|
+
|
25
|
+
struct :flags do
|
26
|
+
bit7 :reserved1, label: 'Reserved Space'
|
27
|
+
bit1 :is_fsctl, label: 'FSCTL not IOCTL'
|
28
|
+
|
29
|
+
bit8 :reserved2, label: 'Reserved Space'
|
30
|
+
bit8 :reserved3, label: 'Reserved Space'
|
31
|
+
bit8 :reserved4, label: 'Reserved Space'
|
32
|
+
end
|
33
|
+
|
34
|
+
uint32 :reserved2, label: 'Reserved Space'
|
35
|
+
string :buffer, label: 'Input Buffer', read_length: -> { input_count + output_count }
|
36
|
+
|
37
|
+
# Calculates the value for the input_offset field.
|
38
|
+
# If the input buffer is empty then this should be set to 0,
|
39
|
+
# otherwise it should return the absolute offset of the input buffer.
|
40
|
+
#
|
41
|
+
# @return [Integer] the value to store in #input_offset
|
42
|
+
def calc_input_offset
|
43
|
+
if input_count.zero?
|
44
|
+
0
|
45
|
+
else
|
46
|
+
buffer.abs_offset
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
def raise_not_error_success(funcName)
|
4
|
+
winError = self[-4,4].unpack("V")[0]
|
5
|
+
error = WindowsError::Win32.find_by_retval(winError)[0]
|
6
|
+
error = WindowsError::NTStatus.find_by_retval(winError)[0] if error.nil?
|
7
|
+
raise "%s Fail, WinError: %s 0x%08x"%[funcName, "UNKNOWN ERROR CODE", winError ] if error.nil?
|
8
|
+
error.value == 0? error.value : (raise "%s Fail, WinError: %s %s"%[funcName, error.name, error.description])
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|