Class: RubySMB::SMB1::Pipe
- Includes:
- Dcerpc
- Defined in:
- lib/ruby_smb/smb1/pipe.rb
Overview
Represents a pipe on the Remote server that we can perform various I/O operations on.
Constant Summary collapse
- STATUS_DISCONNECTED =
0x0001
- STATUS_LISTENING =
0x0002
- STATUS_OK =
0x0003
- STATUS_CLOSED =
0x0004
Constants included from Dcerpc
Dcerpc::DCE_C_AUTHZ_DCE, Dcerpc::DCE_C_AUTHZ_NAME, Dcerpc::MAX_RECV_FRAG, Dcerpc::MAX_XMIT_FRAG, Dcerpc::RPC_C_AUTHN_DEFAULT, Dcerpc::RPC_C_AUTHN_GSS_KERBEROS, Dcerpc::RPC_C_AUTHN_GSS_NEGOTIATE, Dcerpc::RPC_C_AUTHN_GSS_SCHANNEL, Dcerpc::RPC_C_AUTHN_LEVEL_CALL, Dcerpc::RPC_C_AUTHN_LEVEL_CONNECT, Dcerpc::RPC_C_AUTHN_LEVEL_DEFAULT, Dcerpc::RPC_C_AUTHN_LEVEL_NONE, Dcerpc::RPC_C_AUTHN_LEVEL_PKT, Dcerpc::RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY, Dcerpc::RPC_C_AUTHN_NETLOGON, Dcerpc::RPC_C_AUTHN_NONE, Dcerpc::RPC_C_AUTHN_WINNT
Instance Attribute Summary
Attributes inherited from File
#attributes, #fid, #last_access, #last_change, #last_write, #name, #size, #size_on_disk, #tree
Instance Method Summary collapse
- #bind(options = {}) ⇒ Object
-
#dcerpc_request(stub_packet, options = {}) ⇒ String
Send a DCERPC request with the provided stub packet.
-
#initialize(tree:, response:, name:) ⇒ Pipe
constructor
A new instance of Pipe.
-
#is_connected? ⇒ Boolean
True if pipe is connected, false otherwise.
-
#peek(peek_size: 0) ⇒ RubySMB::SMB1::Packet::Trans::PeekNmpipeResponse
Performs a peek operation on the named pipe.
-
#peek_available ⇒ Integer
The number of bytes available to be read from the pipe.
-
#peek_state ⇒ Integer
Pipe status.
Methods included from Dcerpc
#add_auth_verifier, #auth_provider_complete_handshake, #auth_provider_decrypt_and_verify, #auth_provider_encrypt_and_sign, #auth_provider_init, #force_set_auth_params, #get_auth_padding_length, #get_response_full_stub, #handle_integrity_privacy, #max_buffer_size=, #process_ntlm_type2, #recv_struct, #send_packet, #set_decrypted_packet, #set_encrypted_packet, #set_integrity_privacy, #set_signature_on_packet
Methods inherited from File
#append, #close, #delete, #delete_packet, #read, #read_packet, #rename, #rename_packet, #send_recv_read, #send_recv_write, #set_header_fields, #write, #write_packet
Constructor Details
#initialize(tree:, response:, name:) ⇒ Pipe
Returns a new instance of Pipe.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 16 def initialize(tree:, response:, name:) raise ArgumentError, 'No Name Provided' if name.nil? case name when 'netlogon', '\\netlogon' extend RubySMB::Dcerpc::Netlogon when 'srvsvc', '\\srvsvc' extend RubySMB::Dcerpc::Srvsvc when 'svcctl', '\\svcctl' extend RubySMB::Dcerpc::Svcctl when 'winreg', '\\winreg' extend RubySMB::Dcerpc::Winreg when 'samr', '\\samr' extend RubySMB::Dcerpc::Samr when 'wkssvc', '\\wkssvc' extend RubySMB::Dcerpc::Wkssvc when 'lsarpc', '\\lsarpc' extend RubySMB::Dcerpc::Lsarpc when 'netdfs', '\\netdfs' extend RubySMB::Dcerpc::Dfsnm when 'cert', '\\cert' extend RubySMB::Dcerpc::Icpr when 'efsrpc', '\\efsrpc' extend RubySMB::Dcerpc::Efsrpc end super(tree: tree, response: response, name: name) end |
Instance Method Details
#bind(options = {}) ⇒ Object
43 44 45 46 47 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 43 def bind(={}) @size = 1024 @ntlm_client = @tree.client.ntlm_client super end |
#dcerpc_request(stub_packet, options = {}) ⇒ String
Send a DCERPC request with the provided stub packet.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 109 def dcerpc_request(stub_packet, ={}) .merge!(endpoint: stub_packet.class.name.split('::').at(-2)) dcerpc_request = RubySMB::Dcerpc::Request.new({ opnum: stub_packet.opnum }, ) dcerpc_request.stub.read(stub_packet.to_binary_s) if [:auth_level] && [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY].include?([:auth_level]) set_integrity_privacy(dcerpc_request, auth_level: [:auth_level], auth_type: [:auth_type]) end trans_nmpipe_request = RubySMB::SMB1::Packet::Trans::TransactNmpipeRequest.new() @tree.set_header_fields(trans_nmpipe_request) trans_nmpipe_request.set_fid(@fid) trans_nmpipe_request.data_block.trans_data.write_data = dcerpc_request.to_binary_s trans_nmpipe_raw_response = @tree.client.send_recv(trans_nmpipe_request) trans_nmpipe_response = RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse.read(trans_nmpipe_raw_response) unless trans_nmpipe_response.valid? raise RubySMB::Error::InvalidPacket.new( expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID, expected_cmd: RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse::COMMAND, packet: trans_nmpipe_response ) end unless [WindowsError::NTStatus::STATUS_SUCCESS, WindowsError::NTStatus::STATUS_BUFFER_OVERFLOW].include?(trans_nmpipe_response.status_code) raise RubySMB::Error::UnexpectedStatusCode, trans_nmpipe_response.status_code end raw_data = trans_nmpipe_response.data_block.trans_data.read_data.to_binary_s if trans_nmpipe_response.status_code == WindowsError::NTStatus::STATUS_BUFFER_OVERFLOW raw_data << read(bytes: @tree.client.max_buffer_size - trans_nmpipe_response.parameter_block.data_count) dcerpc_response = dcerpc_response_from_raw_response(raw_data) unless dcerpc_response.pdu_header.pfc_flags.first_frag == 1 raise RubySMB::Dcerpc::Error::InvalidPacket, "Not the first fragment" end if [:auth_level] && [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY].include?([:auth_level]) handle_integrity_privacy(dcerpc_response, auth_level: [:auth_level], auth_type: [:auth_type]) end stub_data = dcerpc_response.stub.to_s loop do break if dcerpc_response.pdu_header.pfc_flags.last_frag == 1 raw_data = read(bytes: @tree.client.max_buffer_size) dcerpc_response = dcerpc_response_from_raw_response(raw_data) if [:auth_level] && [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY].include?([:auth_level]) handle_integrity_privacy(dcerpc_response, auth_level: [:auth_level], auth_type: [:auth_type]) end stub_data << dcerpc_response.stub.to_s end stub_data else dcerpc_response = dcerpc_response_from_raw_response(raw_data) if [:auth_level] && [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY].include?([:auth_level]) handle_integrity_privacy(dcerpc_response, auth_level: [:auth_level], auth_type: [:auth_type]) end dcerpc_response.stub.to_s end end |
#is_connected? ⇒ Boolean
Returns True if pipe is connected, false otherwise.
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 91 def is_connected? begin state = peek_state rescue RubySMB::Error::UnexpectedStatusCode => e if e. == 'STATUS_INVALID_HANDLE' return false end raise e end state == STATUS_OK end |
#peek(peek_size: 0) ⇒ RubySMB::SMB1::Packet::Trans::PeekNmpipeResponse
Performs a peek operation on the named pipe
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 55 def peek(peek_size: 0) packet = RubySMB::SMB1::Packet::Trans::PeekNmpipeRequest.new packet.fid = @fid packet.parameter_block.max_data_count = peek_size packet = @tree.set_header_fields(packet) raw_response = @tree.client.send_recv(packet) response = RubySMB::SMB1::Packet::Trans::PeekNmpipeResponse.read(raw_response) unless response.valid? raise RubySMB::Error::InvalidPacket.new( expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID, expected_cmd: RubySMB::SMB1::Packet::Trans::PeekNmpipeRequest::COMMAND, packet: response ) end unless response.status_code == WindowsError::NTStatus::STATUS_BUFFER_OVERFLOW or response.status_code == WindowsError::NTStatus::STATUS_SUCCESS raise RubySMB::Error::UnexpectedStatusCode, response.status_code end response end |
#peek_available ⇒ Integer
Returns The number of bytes available to be read from the pipe.
78 79 80 81 82 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 78 def peek_available packet = peek # Only 1 of these should be non-zero packet.data_block.trans_parameters.read_data_available or packet.data_block.trans_parameters. end |
#peek_state ⇒ Integer
Returns Pipe status.
85 86 87 88 |
# File 'lib/ruby_smb/smb1/pipe.rb', line 85 def peek_state packet = peek packet.data_block.trans_parameters.pipe_state end |