Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/tcp/client.rb
19847 views
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
'SSLKeyLogFile' => opts['SSLKeyLogFile'] || sslkeylogfile,
93
'SSLCipher' => opts['SSLCipher'] || ssl_cipher,
94
'Proxies' => proxies,
95
'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i,
96
'Context' => { 'Msf' => framework, 'MsfExploit' => framework_module }
97
)
98
# enable evasions on this socket
99
set_tcp_evasions(nsock)
100
101
# Set this socket to the global socket as necessary
102
self.sock = nsock if (global)
103
104
return nsock
105
end
106
107
# Enable evasions on a given client
108
def set_tcp_evasions(socket)
109
110
if( max_send_size.to_i == 0 and send_delay.to_i == 0)
111
return
112
end
113
114
return if socket.respond_to?('evasive')
115
116
socket.extend(EvasiveTCP)
117
118
if ( max_send_size.to_i > 0)
119
socket._send_size = max_send_size
120
socket.denagle
121
socket.evasive = true
122
end
123
124
if ( send_delay.to_i > 0)
125
socket._send_delay = send_delay
126
socket.evasive = true
127
end
128
end
129
130
#
131
# Closes the TCP connection
132
#
133
def disconnect(nsock = self.sock)
134
begin
135
if (nsock)
136
nsock.shutdown
137
nsock.close
138
end
139
rescue IOError
140
end
141
142
if (nsock == sock)
143
self.sock = nil
144
end
145
146
end
147
148
##
149
#
150
# Wrappers for getters
151
#
152
##
153
154
#
155
# Returns the target host
156
#
157
def rhost
158
raise NotImplementedError
159
end
160
161
#
162
# Returns the remote port
163
#
164
def rport
165
raise NotImplementedError
166
end
167
168
#
169
# Returns the local host for outgoing connections
170
#
171
def chost
172
raise NotImplementedError
173
end
174
175
#
176
# Returns the local port for outgoing connections
177
#
178
def cport
179
raise NotImplementedError
180
end
181
182
#
183
# Returns the boolean indicating SSL
184
#
185
def ssl
186
raise NotImplementedError
187
end
188
189
#
190
# Returns the string indicating SSLVersion
191
#
192
def ssl_version
193
raise NotImplementedError
194
end
195
196
#
197
# Returns the proxy configuration
198
#
199
def proxies
200
raise NotImplementedError
201
end
202
203
attr_accessor :sock
204
205
end
206
end
207
end
208
end
209
210