CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/meterpreter/channels/socket_abstraction.rb
Views: 1904
1
# -*- coding: binary -*-
2
3
require 'rex/post/channel'
4
require 'rex/post/meterpreter/channel'
5
6
module Rex
7
module Post
8
module Meterpreter
9
10
###
11
#
12
# Abstraction
13
# ------
14
#
15
# This class represents a channel that is streaming. This means
16
# that sequential data is flowing in either one or both directions.
17
#
18
###
19
module SocketAbstraction
20
21
include Rex::Post::Channel::SocketAbstraction
22
23
#
24
# Simple mixin for lsock in order to help avoid a ruby interpreter issue with ::Socket.pair
25
# Instead of writing to the lsock, reading from the rsock and then writing to the channel,
26
# we use this mixin to directly write to the channel.
27
#
28
# Note: This does not work with OpenSSL as OpenSSL is implemented natively and requires a real
29
# socket to write to and we cant intercept the sockets syswrite at a native level.
30
#
31
# Note: The deadlock only seems to effect the Ruby build for cygwin.
32
#
33
module DirectChannelWrite
34
35
def syswrite(buf)
36
channel._write(buf)
37
end
38
39
attr_accessor :channel
40
end
41
42
##
43
#
44
# Constructor
45
#
46
##
47
48
#
49
# Passes the initialization information up to the base class
50
#
51
def initialize(client, cid, type, flags, packet, **_)
52
# sf: initialize_abstraction() before super() as we can get a scenario where dio_write_handler() is called
53
# with data to write to the rsock but rsock has not yet been initialized. This happens if the channel
54
# is registered (client.add_channel(self) in Channel.initialize) to a session and a COMMAND_ID_CORE_CHANNEL_WRITE
55
# request comes in before we have called self.initialize_abstraction()
56
initialize_abstraction
57
super(client, cid, type, flags, packet)
58
end
59
60
##
61
#
62
# Remote I/O handlers
63
#
64
##
65
66
#
67
# Performs a write operation on the right side of the local stream.
68
#
69
def dio_write_handler(packet, data)
70
rv = Rex::ThreadSafe.select(nil, [rsock], nil, 0.01)
71
if(rv)
72
rsock.syswrite(data)
73
return true
74
else
75
return false
76
end
77
end
78
79
#
80
# Performs a close operation on the right side of the local stream.
81
#
82
def dio_close_handler(packet)
83
rsock.close
84
85
return super(packet)
86
end
87
88
#
89
# Cleans up the stream abstraction.
90
#
91
def cleanup
92
super
93
94
cleanup_abstraction
95
end
96
97
#
98
# Wrap the _write() call in order to catch some common, but harmless Windows exceptions
99
#
100
def _write(*args)
101
begin
102
super(*args)
103
rescue ::Rex::Post::Meterpreter::RequestError => e
104
case e.code
105
when 10000 .. 10100
106
raise ::Rex::ConnectionError.new
107
end
108
end
109
end
110
111
end
112
113
end; end; end
114
115