From 3c73c3c2f80077e42238aa113fea3846f22d10fe Mon Sep 17 00:00:00 2001 From: HD Moore Date: Fri, 14 Oct 2011 23:07:09 +0000 Subject: [PATCH] Pile of small bug fixes for the FTP server and mixin git-svn-id: file:///home/svn/framework3/trunk@13924 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/exploit/ftpserver.rb | 14 ++++++--- modules/auxiliary/server/ftp.rb | 50 +++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/lib/msf/core/exploit/ftpserver.rb b/lib/msf/core/exploit/ftpserver.rb index fe13dc2223..127f8388bc 100644 --- a/lib/msf/core/exploit/ftpserver.rb +++ b/lib/msf/core/exploit/ftpserver.rb @@ -36,7 +36,8 @@ module Exploit::Remote::FtpServer :ip => c.peerhost, :port => c.peerport, :user => nil, - :pass => nil + :pass => nil, + :cwd => '/' } active_data_port_for_client(c, 20) @@ -87,7 +88,7 @@ module Exploit::Remote::FtpServer return when 'PWD' - c.put "257 \"/\" is current directory.\r\n" + c.put "257 \"#{@state[c][:cwd]}\" is current directory.\r\n" return when 'SIZE' @@ -121,7 +122,7 @@ module Exploit::Remote::FtpServer return when /^(STOR|MKD|REM|DEL|RMD)$/ - c.put "500 Access Denied\r\n" + c.put "500 Access denied\r\n" return else @@ -157,6 +158,7 @@ module Exploit::Remote::FtpServer @state[c][:passive_sock] = s @state[c][:passive_port] = dport + add_socket(s) end @state[c][:passive_port] @@ -172,6 +174,8 @@ module Exploit::Remote::FtpServer 'PeerPort' => port, 'Context' => { 'Msf' => framework, 'MsfExploit' => self } ) + add_socket(sock) + sock } @state[c][:active_connector] = connector @@ -186,7 +190,9 @@ module Exploit::Remote::FtpServer return @state[c][:active_connector].call() end if(@state[c][:mode] == :passive) - return @state[c][:passive_sock].accept + c = @state[c][:passive_sock].accept + add_socket(c) + return c end end diff --git a/modules/auxiliary/server/ftp.rb b/modules/auxiliary/server/ftp.rb index 88e9f36a46..dd6cf51e34 100644 --- a/modules/auxiliary/server/ftp.rb +++ b/modules/auxiliary/server/ftp.rb @@ -111,16 +111,20 @@ class Metasploit3 < Msf::Auxiliary return end - pwd = datastore['FTPROOT'] + pwd = ::File.join(datastore['FTPROOT'], @state[c][:cwd]) buf = '' - Dir.new(pwd).entries.each do |ent| - path = ::File.join(datastore['FTPROOT'], ent) - if(::File.directory?(path)) - buf << "d--x--x--x 1 1 512 Jun 1 2001 #{ent}\r\n" - end - if(::File.file?(path)) - buf << "rwsx--r--r 1 1 512 Jun 1 2001 #{ent}\r\n" + + begin + Dir.new(pwd).entries.each do |ent| + path = ::File.join(datastore['FTPROOT'], ent) + if(::File.directory?(path)) + buf << "drwxr-xr-x 2 0 0 512 Jan 1 2000 #{ent}\r\n" + end + if(::File.file?(path)) + buf << "-rw-r--r-- 1 0 0 #{::File.size(path)} Jan 1 2000 #{ent}\r\n" + end end + rescue ::Exception end c.put("150 Opening ASCII mode data connection for /bin/ls\r\n") @@ -136,7 +140,7 @@ class Metasploit3 < Msf::Auxiliary return end - path = ::File.join(datastore['FTPROOT'], arg.gsub("../", '').gsub("..\\", '')) + path = ::File.join(datastore['FTPROOT'], Rex::FileUtils.clean_path(arg)) if(not ::File.exists?(path)) c.put "550 File does not exist\r\n" return @@ -145,4 +149,32 @@ class Metasploit3 < Msf::Auxiliary c.put("213 #{::File.size(path)}\r\n") end + + def on_client_command_cwd(c,arg) + + if(not @state[c][:auth]) + c.put "500 Access denied\r\n" + return + end + + upath = ::File.expand_path(datastore['FTPROOT']) + npath = ::File.expand_path(::File.join(datastore['FTPROOT'], @state[c][:cwd], arg)) + bpath = npath[upath.length, npath.length - upath.length] + + # Check for traversal above the root directory + if not (npath[0, upath.length] == upath or bpath == '') + bpath = '/' + end + + npath = ::File.expand_path(::File.join(datastore['FTPROOT'], bpath)) + if not (::File.exists?(npath) and ::File.directory?(npath)) + c.put "550 Directory does not exist\r\n" + return + end + + bpath = '/' if bpath == '' + @state[c][:cwd] = bpath + + c.put "250 CWD command successful.\r\n" + end end