{"record":{"id":"7016d12e362912c4","repo":"frohoff/ysoserial","slug":"unknown-transport-op-op","errorCode":null,"errorMessage":"unknown transport op ${op}","messagePattern":"unknown transport op (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"src/main/java/ysoserial/exploit/JRMPListener.java","lineNumber":237,"sourceCode":"        int op = in.read();\n\n        switch ( op ) {\n        case TransportConstants.Call:\n            // service incoming RMI call\n            doCall(in, out, payload);\n            break;\n\n        case TransportConstants.Ping:\n            // send ack for ping\n            out.writeByte(TransportConstants.PingAck);\n            break;\n\n        case TransportConstants.DGCAck:\n            UID u = UID.read(in);\n            break;\n\n        default:\n            throw new IOException(\"unknown transport op \" + op);\n        }\n\n        s.close();\n    }\n\n\n    private void doCall ( DataInputStream in, DataOutputStream out, Object payload ) throws Exception {\n        ObjectInputStream ois = new ObjectInputStream(in) {\n\n            @Override\n            protected Class<?> resolveClass ( ObjectStreamClass desc ) throws IOException, ClassNotFoundException {\n                if ( \"[Ljava.rmi.server.ObjID;\".equals(desc.getName())) {\n                    return ObjID[].class;\n                } else if (\"java.rmi.server.ObjID\".equals(desc.getName())) {\n                    return ObjID.class;\n                } else if ( \"java.rmi.server.UID\".equals(desc.getName())) {\n                    return UID.class;\n                }","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/frohoff/ysoserial/blob/218bcffcaaa904a4e392f0c15d9e2874533635a3/src/main/java/ysoserial/exploit/JRMPListener.java#L219-L255","documentation":"JRMPListener.doMessage reads the first transport operation code from an incoming JRMP stream and switches on it. Any op code that is not one of the known TransportConstants (Call, Ping, PingAck, DGCAck, etc.) throws IOException(\"unknown transport op \" + op). The listener only implements the subset of the JRMP protocol needed for the exploit.","triggerScenarios":"A client sends a JRMP protocol operation the listener does not implement — either a non-JRMP/garbage stream hitting the port, a JRMP client using ops beyond the supported subset, or a misaligned stream producing a bogus op value.","commonSituations":"Port scanners, health checks, or other services connecting to the fake JRMP listener port; a JRMP client on an incompatible Java version sending unsupported operations; probing the listener with curl/netcat.","solutions":["Ensure only the intended JRMP exploit client connects to the listener port","Check the printed op value to identify what connected; filter or ignore benign scanners","If a legitimate client is failing, verify its Java/JRMP version compatibility with the supported op subset","Compare the op code against TransportConstants to see which operation is missing and add a case if needed"],"exampleFix":"// before\ndefault:\n    throw new IOException(\"unknown transport op \" + op);\n// after\ndefault:\n    System.err.println(\"ignoring unknown transport op \" + op);\n    break;","handlingStrategy":"validation","validationCode":"// verify you are speaking to the JRMP listener with a supported client\nint op = rawStreamFirstByte;\nif (op != TransportConstants.SINGLEOP && op != TransportConstants.PING && op != TransportConstants.DGCAck) {\n    throw new IllegalArgumentException(\"unsupported JRMP op \" + op);\n}","typeGuard":null,"tryCatchPattern":"try {\n    listener.join();\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"unknown transport op\")) {\n        // log op value; treat as noise from scanners/probes\n    }\n}","preventionTips":["Dedicate the listener port to the exploit client only","Ignore/log port-scan noise instead of crashing","Keep the client's JRMP/Java version aligned with the ops the listener implements"],"tags":["java","rmi","jrmp","protocol"],"backgroundTag":"unexpected-response-shape","analyzedSha":"218bcffcaaa904a4e392f0c15d9e2874533635a3","analyzedAt":"2026-09-12T01:53:58.488Z","contentChangedAt":"2026-09-12T01:53:58.488Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}