Unauthenticated RCE as Qsecofr via IBM i Management Central

dnet1 pts0 comments

Unauthenticated RCE as QSECOFR via IBM i Management Central - Silent Signal Techblog

Intro

We discovered and developed an exploit for a pre-authentication remote code execution vulnerability in IBM i Management Central (MGTC). The vulnerability allows an unauthenticated attacker to execute arbitrary CL commands as QSECOFR – the root-equivalent profile on IBM i – by abusing the MGTC packet protocol on port 5555.

What is Management Central?

Management Central is a Java-based system management framework that has been part of IBM i since the early 2000s. It provides centralized task scheduling, system monitoring, software distribution, and remote command execution across groups of IBM i systems. If that sounds like a powerful service to expose on the network, it is.

The service runs as two listeners. Port 5544 is an RMI-based interface that uses McRMISocketFactory – a custom RMISocketFactory – to wrap every incoming connection in a serialized McSocketBundle exchange before any RMI method calls occur. There was a deserialization vulnerability in Management Central that we discovered and reported to IBM PSIRT.<br>(CVE-2024-31879).

Port 5555 runs McSocketListener, which extends java.net.ServerSocket directly, skipping RMI and Java serialization. It accepts raw TCP connections, performs a custom binary handshake, and then creates a McPacketConnection that processes packets using McBuffer, a custom binary serialization format. This is the port and protocol we exploit in this post.

Both ports are started by the MGTC server job (QYPSJSVR) when the service is active. The CL command is STRTCPSVR SERVER(*MGTC).

IBM has been deprecating Management Central. Starting with V7R5, the service is no longer part of the operating system. On V7R4 and earlier, it is a standard component and often starts automatically. Given IBM i’s long upgrade cycles, there are plenty of V7R4 systems in production.

Finding the Pieces

The MGTC implementation ships as a set of JAR files. The client-side classes are included in IBM i Access Client Solutions (ACS): McClient.jar, McPacketClient.jar, McServer.jar, and McOSClient.jar. On the server side, the same JARs live under /QIBM/ProdData/OS400/Mgtc/ – over 40 JARs in total, plus jt400.jar from /QIBM/ProdData/OS400/jt400/lib/.

Decompiling these JARs gives us the complete picture. The MGTC protocol has no public documentation – everything described in this post was reconstructed from the bytecode using javap -p -c on the class files.

The key classes are:

Class<br>Role

McSocketListener<br>Server socket for port 5555 (extends ServerSocket)

McSocketConnection<br>Handles the binary handshake, sends/receives packets

McPacketConnection<br>Wraps McSocketConnection, manages the packet lifecycle

McBuffer<br>Custom binary serializer (not ObjectInputStream)

McPacket<br>Base class for all packets; carries routing + auth data

McClassManager<br>Maps integer classIds to Java class names

McPacketableAuthenticationData<br>Per-packet auth structure (the vulnerable component)

McPacketManager<br>Routes packets, calls authenticate() and execute()

The Class ID System

MGTC uses integer class identifiers to map packet types to Java classes. McClassManager maintains a static array of 3000 entries initialized at startup. The important ones for this exploit:

classId 3 → McCreateRequest (registers a managed object)<br>classId 16 → McStartRequest (starts/executes an activity)<br>classId 21 → McTaskRequest (task lifecycle operations)<br>classId 82 → McStatusReply (success response)<br>classId 87 → McManagedObjectReply (returns created object with assigned ID)<br>classId 99 → McSlashedAndBurnedReply (error response)<br>classId 251 → McEndpointManagedCmdData (command task data)<br>classId 252 → McManagedCmdDefinition (command definition with CL string)

When the server receives a packet, it reads the classId from the wire, looks up the corresponding class name in the array, instantiates it via reflection, and calls inflate() to deserialize the packet from a McBuffer.

The McBuffer Format

McBuffer is the serialization engine for all MGTC packet data. Instead of using the built-in Java ObjectInputStream, it uses a custom binary format with explicit type encoding. The primitives:

Method<br>Wire format

deflate(int)<br>4 bytes big-endian

deflate(long)<br>8 bytes big-endian

deflate(float)<br>4 bytes IEEE 754

deflate(byte)<br>1 byte

deflate(byte[])<br>raw bytes, no length prefix

deflate(String)<br>2-byte length (short) + UTF-16BE data

deflate(String, (short)4)<br>4-byte length (int) + UTF-16BE data

When the server creates a McBuffer for outgoing data, it calls allocate() which writes a 4-byte version float (e.g., 7.2f = 0x40e66666) as the first bytes. Incoming data is expected to start with this version header.

The Binary Handshake

The handshake on port 5555 is the first barrier. McSocketConnection.sendHandshake() and receiveHandshake() implement a multi-step exchange. The connector (client) sends a 1144-byte structure for IPv4:

Buffer (1120 bytes):

Offset 0-511: hostname...

mgtc classid management central packet class

Related Articles