Skip to content

Commit

Permalink
Land #11798, Add Extended Passive Mode for FTP client
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'upstream/pr/11798' into upstream-master
  • Loading branch information
busterb authored and msjenkins-r7 committed Jun 7, 2019
1 parent 2caf3a1 commit 1d9f751
Showing 1 changed file with 37 additions and 14 deletions.
51 changes: 37 additions & 14 deletions lib/msf/core/exploit/ftp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def initialize(info = {})
register_advanced_options(
[
OptInt.new('FTPTimeout', [ true, 'The number of seconds to wait for a reply from an FTP command', 16]),
OptBool.new('FTPDEBUG', [ false, 'Whether or not to print verbose debug statements', false ])
OptBool.new('FTPDEBUG', [ false, 'Whether or not to print verbose debug statements', false ]),
OptBool.new('PassiveMode', [ false, 'Set true for extended passive (EPSV) ftp mode.', false])
], Msf::Exploit::Remote::Ftp)

register_autofilter_ports([ 21, 2121])
Expand Down Expand Up @@ -67,6 +68,8 @@ def connect(global = true, verbose = nil)
# This method handles establishing datasocket for data channel
#
def data_connect(mode = nil, nsock = self.sock)
pass_mode = datastore['PassiveMode']

if mode
res = send_cmd([ 'TYPE' , mode ], true, nsock)
return nil if not res =~ /^200/
Expand All @@ -75,20 +78,40 @@ def data_connect(mode = nil, nsock = self.sock)
# force datasocket to renegotiate
self.datasocket.shutdown if self.datasocket != nil

res = send_cmd(['PASV'], true, nsock)
return nil if not res =~ /^227/

# 227 Entering Passive Mode (127,0,0,1,196,5)
if res =~ /\((\d+)\,(\d+),(\d+),(\d+),(\d+),(\d+)/
# convert port to FTP syntax
datahost = "#{$1}.#{$2}.#{$3}.#{$4}"
dataport = ($5.to_i * 256) + $6.to_i
self.datasocket = Rex::Socket::Tcp.create(
'PeerHost' => datahost,
'PeerPort' => dataport,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
# Need to be able to do both extended and normal
# passive modes. normal passive mode is default
# details of EPSV are in RFC2428
# pass_mode = true is EPSV; false is PASV
if pass_mode
res = send_cmd(['EPSV'], true, nsock)
return nil if not res =~ /^229/
# 229 Entering Passive Mode (|||port|)
if res =~ /\(\|\|\|(\d+)\|\)/
# convert port to FTP syntax
datahost = "#{rhost}"
dataport = $1.to_i
self.datasocket = Rex::Socket::Tcp.create(
'PeerHost' => datahost,
'PeerPort' => dataport,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
end
else
res = send_cmd(['PASV'], true, nsock)
return nil if not res =~ /^227/
# 227 Entering Passive Mode (127,0,0,1,196,5)
if res =~ /\((\d+)\,(\d+),(\d+),(\d+),(\d+),(\d+)/
# convert port to FTP syntax
datahost = "#{$1}.#{$2}.#{$3}.#{$4}"
dataport = ($5.to_i * 256) + $6.to_i
self.datasocket = Rex::Socket::Tcp.create(
'PeerHost' => datahost,
'PeerPort' => dataport,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
end
end

self.datasocket
end

Expand Down

0 comments on commit 1d9f751

Please sign in to comment.