AS/400 Forensics: Retrieving your Licence Keys from disk images

Table of contents :

DISCLAIMER:

This article is a technical guide describing forensic techniques used to recover lost or forgotten licence keys from your own IBM AS/400, iSeries, or Power Systems.

It does not explain how to generate licence keys or bypass the licence validation mechanism. The original licence keys must already be present on your system’s disks.

All licence keys and system serial numbers shown below are fictitious and used solely for demonstration purposes.

Introduction

Two years ago, I acquired an IBM iSeries 9406-810 that unfortunately refused to IPL due to a severely corrupted ASP.

Several disks were missing from the ASP, while others appeared duplicated in the configuration. This inconsistent state made the system unbootable, leaving me effectively stuck. To make matters worse, I had neither saved nor printed the system’s licence keys beforehand, which ruled out a full reinstallation as a viable option.

This article explores practical techniques and technical considerations for extracting existing licence keys from IBM AS/400, iSeries, and Power Systems, based on that experience.

A simple test environment

Since my 9406-810 was non-functional, I set up a 9401-170 as a controlled test system, on which I had all the required licence keys available.

I started by wiping a 17 GB SCSI disk (Type 6718, Model 050) and installing OS/400 V5R1M0 from the original installation CDs. After the initial installation completed, I allowed the first IPL to finish but deliberately did not enter any licence keys at that stage. I then left the system running overnight while the objects decompressed. The next morning, I shut it down using PWRDWNSYS *IMMED.

I removed the disk and connected it to my SCSI station in order to create a raw dump of its contents.

Next, I reinstalled the disk in the AS/400 9401-170 and IPLed the system again. After logging in as QSECOFR, I added one of my licence keys using the ADDLICKEY command:

ADDLICKEY PRDID(5722SS1) LICTRM(V5R1M0) FEATURE(5050) SERIAL(*LOCAL) PRCGRP(*ANY) LICKEY(14776E 9C1D2B 587C57) USGLMT(*NONE) EXPDATE(*NONE) VNDDTA(*NONE)

Once the licence key was applied, I shut the system down again with PWRDWNSYS *IMMED, removed the disk a second time, and connected it back to my SCSI station to produce a second disk dump for comparison.

Differential analysis of the disk images

Now that we have two versions of the same disk, one captured before and one after adding a licence key, the next step is to compare them and identify the differences.

To do this, I tested several tools, but only a handful were capable of handling a 17 GB disk image efficiently. I eventually settled on vbindiff, which proved to be the most reliable and responsive option for working with files of this size.

vbindiff offers several features that are particularly useful for this kind of analysis. The first is the Find function (press F), which allows searching for hexadecimal data (press H) or plain text (press T). The second is the ability to toggle between EBCDIC and ASCII decoding (press C). This is especially valuable when working with IBM systems, where data is typically stored in EBCDIC.

Below is an example of the vbindiff interface highlighting a difference in a binary file after modifying a section to contain the string PODALIRIUS:

Finding an Initial Licence Key Structure (LICENCEINFO1)

On a 17 GB disk image, short strings are likely to appear many times purely by chance. To reliably identify the licence key structure, we therefore need to search for a sufficiently long and distinctive sequence of data.

The first step is to switch the decoding mode in vbindiff from ASCII to EBCDIC by pressing C, allowing the data to be displayed in a human-readable form.

Looking back at the ADDLICKEY command used earlier, we can identify several pieces of information that should be present on disk and can serve as useful search anchors:

PRDID(5722SS1)
LICTRM(V5R1M0)
FEATURE(5050)
LICKEY(14776E 9C1D2B 587C57)

The longest and most distinctive piece of data available to us is the LICKEY value, so we will start our search there. Looking for 14776E 9C1D2B 587C57 (with spaces) does not return any matches. However, searching for the same value without spaces, 14776E9C1D2B587C57 does yield a result and brings us to the following location:

06F51 DFB0:  01 18 F0 E5 1E 00 12 10  F0 F2 F3 00 00 00 01 10  ..0V.... 023.....
06F51 DFC0:  00 00 00 00 F5 F7 F2 F2  E2 E2 F1 E5 F5 D9 F1 D4  ....5722 SS1V5R1M
06F51 DFD0:  F0 F5 F0 F5 F0 00 00 00  FF FF FF FF FF FF FF FF  05050... ........
06F51 DFE0:  00 00 00 00 00 00 00 00  00 00 40 40 40 40 40 40  ........ ..      
06F51 DFF0:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40                   
06F51 E000:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40                   
06F51 E010:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40                   
06F51 E020:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40                   
06F51 E030:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40                   
06F51 E040:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 D5 00                 N.
06F51 E050:  AE 28 76 51 C5 9F 00 00  00 00 00 00 00 00 00 00  ....E... ........
06F51 E060:  F1 F4 F7 F7 F6 C5 F9 C3  F1 C4 F2 C2 F5 F8 F7 C3  14776E9C 1D2B587C
06F51 E070:  F5 F7 FF FF FF FF FF FF  FF FF 40 40 40 40 40 40  57...... ..      
06F51 E080:  40 40 40 F2 F3 F7 C2 C4  F8 C6 F9 F9 F9 AE 27 72     237BD 8F999...
06F51 E090:  3F 4E C7 00 00 AE 28 76  CE A5 C4 00 00 00 00 00  .+G..... .vD.....
06F51 E0A0:  00 00 01 10 00 1A 00 4C  00 00 00 00 00 00 00 00  .......< ........

