Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ftpserver.rb 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. # -*- coding: binary -*-
  2. module Msf
  3. require 'msf/core/exploit/tcp'
  4. ###
  5. #
  6. # This module exposes methods that may be useful to exploits that deal with
  7. # clients that speak the File Transfer Protocol (FTP).
  8. #
  9. ###
  10. module Exploit::Remote::FtpServer
  11. include Exploit::Remote::TcpServer
  12. #
  13. # Creates an instance of an FTP exploit module.
  14. #
  15. def initialize(info = {})
  16. super
  17. # Register the options that all FTP exploits may make use of.
  18. register_options(
  19. [
  20. OptPort.new('SRVPORT', [ true, "The local port to listen on.", 21 ]),
  21. OptPort.new('PASVPORT', [ false, "The local PASV data port to listen on (0 is random)", 0 ])
  22. ], Msf::Exploit::Remote::FtpServer)
  23. end
  24. # (see Msf::Exploit#setup)
  25. def setup
  26. super
  27. @state = {}
  28. end
  29. # (see TcpServer#on_client_connect)
  30. def on_client_connect(c)
  31. @state[c] = {
  32. :name => "#{c.peerhost}:#{c.peerport}",
  33. :ip => c.peerhost,
  34. :port => c.peerport,
  35. :user => nil,
  36. :pass => nil,
  37. :cwd => '/'
  38. }
  39. active_data_port_for_client(c, 20)
  40. c.put "220 FTP Server Ready\r\n"
  41. end
  42. # Dispatches client requests to command handlers.
  43. #
  44. # Handlers should be named +on_client_command_*+, ending with a
  45. # downcased FTP verb, e.g. +on_client_command_user+. If no handler
  46. # exists for the given command, returns a generic default response.
  47. #
  48. # @example Handle SYST requests
  49. # class MetasploitModule < Msf::Exploit
  50. # include Msf::Exploit::Remote::FtpServer
  51. # ...
  52. # def on_client_command_syst(cmd_conn, arg)
  53. # print_status("Responding to SYST request")
  54. # buf = build_exploit_buffer(cmd_conn)
  55. # cmd_conn.put("215 Unix Type: #{buf}\r\n")
  56. # end
  57. # end
  58. #
  59. # @param (see TcpServer#on_client_data)
  60. # @return (see TcpServer#on_client_data)
  61. def on_client_data(c)
  62. data = c.get_once
  63. return if not data
  64. cmd,arg = data.strip.split(/\s+/, 2)
  65. arg ||= ""
  66. return if not cmd
  67. # Allow per-command overrides
  68. if self.respond_to?("on_client_command_#{cmd.downcase}", true)
  69. return self.send("on_client_command_#{cmd.downcase}", c, arg)
  70. end
  71. case cmd.upcase
  72. when 'USER'
  73. @state[c][:user] = arg
  74. c.put "331 User name okay, need password...\r\n"
  75. return
  76. when 'PASS'
  77. @state[c][:pass] = arg
  78. print_status("#{@state[c][:name]} LOGIN #{@state[c][:user]} / #{@state[c][:pass]}")
  79. c.put "230 Login OK\r\n"
  80. return
  81. when 'QUIT'
  82. c.put "221 Logout\r\n"
  83. return
  84. when 'SYST'
  85. c.put "215 UNIX Type: L8\r\n"
  86. return
  87. when 'TYPE'
  88. c.put "200 Type is set\r\n"
  89. return
  90. when 'CWD'
  91. c.put "250 CWD command successful.\r\n"
  92. return
  93. when 'PWD'
  94. c.put "257 \"#{@state[c][:cwd]}\" is current directory.\r\n"
  95. return
  96. when 'SIZE'
  97. c.put "213 1\r\n"
  98. return
  99. when 'MDTM'
  100. c.put "213 #{Time.now.strftime("%Y%m%d%H%M%S")}\r\n"
  101. return
  102. when 'PORT'
  103. port = arg.split(',')[4,2]
  104. if(not port and port.length == 2)
  105. c.put("500 Illegal PORT command.\r\n")
  106. return
  107. end
  108. port = port.map{|x| x.to_i}.pack('C*').unpack('n')[0]
  109. active_data_port_for_client(c, port)
  110. c.put "200 PORT command successful.\r\n"
  111. return
  112. when 'PASV'
  113. daddr = Rex::Socket.source_address(c.peerhost)
  114. dport = passive_data_port_for_client(c)
  115. @state[c][:daddr] = daddr
  116. @state[c][:dport] = dport
  117. pasv = (daddr.split('.') + [dport].pack('n').unpack('CC')).join(',')
  118. c.put "227 Entering Passive Mode (#{pasv})\r\n"
  119. return
  120. when /^(STOR|MKD|REM|DEL|RMD)$/
  121. c.put "500 Access denied\r\n"
  122. return
  123. else
  124. # Allow per-command overrides
  125. if(self.respond_to?("on_client_unknown_command"))
  126. return self.send("on_client_unknown_command", c, cmd.upcase, arg)
  127. end
  128. print_status("#{@state[c][:name]} UNKNOWN '#{cmd} #{arg}'")
  129. c.put("500 '#{cmd} #{arg}': command not understood.\r\n")
  130. return
  131. end
  132. return
  133. end
  134. def on_client_close(c)
  135. @state.delete(c)
  136. end
  137. def passive_data_port_for_client(c)
  138. @state[c][:mode] = :passive
  139. if(not @state[c][:passive_sock])
  140. s = Rex::Socket::TcpServer.create(
  141. 'LocalHost' => '0.0.0.0',
  142. 'LocalPort' => datastore['PASVPORT'].to_i,
  143. 'Context' => { 'Msf' => framework, 'MsfExploit' => self }
  144. )
  145. dport = s.getsockname[2]
  146. @state[c][:passive_sock] = s
  147. @state[c][:passive_port] = dport
  148. add_socket(s)
  149. end
  150. @state[c][:passive_port]
  151. end
  152. def active_data_port_for_client(c,port)
  153. @state[c][:mode] = :active
  154. connector = Proc.new {
  155. host = c.peerhost.dup
  156. sock = Rex::Socket::Tcp.create(
  157. 'PeerHost' => host,
  158. 'PeerPort' => port,
  159. 'Context' => { 'Msf' => framework, 'MsfExploit' => self }
  160. )
  161. add_socket(sock)
  162. sock
  163. }
  164. @state[c][:active_connector] = connector
  165. @state[c][:active_port] = port
  166. end
  167. # Create a socket for the protocol data, either PASV or PORT,
  168. # depending on the client.
  169. #
  170. # @see http://tools.ietf.org/html/rfc3659 RFC 3659
  171. # @see http://tools.ietf.org/html/rfc959 RFC 959
  172. # @param c [Socket] Control connection socket
  173. #
  174. # @return [Socket] A connected socket for the data connection
  175. # @return [nil] on failure
  176. def establish_data_connection(c)
  177. begin
  178. Timeout.timeout(20) do
  179. if(@state[c][:mode] == :active)
  180. return @state[c][:active_connector].call()
  181. end
  182. if(@state[c][:mode] == :passive)
  183. c = @state[c][:passive_sock].accept
  184. add_socket(c)
  185. return c
  186. end
  187. end
  188. rescue ::Exception => e
  189. print_error("Failed to establish data connection: #{e.class} #{e}")
  190. end
  191. nil
  192. end
  193. end
  194. end