Module: RubySMB::SMB1::Dcerpc

Included in:
Pipe
Defined in:
lib/ruby_smb/smb1/dcerpc.rb

Instance Method Summary collapse

Instance Method Details

#bind(options = {}) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ruby_smb/smb1/dcerpc.rb', line 14

def bind(options={})
  bind_req = RubySMB::Dcerpc::Bind.new(options)
  write(data: bind_req.to_binary_s)
  @size = 1024
  dcerpc_raw_response = read()
  begin
    dcerpc_response = RubySMB::Dcerpc::BindAck.read(dcerpc_raw_response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
  end
  unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::BIND_ACK
    raise RubySMB::Dcerpc::Error::BindError, "Not a BindAck packet"
  end

  res_list = dcerpc_response.p_result_list
  if res_list.n_results == 0 ||
     res_list.p_results[0].result != RubySMB::Dcerpc::BindAck::ACCEPTANCE
    raise RubySMB::Dcerpc::Error::BindError,
      "Bind Failed (Result: #{res_list.p_results[0].result}, Reason: #{res_list.p_results[0].reason})"
  end
  dcerpc_response
end

#net_share_enum_all(host) ⇒ Object



5
6
7
8
9
10
11
12
# File 'lib/ruby_smb/smb1/dcerpc.rb', line 5

def net_share_enum_all(host)
  bind(endpoint: RubySMB::Dcerpc::Srvsvc)

  response = request(RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: host)

  shares = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.parse_response(response.stub.to_binary_s)
  shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
end

#request(opnum, options = {}) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ruby_smb/smb1/dcerpc.rb', line 37

def request(opnum, options={})
  dcerpc_request = RubySMB::Dcerpc::Request.new({ :opnum => opnum }, options)
  request = RubySMB::SMB1::Packet::Trans::TransactNmpipeRequest.new(options)
  @tree.set_header_fields(request)
  request.set_fid(@fid)
  request.data_block.trans_data.write_data = dcerpc_request.to_binary_s

  trans_nmpipe_raw_response = @tree.client.send_recv(request)
  trans_nmpipe_response = RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse.read(trans_nmpipe_raw_response)
  unless trans_nmpipe_response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_TRANSACTION
    raise RubySMB::Error::InvalidPacket, 'Not a Trans packet'
  end
  unless trans_nmpipe_response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Error::UnexpectedStatusCode, trans_nmpipe_response.status_code.name
  end

  begin
    dcerpc_response = RubySMB::Dcerpc::Response.read(trans_nmpipe_response.data_block.trans_data.read_data)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
  end
  unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::RESPONSE
    raise RubySMB::Dcerpc::Error::InvalidPacket, "Not a Response packet"
  end
  dcerpc_response
end