This occurrence of the 14776E9C1D2B587C57 string appears within a structure that stores licence-related information, where we can clearly recognize the data previously entered via the ADDLICKEY command.

NameData
Product ID5722SS1
Licence TermV5R1M0
Feature5050
Licence Key14776E9C1D2B587C57
Serial237BD8F

We can highlight the different fields by color-coding sections of the structure, making the stored data easier to identify and interpret:

We will name this first structure LICENCEINFO1 in the next parts.

Finding a second licence key structure (LICENCEINFO2)

In another section of the disk image we can find another format of structure that contains the same licence information but in another form. We will name this second structure LICENCEINFO2 in the next parts.

078FE 2039:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40
078FE 2049:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 80 F5                 .5
078FE 2059:  F7 F2 F2 E2 E2 F1 E5 F5  D9 F1 D4 F0 F5 F0 F5 F0  722SS1V5 R1M05050
078FE 2069:  40 F4 F4 F7 C3 C2 C1 C1  F9 F9 F9 F0 F0 F0 F0 F0   447CBAA 99900000
078FE 2079:  D1 F9 F9 F9 F9 F9 F9 F9  40 40 40 40 40 40 40 40  J9999999         
078FE 2089:  F5 F1 C3 C1 F9 F9 F8 F7  F9 C6 C2 C4 C3 F9 C1 F3  51CA9987 9FBDC9A3
078FE 2099:  F0 F1 F0 F0 F0 F0 F0 F0  F0 F0 F0 F0 F0 F0 F0 40  01000000 0000000 
078FE 20A9:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40
078FE 20B9:  40 40 40 40 40 40 40 40  40 40 40 40 40 80 F5 F7                .57
078FE 20C9:  F2 F2 D8 E4 F1 E5 F5 D9  F1 D4 F0 F5 F0 F5 F0 40  22QU1V5R 1M05050 
078FE 20D9:  F4 F4 F7 C3 C2 C1 C1 D7  F0 F5 F0 F0 F0 F0 F0 D1  447CBAAP 0500000J
078FE 20E9:  F9 F9 F9 F9 F9 F9 F9 40  40 40 40 40 40 40 40 C5  9999999         E
078FE 20F9:  C4 F0 C1 C4 F2 F1 F0 F0  F2 F6 C2 F6 C5 F7 F7 F0  D0AD2100 26B6E770
078FE 2109:  F1 F0 F0 F0 F0 F0 F0 F0  F0 F0 F0 F0 F0 F0 40 40  10000000 000000  
078FE 2119:  40 40 40 40 40 40 40 40  40 40 40 40 40 40 40 40
078FE 2129:  40 40 40 40 40 40 40 40  40 40 40 40 00 00 00 00               ....

This match of the 14776E9C1D2B587C57 string is present in a different structure storing the smae licence information, where we recognize the data entered previously through the ADDLICKEY command:

NameData
Product ID5722SS1
Licence TermV5R1M0
Feature5050
Licence Key14776E9C1D2B587C57
Serial237BD8F

We can color the sections of this LICENCEINFO2 structure to better highlight the data stored in this structure:

Writing a Tool to Extract Licence Keys

Now that we have identified the structure and layout of licence key data within the disk image, we can automate the extraction process.

To support this, I wrote and open-sourced a tool called ExtractAS400LickeysFromDisk. This utility scans disk images from AS/400, iSeries, and Power Systems and searches for licence key structures matching the patterns and evidence described earlier in this article.

The tool, along with detailed usage instructions, is available here:

Usage

$ ExtractAS400LickeysFromDisk -h
ExtractAS400LickeysFromDisk - by Remi GASCOU (Podalirius) @ TheManticoreProject - v1.0.0

Usage: ExtractAS400LickeysFromDisk [--debug] [--chunk-size <int>] [--workers <int>] --input <string> [--output-cl <string>] [--output-json <string>]

  --debug         Debug mode. (default: false)

  Configuration:
    -c, --chunk-size <int> Chunk size in bytes for reading the file (default: 100MB). (default: 104857600)
    -w, --workers <int>    Maximum number of worker threads (default: number of files). (default: 32)

  Input:
    -i, --input <string> Path(s) to the disk image file(s) to scan. Can be specified multiple times.

  Output:
    -c, --output-cl <string>   Output file for control language ADDLICKEY commands (default: ./addlickey.cl). (default: "./addlickey.cl")
    -j, --output-json <string> Output file for JSON output (default: ./lickeys.json). (default: "./lickeys.json")

Demonstration

Here is an example of how to use the tool to extract licence keys from a raw disk image from the 17Gb disk of an IBM AS/400 9406-170:

./ExtractAS400LickeysFromDisk --input "./disk.raw"

References