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/metasploit/framework/tcp/client.rb
Views: 1904
1
module Metasploit
2
module Framework
3
module Tcp
4
5
module EvasiveTCP
6
attr_accessor :_send_size, :_send_delay, :evasive
7
8
def denagle
9
begin
10
setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
11
rescue ::Exception
12
end
13
end
14
15
def write(buf, opts={})
16
17
return super(buf, opts) if not @evasive
18
19
ret = 0
20
idx = 0
21
len = @_send_size || buf.length
22
23
while(idx < buf.length)
24
25
if(@_send_delay and idx > 0)
26
::IO.select(nil, nil, nil, @_send_delay)
27
end
28
29
pkt = buf[idx, len]
30
31
res = super(pkt, opts)
32
flush()
33
34
idx += len
35
ret += res if res
36
end
37
ret
38
end
39
end
40
41
module Client
42
43
extend ActiveSupport::Concern
44
45
# @!attribute max_send_size
46
# @return [Integer] The max size of the data to encapsulate in a single packet
47
attr_accessor :max_send_size
48
# @!attribute send_delay
49
# @return [Integer] The delay between sending packets
50
attr_accessor :send_delay
51
52
included do
53
include ActiveModel::Validations
54
validates :max_send_size,
55
presence: true,
56
numericality: {
57
only_integer: true,
58
greater_than_or_equal_to: 0
59
}
60
61
validates :send_delay,
62
presence: true,
63
numericality: {
64
only_integer: true,
65
greater_than_or_equal_to: 0
66
}
67
68
end
69
70
#
71
# Establishes a TCP connection to the specified RHOST/RPORT
72
#
73
# @see Rex::Socket::Tcp
74
# @see Rex::Socket::Tcp.create
75
def connect(global = true, opts={})
76
dossl = false
77
if(opts.has_key?('SSL'))
78
dossl = opts['SSL']
79
else
80
dossl = ssl
81
end
82
83
nsock = Rex::Socket::Tcp.create(
84
'PeerHost' => opts['RHOST'] || rhost,
85
'PeerHostname' => opts['SSLServerNameIndication'] || opts['RHOSTNAME'],
86
'PeerPort' => (opts['RPORT'] || rport).to_i,
87
'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",
88
'LocalPort' => (opts['CPORT'] || cport || 0).to_i,
89
'SSL' => dossl,
90
'SSLVersion' => opts['SSLVersion'] || ssl_version,
91
'SSLVerifyMode' => opts['SSLVerifyMode'] || ssl_verify_mode,
92
'SSLCipher' => opts['SSLCipher'] || ssl_cipher,
93
'Proxies' => proxies,
94
'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i,
95
'Context' => { 'Msf' => framework, 'MsfExploit' => framework_module }
96
)
97
# enable evasions on this socket
98
set_tcp_evasions(nsock)
99
100
# Set this socket to the global socket as necessary
101
self.sock = nsock if (global)
102
103
return nsock
104
end
105
106
# Enable evasions on a given client
107
def set_tcp_evasions(socket)
108
109
if( max_send_size.to_i == 0 and send_delay.to_i == 0)
110
return
111
end
112
113
return if socket.respond_to?('evasive')
114
115
socket.extend(EvasiveTCP)
116
117
if ( max_send_size.to_i > 0)
118
socket._send_size = max_send_size
119
socket.denagle
120
socket.evasive = true
121
end
122
123
if ( send_delay.to_i > 0)
124
socket._send_delay = send_delay
125
socket.evasive = true
126
end
127
end
128
129
#
130
# Closes the TCP connection
131
#
132
def disconnect(nsock = self.sock)
133
begin
134
if (nsock)
135
nsock.shutdown
136
nsock.close
137
end
138
rescue IOError
139
end
140
141
if (nsock == sock)
142
self.sock = nil
143
end
144
145
end
146
147
##
148
#
149
# Wrappers for getters
150
#
151
##
152
153
#
154
# Returns the target host
155
#
156
def rhost
157
raise NotImplementedError
158
end
159
160
#
161
# Returns the remote port
162
#
163
def rport
164
raise NotImplementedError
165
end
166
167
#
168
# Returns the local host for outgoing connections
169
#
170
def chost
171
raise NotImplementedError
172
end
173
174
#
175
# Returns the local port for outgoing connections
176
#
177
def cport
178
raise NotImplementedError
179
end
180
181
#
182
# Returns the boolean indicating SSL
183
#
184
def ssl
185
raise NotImplementedError
186
end
187
188
#
189
# Returns the string indicating SSLVersion
190
#
191
def ssl_version
192
raise NotImplementedError
193
end
194
195
#
196
# Returns the proxy configuration
197
#
198
def proxies
199
raise NotImplementedError
200
end
201
202
attr_accessor :sock
203
204
end
205
end
206
end
207
end
208
209